diff --git a/packages/combobox/README.md b/packages/combobox/README.md
index 56736707f..1094a3b3c 100644
--- a/packages/combobox/README.md
+++ b/packages/combobox/README.md
@@ -267,7 +267,7 @@ export const invokerButton = () => html`
Validation can be used as normal, below is an example of a combobox with a `Required` validator.
-```js story
+```js preview-story
export const validation = () => {
loadDefaultFeedbackMessages();
Required.getMessage = () => 'Please enter a value';
@@ -278,7 +278,6 @@ export const validation = () => {
.validators="${[new Required()]}"
name="favoriteMovie"
label="Favorite movie"
- autocomplete="both"
>
Rocky
Rocky II
diff --git a/packages/combobox/src/LionCombobox.js b/packages/combobox/src/LionCombobox.js
index dfb7f18b4..a08cc6bdc 100644
--- a/packages/combobox/src/LionCombobox.js
+++ b/packages/combobox/src/LionCombobox.js
@@ -433,8 +433,8 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
*
* @param {EventTarget & import('../types/choice-group/ChoiceInputMixinTypes').ChoiceInputHost} target
*/
- _repropagationConditionFails(target) {
- return super._repropagationConditionFails(target) && this.formElements?.some(el => el.checked);
+ _repropagationCondition(target) {
+ return super._repropagationCondition(target) || this.formElements.every(el => !el.checked);
}
/* eslint-disable no-param-reassign */
@@ -482,6 +482,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
prevValue.length &&
curValue.length &&
prevValue[0].toLowerCase() !== curValue[0].toLowerCase();
+
return userIsAddingChars || userStartsNewWord;
}
diff --git a/packages/combobox/test/lion-combobox.test.js b/packages/combobox/test/lion-combobox.test.js
index c9b8756f9..2df02778f 100644
--- a/packages/combobox/test/lion-combobox.test.js
+++ b/packages/combobox/test/lion-combobox.test.js
@@ -450,22 +450,23 @@ describe('lion-combobox', () => {
it('works with validation', async () => {
const el = /** @type {LionCombobox} */ (await fixture(html`
- Artichoke
+ Artichoke
Chard
Chicory
Victoria Plum
`));
-
- // open
- el._comboboxNode.dispatchEvent(new Event('focusin', { bubbles: true, composed: true }));
-
- mimicUserTyping(el, 'art');
- await el.updateComplete;
expect(el.checkedIndex).to.equal(0);
- mimicUserTyping(el, '');
+ // Simulate backspace deleting the char at the end of the string
+ el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Backspace' }));
+ el._inputNode.dispatchEvent(new Event('input'));
+ const arr = el._inputNode.value.split('');
+ arr.splice(el._inputNode.value.length - 1, 1);
+ el._inputNode.value = arr.join('');
await el.updateComplete;
+ el.dispatchEvent(new Event('blur'));
+
expect(el.checkedIndex).to.equal(-1);
await el.feedbackComplete;
expect(el.hasFeedbackFor).to.include('error');
diff --git a/packages/form-core/src/FocusMixin.js b/packages/form-core/src/FocusMixin.js
index f9871ddca..cc016f947 100644
--- a/packages/form-core/src/FocusMixin.js
+++ b/packages/form-core/src/FocusMixin.js
@@ -6,6 +6,7 @@ import { FormControlMixin } from './FormControlMixin.js';
* @param {import('@open-wc/dedupe-mixin').Constructor} superclass
*/
const FocusMixinImplementation = superclass =>
+ // @ts-expect-error false positive for incompatible static get properties. Lit-element merges super properties already for you.
// eslint-disable-next-line no-unused-vars, max-len, no-shadow
class FocusMixin extends FormControlMixin(superclass) {
static get properties() {
diff --git a/packages/form-core/src/FormControlMixin.js b/packages/form-core/src/FormControlMixin.js
index 68e7af09d..e3504c5e5 100644
--- a/packages/form-core/src/FormControlMixin.js
+++ b/packages/form-core/src/FormControlMixin.js
@@ -801,7 +801,7 @@ const FormControlMixinImplementation = superclass =>
// We only send the checked changed up (not the unchecked). In this way a choice group
// (radio-group, checkbox-group, select/listbox) acts as an 'endpoint' (a single Field)
// just like the native