126 lines
5.1 KiB
Markdown
126 lines
5.1 KiB
Markdown
# Phase 10: UX & Interaction - Discussion Log
|
|
|
|
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
|
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
|
|
|
**Date:** 2026-06-14
|
|
**Phase:** 10-UX & Interaction
|
|
**Areas discussed:** Toast position & style, EmptyState illustration approach, AppIcon migration strategy, BreadcrumbBar data source
|
|
|
|
---
|
|
|
|
## Toast Position & Style
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Bottom-right | Most common for document/admin apps. Out of the way of the sidebar and header; stacks upward from the corner. | ✓ |
|
|
| Top-right | Closer to the header. More prominent but overlaps with navigation area. | |
|
|
| Bottom-center | Prominent, symmetrical. Common in mobile-first apps. | |
|
|
|
|
**User's choice:** Bottom-right (Recommended)
|
|
**Notes:** None
|
|
|
|
---
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Colored left border + icon | Thin left accent bar (green/red/amber/blue) + small inline icon. Clean, readable, works with light backgrounds. | ✓ |
|
|
| Colored icon only | White background, type shown only by icon color. More minimal. | |
|
|
| Tinted background | Soft background fill per type. Higher contrast but can feel heavy. | |
|
|
|
|
**User's choice:** Colored left border + icon (Recommended)
|
|
|
|
---
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| `<Teleport to="body">` | ToastContainer.vue teleported to document body. Avoids z-index and overflow issues. | ✓ |
|
|
| Fixed in AppLayout.vue | ToastContainer placed as a fixed div at end of AppLayout. Simpler but can be clipped by parent overflow contexts. | |
|
|
|
|
**User's choice:** `<Teleport to="body">` (Recommended)
|
|
|
|
---
|
|
|
|
## EmptyState Illustration Approach
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Per-context icon from existing Heroicons set | Each context gets its own icon from the same Heroicons-style set already in the app. Simple, consistent, no new assets. | ✓ |
|
|
| Distinct headline + subtext only | One generic icon for all contexts; distinctness via copy alone. | |
|
|
| Custom illustrations | Hand-drawn or SVG illustrations per context. Most visually distinct but requires new assets. | |
|
|
|
|
**User's choice:** Per-context icon from existing Heroicons set (Recommended)
|
|
|
|
---
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Explicit props (icon, headline, subtext) | Maximum flexibility, no hidden variant map. | ✓ |
|
|
| Variant string | EmptyState.vue maintains internal config map. Less repeated markup at call sites. | |
|
|
|
|
**User's choice:** Explicit props (Recommended)
|
|
|
|
---
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Named slot for CTA | EmptyState renders icon+headline+subtext via props; optional #cta slot for action buttons. | ✓ |
|
|
| CTA as props (label + handler) | EmptyState accepts cta-label and cta-action props. Simple but limited. | |
|
|
| No CTA support | Display-only; parent places any CTA above or below. | |
|
|
|
|
**User's choice:** Named slot for CTA (Recommended)
|
|
|
|
---
|
|
|
|
## AppIcon Migration Strategy
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Centralize existing SVG paths as-is | Extract inline SVG paths into name→path map in AppIcon.vue. No new dependency. | ✓ |
|
|
| Install @heroicons/vue | Replace all inline SVGs with imports from @heroicons/vue. Adds ~35 kB dependency. | |
|
|
|
|
**User's choice:** Centralize existing SVG paths as-is (Recommended)
|
|
|
|
---
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Outline only | All existing inline SVGs are stroke style. No variant prop needed. | ✓ |
|
|
| Outline + solid via variant prop | Adds complexity for a future use case. | |
|
|
|
|
**User's choice:** Outline only (Recommended)
|
|
|
|
---
|
|
|
|
## BreadcrumbBar Data Source
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Props from each view | Every view computes its own segments array and passes as prop. Extends existing StorageBrowser pattern. | ✓ |
|
|
| Route meta config | Each route declares a breadcrumb meta field; BreadcrumbBar reads route.matched. Dynamic paths still need store data so meta alone can't cover all cases. | |
|
|
|
|
**User's choice:** Props from each view (Recommended)
|
|
|
|
---
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Emit navigate event with segment index; last segment plain text | Parent handles navigation. Consistent with existing breadcrumb-navigate pattern. Decoupled from Vue Router. | ✓ |
|
|
| Render as `<router-link>` with path per segment | Simpler but couples BreadcrumbBar to Vue Router. | |
|
|
|
|
**User's choice:** Emit navigate event with segment index (Recommended)
|
|
|
|
---
|
|
|
|
## Claude's Discretion
|
|
|
|
- Icon name assignments in AppIcon.vue's internal map
|
|
- Exact icon choices for each EmptyState context (researcher picks most semantically appropriate Heroicon per context)
|
|
- Keyboard shortcut global listener architectural home (App.vue vs dedicated AppKeyboardManager component)
|
|
- Exact query/store plumbing for `U` shortcut to reach upload input ref
|
|
- Which specific dropdowns need `<Teleport>` vs `getBoundingClientRect()` fixed positioning
|
|
|
|
## Deferred Ideas
|
|
|
|
None.
|