-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(side menu): new
<bq-side-menu>
and <bq-side-menu-item>
compo…
…nents (#289)
- Loading branch information
1 parent
a74f0ad
commit a44b2dd
Showing
23 changed files
with
1,268 additions
and
2 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
145 changes: 145 additions & 0 deletions
145
packages/bee-q/src/components/side-menu-item/__tests__/bq-side-menu-item.e2e.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,145 @@ | ||
import { newE2EPage } from '@stencil/core/testing'; | ||
|
||
describe('bq-side-menu-item', () => { | ||
it('should render', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent('<bq-side-menu-item></bq-side-menu-item>'); | ||
|
||
const menuItemElem = await page.find('bq-side-menu-item'); | ||
expect(menuItemElem).toHaveClass('hydrated'); | ||
}); | ||
|
||
it('should have shadow root', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent('<bq-side-menu-item></bq-side-menu-item>'); | ||
|
||
const menuItemElem = await page.find('bq-side-menu-item'); | ||
expect(menuItemElem.shadowRoot).not.toBeNull(); | ||
}); | ||
|
||
it('should display text', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(` | ||
<bq-side-menu-item disabled="true"> | ||
Menu item label | ||
</bq-side-menu-item> | ||
`); | ||
|
||
const menuItemElem = await page.find('bq-side-menu-item'); | ||
expect(menuItemElem).toEqualText('Menu item label'); | ||
}); | ||
|
||
it('should trigger click', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(` | ||
<bq-side-menu-item> | ||
Menu item label | ||
</bq-side-menu-item> | ||
`); | ||
|
||
const bqFocus = await page.spyOnEvent('bqFocus'); | ||
const bqBlur = await page.spyOnEvent('bqBlur'); | ||
const bqClick = await page.spyOnEvent('bqClick'); | ||
|
||
const menuItemElem = await page.find('bq-side-menu-item'); | ||
|
||
await menuItemElem.click(); | ||
|
||
expect(bqFocus).toHaveReceivedEventTimes(1); | ||
expect(bqBlur).toHaveReceivedEventTimes(0); | ||
expect(bqClick).toHaveReceivedEventTimes(1); | ||
}); | ||
}); | ||
|
||
it('should be keyboard accessible', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(` | ||
<bq-side-menu-item> | ||
<bq-icon size="18" name="user" slot="prefix"></bq-icon> | ||
<span>Verified users</span> | ||
</bq-side-menu-item> | ||
`); | ||
|
||
const bqFocus = await page.spyOnEvent('bqFocus'); | ||
const bqBlur = await page.spyOnEvent('bqBlur'); | ||
const bqClick = await page.spyOnEvent('bqClick'); | ||
|
||
await page.keyboard.press('Tab'); | ||
|
||
expect(bqFocus).toHaveReceivedEventTimes(1); | ||
expect(bqClick).toHaveReceivedEventTimes(0); | ||
expect(bqBlur).toHaveReceivedEventTimes(0); | ||
}); | ||
|
||
it('should handle `active` property', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(` | ||
<bq-side-menu-item active="true"> | ||
Menu item label | ||
</bq-side-menu-item> | ||
`); | ||
|
||
const menuItemElem = await page.find('bq-side-menu-item >>> .bq-side-menu--item'); | ||
expect(menuItemElem).toHaveClass('active'); | ||
}); | ||
|
||
it('should handle `disabled` property', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(` | ||
<bq-side-menu-item disabled="true"> | ||
Menu item label | ||
</bq-side-menu-item> | ||
`); | ||
|
||
const bqFocus = await page.spyOnEvent('bqSideMenuItemFocus'); | ||
const bqBlur = await page.spyOnEvent('bqSideMenuItemBlur'); | ||
const bqClick = await page.spyOnEvent('bqSideMenuItemClick'); | ||
|
||
const menuItemElem = await page.find('bq-side-menu-item'); | ||
|
||
menuItemElem.click(); | ||
|
||
await page.waitForChanges(); | ||
|
||
expect(bqFocus).toHaveReceivedEventTimes(0); | ||
expect(bqClick).toHaveReceivedEventTimes(0); | ||
expect(bqBlur).toHaveReceivedEventTimes(0); | ||
}); | ||
|
||
it('should render prefix element', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(` | ||
<bq-side-menu-item> | ||
<span slot="prefix">Prefix</span> | ||
Dashboard | ||
</bq-side-menu-item> | ||
`); | ||
|
||
const prefixText = await page.$eval('bq-side-menu-item', (element) => { | ||
const slotElement = element.shadowRoot.querySelector('slot[name="prefix"]'); | ||
const assignedElements = (slotElement as HTMLSlotElement).assignedElements({ flatten: true })[0]; | ||
|
||
return assignedElements.textContent; | ||
}); | ||
|
||
expect(prefixText).toBe('Prefix'); | ||
}); | ||
|
||
it('should render suffix element', async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(` | ||
<bq-side-menu-item> | ||
<span slot="suffix">Suffix</span> | ||
Dashboard | ||
</bq-side-menu-item> | ||
`); | ||
|
||
const suffixText = await page.$eval('bq-side-menu-item', (element) => { | ||
const slotElement = element.shadowRoot.querySelector('slot[name="suffix"]'); | ||
const assignedElements = (slotElement as HTMLSlotElement).assignedElements({ flatten: true })[0]; | ||
|
||
return assignedElements.textContent; | ||
}); | ||
|
||
expect(suffixText).toEqualText('Suffix'); | ||
}); |
23 changes: 23 additions & 0 deletions
23
packages/bee-q/src/components/side-menu-item/_storybook/bq-side-menu-item.mdx
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,23 @@ | ||
import { ArgTypes, Stories, Title, Subtitle } from '@storybook/addon-docs'; | ||
|
||
<Title>Side menu item</Title> | ||
|
||
A side menu item is a navigation element typically placed on the side or left-hand side of a web page or application. | ||
It serves as a hierarchical or categorical navigation option, allowing users to access different sections or pages within the application. | ||
|
||
> The Side menu item component must be used inside the [Side menu component](?path=/docs/components-side-menu--overview) to function properly. | ||
<Subtitle>Usage</Subtitle> | ||
|
||
Use icons and labels: Users often rely on both visual cues and text labels to understand the purpose of each menu item. Use distinct icons or symbols to represent different sections or actions, and accompany them with clear text labels for better accessibility. | ||
|
||
<Subtitle>👍 When to use</Subtitle> | ||
|
||
Side menu items are commonly used in web and mobile applications that require a hierarchical or multi-level navigation structure. They are particularly useful when: | ||
|
||
- Navigating different sections: If your application has multiple sections or modules that need to be accessed frequently, a side menu item can provide quick and easy navigation between these sections. | ||
- Organizing content: Side menu items are beneficial when you have a large amount of content or options that need to be organized in a hierarchical manner. By displaying submenus or nested items, users can easily navigate through different levels of content. | ||
|
||
<Title>Properties</Title> | ||
|
||
<ArgTypes of="bq-side-menu-item" /> |
55 changes: 55 additions & 0 deletions
55
packages/bee-q/src/components/side-menu-item/_storybook/bq-side-menu-item.stories.tsx
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,55 @@ | ||
import type { Args, Meta, StoryObj } from '@storybook/web-components'; | ||
import { html } from 'lit-html'; | ||
|
||
import mdx from './bq-side-menu-item.mdx'; | ||
|
||
const meta: Meta = { | ||
title: 'Components/Side menu/Side menu item', | ||
component: 'bq-side-menu-item', | ||
parameters: { | ||
docs: { | ||
page: mdx, | ||
}, | ||
}, | ||
argTypes: { | ||
active: { control: 'boolean' }, | ||
disabled: { control: 'boolean' }, | ||
collapse: { control: 'boolean' }, | ||
// Not part of the component | ||
text: { control: 'text', table: { disable: true } }, | ||
// Event handlers | ||
bqBlur: { action: 'bqBlur' }, | ||
bqFocus: { action: 'bqFocus' }, | ||
bqClick: { action: 'bqClick' }, | ||
}, | ||
args: { | ||
active: false, | ||
disabled: false, | ||
collapse: false, | ||
// Not part of the component | ||
text: 'Menu item', | ||
}, | ||
}; | ||
export default meta; | ||
|
||
type Story = StoryObj; | ||
|
||
const Template = (args: Args) => html` | ||
<bq-side-menu-item | ||
?active=${args.active} | ||
?disabled=${args.disabled} | ||
?collapse=${args.collapse} | ||
@bqBlur=${args.bqBlur} | ||
@bqClick=${args.bqClick} | ||
@bqFocus=${args.bqFocus} | ||
> | ||
<bq-icon name="star-four" slot="prefix"></bq-icon> | ||
${args.text} | ||
<bq-badge class="ml-auto" slot="suffix"> 5 </bq-badge> | ||
</bq-side-menu-item> | ||
`; | ||
|
||
export const Default: Story = { | ||
render: Template, | ||
args: {}, | ||
}; |
Oops, something went wrong.