Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add uswds combo box #1373

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 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,115 @@
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,
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,
}) => {

return (
<va-combo-box
label={label}
name={name}
value={value}
required={required}
error={error}
hint={hint}
placeholder={placeholder}
disabled={disabled}
>
{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 Disabled = Template.bind({});
Disabled.args = {
...defaultArgs,
value: 'elderberry',
disabled: true,
Copy link
Contributor

@jamigibbs jamigibbs Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to advertise that there is a disabled state. There are a11y concerns with this functionality.

Or maybe we don't want to have this functionality in the component at all? I will let the design and a11y reviewers weigh in on that though. cc @department-of-veterans-affairs/platform-design-system-designers @rsmithadhoc

Screenshot 2024-11-01 at 9 28 50 AM

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, our stance on disabled states is that instead of disabling something, just don't show it if it serves no purpose. I'm okay with leaving it in for parity with USWDS, but just not advertising it.

};
165 changes: 165 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,64 @@ export namespace Components {
*/
"useFormsPattern"?: string;
}
/**
* @componentName Combo Box
* @maturityCategory dont_use
* @maturityLevel proposed
* @guidanceHref form/combo-box
* @translations English
* @translations Spanish
*/
interface VaComboBox {
/**
* The combo box component will be disabled / read-only.
*/
"disabled"?: boolean;
/**
* Whether or not to fire the analytics events
*/
"enableAnalytics"?: boolean;
/**
* Error message to display. When defined, this indicates an error.
*/
"error"?: string;
/**
* Optional hint text.
*/
"hint"?: string;
/**
* Whether or not `aria-invalid` will be set on the inner select. Useful when composing the component into something larger, like a date component.
*/
"invalid"?: boolean;
/**
* 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;
/**
* Whether an error message should be shown - set to false when this component is used inside va-date or va-memorable-date in which the error for the va-select will be rendered outside of va-select
*/
"showError"?: boolean;
/**
* Selected value (will get updated on select).
*/
"value"?: string;
}
/**
* @componentName Crisis Line Modal
* @maturityCategory caution
Expand Down Expand Up @@ -1777,6 +1835,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 @@ -2182,6 +2244,32 @@ declare global {
prototype: HTMLVaCheckboxGroupElement;
new (): HTMLVaCheckboxGroupElement;
};
interface HTMLVaComboBoxElementEventMap {
"vaSelect": any;
"component-library-analytics": any;
}
/**
* @componentName Combo Box
* @maturityCategory dont_use
* @maturityLevel proposed
* @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 @@ -2915,6 +3003,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 @@ -3458,6 +3547,72 @@ declare namespace LocalJSX {
*/
"useFormsPattern"?: string;
}
/**
* @componentName Combo Box
* @maturityCategory dont_use
* @maturityLevel proposed
* @guidanceHref form/combo-box
* @translations English
* @translations Spanish
*/
interface VaComboBox {
/**
* The combo box component will be disabled / read-only.
*/
"disabled"?: boolean;
/**
* Whether or not to fire the analytics events
*/
"enableAnalytics"?: boolean;
/**
* Error message to display. When defined, this indicates an error.
*/
"error"?: string;
/**
* Optional hint text.
*/
"hint"?: string;
/**
* Whether or not `aria-invalid` will be set on the inner select. Useful when composing the component into something larger, like a date component.
*/
"invalid"?: boolean;
/**
* 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 used to track usage of the component. This is emitted when an option is selected and enableAnalytics is true.
*/
"onComponent-library-analytics"?: (event: VaComboBoxCustomEvent<any>) => void;
/**
* 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;
/**
* Whether an error message should be shown - set to false when this component is used inside va-date or va-memorable-date in which the error for the va-select will be rendered outside of va-select
*/
"showError"?: boolean;
/**
* Selected value (will get updated on select).
*/
"value"?: string;
}
/**
* @componentName Crisis Line Modal
* @maturityCategory caution
Expand Down Expand Up @@ -4934,6 +5089,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 @@ -5073,6 +5229,15 @@ declare module "@stencil/core" {
* @translations Tagalog
*/
"va-checkbox-group": LocalJSX.VaCheckboxGroup & JSXBase.HTMLAttributes<HTMLVaCheckboxGroupElement>;
/**
* @componentName Combo Box
* @maturityCategory dont_use
* @maturityLevel proposed
* @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
Loading