Skip to content

Commit 05a5449

Browse files
authored
feat(combo-box): add inputProps in web components (carbon-design-system#21501)
* feat(combo-box): add inputProps in web components * chore(combobox): clean comments
1 parent 6cf59ea commit 05a5449

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

packages/web-components/src/components/combo-box/combo-box.stories.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const defaultArgs = {
7171
value: '',
7272
warn: false,
7373
warnText: 'Warning message goes here',
74+
inputProps: undefined,
7475
};
7576

7677
const controls = {
@@ -104,6 +105,10 @@ const controls = {
104105
control: 'text',
105106
description: `Message which is displayed if the value is invalid.`,
106107
},
108+
inputProps: {
109+
control: 'object',
110+
description: `Specify native input attributes to place on the internal input, for example \`{ maxlength: 5, autocomplete: 'off'}\`.`,
111+
},
107112
label: {
108113
control: 'text',
109114
description: `The default content of the trigger button.`,
@@ -145,6 +150,7 @@ export const Default = {
145150
...defaultArgs,
146151
helperText: 'Helper text',
147152
titleText: 'Label',
153+
inputProps: {},
148154
},
149155
render: (args) => {
150156
const {
@@ -164,9 +170,11 @@ export const Default = {
164170
invalidText,
165171
value,
166172
typeahead,
173+
inputProps,
167174
} = args ?? {};
168175
return html`
169176
<cds-combo-box
177+
.inputProps=${inputProps}
170178
?disabled=${disabled}
171179
?autoalign=${autoalign}
172180
helper-text=${ifDefined(helperText)}
@@ -253,10 +261,11 @@ export const AllowCustomValue = {
253261
invalidText,
254262
value,
255263
typeahead,
264+
inputProps,
256265
} = args ?? {};
257266
return html`
258267
<cds-combo-box
259-
allow-custom-value="true"
268+
.inputProps=${inputProps}
260269
direction=${ifDefined(direction)}
261270
?disabled=${disabled}
262271
?autoalign=${autoalign}
@@ -313,9 +322,11 @@ export const AutocompleteWithTypeahead = {
313322
invalidText,
314323
value,
315324
typeahead,
325+
inputProps,
316326
} = args ?? {};
317327
return html`
318328
<cds-combo-box
329+
.inputProps=${inputProps}
319330
direction=${ifDefined(direction)}
320331
?disabled=${disabled}
321332
?autoalign=${autoalign}
@@ -373,11 +384,13 @@ export const ExperimentalAutoAlign = {
373384
invalidText,
374385
value,
375386
typeahead,
387+
inputProps,
376388
} = args ?? {};
377389
return html`
378390
<div style="width:400px">
379391
<div style="height: 300px"></div>
380392
<cds-combo-box
393+
.inputProps=${inputProps}
381394
?autoalign=${autoalign}
382395
direction=${ifDefined(direction)}
383396
?disabled=${disabled}
@@ -434,6 +447,7 @@ export const Controlled = {
434447
titleText,
435448
type,
436449
typeahead,
450+
inputProps,
437451
value,
438452
warn,
439453
warnText,
@@ -476,6 +490,7 @@ export const Controlled = {
476490

477491
return html`
478492
<cds-combo-box
493+
.inputProps=${inputProps}
479494
controlled
480495
direction=${ifDefined(direction)}
481496
?autoalign=${autoalign}
@@ -537,9 +552,11 @@ export const WithAILabel = {
537552
invalidText,
538553
value,
539554
typeahead,
555+
inputProps,
540556
} = args ?? {};
541557
return html`
542558
<cds-combo-box
559+
.inputProps=${inputProps}
543560
?disabled=${disabled}
544561
?autoalign=${autoalign}
545562
?hide-label=${hideLabel}
@@ -599,11 +616,13 @@ export const WithLayer = {
599616
invalidText,
600617
value,
601618
typeahead,
619+
inputProps,
602620
} = args ?? {};
603621
return html`
604622
<sb-template-layers>
605623
<div style="width:300px">
606624
<cds-combo-box
625+
.inputProps=${inputProps}
607626
direction=${ifDefined(direction)}
608627
?autoalign=${autoalign}
609628
?disabled=${disabled}

packages/web-components/src/components/combo-box/combo-box.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import styles from './combo-box.scss?lit';
1818
import { carbonElement as customElement } from '../../globals/decorators/carbon-element';
1919
import { ifDefined } from 'lit/directives/if-defined.js';
2020
import ifNonEmpty from '../../globals/directives/if-non-empty';
21+
import spread from '../../globals/directives/spread';
2122

2223
export { DROPDOWN_DIRECTION, DROPDOWN_SIZE } from '../dropdown/dropdown';
2324

@@ -416,6 +417,7 @@ class CDSComboBox extends CDSDropdown {
416417
open,
417418
readOnly,
418419
value,
420+
inputProps,
419421
_activeDescendant: activeDescendant,
420422
_filterInputValue: filterInputValue,
421423
_handleInput: handleInput,
@@ -453,7 +455,8 @@ class CDSComboBox extends CDSDropdown {
453455
)}"
454456
?readonly=${readOnly}
455457
@input=${handleInput}
456-
@keydown=${handleInputKeydown} />
458+
@keydown=${handleInputKeydown}
459+
...="${spread(this._normalizeInputProps(inputProps))}" />
457460
`;
458461
}
459462

@@ -553,6 +556,29 @@ class CDSComboBox extends CDSDropdown {
553556
@property({ type: Boolean, attribute: 'allow-custom-value' })
554557
allowCustomValue = false;
555558

559+
/**
560+
* Additional input attributes to apply to the internal input element.
561+
* Allows passing native HTML input attributes like `maxlength`, `pattern`,
562+
* `autocomplete`, etc.
563+
*/
564+
@property({ type: Object, attribute: false })
565+
inputProps?: Record<string, string | number | boolean>;
566+
567+
private _normalizeInputProps(
568+
inputProps?: Record<string, string | number | boolean>
569+
) {
570+
const normalizedInputProps: Record<string, string> = {};
571+
572+
Object.entries(inputProps ?? {}).forEach(([key, value]) => {
573+
if (value === undefined || value === null || value === false) {
574+
return;
575+
}
576+
normalizedInputProps[key] = value === true ? '' : String(value);
577+
});
578+
579+
return normalizedInputProps;
580+
}
581+
556582
shouldUpdate(changedProperties) {
557583
super.shouldUpdate(changedProperties);
558584
if (!changedProperties.has('value')) {

0 commit comments

Comments
 (0)