Skip to content

Commit

Permalink
feat(UsaSelect): add explicit group prop option
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickcate committed Jan 8, 2023
1 parent de825e0 commit aa08448
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 46 deletions.
100 changes: 57 additions & 43 deletions src/components/UsaSelect/UsaSelect.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ export default {
modelValue: {
control: { type: 'text' },
},
group: {
control: { type: 'boolean' },
},
label: {
control: { type: 'text' },
table: {
Expand Down Expand Up @@ -112,6 +115,7 @@ export default {
options: defaultProps.options,
emptyLabel: defaultProps.emptyLabel,
modelValue: defaultProps.modelValue,
group: defaultProps.group,
label: defaultProps.label,
required: defaultProps.required,
error: defaultProps.error,
Expand Down Expand Up @@ -140,6 +144,7 @@ const DefaultTemplate = (args, { argTypes }) => ({
v-bind="$attrs"
:options="options"
:empty-label="emptyLabel"
:group="group"
:label="label"
:required="required"
:error="error"
Expand All @@ -160,103 +165,112 @@ const DefaultTemplate = (args, { argTypes }) => ({
</UsaSelect>`,
})

export const DefaultDropdown = DefaultTemplate.bind({})
DefaultDropdown.args = {
export const DefaultSelect = DefaultTemplate.bind({})
DefaultSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
}
DefaultDropdown.storyName = 'Default'
DefaultSelect.storyName = 'Default'

export const DefaultByDefaultDropdown = DefaultTemplate.bind({})
DefaultByDefaultDropdown.args = {
export const DefaultByDefaultSelect = DefaultTemplate.bind({})
DefaultByDefaultSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
modelValue: '2',
}
DefaultByDefaultDropdown.storyName = 'Selected by Default'
DefaultByDefaultSelect.storyName = 'Selected by Default'

export const HintDropdown = DefaultTemplate.bind({})
HintDropdown.args = {
export const HintSelect = DefaultTemplate.bind({})
HintSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
hint: 'Choose wisely',
}
HintDropdown.storyName = 'Hint'
HintSelect.storyName = 'Hint'

export const ErrorDropdown = DefaultTemplate.bind({})
ErrorDropdown.args = {
export const ErrorSelect = DefaultTemplate.bind({})
ErrorSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
error: true,
}
ErrorDropdown.storyName = 'Error'
ErrorSelect.storyName = 'Error'

export const ErrorMessageDropdown = DefaultTemplate.bind({})
ErrorMessageDropdown.args = {
export const ErrorMessageSelect = DefaultTemplate.bind({})
ErrorMessageSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
error: true,
'error-message': 'Error message here',
}
ErrorMessageDropdown.storyName = 'Error Message'
ErrorMessageSelect.storyName = 'Error Message'

export const GroupedSelect = DefaultTemplate.bind({})
GroupedSelect.args = {
...defaultProps,
label: 'Select label',
options: testOptions,
group: true,
}
GroupedSelect.storyName = 'Group Elements'

export const RequiredDropdown = DefaultTemplate.bind({})
RequiredDropdown.args = {
export const RequiredSelect = DefaultTemplate.bind({})
RequiredSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
required: true,
}
RequiredDropdown.storyName = 'Required'
RequiredSelect.storyName = 'Required'

export const CustomEmptyLabelDropdown = DefaultTemplate.bind({})
CustomEmptyLabelDropdown.args = {
export const CustomEmptyLabelSelect = DefaultTemplate.bind({})
CustomEmptyLabelSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
emptyLabel: 'Custom empty label',
}
CustomEmptyLabelDropdown.storyName = 'Custom Empty Label'
CustomEmptyLabelSelect.storyName = 'Custom Empty Label'

export const LabelSlotDropdown = DefaultTemplate.bind({})
LabelSlotDropdown.args = {
export const LabelSlotSelect = DefaultTemplate.bind({})
LabelSlotSelect.args = {
...defaultProps,
options: testOptions,
'slot:label': `<em>Label slot content</em>`,
}
LabelSlotDropdown.storyName = 'Label Slot'
LabelSlotSelect.storyName = 'Label Slot'

export const ScopedSlotDropdown = DefaultTemplate.bind({})
ScopedSlotDropdown.args = {
export const ScopedSlotSelect = DefaultTemplate.bind({})
ScopedSlotSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
default: `<option :value="options[0].value">{{ options[0].value }}</option>`,
}
ScopedSlotDropdown.storyName = 'Scoped Slot'
ScopedSlotSelect.storyName = 'Scoped Slot'

export const CustomIdDropdown = DefaultTemplate.bind({})
CustomIdDropdown.args = {
export const CustomIdSelect = DefaultTemplate.bind({})
CustomIdSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
id: 'custom-id',
}
CustomIdDropdown.storyName = 'Custom ID'
CustomIdSelect.storyName = 'Custom ID'

export const CustomClassesDropdown = DefaultTemplate.bind({})
CustomClassesDropdown.args = {
export const CustomClassesSelect = DefaultTemplate.bind({})
CustomClassesSelect.args = {
...defaultProps,
label: 'Dropdown label',
label: 'Select label',
options: testOptions,
customClasses: {
component: ['test-component-class'],
label: ['test-label-class'],
},
}
CustomClassesDropdown.storyName = 'Custom CSS Classes'
CustomClassesSelect.storyName = 'Custom CSS Classes'
14 changes: 14 additions & 0 deletions src/components/UsaSelect/UsaSelect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,4 +360,18 @@ describe('UsaSelect', () => {
cy.get('.usa-form-group').should('have.class', 'test-component-class')
cy.get('.usa-label').should('have.class', 'test-label-class')
})

it('use group wrapper if `group` prop is true', () => {
mount(UsaSelect, {
props: {
group: true,
},
attrs: {
'aria-describedby': 'test-hint',
},
})

cy.get('div.usa-form-group').should('exist')
cy.get('select').should('have.attr', 'aria-describedby', 'test-hint')
})
})
19 changes: 16 additions & 3 deletions src/components/UsaSelect/UsaSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ export default {
</script>

<script setup>
import { computed, useSlots } from 'vue'
import { computed, useSlots, useAttrs } from 'vue'
import { nextId } from '@/utils/unique-id.js'
import UsaFormGroup from '@/components/UsaFormGroup'
import UsaLabel from '@/components/UsaLabel'
const slots = useSlots()
const attrs = useAttrs()
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
Expand All @@ -23,9 +24,13 @@ const props = defineProps({
default: '- Select -',
},
modelValue: {
type: undefined,
type: [String, Number],
default: '',
},
group: {
type: Boolean,
default: false,
},
label: {
type: String,
default: '',
Expand Down Expand Up @@ -73,6 +78,10 @@ const classes = computed(() => [{ 'usa-input--error': props.error }])
const ariaDescribedby = computed(() => {
const ids = []
if (attrs['aria-describedby']) {
ids.push(attrs['aria-describedby'])
}
if (slots.hint) {
ids.push(computedHintId.value)
}
Expand All @@ -83,11 +92,15 @@ const ariaDescribedby = computed(() => {
return ids.length ? ids.join(' ') : null
})
const groupElements = computed(
() => props.group || !!slots.hint || (props.error && !!slots['error-message'])
)
</script>

<template>
<UsaFormGroup
:group="!!$slots.hint || (error && !!$slots['error-message'])"
:group="groupElements"
:error="error"
:class="props.customClasses?.component"
>
Expand Down

0 comments on commit aa08448

Please sign in to comment.