Skip to content

Commit

Permalink
feat(dropdown/combo-box): syncing dropdown and combo-box to v11 (#10343)
Browse files Browse the repository at this point in the history
* feat(dropdown): syncing dropdown react v11
* feat(combo-box): syncing with react v11
---------

Co-authored-by: kennylam <[email protected]>
  • Loading branch information
IgnacioBecerra and kennylam authored Apr 25, 2023
1 parent 8735972 commit 017043d
Show file tree
Hide file tree
Showing 18 changed files with 778 additions and 476 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import { customElement } from 'lit/decorators.js';
import { prefix } from '../../globals/settings';
import BXDropdownItem from '../dropdown/dropdown-item';
import CDSDropdownItem from '../dropdown/dropdown-item';
import styles from './combo-box.scss';

/**
Expand All @@ -18,8 +18,8 @@ import styles from './combo-box.scss';
* @element cds-combo-box-item
*/
@customElement(`${prefix}-combo-box-item`)
class BXComboBoxItem extends BXDropdownItem {
class CDSComboBoxItem extends CDSDropdownItem {
static styles = styles;
}

export default BXComboBoxItem;
export default CDSComboBoxItem;
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,7 @@ import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn';
[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/combo-box)

Combo box realizes a notion of "filterable dropdown". By default, the dropdown
displays a label when closed. When the user hovers over the label area, a text
cursor will appear. The drawer opens on click (anywhere in the field) and the
user can type to filter through the list of options below. Once the user begins
typing, the close (X) icon will appear to the right of the label. This will
clear any user-inputted text. Selecting an item from the dropdown will close the
drawer and the selected option will replace the default label.
A combobox allows the user to make a selection from a predefined list of options and is typically used when there are a large amount of options to choose from.

## Getting started

Expand All @@ -34,9 +28,9 @@ import '@carbon/web-components/es/components/combo-box/index.js';

```html
<cds-combo-box
helper-text="Optional helper text"
label-text="Combo box title"
trigger-content="Filter..."
helper-text="This is some helper text"
title-text="Combo box title"
label="Filter..."
>
<cds-combo-box-item value="all">Option 1</cds-combo-box-item>
<cds-combo-box-item value="cloudFoundry">Option 2</cds-combo-box-item>
Expand All @@ -49,6 +43,36 @@ import '@carbon/web-components/es/components/combo-box/index.js';
</cds-combo-box>
```

## Disabled

A disabled combobox is available but should not be used as the sole means of conveying information.
For example, if the user must complete a previous form input before moving on to the combobox,
make sure to make that clear to the user via an error state on the previous form element in addition
to disabling the next element.

```html
<cds-combo-box
helper-text="This is some helper text"
title-text="Combo box title"
label="Filter..."
disabled
>
<cds-combo-box-item value="all">Option 1</cds-combo-box-item>
<cds-combo-box-item value="cloudFoundry">Option 2</cds-combo-box-item>
<cds-combo-box-item value="staging">Option 3</cds-combo-box-item>
<cds-combo-box-item value="dea">Option 4</cds-combo-box-item>
<cds-combo-box-item value="router">Option 5</cds-combo-box-item>
<cds-combo-box-item value="support">Option 6</cds-combo-box-item>
<cds-combo-box-item value="services">Option 7</cds-combo-box-item>
<cds-combo-box-item value="products">Option 8</cds-combo-box-item>
</cds-combo-box>
```

## Labels and Helper Texts
The label is not a replacement for a helper or title text under any circumstances including space restraints.
A label should be used to provide additive information regarding the format of the input.
In all cases a helper text is required in addition to a placeholder.

## Selection

When user attempts to select a combo box item, `cds-combo-box-beingselected`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,138 +9,177 @@

import { html } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { action } from '@storybook/addon-actions';
import { boolean, select, text } from '@storybook/addon-knobs';
import {
DROPDOWN_COLOR_SCHEME,
DROPDOWN_SIZE,
DROPDOWN_TYPE,
} from './combo-box';
import { boolean, select } from '@storybook/addon-knobs';
import { DROPDOWN_DIRECTION, DROPDOWN_SIZE } from './combo-box';
import './combo-box-item';
import storyDocs from './combo-box-story.mdx';
import { prefix } from '../../globals/settings';
import textNullable from '../../../.storybook/knob-text-nullable';

const colorSchemes = {
[`Regular`]: null,
[`Light (${DROPDOWN_COLOR_SCHEME.LIGHT})`]: DROPDOWN_COLOR_SCHEME.LIGHT,
};
const items = [
{
value: 'option-0',
text: 'An example option that is really long to show what should be done to handle long text',
},
{
value: 'option-1',
text: 'Option 1',
},
{
value: 'option-2',
text: 'Option 2',
},
{
value: 'option-3',
text: 'Option 3 - a disabled item',
disabled: true,
},
{
value: 'option-4',
text: 'Option 4',
},
{
value: 'option-5',
text: 'Option 5',
},
];

const types = {
Regular: null,
[`Inline (${DROPDOWN_TYPE.INLINE})`]: DROPDOWN_TYPE.INLINE,
const directionOptions = {
[`Top`]: DROPDOWN_DIRECTION.TOP,
[`Bottom`]: DROPDOWN_DIRECTION.BOTTOM,
};

const sizes = {
'Regular size': null,
[`Small size (${DROPDOWN_SIZE.SMALL})`]: DROPDOWN_SIZE.SMALL,
[`Extra large size (${DROPDOWN_SIZE.EXTRA_LARGE})`]:
DROPDOWN_SIZE.EXTRA_LARGE,
'Regular size': null,
[`Large size (${DROPDOWN_SIZE.LARGE})`]: DROPDOWN_SIZE.LARGE,
};

export const Default = () => {
return html`
<cds-combo-box
helper-text="Combobox helper text"
title-text="ComboBox title">
${items.map(
(elem) => html`
<cds-combo-box-item ?disabled=${elem.disabled} value="${elem.value}"
>${elem.text}</cds-combo-box-item
>
`
)}
</cds-combo-box>
`;
};

export const WithLayer = () => {
return html`
<sb-template-layers>
<div style="width:400px">
<cds-combo-box
title-text="ComboBox label"
helper-text="Combobox helper text"
label="Dropdown menu options">
${items.map(
(elem) => html`
<cds-combo-box-item
?disabled=${elem.disabled}
value="${elem.value}"
>${elem.text}</cds-combo-box-item
>
`
)}
</cds-combo-box>
</div>
</sb-template-layers>
`;
};

export const Default = (args) => {
export const Playground = (args) => {
const {
open,
colorScheme,
disabled,
helperText,
invalid,
labelText,
titleText,
hideLabel,
direction,
readOnly,
warn,
warnText,
size,
triggerContent,
label,
type,
validityMessage,
invalidText,
value,
disableSelection,
disableToggle,
onBeforeSelect,
onBeforeToggle,
onSelect,
onToggle,
} = args?.[`${prefix}-combo-box`] ?? {};
const handleBeforeSelect = (event: CustomEvent) => {
if (onBeforeSelect) {
onBeforeSelect(event);
}
if (disableSelection) {
event.preventDefault();
}
};
const handleBeforeToggle = (event: CustomEvent) => {
if (onBeforeToggle) {
onBeforeToggle(event);
}
if (disableToggle) {
event.preventDefault();
}
};
return html`
<cds-combo-box
?open=${open}
color-scheme="${ifDefined(colorScheme)}"
?disabled=${disabled}
?disabled="${disabled}"
?hide-label=${hideLabel}
helper-text=${ifDefined(helperText)}
?invalid=${invalid}
helper-text=${helperText}
label-text=${labelText}
invalid-text=${invalidText}
direction="${direction}"
?read-only=${readOnly}
title-text=${ifDefined(titleText)}
size="${ifDefined(size)}"
validity-message=${validityMessage}
value=${value}
trigger-content=${triggerContent}
type=${ifDefined(type)}
@cds-combo-box-beingselected=${handleBeforeSelect}
@cds-combo-box-beingtoggled=${handleBeforeToggle}
@cds-combo-box-selected=${onSelect}
@cds-combo-box-toggled=${onToggle}>
<cds-combo-box-item value="all">Option 1</cds-combo-box-item>
<cds-combo-box-item value="cloudFoundry">Option 2</cds-combo-box-item>
<cds-combo-box-item value="staging">Option 3</cds-combo-box-item>
<cds-combo-box-item value="dea">Option 4</cds-combo-box-item>
<cds-combo-box-item value="router">Option 5</cds-combo-box-item>
<cds-combo-box-item value="support">Option 6</cds-combo-box-item>
<cds-combo-box-item value="services">Option 7</cds-combo-box-item>
<cds-combo-box-item value="products">Option 8</cds-combo-box-item>
type="${ifDefined(type)}"
value=${ifDefined(value)}
label=${ifDefined(label)}
?warn=${warn}
warn-text=${warnText}>
${items.map(
(elem) => html`
<cds-combo-box-item ?disabled=${elem.disabled} value="${elem.value}"
>${elem.text}</cds-combo-box-item
>
`
)}
</cds-combo-box>
`;
};

Default.decorators = [
(story) => html` <div style="width:300px">${story()}</div> `,
];

Default.storyName = 'Default';
Playground.parameters = {
knobs: {
[`${prefix}-combo-box`]: () => ({
direction: select(
'Direction',
directionOptions,
DROPDOWN_DIRECTION.BOTTOM
),
disabled: boolean('Disabled (disabled)', false),
helperText: textNullable(
'Helper text (helper-text)',
'Optional helper text'
),
hideLabel: boolean('Hide label (hide-label)', false),
invalid: boolean('Invalid (invalid)', false),
invalidText: textNullable(
'Invalid text (invalid-text)',
'invalid selection'
),
readOnly: boolean('Read only (read-only)', false),
titleText: textNullable('Title text (title-text)', 'ComboBox title'),
size: select('Size (size)', sizes, null),
value: textNullable('Selected value (value)', ''),
label: textNullable('Placeholder (label)', ''),
warn: boolean('Warn (warn)', false),
warnText: textNullable(
'Warn text (warn-text)',
'please notice the warning'
),
}),
},
};

export default {
title: 'Components/Combo box',
parameters: {
...storyDocs.parameters,
knobs: {
[`${prefix}-combo-box`]: () => ({
open: boolean('Open (open)', false),
colorScheme: select('Color scheme (color-scheme)', colorSchemes, null),
disabled: boolean('Disabled (disabled)', false),
helperText: text('Helper text (helper-text)', 'Optional helper text'),
invalid: boolean('Show invalid state (invalid)', false),
labelText: text('Label text (label-text)', 'Combo box title'),
size: select('Dropdown size (size)', sizes, null),
triggerContent: text(
'The placeholder content (trigger-content)',
'Filter...'
),
type: select('UI type (type)', types, null),
validityMessage: text('The validity message (validity-message)', ''),
value: text('The value of the selected item (value)', ''),
disableSelection: boolean(
`Disable user-initiated selection change (Call event.preventDefault() in ${prefix}-combo-box-beingselected event)`,
false
),
disableToggle: boolean(
`Disable user-initiated toggle of open state (Call event.preventDefault() in ${prefix}-combo-box-beingtoggled event)`,
false
),
onBeforeSelect: action(`${prefix}-combo-box-beingselected`),
onBeforeToggle: action(`${prefix}-combo-box-beingtoggled`),
onSelect: action(`${prefix}-combo-box-selected`),
onToggle: action(`${prefix}-combo-box-toggled`),
}),
},
},
decorators: [
(story, { name }) => {
const width = !name.toLowerCase().includes('layer') ? `width:400px` : ``;
return html` <div style="${width}">${story()}</div> `;
},
],
};
Loading

0 comments on commit 017043d

Please sign in to comment.