-
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(UsaIconList): implement
UsaIconList
component
ISSUES CLOSED: #175
- Loading branch information
1 parent
7377534
commit cafeb54
Showing
5 changed files
with
225 additions
and
0 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,68 @@ | ||
import UsaIconList from './UsaIconList.vue' | ||
import UsaIconListItem from '@/components/UsaIconListItem' | ||
|
||
const defaultProps = { | ||
color: UsaIconList.props.color.default, | ||
size: UsaIconList.props.size.default, | ||
} | ||
|
||
export default { | ||
component: UsaIconList, | ||
title: 'Components/UsaIconList', | ||
argTypes: { | ||
color: { | ||
control: { type: 'text' }, | ||
}, | ||
defaultSlot: { | ||
control: { type: 'text' }, | ||
}, | ||
}, | ||
args: { | ||
color: defaultProps.color, | ||
size: defaultProps.size, | ||
defaultSlot: `<UsaIconListItem icon="check_circle">Icon list item</UsaIconListItem><UsaIconListItem icon="check_circle">Icon list item</UsaIconListItem><UsaIconListItem icon="check_circle">Icon list item</UsaIconListItem>`, | ||
}, | ||
} | ||
|
||
const DefaultTemplate = (args, { argTypes }) => ({ | ||
components: { UsaIconList, UsaIconListItem }, | ||
props: Object.keys(argTypes), | ||
setup() { | ||
return { ...args } | ||
}, | ||
template: `<UsaIconList | ||
:color="color" | ||
:size="size" | ||
>${args.defaultSlot}</UsaIconList>`, | ||
}) | ||
|
||
export const DefaultIconList = DefaultTemplate.bind({}) | ||
DefaultIconList.args = { | ||
...defaultProps, | ||
} | ||
DefaultIconList.storyName = 'Default' | ||
|
||
export const ColorIconList = DefaultTemplate.bind({}) | ||
ColorIconList.args = { | ||
...defaultProps, | ||
color: 'success', | ||
} | ||
ColorIconList.storyName = 'Color' | ||
|
||
export const SingleSizeIconList = DefaultTemplate.bind({}) | ||
SingleSizeIconList.args = { | ||
...defaultProps, | ||
size: 'lg', | ||
} | ||
SingleSizeIconList.storyName = 'Single Size' | ||
|
||
export const ResponsiveSizesIconList = DefaultTemplate.bind({}) | ||
ResponsiveSizesIconList.args = { | ||
...defaultProps, | ||
size: { | ||
mobile: 'lg', | ||
tablet: 'xl', | ||
desktop: '2xl', | ||
}, | ||
} | ||
ResponsiveSizesIconList.storyName = 'Responsive Sizes' |
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,86 @@ | ||
import '@module/uswds/dist/css/uswds.min.css' | ||
import { mount } from '@cypress/vue' | ||
import { h } from 'vue' | ||
import UsaIconList from './UsaIconList.vue' | ||
|
||
describe('UsaIconList', () => { | ||
it('renders the component', () => { | ||
mount(UsaIconList, { | ||
slots: { | ||
default: () => h('li', {}, 'Test icon list item'), | ||
}, | ||
}) | ||
|
||
cy.get('ul.usa-icon-list') | ||
.should('have.attr', 'class') | ||
.and('not.match', /usa-icon-list--/) | ||
cy.get('.usa-icon-list > li').should('contain', 'Test icon list item') | ||
}) | ||
|
||
it('applied color and size CSS classes from prop values', () => { | ||
mount(UsaIconList, { | ||
props: { | ||
color: 'primary', | ||
size: 'xl', | ||
}, | ||
}) | ||
|
||
cy.get('.usa-icon-list') | ||
.should('have.class', 'usa-icon-list--primary') | ||
.and('have.class', 'usa-icon-list--size-xl') | ||
}) | ||
|
||
it('formats RWD CSS size classes', () => { | ||
mount(UsaIconList, { | ||
props: { | ||
size: { | ||
mobile: 'sm', | ||
tablet: 'lg', | ||
desktop: '2xl', | ||
}, | ||
}, | ||
}) | ||
|
||
cy.get('.usa-icon-list') | ||
.should('have.class', 'mobile:usa-icon-list--size-sm') | ||
.and('have.class', 'tablet:usa-icon-list--size-lg') | ||
.and('have.class', 'desktop:usa-icon-list--size-2xl') | ||
}) | ||
|
||
it('uses custom responsive prefix separator', () => { | ||
mount(UsaIconList, { | ||
props: { | ||
size: { | ||
mobile: 'sm', | ||
tablet: 'lg', | ||
desktop: '2xl', | ||
}, | ||
}, | ||
global: { | ||
provide: { | ||
'vueUswds.prefixSeparator': '-', | ||
}, | ||
}, | ||
}) | ||
|
||
cy.get('.usa-icon-list') | ||
.should('have.class', 'mobile-usa-icon-list--size-sm') | ||
.and('have.class', 'tablet-usa-icon-list--size-lg') | ||
.and('have.class', 'desktop-usa-icon-list--size-2xl') | ||
}) | ||
|
||
it('warns in console about invalid `size` prop', () => { | ||
cy.stub(window.console, 'warn').as('consoleWarn') | ||
|
||
mount(UsaIconList, { | ||
props: { | ||
size: 'invalidsize', | ||
}, | ||
}) | ||
|
||
cy.get('@consoleWarn').should( | ||
'be.calledWith', | ||
`'invalidsize' is not a valid icon list size` | ||
) | ||
}) | ||
}) |
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,66 @@ | ||
<script setup> | ||
import { computed, inject } from 'vue' | ||
import { PREFIX_SEPARATOR } from '@/utils/constants.js' | ||
const prefixSeparator = inject('vueUswds.prefixSeparator', PREFIX_SEPARATOR) | ||
const props = defineProps({ | ||
color: { | ||
type: String, | ||
default: '', | ||
}, | ||
size: { | ||
type: [String, Object], | ||
default: '', | ||
validator(size) { | ||
let isValidSize = false | ||
const validSizes = ['', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl'] | ||
if (typeof size === 'string') { | ||
isValidSize = validSizes.includes(size) | ||
} | ||
if (typeof size === 'object') { | ||
isValidSize = Object.values(size).some(breakpointSize => | ||
validSizes.includes(breakpointSize) | ||
) | ||
} | ||
if (!isValidSize) { | ||
console.warn(`'${size}' is not a valid icon list size`) | ||
} | ||
return isValidSize | ||
}, | ||
}, | ||
}) | ||
const sizeClasses = computed(() => { | ||
if (!!props.size && typeof props.size === 'string') { | ||
return [`usa-icon-list--size-${props.size}`] | ||
} | ||
if (typeof props.size === 'object' && Object.keys(props.size).length) { | ||
return Object.keys(props.size).reduce((acc, breakpoint) => { | ||
acc.push( | ||
`${breakpoint}${prefixSeparator}usa-icon-list--size-${props.size[breakpoint]}` | ||
) | ||
return acc | ||
}, []) | ||
} | ||
return [] | ||
}) | ||
const classes = computed(() => [ | ||
{ [`usa-icon-list--${props.color}`]: props.color }, | ||
...sizeClasses.value, | ||
]) | ||
</script> | ||
|
||
<template> | ||
<ul class="usa-icon-list" :class="classes" | ||
><slot></slot | ||
></ul> | ||
</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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import UsaIconList from './UsaIconList.vue' | ||
|
||
export { UsaIconList } | ||
export default UsaIconList |
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