Skip to content

Commit

Permalink
feat(UsaFooterCollapsibleMenu): implement UsaFooterCollapsibleMenu
Browse files Browse the repository at this point in the history
…component
  • Loading branch information
patrickcate committed May 23, 2022
1 parent 23dc8a0 commit 4c379d3
Show file tree
Hide file tree
Showing 7 changed files with 449 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'
import UsaFooterCollapsibleMenu from './UsaFooterCollapsibleMenu.vue'

const testItems = [
{
text: 'Test Item 1',
children: [
{
href: '/test-1/test-1-1',
text: 'Test Item 1.1',
},
{
href: '/test-1/test-1-2',
text: 'Test Item 1.2',
},
{
href: '/test-1/test-1-3',
text: 'Test Item 1.3',
},
],
},
{
text: 'Test Item 2',
children: [
{
to: '/test-2/test-2-1',
text: 'Test Item 2.1',
},
{
to: '/test-2/test-2-2',
routerComponentName: 'nuxt-link',
text: 'Test Item 2.2',
},
{
href: '/test-2/test-2-3',
text: 'Test Item 2.3',
},
],
},
{
id: 'test-3',
text: 'Test Item 3',
children: [
{
href: '/test-3/test-3-1',
text: 'Test Item 3.1',
},
{
href: '/test-3/test-3-2',
text: 'Test Item 3.2',
},
{
href: '/test-3/test-3-3',
text: 'Test Item 3.3',
},
],
},
]

const defaultProps = {
items: UsaFooterCollapsibleMenu.props.items.default(),
headingTag: UsaFooterCollapsibleMenu.props.headingTag.default,
customClasses: UsaFooterCollapsibleMenu.props.customClasses.default(),
}

export default {
component: UsaFooterCollapsibleMenu,
title: 'Components/UsaFooterCollapsibleMenu',
argTypes: {
items: {
control: { type: 'object' },
},
headingTag: {
control: { type: 'text' },
},
customClasses: {
control: { type: 'object' },
},
},
args: {
items: defaultProps.items,
headingTag: defaultProps.headingTag,
customClasses: defaultProps.customClasses,
},
parameters: {
viewport: {
viewports: INITIAL_VIEWPORTS,
},
},
decorators: [
() => ({
template:
'<div class="usa-footer"><div class="usa-footer__nav"><story /></div></div>',
}),
],
}

const DefaultTemplate = (args, { argTypes }) => ({
components: { UsaFooterCollapsibleMenu },
props: Object.keys(argTypes),
setup() {
return { ...args }
},
template: `<UsaFooterCollapsibleMenu
:items="items"
:heading-tag="headingTag"
:custom-classes="customClasses"
></UsaFooterCollapsibleMenu>`,
})

export const DefaultFooterCollapsibleMenu = DefaultTemplate.bind({})
DefaultFooterCollapsibleMenu.args = {
...defaultProps,
items: testItems,
}
DefaultFooterCollapsibleMenu.storyName = 'Default'

export const HeadingTagFooterCollapsibleMenu = DefaultTemplate.bind({})
HeadingTagFooterCollapsibleMenu.args = {
...defaultProps,
items: testItems,
headingTag: 'h3',
}
HeadingTagFooterCollapsibleMenu.storyName = 'Custom Heading Tag'

export const MobileCollapsibleMenu = DefaultTemplate.bind({})
MobileCollapsibleMenu.args = {
...defaultProps,
items: testItems,
}
MobileCollapsibleMenu.parameters = {
viewport: {
defaultViewport: 'iphone6',
},
}
MobileCollapsibleMenu.storyName = 'Mobile Collapsible'

export const CustomClassesFooterCollapsibleMenu = DefaultTemplate.bind({})
CustomClassesFooterCollapsibleMenu.args = {
...defaultProps,
items: testItems,
customClasses: {
gridRow: ['test-grid-row-class'],
gridCol: ['test-grid-col-class'],
},
}
CustomClassesFooterCollapsibleMenu.storyName = 'Custom CSS Classes'
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import '@module/uswds/dist/css/uswds.min.css'
import { mount } from '@cypress/vue'
import UsaFooterCollapsibleMenu from './UsaFooterCollapsibleMenu.vue'

describe('UsaFooterCollapsibleMenu', () => {
let testItems = []

beforeEach(() => {
testItems = [
{
text: 'Test Item 1',
children: [
{
href: '/test-1/test-1-1',
text: 'Test Item 1.1',
},
{
href: '/test-1/test-1-2',
text: 'Test Item 1.2',
},
{
href: '/test-1/test-1-3',
text: 'Test Item 1.3',
},
],
},
{
text: 'Test Item 2',
children: [
{
to: '/test-2/test-2-1',
text: 'Test Item 2.1',
},
{
to: '/test-2/test-2-2',
routerComponentName: 'nuxt-link',
text: 'Test Item 2.2',
},
{
href: '/test-2/test-2-3',
text: 'Test Item 2.3',
},
],
},
{
id: 'test-3',
text: 'Test Item 3',
children: [
{
href: '/test-3/test-3-1',
text: 'Test Item 3.1',
},
{
href: '/test-3/test-3-2',
text: 'Test Item 3.2',
},
{
href: '/test-3/test-3-3',
text: 'Test Item 3.3',
},
],
},
]
})

it('renders the component', () => {
mount(UsaFooterCollapsibleMenu, {
props: {
items: testItems,
},
})

cy.get('div.grid-row').should('have.class', 'grid-gap-4')
cy.get('.grid-row > div')
.should('have.class', 'mobile-lg:grid-col-6')
.and('have.class', 'desktop:grid-col-3')

cy.get('section')
.should('have.length', 3)
.and('have.class', 'usa-footer__primary-content')
.and('have.class', 'usa-footer__primary-content--collapsible')

cy.get('section h4').should('have.length', 3)
cy.get('section ul').should('have.length', 3)
cy.get('section li').should('have.length', 9)

cy.viewport(480, 600)

cy.get('section h4').should('have.length', 0)
cy.get('section button').should('have.length', 3)
cy.get('section ul').should('not.have.visible')

cy.get('section:nth-of-type(1) button').click()
cy.get('section:nth-of-type(1) ul').should('be.visible')
cy.get('section:nth-of-type(2) ul').should('not.be.visible')
cy.get('section:nth-of-type(3) ul').should('not.be.visible')

cy.get('section:nth-of-type(3) button').click()
cy.get('section:nth-of-type(1) ul').should('not.be.visible')
cy.get('section:nth-of-type(2) ul').should('not.be.visible')
cy.get('section:nth-of-type(3) ul').should('be.visible')

cy.viewport('macbook-15')

cy.get('section h4').should('have.length', 3)
cy.get('section button').should('have.length', 0)
cy.get('section ul').should('be.visible')

cy.viewport(480, 600)

cy.get('section h4').should('have.length', 0)
cy.get('section button').should('have.length', 3)
cy.get('section ul').should('not.be.visible')

cy.get('section:nth-of-type(2) button').click()
cy.get('section:nth-of-type(2) ul').should('be.visible')
})

it('starts as collapsible at small screens', () => {
cy.viewport(480, 600)

mount(UsaFooterCollapsibleMenu, {
props: {
items: testItems,
},
})

cy.get('section h4').should('have.length', 0)
cy.get('section button').should('have.length', 3)
cy.get('section ul').should('not.be.visible')

cy.get('section:nth-of-type(2) button').click()
cy.get('section:nth-of-type(2) ul').should('be.visible')
})

it('headings use custom `h3` size', () => {
mount(UsaFooterCollapsibleMenu, {
props: {
items: testItems,
headingTag: 'h3',
},
})

cy.get('section h3')
.should('have.length', 3)
.and('have.class', 'usa-footer__primary-link')
.and('not.have.class', 'usa-footer__primary-link--button')
})

it('uses custom grid prefix and separator and nav breakpoint', () => {
cy.viewport('macbook-15')

mount(UsaFooterCollapsibleMenu, {
props: {
items: testItems,
},
global: {
provide: {
'vueUswds.footerNavBigBreakpoint': '55rem',
'vueUswds.prefixSeparator': '@',
'vueUswds.gridNamespace': 'test-grid-namespace-',
},
},
})

cy.get('div.test-grid-namespace-row').should(
'have.class',
'test-grid-namespace-gap-4'
)
cy.get('.test-grid-namespace-row > div')
.should('have.class', 'mobile-lg@test-grid-namespace-col-6')
.and('have.class', 'desktop@test-grid-namespace-col-3')

cy.get('section h4').should('have.length', 3)
cy.get('section button').should('have.length', 0)

cy.viewport(881, 1200)

cy.get('section h4').should('have.length', 3)
cy.get('section button').should('have.length', 0)

cy.viewport(880, 1200)

cy.get('section h4').should('have.length', 0)
cy.get('section button').should('have.length', 3)
})

it('has custom grid CSS classes', () => {
mount(UsaFooterCollapsibleMenu, {
props: {
items: testItems,
customClasses: {
gridRow: ['test-grid-row-class'],
gridCol: ['test-grid-col-class'],
},
},
})

cy.get('div:first-of-type').should('have.class', 'test-grid-row-class')
cy.get('div:first-of-type > div').should(
'have.class',
'test-grid-col-class'
)
})
})
Loading

0 comments on commit 4c379d3

Please sign in to comment.