From 75c12328606b5a5aec19ba7a46d3e3c353bc59ac Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 23 Mar 2026 22:32:50 +0100 Subject: [PATCH] feat(package/ui): os-menu (#9431) --- .../there_is_no_button_to_pin_a_post.js | 2 +- ..._Post_from_the_content_menu_of_the_post.js | 2 +- ...m_the_content_menu_in_the_user_info_box.js | 2 +- .../common/I_click_on_{string}.js | 2 +- ...m_the_content_menu_in_the_user_info_box.js | 2 +- ...I_navigate_to_my_{string}_settings_page.js | 2 +- packages/ui/.storybook/preview.ts | 3 + packages/ui/KATALOG.md | 15 +- packages/ui/PROJEKT.md | 16 +- .../ui/src/components/OsMenu/OsMenu.spec.ts | 244 ++++++++++++++ .../src/components/OsMenu/OsMenu.stories.ts | 134 ++++++++ .../components/OsMenu/OsMenu.visual.spec.ts | 85 +++++ packages/ui/src/components/OsMenu/OsMenu.vue | 151 +++++++++ .../src/components/OsMenu/OsMenuItem.spec.ts | 30 ++ .../components/OsMenu/OsMenuItem.stories.ts | 38 +++ .../OsMenu/OsMenuItem.visual.spec.ts | 48 +++ .../ui/src/components/OsMenu/OsMenuItem.vue | 251 ++++++++++++++ .../__screenshots__/chromium/dropdown.png | Bin 0 -> 5290 bytes .../chromium/menuitem-custom.png | Bin 0 -> 4630 bytes .../__screenshots__/chromium/nested.png | Bin 0 -> 5207 bytes .../chromium/sidebar-active.png | Bin 0 -> 6570 bytes .../__screenshots__/chromium/sidebar.png | Bin 0 -> 6538 bytes packages/ui/src/components/OsMenu/index.ts | 4 + .../ui/src/components/OsMenu/menu.variants.ts | 26 ++ packages/ui/src/components/index.ts | 1 + packages/ui/src/styles/index.css | 86 +++++ webapp/assets/styles/imports/_tooltip.scss | 8 - .../components/AvatarMenu/AvatarMenu.spec.js | 18 +- webapp/components/AvatarMenu/AvatarMenu.vue | 34 +- .../ContentMenu/ContentMenu.Group.spec.js | 48 +-- .../ContentMenu/ContentMenu.spec.js | 102 +++--- webapp/components/ContentMenu/ContentMenu.vue | 21 +- .../ContentMenu/GroupContentMenu.vue | 22 +- .../GroupContentMenu.spec.js.snap | 67 ++-- .../DropdownFilter/DropdownFilter.vue | 12 +- .../components/LocaleSwitch/LocaleSwitch.vue | 12 +- .../pages/__snapshots__/settings.spec.js.snap | 307 ++++++------------ webapp/pages/admin.vue | 7 +- .../_id/__snapshots__/_slug.spec.js.snap | 198 ++++------- webapp/pages/groups/edit/_id.vue | 6 +- webapp/pages/moderation.vue | 7 +- webapp/pages/post/_id/_slug/index.vue | 5 +- webapp/pages/post/create/_type.vue | 11 +- .../_id/__snapshots__/_slug.spec.js.snap | 134 ++++---- webapp/pages/settings.vue | 7 +- webapp/test/testSetup.js | 17 + 46 files changed, 1549 insertions(+), 638 deletions(-) create mode 100644 packages/ui/src/components/OsMenu/OsMenu.spec.ts create mode 100644 packages/ui/src/components/OsMenu/OsMenu.stories.ts create mode 100644 packages/ui/src/components/OsMenu/OsMenu.visual.spec.ts create mode 100644 packages/ui/src/components/OsMenu/OsMenu.vue create mode 100644 packages/ui/src/components/OsMenu/OsMenuItem.spec.ts create mode 100644 packages/ui/src/components/OsMenu/OsMenuItem.stories.ts create mode 100644 packages/ui/src/components/OsMenu/OsMenuItem.visual.spec.ts create mode 100644 packages/ui/src/components/OsMenu/OsMenuItem.vue create mode 100644 packages/ui/src/components/OsMenu/__screenshots__/chromium/dropdown.png create mode 100644 packages/ui/src/components/OsMenu/__screenshots__/chromium/menuitem-custom.png create mode 100644 packages/ui/src/components/OsMenu/__screenshots__/chromium/nested.png create mode 100644 packages/ui/src/components/OsMenu/__screenshots__/chromium/sidebar-active.png create mode 100644 packages/ui/src/components/OsMenu/__screenshots__/chromium/sidebar.png create mode 100644 packages/ui/src/components/OsMenu/index.ts create mode 100644 packages/ui/src/components/OsMenu/menu.variants.ts diff --git a/cypress/support/step_definitions/Admin.PinPost/there_is_no_button_to_pin_a_post.js b/cypress/support/step_definitions/Admin.PinPost/there_is_no_button_to_pin_a_post.js index 5d75e9a87..2a407e440 100644 --- a/cypress/support/step_definitions/Admin.PinPost/there_is_no_button_to_pin_a_post.js +++ b/cypress/support/step_definitions/Admin.PinPost/there_is_no_button_to_pin_a_post.js @@ -1,7 +1,7 @@ import { defineStep } from '@badeball/cypress-cucumber-preprocessor' defineStep('there is no button to pin a post', () => { - cy.get('a.ds-menu-item-link') + cy.get('a.os-menu-item-link') .should('contain', 'Report Post') // sanity check .should('not.contain', 'Pin post') }) diff --git a/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js index 7f7eb8664..74b64283e 100644 --- a/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js @@ -5,7 +5,7 @@ defineStep('I click on "Report Post" from the content menu of the post', () => { .find('[data-test="content-menu-button"]') .click() - cy.get('.popover .ds-menu-item-link') + cy.get('.popover .os-menu-item-link') .contains('Report Post') .click() }) diff --git a/cypress/support/step_definitions/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js b/cypress/support/step_definitions/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js index f9d966299..e2fb1a474 100644 --- a/cypress/support/step_definitions/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js +++ b/cypress/support/step_definitions/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js @@ -2,6 +2,6 @@ import { defineStep } from '@badeball/cypress-cucumber-preprocessor' defineStep('I {string} see {string} from the content menu in the user info box', (condition, link) => { cy.get('.user-content-menu [data-test="content-menu-button"]').click() - cy.get('.popover .ds-menu-item-link') + cy.get('.popover .os-menu-item-link') .should(condition === 'should' ? 'contain' : 'not.contain', link) }) diff --git a/cypress/support/step_definitions/common/I_click_on_{string}.js b/cypress/support/step_definitions/common/I_click_on_{string}.js index 78a1ad8da..c9288dbed 100644 --- a/cypress/support/step_definitions/common/I_click_on_{string}.js +++ b/cypress/support/step_definitions/common/I_click_on_{string}.js @@ -10,7 +10,7 @@ defineStep('I click on {string}', element => { 'comment button': 'button[type=submit]', 'reply button': '.reply-button', 'security menu': 'a[href="/settings/security"]', - 'pin post': '.ds-menu-item:first-child', + 'pin post': '.os-menu-item:first-child', 'Moderation': 'a[href="/moderation"]', } diff --git a/cypress/support/step_definitions/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js b/cypress/support/step_definitions/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js index 676dc12c1..9afc33f3e 100644 --- a/cypress/support/step_definitions/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js +++ b/cypress/support/step_definitions/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js @@ -3,7 +3,7 @@ import { defineStep } from '@badeball/cypress-cucumber-preprocessor' defineStep('I click on {string} from the content menu in the user info box', button => { cy.get('.user-content-menu [data-test="content-menu-button"]').click() - cy.get('.popover .ds-menu-item-link') + cy.get('.popover .os-menu-item-link') .contains(button) .click({ force: true diff --git a/cypress/support/step_definitions/common/I_navigate_to_my_{string}_settings_page.js b/cypress/support/step_definitions/common/I_navigate_to_my_{string}_settings_page.js index 73b93d3d3..c13f394db 100644 --- a/cypress/support/step_definitions/common/I_navigate_to_my_{string}_settings_page.js +++ b/cypress/support/step_definitions/common/I_navigate_to_my_{string}_settings_page.js @@ -6,5 +6,5 @@ defineStep('I navigate to my {string} settings page', settingsPage => { .find('a[href]') .contains('Settings') .click() - cy.contains('.ds-menu-item-link', settingsPage).click() + cy.contains('.os-menu-item-link', settingsPage).click() }) diff --git a/packages/ui/.storybook/preview.ts b/packages/ui/.storybook/preview.ts index 7d0b4abc3..7e202fded 100644 --- a/packages/ui/.storybook/preview.ts +++ b/packages/ui/.storybook/preview.ts @@ -1,5 +1,8 @@ // eslint-disable-next-line import-x/no-unassigned-import import '@fontsource-variable/inter' + +// eslint-disable-next-line import-x/no-relative-parent-imports +import '../src/styles/index.css' // eslint-disable-next-line import-x/no-unassigned-import import './storybook.css' diff --git a/packages/ui/KATALOG.md b/packages/ui/KATALOG.md index 9b57d023b..f9ca23d61 100644 --- a/packages/ui/KATALOG.md +++ b/packages/ui/KATALOG.md @@ -15,7 +15,7 @@ Phase 4: Tier 1 ██████████ 100% (OsButton, OsIcon, Os Phase 4: Tier A → HTML ██████████ 100% (10 ds-* Wrapper → Plain HTML) ✅ Phase 4: Tier B ██████████ 100% (ds-chip→OsBadge✅, ds-tag→OsBadge✅, ds-grid✅, ds-number→OsNumber✅, ds-radio→HTML✅) Phase 4: Tier B ██████████ 100% (Chip→OsBadge, Tag→OsBadge, Grid→HTML, Number→OsNumber, Radio→HTML, Table→HTML) ✅ -Phase 4: Tier 2+ ████████░░ 70% (OsModal✅, ds-form entkoppelt✅, ds-input→OcelotInput✅, ds-select→OcelotSelect✅) | Rest ausstehend (OsMenu, OsDropdown, OsAvatar) +Phase 4: Tier 2+ ██████████ 100% (OsModal✅, ds-form✅, OcelotInput✅, OcelotSelect✅, OsMenu/OsMenuItem✅) | 0 ds-* Tags verbleibend ✅ ``` ### Statistiken @@ -33,7 +33,7 @@ Phase 4: Tier 2+ ████████░░ 70% (OsModal✅, ds-form | ✅ ds-input → OcelotInput | Input (23 Dateien → OcelotInput Webapp-Komponente, lokale Imports, formValidation-kompatibel) | | ✅ ds-form entkoppelt | Form-Validierung → formValidation Mixin (async-validator), vuelidate entfernt | | ✅ ds-select → OcelotSelect | Select (3 Dateien → OcelotSelect Webapp-Komponente, lokale Imports, click-outside inline) | -| ⬜ → UI-Library | Menu, MenuItem (2) — Tier 3 | +| ✅ → OsMenu/OsMenuItem | Menu, MenuItem (17 Nutzungen → packages/ui, dropdown Prop, eigene CSS) | | ⬜ Nicht in Webapp | Code, CopyField, FormItem, InputError, InputLabel, Page, PageTitle, Logo, Avatar, TableCol, TableHeadCol (11) | ### OsButton Migration (Phase 3) ✅ @@ -103,8 +103,8 @@ Phase 4: Tier 2+ ████████░░ 70% (OsModal✅, ds-form | 32 | List | ✅ → HTML | Tier A: `