feat(admin): complete Task 5 dropdown primitives (Option A)
Task 5 was ~85% complete when reviewed. This commit finalizes the
implementation with minimal cleanup and comprehensive documentation.
Changes:
- Refactored GenericMetadataPopover to use clickOutside action
- Removed manual document.addEventListener for click outside
- Now uses standardized action with trigger exclusion logic
- Cleaner code, consistent with other components
Documentation:
- Created task-5-dropdown-primitives-completion.md
- Documented existing infrastructure (clickOutside, BaseDropdown)
- Justified 15 remaining manual event listeners
- API documentation for clickOutside action and BaseDropdown
What Already Existed:
- clickOutside action (full TypeScript, proper cleanup)
- BaseDropdown component (Svelte 5 snippets)
- Dropdown primitives (DropdownMenuContainer, DropdownItem, DropdownMenu)
- ~10 components already using clickOutside
- Specialized dropdowns (StatusDropdown, PostDropdown, etc.)
Justified Exceptions (manual listeners kept):
- DropdownMenu.svelte: Complex submenu logic with Floating UI
- ProjectListItem/PostListItem: Global dropdown coordination pattern
- BaseModal + forms: Keyboard shortcuts (Escape, Cmd+S)
- Various: Scroll/resize positioning (layout concerns)
Decision: Did NOT use Runed library
- Custom clickOutside implementation is production-ready
- No advantage from external dependency
- Current solution is type-safe and well-tested
Phase 3 (List Utilities & Primitives) now complete!
- Task 4: List filtering utilities ✅
- Task 5: Dropdown primitives ✅
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>