Skip to content

feat(core): app menu waffle launcher - #60180

Merged
artonge merged 11 commits into
masterfrom
feat/59888/waffle-menu
May 7, 2026
Merged

feat(core): app menu waffle launcher#60180
artonge merged 11 commits into
masterfrom
feat/59888/waffle-menu

Conversation

@pringelmann

@pringelmannpringelmann commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

First pass at the waffle launcher behind the apps icon in the header. Opening it shows a 4-wide grid of installed apps in a popover; admins also see a "More apps" tile linking to the app store. The existing current-app button is kept as a second trigger for the same popover.

Preview link

image

What's in:

  • Popover grid replaces the old hamburger overlay
  • Roving tabindex keyboard nav (arrow keys, Home/End, Enter/Space)
  • Focus returns to whichever trigger opened the popover
  • RTL-aware horizontal alignment
  • Admin-only "More apps" tile
  • Unit + Cypress coverage

TODO

Follow-ups for later PRs:

  • Live unread/notification counts on the tiles
  • Drag-and-drop reordering, persisted per user
  • Broaden test coverage (RTL, focus trap edge cases, keyboard variants, viewport breakpoints)

Checklist

  • Code is properly formatted
  • Sign-off message is added to all commits
  • Tests (unit, integration, api and/or acceptance) are included
  • Screenshots before/after for front-end changes (preview link)
  • Documentation (manuals or wiki) has been updated or is not required
  • Backports requested where applicable (ex: critical bugfixes)
  • Labels added where applicable (ex: bug/enhancement, 3. to review, feature component)
  • Milestone added for target branch/version (ex: 32.x for stable32)

@pringelmannpringelmann self-assigned this May 6, 2026
Comment threadcore/src/components/AppItem.vue Outdated
</script>

<style scoped lang="scss">
.app-item {

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can consider moving this to @nextcloud/vue in future, since this item will be used on dashboard, universal search, etc.

Would like to ship in-place for first iteration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if planned for nextcloud-vue it would be great to use css modules instead of scoped styles for two-way isolation of styles.

// NcPopover's focus-trap only knows the slot trigger (waffle).
// The current-app button lives outside the slot, so we track the
// source and restore focus manually via setReturnFocus.
openedFrom: null as 'waffle' | 'currentApp' | null,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UX behaviour relevant question here. Used common sense for first iteration.

return
}

const cols = 4

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number 😬 imo fine for first iteration, but some rework might be needed here.

case ' ': {
// Space's default scrolls the nearest scrollable ancestor (the
// popover); intercept and click programmatically. Enter gets
// the same treatment so we can close the popover uniformly.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistent with other waffle menus I looked at, but worth flagging as UX question

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space seems a bit unexpected here rest seems fine (for accessibility)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw APG recommends this behaviour:

https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/#:~:text=activates%20the%20menu%20item%2C

My reasoning is that arrows, Home and End all trigger focus events (which will auto-scroll), making it possible for users to scroll the list without needing a dedicated key for it.

// which is dark on light themes. The header sits on the theme primary
// background, so override to use the matching plain-text color.
--color-main-text: var(--color-background-plain-text);
color: var(--color-background-plain-text);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to add variants to @nextcloud/vue, but imo fine for first iteration

--app-item-row-height: 64px;
--app-menu-rows-visible: 6;
padding: calc(var(--default-grid-baseline) * 3) calc(var(--default-grid-baseline) * 2);
display: grid;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can debate whether grid is best/simplest solution here. Happy to iterate on this.

scrollbar-color: var(--color-scrollbar) transparent !important;

&::-webkit-scrollbar {
width: 6px !important;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick and dirty scrollbar styling. Happy to iterate on this.

@pringelmannpringelmann added 3. to review Waiting for reviews enhancement design Design, UI, UX, etc. labels May 6, 2026
@pringelmannpringelmann added this to the Nextcloud 34 milestone May 6, 2026
@pringelmann
pringelmann marked this pull request as ready for review May 6, 2026 08:33
@pringelmann
pringelmann requested a review from a team as a code ownerMay 6, 2026 08:34
@pringelmann
pringelmann requested review from ShGKme, artonge, kra-mo, nfebe, sorbaugh and susnux and removed request for a teamMay 6, 2026 08:34
Comment threadcore/src/components/AppItem.vue Outdated
v-if="currentApp"
class="app-menu__current-app"
type="button"
:aria-label="t('core', 'Open apps menu')"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so both buttons open the waffle menu?
I would expect this button to open the index of the current app instead

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes as per design spec

This also feels like a weird interaction to me, especially since the popup anchor still points to the waffle. Would you mind expanding on what the rationale is here @kra-mo?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree UX wise this is unexpected

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also feels like a weird interaction to me, especially since the popup anchor still points to the waffle. Would you mind expanding on what the rationale is here @kra-mo?

Since most apps that need it already provide a navigation item to go "Home", it was to make the menu more easy to access and discover.

I thought of both behaviors and this just felt "safer", even if more unconventional. Maybe I'm just being overly cautious though.

Were we to keep this, it would be good to link the two as a single button (when focused or hovered for example).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok yeah that makes sense. I think a single button would definitely help yes. Perhaps we go with what we have for the first step and gather some internal feedback?

@pringelmann
pringelmannforce-pushed the feat/59888/waffle-menu branch from f177035 to c115c2fCompareMay 7, 2026 09:49
@artonge

Copy link
Copy Markdown
Collaborator

Approved to be merged for the screenshots, we will address all the raised concerns in a follow-up.

@schiessle

schiessle commented May 7, 2026

Copy link
Copy Markdown
Member

Because truncated app names are a concern raised from users every now and than with the "old menu". Does this menu adjust the column width automatically so that the app name is always completely readable (also think about translation where app names might be longer)?

@artonge
artonge dismissed kra-mo’s stale reviewMay 7, 2026 11:44

Will be done in a follow-up

@nextcloudnextcloud deleted a comment from backportbotBotMay 7, 2026
@artongeartonge mentioned this pull request May 7, 2026
@pringelmann
pringelmannforce-pushed the feat/59888/waffle-menu branch from 459eb89 to 2319472CompareMay 7, 2026 12:53
@jancborchardtjancborchardt moved this to 🏗️ At engineering in 🖍 Design teamMay 7, 2026
- Popover grid replaces the old hamburger overlay
- Roving tabindex keyboard nav (arrow keys, Home/End, Enter/Space)
- Focus returns to whichever trigger opened the popover
- RTL-aware horizontal alignment
- Admin-only "More apps" tile
- Unit + Cypress coverage
Resolves: #59888
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
-e
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
…cher
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
@pringelmann
pringelmannforce-pushed the feat/59888/waffle-menu branch from d2c9166 to c36d64dCompareMay 7, 2026 17:25
@artonge

Copy link
Copy Markdown
Collaborator

CI failure unrelated

@artonge
artonge merged commit f501b44 into masterMay 7, 2026
312 of 352 checks passed
@artonge
artonge deleted the feat/59888/waffle-menu branch May 7, 2026 19:50
@github-project-automationgithub-project-automationBot moved this from 🏗️ At engineering to 🎉 Done in 🖍 Design teamMay 7, 2026
@nextcloud-botnextcloud-bot mentioned this pull request May 12, 2026
@nextcloud-botnextcloud-bot mentioned this pull request May 15, 2026
@nextcloud-botnextcloud-bot mentioned this pull request May 20, 2026
@nextcloud-botnextcloud-bot mentioned this pull request May 27, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to reviewWaiting for reviewsdesignDesign, UI, UX, etc.enhancement

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

App navigation: waffle menu and header layout

7 participants

@pringelmann@artonge@schiessle@kra-mo@jancborchardt@AndyScherzinger@susnux