Skip to content

Commit

Permalink
va-combo-box: add new component (#1373)
Browse files Browse the repository at this point in the history
* initial component plot

* tweaks and styling

* adding label

* adding disabled prop

* adding defaultValue prop

* placeholder prop

* format and cleanup

* handle label and value change

* handle required prop

* update doc attributes + cleanup

* update default value prop

* handling hint text and aria

* docs

* build

* styling cleanup

* update docs

* e2e tests

* cleanup

* remove disabled state from docs

* focus style mixin

* remove analytics props

* showError prop non applicable

* input styling

* buttons positioning

* max-width for high zoom

* redo message-aria-describedby

* remove not needed styling

* update maturity level

* console log cleanup

* remove analytics event emitter

* remove irrelevant error

* Update components.d.ts

* non-used props

* e2e tests

* style updates
  • Loading branch information
oleksii-morgun authored Dec 4, 2024
1 parent 28824e7 commit 08ed91f
Show file tree
Hide file tree
Showing 6 changed files with 1,551 additions and 0 deletions.
117 changes: 117 additions & 0 deletions packages/storybook/stories/va-combo-box-uswds.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import React from 'react';
import { getWebComponentDocs, propStructure, StoryDocs } from './wc-helpers';

const comboBoxDocs = getWebComponentDocs('va-combo-box');

export default {
title: 'Components/Combo Box USWDS',
id: 'uswds/va-combo-box',
parameters: {
componentSubtitle: 'va-combo-box web component',
docs: {
page: () => <StoryDocs storyDefault={Default} data={comboBoxDocs} />,
},
},
};

const defaultArgs = {
label: 'Select a fruit',
name: 'fruit',
value: '',
required: false,
error: undefined,
messageAriaDescribedby: undefined,
options: [
<option value="apple">Apple</option>,
<option value="banana">Banana</option>,
<option value="blackberry">Blackberry</option>,
<option value="blueberry">Blueberry</option>,
<option value="boysenberry">Boysenberry</option>,
<option value="cherry">Cherry</option>,
<option value="crab apple">Crab Apple</option>,
<option value="cranberry">Cranberry</option>,
<option value="custard apple">Custard apple</option>,
<option value="date">Date</option>,
<option value="elderberry">Elderberry</option>,
<option value="fig">Fig</option>,
<option value="gooseberry">Gooseberry</option>,
<option value="mango">Mango</option>,
<option value="mangosteen">Mangosteen</option>,
<option value="marionberry">Marionberry</option>,
<option value="pineapple">Pineapple</option>,
<option value="raspberry">Raspberry</option>,
<option value="rambutan">Rambutan</option>,
<option value="starfruit">Starfruit</option>,
<option value="strawberry">Strawberry</option>
],
};

const Template = ({
label,
name,
value,
required,
error,
hint,
options,
placeholder,
disabled,
messageAriaDescribedby,
}) => {

return (
<va-combo-box
label={label}
name={name}
value={value}
required={required}
error={error}
hint={hint}
placeholder={placeholder}
disabled={disabled}
message-aria-describedby={messageAriaDescribedby}
>
{options}
</va-combo-box>
);
};

export const Default = Template.bind({});
Default.args = { ...defaultArgs };
Default.argTypes = propStructure(comboBoxDocs);

export const WithDefaultValue = Template.bind({});
WithDefaultValue.args = {
...defaultArgs,
value: 'banana',
};

export const WithError = Template.bind({});
WithError.args = {
...defaultArgs,
error: 'This field contains an error.',
};

export const Required = Template.bind({});
Required.args = {
...defaultArgs,
required: true,
};

export const WithPlaceholderText = Template.bind({});
WithPlaceholderText.args = {
...defaultArgs,
placeholder: '--Select--',
};

export const WithHintText = Template.bind({});
WithHintText.args = {
...defaultArgs,
hint: 'This is example hint text',
};

export const WithMessageAriaDescribedBy = Template.bind({});
WithMessageAriaDescribedBy.args = {
...defaultArgs,
messageAriaDescribedby: 'This is example aria message',
};
136 changes: 136 additions & 0 deletions packages/web-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,52 @@ export namespace Components {
*/
"useFormsPattern"?: string;
}
/**
* @componentName Combo Box
* @maturityCategory caution
* @maturityLevel candidate
* @guidanceHref form/combo-box
* @translations English
* @translations Spanish
*/
interface VaComboBox {
/**
* The combo box component will be disabled / read-only.
*/
"disabled"?: boolean;
/**
* Error message to display. When defined, this indicates an error.
*/
"error"?: string;
/**
* Optional hint text.
*/
"hint"?: string;
/**
* Text label for the field.
*/
"label": string;
/**
* An optional message that will be read by screen readers when the select is focused.
*/
"messageAriaDescribedby"?: string;
/**
* Name attribute for the select field.
*/
"name": string;
/**
* The placeholder string.
*/
"placeholder"?: string;
/**
* Whether or not this is a required field.
*/
"required"?: boolean;
/**
* Selected value (will get updated on select).
*/
"value"?: string;
}
/**
* @componentName Crisis Line Modal
* @maturityCategory caution
Expand Down Expand Up @@ -1848,6 +1894,10 @@ export interface VaCheckboxGroupCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLVaCheckboxGroupElement;
}
export interface VaComboBoxCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLVaComboBoxElement;
}
export interface VaDateCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLVaDateElement;
Expand Down Expand Up @@ -2261,6 +2311,31 @@ declare global {
prototype: HTMLVaCheckboxGroupElement;
new (): HTMLVaCheckboxGroupElement;
};
interface HTMLVaComboBoxElementEventMap {
"vaSelect": any;
}
/**
* @componentName Combo Box
* @maturityCategory caution
* @maturityLevel candidate
* @guidanceHref form/combo-box
* @translations English
* @translations Spanish
*/
interface HTMLVaComboBoxElement extends Components.VaComboBox, HTMLStencilElement {
addEventListener<K extends keyof HTMLVaComboBoxElementEventMap>(type: K, listener: (this: HTMLVaComboBoxElement, ev: VaComboBoxCustomEvent<HTMLVaComboBoxElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof HTMLVaComboBoxElementEventMap>(type: K, listener: (this: HTMLVaComboBoxElement, ev: VaComboBoxCustomEvent<HTMLVaComboBoxElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
var HTMLVaComboBoxElement: {
prototype: HTMLVaComboBoxElement;
new (): HTMLVaComboBoxElement;
};
/**
* @componentName Crisis Line Modal
* @maturityCategory caution
Expand Down Expand Up @@ -3028,6 +3103,7 @@ declare global {
"va-card": HTMLVaCardElement;
"va-checkbox": HTMLVaCheckboxElement;
"va-checkbox-group": HTMLVaCheckboxGroupElement;
"va-combo-box": HTMLVaComboBoxElement;
"va-crisis-line-modal": HTMLVaCrisisLineModalElement;
"va-date": HTMLVaDateElement;
"va-file-input": HTMLVaFileInputElement;
Expand Down Expand Up @@ -3572,6 +3648,56 @@ declare namespace LocalJSX {
*/
"useFormsPattern"?: string;
}
/**
* @componentName Combo Box
* @maturityCategory caution
* @maturityLevel candidate
* @guidanceHref form/combo-box
* @translations English
* @translations Spanish
*/
interface VaComboBox {
/**
* The combo box component will be disabled / read-only.
*/
"disabled"?: boolean;
/**
* Error message to display. When defined, this indicates an error.
*/
"error"?: string;
/**
* Optional hint text.
*/
"hint"?: string;
/**
* Text label for the field.
*/
"label": string;
/**
* An optional message that will be read by screen readers when the select is focused.
*/
"messageAriaDescribedby"?: string;
/**
* Name attribute for the select field.
*/
"name": string;
/**
* The event emitted when the selected value changes
*/
"onVaSelect"?: (event: VaComboBoxCustomEvent<any>) => void;
/**
* The placeholder string.
*/
"placeholder"?: string;
/**
* Whether or not this is a required field.
*/
"required"?: boolean;
/**
* Selected value (will get updated on select).
*/
"value"?: string;
}
/**
* @componentName Crisis Line Modal
* @maturityCategory caution
Expand Down Expand Up @@ -5128,6 +5254,7 @@ declare namespace LocalJSX {
"va-card": VaCard;
"va-checkbox": VaCheckbox;
"va-checkbox-group": VaCheckboxGroup;
"va-combo-box": VaComboBox;
"va-crisis-line-modal": VaCrisisLineModal;
"va-date": VaDate;
"va-file-input": VaFileInput;
Expand Down Expand Up @@ -5268,6 +5395,15 @@ declare module "@stencil/core" {
* @translations Tagalog
*/
"va-checkbox-group": LocalJSX.VaCheckboxGroup & JSXBase.HTMLAttributes<HTMLVaCheckboxGroupElement>;
/**
* @componentName Combo Box
* @maturityCategory caution
* @maturityLevel candidate
* @guidanceHref form/combo-box
* @translations English
* @translations Spanish
*/
"va-combo-box": LocalJSX.VaComboBox & JSXBase.HTMLAttributes<HTMLVaComboBoxElement>;
/**
* @componentName Crisis Line Modal
* @maturityCategory caution
Expand Down
Loading

0 comments on commit 08ed91f

Please sign in to comment.