Files
chore/.github/specs/active/profile-button-menu/feat-profile-icon-button-menu.md
Ryan Kegel 47541afbbf
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 46s
Add unit tests for LoginButton component with comprehensive coverage
2026-02-05 16:37:10 -05:00

66 lines
4.6 KiB
Markdown

# Feature: Replace the text-based "Parent" button with an image icon and modernize the dropdown menu
## Visual Reference:
- **Sample Design:** #mockup.png
- **Design:**
1. Dropdown header colors need to match color theme inside #colors.css
2. The icon button shall be circular and use all the space of it's container. It should be centered in it's container.
3. The three dropdown items should be "Profile", "Child Mode", and "Sign out"
4. Currently, the dropdown shows "Log out" for "Child Mode", that should be changed to "Child Mode"
## Context:
- **Goal:** I want a user image icon to display in place of the current "Parent" button
- **User Story:** As a [user], I want to see the image assigned in my profile as an icon button at the top right of the screen. When I click the button I want to see a dropdown appear if I'm in 'parent mode.' I to have the options to see/edit my profile, go back to child mode, or sign out. In child mode, I want the button to trigger the parent pin modal if clicked.
## Technical Requirements
- **File Affected:** LoginButton.vue, ParentLayout.vue, ChildLayout.vue, AuthLayout.vue
- **Backend:** When LoginButton loads, it should query the backend for the current user data (/user/profile) The returned data will provide the image_id and first_name of the user.
- **Navigation:**
1. When the avatar button is focused, pressing Enter or Space opens the dropdown.
2. When the dropdown is open:
- Up/Down arrow keys move focus between menu items.
- Enter or Space activates the focused menu item.
- Esc closes the dropdown and returns focus to the avatar button.
3. Tabbing away from the dropdown closes it.
- **ARIA:**
1. The avatar button must have aria-haspopup="menu" and aria-expanded reflecting the dropdown state.
2. The dropdown menu must use role="menu", and each item must use role="menuitem".
3. The currently focused menu item should have aria-selected="true".
- **Focus Ring:** All interactive elements (avatar button and dropdown menu items) must display a visible focus ring when focused via keyboard navigation. The focus ring color should use a theme variable from colors.css and meet accessibility contrast guidelines.
- **Mobile & Layout:**
1. The avatar icon button must always be positioned at the top right of the screen, regardless of device size.
2. The icon must never exceed 44px in width or height.
3. On mobile, ensure the button is at least 44x44px for touch accessibility.
- **Avatar Fallback:** If user.first_name does not exist, display a ? as the fallback initial.
- **Dropdown Placement and Animation:**
1. The dropdown menu must always appear directly below the avatar icon, right-aligned to the screen edge.
2. Use a slide down/up animation for showing/hiding the dropdown.
- **State Requirements:**
- Collapsed: Button shows the user.image_id or a fallback icon with the initial of the user.first_name
- Expanded: Shows the dropdown with the three menu options shown in the #mockup.png. -**Menu Item Icons:**: For now, use a stub element or placeholder for each menu item icon, to be replaced with real icons later.
- **Logic:**
1. Clicking an item in the dropdown should already be implemented. Do not change this.
2. When clicking a menu item or clicking outside the menu, collapse the menu.
3. When in 'child mode' (parent not authenticated), show the parent PIN modal or create PIN view (/parent/pin-setup) if user.pin doesn't exist or is empty. (this is already implemented)
## UI Acceptance Criteria (The "Definition of Done")
- [x] UI: Swap the "Parent" button with the user's avatar image.
- [x] UI: Refactor #LoginButton.vue to use new CSS generated from #mockup.png
- [x] Logic: Make sure the dropdown does not show when in child mode.
- [x] Logic: Make sure the parent PIN modal shows when the button is pressed in child mode.
- [x] Logic: Make sure the parent PIN creation view shows when the button is pressed in child mode if no user.pin doesn't exist or is empty.
- [x] Frontend Tests: Add vitest for this feature in the frontend to make sure the logic for button clicking in parent mode and child mode act correctly.
1. [x] Avatar button renders image, initial, or ? as fallback
2. [x] Dropdown opens/closes via click, Enter, Space, Esc, and outside click.
3. [x] Dropdown is positioned and animated correctly.
4. [x] Keyboard navigation (Up/Down, Enter, Space, Esc) works as specified.
5. [x] ARIA attributes and roles are set correctly.
6. [x] Focus ring is visible and uses theme color.
7. [x] Avatar button meets size and position requirements on all devices.
8. [x] Menu logic for parent/child mode is correct.
9. [x] Stub icons are rendered for menu items.