Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
feat(Menu): implement menu component
Browse files Browse the repository at this point in the history
  • Loading branch information
lukicenturi authored and kelsos committed Feb 21, 2024
1 parent 2b55755 commit d964c17
Show file tree
Hide file tree
Showing 13 changed files with 863 additions and 20 deletions.
64 changes: 64 additions & 0 deletions example/cypress/e2e/overlays/menu.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// https://docs.cypress.io/api/introduction/api.html

describe('menu', () => {
beforeEach(() => {
cy.visit('/menus');
});

it('checks for and trigger menu', () => {
cy.contains('h2[data-cy=menus]', 'Menus');

cy.get('div[data-cy=menu-0]').as('defaultMenu');

cy.get('@defaultMenu').find('[data-cy=activator]').as('activator');
cy.get('@activator').trigger('click');
cy.get('body').find('div[role=menu]');
cy.get('@activator').trigger('click');
cy.get('body').find('div[role=menu-content]').should('not.exist');

cy.get('@activator').trigger('click');
cy.get('body').find('div[role=menu-content]').should('exist').as('menuContent');
cy.get('@menuContent').trigger('click');
cy.get('body').find('div[role=menu-content]').should('exist');
cy.get('body').trigger('click');
cy.get('body').find('div[role=menu-content]').should('not.exist');
});

it('disabled should not trigger menu', () => {
cy.get('div[data-cy=menu-4]').as('disabledMenu');

cy.get('@disabledMenu').find('[data-cy=activator]').as('activator');
cy.get('@activator').trigger('click');
cy.get('body').find('div[role=menu-content]').should('not.exist');
});

it('menu should be opened on hover', () => {
cy.get('div[data-cy=menu-8]').as('menu');

cy.get('@menu').find('[data-cy=activator]').as('activator');
cy.get('@activator').trigger('mouseover');
cy.get('body').find('div[role=menu-content]').should('exist');
cy.get('@activator').trigger('mouseleave');
cy.get('body').find('div[role=menu-content]').should('not.exist');

cy.get('@activator').trigger('click');
cy.get('body').find('div[role=menu-content]').should('exist');

cy.get('@activator').trigger('mouseleave');
cy.get('body').find('div[role=menu-content]').should('exist');

cy.get('@activator').trigger('click');
cy.get('body').find('div[role=menu-content]').should('not.exist');
});

it('menu should be closed by clicking the menu content', () => {
cy.get('div[data-cy=menu-12]').as('menu');

cy.get('@menu').find('[data-cy=activator]').as('activator');
cy.get('@activator').trigger('click');
cy.get('body').find('div[role=menu]').as('menuContent');
cy.get('body').find('div[role=menu-content]');
cy.get('@menuContent').trigger('click');
cy.get('body').find('div[role=menu-content]').should('not.exist');
});
});
1 change: 1 addition & 0 deletions example/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const navigation = ref([
{ to: { name: 'chips' }, title: 'Chips' },
{ to: { name: 'alerts' }, title: 'Alerts' },
{ to: { name: 'tooltips' }, title: 'Tooltips' },
{ to: { name: 'menus' }, title: 'Menus' },
{ to: { name: 'data-tables' }, title: 'Data Tables' },
{ to: { name: 'cards' }, title: 'Cards' },
{ to: { name: 'tabs' }, title: 'Tabs' },
Expand Down
6 changes: 6 additions & 0 deletions example/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/max-dependencies */
import VueRouter from 'vue-router';
import Vue from 'vue';
import ButtonView from '@/views/ButtonView.vue';
Expand Down Expand Up @@ -96,6 +97,11 @@ const router = new VueRouter({
name: 'tooltips',
component: () => import('@/views/TooltipView.vue'),
},
{
path: '/menus',
name: 'menus',
component: () => import('@/views/MenuView.vue'),
},
{
path: '/data-tables',
name: 'data-tables',
Expand Down
155 changes: 155 additions & 0 deletions example/src/views/MenuView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<script lang="ts" setup>
import {
type ButtonProps,
type MenuProps,
RuiButton,
RuiMenu,
} from '@rotki/ui-library-compat/components';
import { objectOmit } from '@vueuse/shared';
import { ref } from 'vue';
const menus = ref<
(MenuProps & { buttonColor?: ButtonProps['color']; buttonText: string })[]
>([
{
disabled: false,
buttonText: 'Bottom',
buttonColor: 'primary',
popper: { placement: 'bottom' },
},
{
disabled: false,
buttonText: 'Top',
buttonColor: 'secondary',
popper: { placement: 'top' },
},
{
disabled: false,
buttonText: 'Left',
buttonColor: 'error',
popper: { placement: 'left' },
},
{
disabled: false,
buttonText: 'Right',
buttonColor: 'info',
popper: { placement: 'right' },
},
{
disabled: true,
buttonText: 'Menu disabled',
buttonColor: 'primary',
popper: { placement: 'bottom' },
},
{
disabled: true,
buttonText: 'Menu disabled',
buttonColor: 'secondary',
popper: { placement: 'top' },
},
{
disabled: true,
buttonText: 'Menu disabled',
buttonColor: 'error',
popper: { placement: 'left' },
},
{
disabled: true,
buttonText: 'Menu disabled',
buttonColor: 'info',
popper: { placement: 'right' },
},
{
disabled: false,
buttonText: 'Bottom (Open on Hover)',
buttonColor: 'primary',
popper: { placement: 'bottom' },
openOnHover: true,
},
{
disabled: false,
buttonText: 'Top (Open on Hover)',
buttonColor: 'secondary',
popper: { placement: 'top' },
openOnHover: true,
},
{
disabled: false,
buttonText: 'Left (Open on Hover)',
buttonColor: 'error',
popper: { placement: 'left' },
openOnHover: true,
},
{
disabled: false,
buttonText: 'Right (Open on Hover)',
buttonColor: 'info',
popper: { placement: 'right' },
openOnHover: true,
},
{
disabled: false,
buttonText: 'Bottom (Close on Content Click)',
buttonColor: 'primary',
popper: { placement: 'bottom' },
closeOnContentClick: true,
},
{
disabled: false,
buttonText: 'Top (Close on Content Click)',
buttonColor: 'secondary',
popper: { placement: 'top' },
closeOnContentClick: true,
},
{
disabled: false,
buttonText: 'Left (Close on Content Click)',
buttonColor: 'error',
popper: { placement: 'left' },
closeOnContentClick: true,
},
{
disabled: false,
buttonText: 'Right (Close on Content Click)',
buttonColor: 'info',
popper: { placement: 'right' },
closeOnContentClick: true,
},
]);
</script>

<template>
<div>
<h2
class="text-h4 mb-6"
data-cy="menus"
>
Menus
</h2>
<div class="grid gap-6 grid-cols-4">
<div
v-for="(menu, i) in menus"
:key="i"
class="p-4"
>
<RuiMenu
v-bind="objectOmit(menu, ['buttonColor'])"
:data-cy="`menu-${i}`"
>
<template #activator="{ on }">
<RuiButton
data-cy="activator"
:color="menu.buttonColor"
v-on="on"
>
{{ menu.buttonText }}
</RuiButton>
</template>
<div class="px-3 py-2">
This is menu
</div>
</RuiMenu>
</div>
</div>
</div>
</template>
6 changes: 6 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ import {
type Props as BadgeProps,
default as RuiBadge,
} from '@/components/overlays/badge/Badge.vue';
import {
type Props as MenuProps,
default as RuiMenu,
} from '@/components/overlays/menu/Menu.vue';
import {
default as RuiTooltip,
type Props as TooltipProps,
Expand Down Expand Up @@ -137,6 +141,7 @@ export {
RuiRevealableTextField,
RuiStepper,
RuiTextField,
RuiMenu,
RuiTooltip,
RuiDataTable,
RuiSimpleSelect,
Expand All @@ -155,6 +160,7 @@ export {
ProgressProps,
ChipProps,
TextFieldProps,
MenuProps,
TooltipProps,
SimpleSelectProps,
DataTableProps,
Expand Down
Loading

0 comments on commit d964c17

Please sign in to comment.