fix(select-rich): trigger manual update invoker selected elem on sync
This commit is contained in:
parent
f7ab53910d
commit
1671c705b8
4 changed files with 51 additions and 6 deletions
5
.changeset/tricky-pumpkins-lie.md
Normal file
5
.changeset/tricky-pumpkins-lie.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/select-rich': patch
|
||||
---
|
||||
|
||||
Fix select rich to manually request update for the invoker selected element when it synchronizes, as the modelValue could be changed but would not trigger a change since the old and new value are both referenced from the updated node reference, meaning they will always be the same and never pass the dirty check.
|
||||
|
|
@ -265,6 +265,13 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
|
|||
this._invokerNode.selectedElement = this.formElements[
|
||||
/** @type {number} */ (this.checkedIndex)
|
||||
];
|
||||
/**
|
||||
* Manually update this, as the node reference may be the same, but the modelValue might not.
|
||||
* This would mean that it won't pass the LitElement dirty check.
|
||||
* hasChanged in selectedElement won't work, since the oldValue and the newValue's modelValues will be the same,
|
||||
* as they are referenced through the same node reference.
|
||||
*/
|
||||
this._invokerNode.requestUpdate('selectedElement');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { LitElement } from '@lion/core';
|
||||
// @ts-expect-error
|
||||
import { renderLitAsNode } from '@lion/helpers';
|
||||
import { OverlayController } from '@lion/overlays';
|
||||
import { LionOption } from '@lion/listbox';
|
||||
import {
|
||||
aTimeout,
|
||||
defineCE,
|
||||
|
|
@ -16,10 +19,6 @@ import '@lion/listbox/lion-option.js';
|
|||
import '@lion/listbox/lion-options.js';
|
||||
import '../lion-select-rich.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('@lion/listbox').LionOption} LionOption
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {LionSelectRich} lionSelectEl
|
||||
*/
|
||||
|
|
@ -155,6 +154,40 @@ describe('lion-select-rich', () => {
|
|||
// @ts-ignore allow protected access in tests
|
||||
expect(el._invokerNode.hasAttribute('single-option')).to.be.true;
|
||||
});
|
||||
|
||||
it('updates the invoker when the selected element is the same but the modelValue was updated asynchronously', async () => {
|
||||
const tag = defineCE(
|
||||
class LionCustomOption extends LionOption {
|
||||
render() {
|
||||
return html`${this.modelValue.value}`;
|
||||
}
|
||||
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
},
|
||||
);
|
||||
const tagString = unsafeStatic(tag);
|
||||
|
||||
const firstOption = renderLitAsNode(
|
||||
html`<${tagString} checked .choiceValue=${10}></${tagString}>`,
|
||||
);
|
||||
|
||||
const el = /** @type {LionSelectRich} */ (await fixture(html`
|
||||
<lion-select-rich>
|
||||
${firstOption}
|
||||
<${tagString} .choiceValue=${20}></${tagString}>
|
||||
</lion-select-rich>
|
||||
`));
|
||||
|
||||
// @ts-ignore allow protected access in tests
|
||||
expect(el._invokerNode.shadowRoot.firstElementChild.textContent).to.equal('10');
|
||||
|
||||
firstOption.modelValue = { value: 30, checked: true };
|
||||
await el.updateComplete;
|
||||
// @ts-ignore allow protected access in tests
|
||||
expect(el._invokerNode.shadowRoot.firstElementChild.textContent).to.equal('30');
|
||||
});
|
||||
});
|
||||
|
||||
describe('overlay', () => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { expect, fixture as _fixture, html, nextFrame } from '@open-wc/testing';
|
||||
import { aTimeout, expect, fixture as _fixture, html } from '@open-wc/testing';
|
||||
import sinon from 'sinon';
|
||||
import '../lion-textarea.js';
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ describe('<lion-textarea>', () => {
|
|||
|
||||
const resizeSpy = sinon.spy(textArea, 'resizeTextarea');
|
||||
el.style.display = 'block';
|
||||
await nextFrame();
|
||||
await aTimeout(0);
|
||||
expect(resizeSpy.calledOnce).to.be.true;
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue