-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(NavigationDrawer): introduce NavigationDrawer component
- Loading branch information
1 parent
ac26bb8
commit 127d366
Showing
11 changed files
with
497 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// https://docs.cypress.io/api/introduction/api.html | ||
|
||
describe('navigation drawer', () => { | ||
beforeEach(() => { | ||
cy.visit('/navigation-drawers'); | ||
}); | ||
|
||
it('check non-persistent navigation-drawer', () => { | ||
cy.contains('h2[data-cy=navigation-drawers]', 'Navigation Drawers'); | ||
|
||
cy.get('div[data-cy=navigation-drawer-0]').as('defaultDrawer'); | ||
|
||
// open dialog | ||
cy.get('@defaultDrawer').find('[data-cy=activator]').as('activator'); | ||
cy.get('@activator').trigger('click'); | ||
cy.get('body').find('aside').should('be.visible'); | ||
|
||
// should close the dialog | ||
cy.get('h2[data-cy=navigation-drawers]').trigger('click'); | ||
cy.get('body').find('aside').should('not.be.visible'); | ||
}); | ||
|
||
it('check persistent dialog', () => { | ||
cy.get('div[data-cy=navigation-drawer-2]').as('defaultDrawer'); | ||
|
||
// open dialog | ||
cy.get('@defaultDrawer').find('[data-cy=activator]').as('activator'); | ||
cy.get('@activator').trigger('click'); | ||
cy.get('body').find('aside').should('be.visible'); | ||
|
||
// should not close the dialog | ||
cy.get('h2[data-cy=navigation-drawers]').trigger('click'); | ||
cy.get('body').find('aside').should('be.visible'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<script lang="ts" setup> | ||
import { ref } from 'vue'; | ||
import { type NavigationDrawerProps, RuiButton, RuiNavigationDrawer } from '@rotki/ui-library-compat'; | ||
interface ExtraProperties { | ||
label: string; | ||
} | ||
type NavigationDrawerData = NavigationDrawerProps & ExtraProperties; | ||
const navigationDrawers = ref<NavigationDrawerData[]>([ | ||
{ value: false, label: 'Left', temporary: true }, | ||
{ value: false, label: 'Right', position: 'right', temporary: true }, | ||
{ value: false, label: 'Persistent', temporary: false }, | ||
]); | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<h2 | ||
class="text-h4 mb-6" | ||
data-cy="navigation-drawers" | ||
> | ||
Navigation Drawers | ||
</h2> | ||
<div class="grid gap-4 grid-cols-2"> | ||
<div | ||
v-for="(navigationDrawer, i) in navigationDrawers" | ||
:key="i" | ||
:data-cy="`navigation-drawer-${i}`" | ||
> | ||
<RuiNavigationDrawer | ||
v-bind="navigationDrawer" | ||
v-model="navigationDrawer.value" | ||
content-class="!top-16" | ||
> | ||
<template #activator="{ on }"> | ||
<RuiButton | ||
color="primary" | ||
data-cy="activator" | ||
v-on="on" | ||
> | ||
{{ navigationDrawer.label }} | ||
</RuiButton> | ||
</template> | ||
|
||
<div class="p-4"> | ||
{{ navigationDrawer.label }} Navigation Drawer | ||
</div> | ||
</RuiNavigationDrawer> | ||
</div> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
src/components/overlays/navigation-drawer/NavigationDrawer.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { describe, expect, it, vi } from 'vitest'; | ||
import Vue from 'vue'; | ||
import { mount } from '@vue/test-utils'; | ||
import { TeleportPlugin } from '@/components/overlays/teleport-container'; | ||
import NavigationDrawer from '@/components/overlays/navigation-drawer/NavigationDrawer.vue'; | ||
import Button from '@/components/buttons/button/Button.vue'; | ||
|
||
const text = 'Navigation Drawer Content'; | ||
|
||
Vue.use(TeleportPlugin); | ||
|
||
function createWrapper(options?: any) { | ||
return mount(NavigationDrawer, { | ||
...options, | ||
scopedSlots: { | ||
activator: `<rui-button id="trigger" v-on="props.on"> | ||
Click me! | ||
</rui-button>`, | ||
default: ` | ||
<div> | ||
${text} | ||
<rui-button id="close" @click="props.close()" /> | ||
</div> | ||
`, | ||
}, | ||
stubs: { RuiButton: Button }, | ||
}); | ||
} | ||
|
||
describe('dialog', () => { | ||
it('renders properly', async () => { | ||
const wrapper = createWrapper(); | ||
await nextTick(); | ||
let drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
|
||
expect(drawer).toBeFalsy(); | ||
|
||
// Open drawer by clicking activator | ||
await wrapper.find('#trigger').trigger('click'); | ||
|
||
drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
|
||
expect(drawer).toBeTruthy(); | ||
|
||
// Click the button that call close function | ||
const closeButton = drawer.querySelector('#close') as HTMLButtonElement; | ||
closeButton.click(); | ||
|
||
await nextTick(); | ||
|
||
drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
|
||
expect(drawer).toBeFalsy(); | ||
wrapper.destroy(); | ||
}); | ||
|
||
it('should pass width and position props', async () => { | ||
const wrapper = createWrapper(); | ||
await nextTick(); | ||
|
||
// Open dialog by clicking activator | ||
await wrapper.find('#trigger').trigger('click'); | ||
|
||
let drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
expect(drawer).toBeTruthy(); | ||
|
||
expect(drawer.style.width).toBe('360px'); | ||
|
||
await wrapper.setProps({ | ||
position: 'right', | ||
width: '500', | ||
}); | ||
|
||
drawer = document.body.querySelector('aside[class*=_visible_][class*=_right_]') as HTMLDivElement; | ||
|
||
expect(drawer).toBeTruthy(); | ||
expect(drawer.style.width).toBe('500px'); | ||
|
||
wrapper.destroy(); | ||
}); | ||
|
||
it('dialog works with `temporary=false`', async () => { | ||
const wrapper = createWrapper(); | ||
await nextTick(); | ||
|
||
// Open dialog by clicking activator | ||
await wrapper.find('#trigger').trigger('click'); | ||
|
||
let drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
expect(drawer).toBeTruthy(); | ||
|
||
// Click outside should not close the drawer | ||
document.body.click(); | ||
await vi.delay(); | ||
|
||
drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
|
||
expect(drawer).toBeTruthy(); | ||
|
||
wrapper.destroy(); | ||
}); | ||
|
||
it('dialog works with `temporary=true`', async () => { | ||
const wrapper = createWrapper({ | ||
propsData: { | ||
temporary: true, | ||
}, | ||
}); | ||
await nextTick(); | ||
|
||
// Open dialog by clicking activator | ||
await wrapper.find('#trigger').trigger('click'); | ||
|
||
let drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
expect(drawer).toBeTruthy(); | ||
|
||
// Click outside should not close the drawer | ||
document.body.click(); | ||
await vi.delay(); | ||
|
||
drawer = document.body.querySelector('aside[class*=_visible_]') as HTMLDivElement; | ||
|
||
expect(drawer).toBeFalsy(); | ||
|
||
wrapper.destroy(); | ||
}); | ||
}); |
74 changes: 74 additions & 0 deletions
74
src/components/overlays/navigation-drawer/NavigationDrawer.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import Button from '@/components/buttons/button/Button.vue'; | ||
import NavigationDrawer, { type NavigationDrawerProps } from './NavigationDrawer.vue'; | ||
import type { Meta, StoryFn, StoryObj } from '@storybook/vue'; | ||
|
||
const render: StoryFn<NavigationDrawerProps> = args => ({ | ||
components: { Button, NavigationDrawer }, | ||
setup() { | ||
const value = computed({ | ||
get() { | ||
return args.value; | ||
}, | ||
set(val) { | ||
args.value = val; | ||
}, | ||
}); | ||
|
||
return { args, value }; | ||
}, | ||
template: ` | ||
<NavigationDrawer v-bind="args" v-model='value'> | ||
<template #activator="{ on }"> | ||
<Button v-on="on"> | ||
Click me! | ||
</Button> | ||
</template> | ||
<div class="p-4"> | ||
Navigation Drawer | ||
</div> | ||
</NavigationDrawer> | ||
`, | ||
}); | ||
|
||
const meta: Meta<NavigationDrawerProps> = { | ||
args: {}, | ||
argTypes: { | ||
position: { | ||
control: 'select', | ||
options: ['left', 'right'], | ||
table: { category: 'State' }, | ||
}, | ||
temporary: { control: 'boolean' }, | ||
width: { control: 'text' }, | ||
}, | ||
component: NavigationDrawer, | ||
parameters: { | ||
docs: { | ||
controls: { exclude: ['default'] }, | ||
}, | ||
}, | ||
render, | ||
tags: ['autodocs'], | ||
title: 'Components/Overlays/NavigationDrawer', | ||
}; | ||
|
||
type Story = StoryObj<NavigationDrawerProps>; | ||
|
||
export const Default: Story = { | ||
args: { | ||
temporary: true, | ||
}, | ||
}; | ||
|
||
export const Right: Story = { | ||
args: { | ||
position: 'right', | ||
temporary: true, | ||
}, | ||
}; | ||
|
||
export const Persistent: Story = { | ||
args: {}, | ||
}; | ||
|
||
export default meta; |
Oops, something went wrong.