Skip to content
Draft
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
7 changes: 7 additions & 0 deletions .changeset/add-combobox-input-value.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@solid-design-system/components': minor
'@solid-design-system/styles': minor
'@solid-design-system/tokens': minor
---

`sd-combobox`: Added `inputValue` property and `input-value` attribute to expose and control the current text in the combobox's input field without querying the shadow DOM.
2 changes: 2 additions & 0 deletions .github/skills/component-conventions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ JSDoc tag → Storybook mapping:
| `@event` | EVENTS |
| `@state` + `/** @internal */` | Hidden from docs |

> **Do NOT add `@property` tags to the class-level JSDoc block.** Properties are auto-documented by the custom elements manifest analyzer from the `@property` decorator and inline JSDoc comment on each property. Adding manual `@property` entries in the class JSDoc is redundant and will cause duplicate documentation.

CSS property naming convention: `--sd-{component}--{variant}--{state}-{css-property}`

---
Expand Down
46 changes: 46 additions & 0 deletions packages/components/src/components/combobox/combobox.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1448,4 +1448,50 @@ describe('<sd-combobox>', () => {
// Expect input to lose focus (activeElement in shadow root is not the input)
expect(el.shadowRoot!.activeElement).to.not.equal(input);
});

describe('inputValue', () => {
it('should default to an empty string', async () => {
const combobox = await fixture<SdCombobox>(html`
<sd-combobox>
<sd-option value="option-1">Option 1</sd-option>
</sd-combobox>
`);
expect(combobox.inputValue).to.equal('');
});

it('should reflect inputValue as an attribute', async () => {
const combobox = await fixture<SdCombobox>(html`
<sd-combobox input-value="test">
<sd-option value="option-1">Option 1</sd-option>
</sd-combobox>
`);
expect(combobox.inputValue).to.equal('test');
expect(combobox.getAttribute('input-value')).to.equal('test');
});

it('should update the display input when inputValue is set programmatically', async () => {
const combobox = await fixture<SdCombobox>(html`
<sd-combobox>
<sd-option value="option-1">Option 1</sd-option>
</sd-combobox>
`);
combobox.inputValue = 'hello';
await combobox.updateComplete;
const displayInput = combobox.shadowRoot!.querySelector<HTMLInputElement>('[part~="display-input"]')!;
expect(displayInput.value).to.equal('hello');
});

it('should update inputValue when the user types', async () => {
const combobox = await fixture<SdCombobox>(html`
<sd-combobox>
<sd-option value="option-1">Option 1</sd-option>
</sd-combobox>
`);
const displayInput = combobox.shadowRoot!.querySelector<HTMLInputElement>('[part~="display-input"]')!;
displayInput.focus();
await sendKeys({ type: 'opt' });
await combobox.updateComplete;
expect(combobox.inputValue).to.equal('opt');
});
});
});
18 changes: 18 additions & 0 deletions packages/components/src/components/combobox/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,24 @@ export default class SdCombobox extends SolidElement implements SolidFormControl
/** Shows success styles if the validity of the input is valid. */
@property({ type: Boolean, reflect: true, attribute: 'style-on-valid' }) styleOnValid = false;

/**
* The current value of the combobox's internal text input. Setting this property will update the
* displayed text in the input field without selecting an option. This is useful for pre-filling
* the search input or reading the current query string.
*/
@property({ type: String, reflect: true, attribute: 'input-value' })
get inputValue() {
return this.displayInputValue;
}
set inputValue(value: string) {
this.displayInputValue = value;
this.updateComplete.then(() => {
if (this.displayInput) {
this.displayInput.value = value;
}
});
}

/**
* A function used to filter options in the combobox component.
* The default filter method is a case- and diacritic-insensitive string comparison.
Expand Down
Loading