@vaadin/combo-box
Advanced tools
Comparing version 23.2.0-alpha2 to 23.2.0-alpha3
{ | ||
"name": "@vaadin/combo-box", | ||
"version": "23.2.0-alpha2", | ||
"version": "23.2.0-alpha3", | ||
"publishConfig": { | ||
@@ -39,21 +39,21 @@ "access": "public" | ||
"@polymer/polymer": "^3.0.0", | ||
"@vaadin/component-base": "23.2.0-alpha2", | ||
"@vaadin/field-base": "23.2.0-alpha2", | ||
"@vaadin/input-container": "23.2.0-alpha2", | ||
"@vaadin/item": "23.2.0-alpha2", | ||
"@vaadin/lit-renderer": "23.2.0-alpha2", | ||
"@vaadin/vaadin-lumo-styles": "23.2.0-alpha2", | ||
"@vaadin/vaadin-material-styles": "23.2.0-alpha2", | ||
"@vaadin/vaadin-overlay": "23.2.0-alpha2", | ||
"@vaadin/vaadin-themable-mixin": "23.2.0-alpha2" | ||
"@vaadin/component-base": "23.2.0-alpha3", | ||
"@vaadin/field-base": "23.2.0-alpha3", | ||
"@vaadin/input-container": "23.2.0-alpha3", | ||
"@vaadin/item": "23.2.0-alpha3", | ||
"@vaadin/lit-renderer": "23.2.0-alpha3", | ||
"@vaadin/vaadin-lumo-styles": "23.2.0-alpha3", | ||
"@vaadin/vaadin-material-styles": "23.2.0-alpha3", | ||
"@vaadin/vaadin-overlay": "23.2.0-alpha3", | ||
"@vaadin/vaadin-themable-mixin": "23.2.0-alpha3" | ||
}, | ||
"devDependencies": { | ||
"@esm-bundle/chai": "^4.3.4", | ||
"@vaadin/polymer-legacy-adapter": "23.2.0-alpha2", | ||
"@vaadin/polymer-legacy-adapter": "23.2.0-alpha3", | ||
"@vaadin/testing-helpers": "^0.3.2", | ||
"@vaadin/text-field": "23.2.0-alpha2", | ||
"@vaadin/text-field": "23.2.0-alpha3", | ||
"lit": "^2.0.0", | ||
"sinon": "^13.0.2" | ||
}, | ||
"gitHead": "c9b8113d0fa9a602f8b9cb915c1826355af2e8df" | ||
"gitHead": "06e5875be93ca50da2846dafc65a8531010c0576" | ||
} |
@@ -6,6 +6,6 @@ /** | ||
*/ | ||
import { TemplateResult } from 'lit'; | ||
import { DirectiveResult } from 'lit/directive.js'; | ||
import type { TemplateResult } from 'lit'; | ||
import type { DirectiveResult } from 'lit/directive.js'; | ||
import { LitRendererDirective } from '@vaadin/lit-renderer'; | ||
import { ComboBox, ComboBoxItemModel } from '../vaadin-combo-box.js'; | ||
import type { ComboBox, ComboBoxItemModel } from '../vaadin-combo-box.js'; | ||
@@ -12,0 +12,0 @@ export type ComboBoxLitRenderer<TItem> = ( |
@@ -6,5 +6,5 @@ /** | ||
*/ | ||
import { Constructor } from '@open-wc/dedupe-mixin'; | ||
import type { Constructor } from '@open-wc/dedupe-mixin'; | ||
export type ComboBoxDataProviderCallback<TItem> = (items: TItem[], size: number) => void; | ||
export type ComboBoxDataProviderCallback<TItem> = (items: TItem[], size?: number) => void; | ||
@@ -11,0 +11,0 @@ export interface ComboBoxDataProviderParams { |
@@ -65,2 +65,7 @@ /** | ||
}, | ||
/** @private */ | ||
__previousDataProviderFilter: { | ||
type: String, | ||
}, | ||
}; | ||
@@ -71,4 +76,3 @@ } | ||
return [ | ||
'_dataProviderFilterChanged(filter, dataProvider)', | ||
'_dataProviderClearFilter(dataProvider, opened, value)', | ||
'_dataProviderFilterChanged(filter)', | ||
'_warnDataProviderValue(dataProvider, value)', | ||
@@ -82,3 +86,2 @@ '_ensureFirstPage(opened)', | ||
super.ready(); | ||
this.clearCache(); | ||
this._scroller.addEventListener('index-requested', (e) => { | ||
@@ -107,34 +110,21 @@ const index = e.detail.index; | ||
/** @private */ | ||
_dataProviderFilterChanged() { | ||
if (!this._shouldFetchData()) { | ||
_dataProviderFilterChanged(filter) { | ||
if (this.__previousDataProviderFilter === undefined && filter === '') { | ||
this.__previousDataProviderFilter = filter; | ||
return; | ||
} | ||
this._refreshData(); | ||
} | ||
if (this.__previousDataProviderFilter !== filter) { | ||
this.__previousDataProviderFilter = filter; | ||
/** @private */ | ||
_dataProviderClearFilter(dataProvider, opened, value) { | ||
// Can't depend on filter in this observer as we don't want | ||
// to clear the filter whenever it's set | ||
if (dataProvider && !this.loading && this.filter && !(opened && this.autoOpenDisabled && value === this.filter)) { | ||
this._refreshData(true); | ||
} | ||
} | ||
this._pendingRequests = {}; | ||
// Immediately mark as loading if this refresh leads to re-fetching pages | ||
// This prevents some issues with the properties below triggering | ||
// observers that also rely on the loading state | ||
this.loading = this._shouldFetchData(); | ||
// Reset size and internal loading state | ||
this.size = undefined; | ||
/** @private */ | ||
_refreshData(clearFilter) { | ||
// Immediately mark as loading if this refresh leads to re-fetching pages | ||
// This prevents some issues with the properties below triggering | ||
// observers that also rely on the loading state | ||
this.loading = this._shouldFetchData(); | ||
// Reset size and internal loading state | ||
this.size = undefined; | ||
this._pendingRequests = {}; | ||
// Clear filter if requested | ||
if (clearFilter) { | ||
this.filter = ''; | ||
this.clearCache(); | ||
} | ||
// Clear cached pages, and reload current page if we need the data | ||
this.clearCache(); | ||
} | ||
@@ -206,4 +196,7 @@ | ||
} | ||
this.size = size; | ||
if (size !== undefined) { | ||
this.size = size; | ||
} | ||
delete this._pendingRequests[page]; | ||
@@ -237,2 +230,3 @@ | ||
} | ||
this._pendingRequests = {}; | ||
@@ -244,3 +238,5 @@ const filteredItems = []; | ||
this.filteredItems = filteredItems; | ||
if (this._shouldFetchData()) { | ||
this._forceNextRequest = false; | ||
this._loadPage(0); | ||
@@ -279,2 +275,4 @@ } else { | ||
}); | ||
this.clearCache(); | ||
} | ||
@@ -281,0 +279,0 @@ |
@@ -6,9 +6,9 @@ /** | ||
*/ | ||
import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js'; | ||
import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js'; | ||
import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js'; | ||
import { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
import { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js'; | ||
import { ComboBoxMixinClass } from './vaadin-combo-box-mixin.js'; | ||
import { ComboBoxDefaultItem } from './vaadin-combo-box-mixin.js'; | ||
import type { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js'; | ||
import type { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js'; | ||
import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js'; | ||
import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js'; | ||
import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
import type { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js'; | ||
import type { ComboBoxDefaultItem, ComboBoxMixinClass } from './vaadin-combo-box-mixin.js'; | ||
export { | ||
@@ -58,2 +58,7 @@ ComboBoxDataProvider, | ||
/** | ||
* Fired whenever the field is validated. | ||
*/ | ||
export type ComboBoxLightValidatedEvent = CustomEvent<{ valid: boolean }>; | ||
export interface ComboBoxLightEventMap<TItem> extends HTMLElementEventMap { | ||
@@ -73,2 +78,4 @@ change: ComboBoxLightChangeEvent<TItem>; | ||
'selected-item-changed': ComboBoxLightSelectedItemChangedEvent<TItem>; | ||
validated: ComboBoxLightValidatedEvent; | ||
} | ||
@@ -120,2 +127,3 @@ | ||
* @fires {CustomEvent} value-changed - Fired when the `value` property changes. | ||
* @fires {CustomEvent} validated - Fired whenever the field is validated. | ||
*/ | ||
@@ -149,3 +157,4 @@ declare class ComboBoxLight<TItem = ComboBoxDefaultItem> extends HTMLElement { | ||
DisabledMixinClass, | ||
ThemableMixinClass {} | ||
ThemableMixinClass, | ||
ValidateMixinClass {} | ||
@@ -152,0 +161,0 @@ declare global { |
@@ -11,2 +11,3 @@ /** | ||
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; | ||
import { ValidateMixin } from '@vaadin/field-base/src/validate-mixin.js'; | ||
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
@@ -60,2 +61,3 @@ import { ComboBoxDataProviderMixin } from './vaadin-combo-box-data-provider-mixin.js'; | ||
* @fires {CustomEvent} value-changed - Fired when the `value` property changes. | ||
* @fires {CustomEvent} validated - Fired whenever the field is validated. | ||
* | ||
@@ -66,4 +68,5 @@ * @extends HTMLElement | ||
* @mixes ThemableMixin | ||
* @mixes ValidateMixin | ||
*/ | ||
class ComboBoxLight extends ComboBoxDataProviderMixin(ComboBoxMixin(ThemableMixin(PolymerElement))) { | ||
class ComboBoxLight extends ComboBoxDataProviderMixin(ComboBoxMixin(ValidateMixin(ThemableMixin(PolymerElement)))) { | ||
static get is() { | ||
@@ -70,0 +73,0 @@ return 'vaadin-combo-box-light'; |
@@ -6,7 +6,7 @@ /** | ||
*/ | ||
import { Constructor } from '@open-wc/dedupe-mixin'; | ||
import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js'; | ||
import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js'; | ||
import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js'; | ||
import { ComboBox } from './vaadin-combo-box.js'; | ||
import type { Constructor } from '@open-wc/dedupe-mixin'; | ||
import type { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js'; | ||
import type { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js'; | ||
import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js'; | ||
import type { ComboBox } from './vaadin-combo-box.js'; | ||
@@ -142,7 +142,2 @@ export type ComboBoxDefaultItem = any; | ||
/** | ||
* Set to true if the value is invalid. | ||
*/ | ||
invalid: boolean; | ||
protected readonly _propertyForValue: string; | ||
@@ -149,0 +144,0 @@ |
@@ -239,3 +239,2 @@ /** | ||
return [ | ||
'_filterChanged(filter, itemValuePath, itemLabelPath)', | ||
'_selectedItemChanged(selectedItem, itemValuePath, itemLabelPath)', | ||
@@ -386,2 +385,21 @@ '_openedOrItemsChanged(opened, filteredItems, loading)', | ||
/** | ||
* Override Polymer lifecycle callback to handle `filter` property change after | ||
* the observer for `opened` property is triggered. This is needed when opening | ||
* combo-box on user input to ensure the focused index is set correctly. | ||
* | ||
* @param {!Object} currentProps Current accessor values | ||
* @param {?Object} changedProps Properties changed since the last call | ||
* @param {?Object} oldProps Previous values for each changed property | ||
* @protected | ||
* @override | ||
*/ | ||
_propertiesChanged(currentProps, changedProps, oldProps) { | ||
super._propertiesChanged(currentProps, changedProps, oldProps); | ||
if (changedProps.filter !== undefined) { | ||
this._filterChanged(changedProps.filter); | ||
} | ||
} | ||
/** @private */ | ||
@@ -931,5 +949,3 @@ _initOverlay() { | ||
if (!this.dataProvider) { | ||
this.filter = ''; | ||
} | ||
this.filter = ''; | ||
} | ||
@@ -952,15 +968,23 @@ | ||
_onInput(event) { | ||
if (!this.opened && !this._isClearButton(event) && !this.autoOpenDisabled) { | ||
this.open(); | ||
} | ||
const filter = this._inputElementValue; | ||
const value = this._inputElementValue; | ||
if (this.filter === value) { | ||
// When opening dropdown on user input, both `opened` and `filter` properties are set. | ||
// Perform a batched property update instead of relying on sync property observers. | ||
// This is necessary to avoid an extra data-provider request for loading first page. | ||
const props = {}; | ||
if (this.filter === filter) { | ||
// Filter and input value might get out of sync, while keyboard navigating for example. | ||
// Afterwards, input value might be changed to the same value as used in filtering. | ||
// In situation like these, we need to make sure all the filter changes handlers are run. | ||
this._filterChanged(this.filter, this.itemValuePath, this.itemLabelPath); | ||
this._filterChanged(this.filter); | ||
} else { | ||
this.filter = value; | ||
props.filter = filter; | ||
} | ||
if (!this.opened && !this._isClearButton(event) && !this.autoOpenDisabled) { | ||
props.opened = true; | ||
} | ||
this.setProperties(props); | ||
} | ||
@@ -988,7 +1012,3 @@ | ||
/** @private */ | ||
_filterChanged(filter, _itemValuePath, _itemLabelPath) { | ||
if (filter === undefined) { | ||
return; | ||
} | ||
_filterChanged(filter) { | ||
// Scroll to the top of the list whenever the filter changes. | ||
@@ -1072,10 +1092,7 @@ this._scrollIntoView(0); | ||
if (isValidValue(value)) { | ||
let item; | ||
if (this._getItemValue(this.selectedItem) !== value) { | ||
this._selectItemForValue(value); | ||
} else { | ||
item = this.selectedItem; | ||
} | ||
if (!item && this.allowCustomValue) { | ||
if (!this.selectedItem && this.allowCustomValue) { | ||
this._inputElementValue = value; | ||
@@ -1088,2 +1105,5 @@ } | ||
} | ||
this.filter = ''; | ||
// In the next _detectAndDispatchChange() call, the change detection should pass | ||
@@ -1288,25 +1308,2 @@ this._lastCommittedValue = undefined; | ||
/** | ||
* Returns true if `value` is valid, and sets the `invalid` flag appropriately. | ||
* | ||
* @return {boolean} True if the value is valid and sets the `invalid` flag appropriately | ||
*/ | ||
validate() { | ||
return !(this.invalid = !this.checkValidity()); | ||
} | ||
/** | ||
* Returns true if the current input value satisfies all constraints (if any). | ||
* You can override this method for custom validations. | ||
* | ||
* @return {boolean} | ||
*/ | ||
checkValidity() { | ||
if (super.checkValidity) { | ||
return super.checkValidity(); | ||
} | ||
return !this.required || !!this.value; | ||
} | ||
/** | ||
* Fired when the value changes. | ||
@@ -1316,3 +1313,3 @@ * | ||
* @param {Object} detail | ||
* @param {String} detail.value the combobox value | ||
* @param {String} detail.value the combobox value | ||
*/ | ||
@@ -1325,3 +1322,3 @@ | ||
* @param {Object} detail | ||
* @param {Object|String} detail.value the selected item. Type is the same as the type of `items`. | ||
* @param {Object|String} detail.value the selected item. Type is the same as the type of `items`. | ||
*/ | ||
@@ -1328,0 +1325,0 @@ |
@@ -6,20 +6,20 @@ /** | ||
*/ | ||
import { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js'; | ||
import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js'; | ||
import { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js'; | ||
import { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js'; | ||
import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js'; | ||
import { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js'; | ||
import { DelegateStateMixinClass } from '@vaadin/field-base/src/delegate-state-mixin.js'; | ||
import { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js'; | ||
import { InputConstraintsMixinClass } from '@vaadin/field-base/src/input-constraints-mixin.js'; | ||
import { InputControlMixinClass } from '@vaadin/field-base/src/input-control-mixin.js'; | ||
import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js'; | ||
import { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js'; | ||
import { PatternMixinClass } from '@vaadin/field-base/src/pattern-mixin.js'; | ||
import { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js'; | ||
import { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
import { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js'; | ||
import { ComboBoxMixinClass } from './vaadin-combo-box-mixin.js'; | ||
import { ComboBoxDefaultItem } from './vaadin-combo-box-mixin.js'; | ||
import type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js'; | ||
import type { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js'; | ||
import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js'; | ||
import type { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js'; | ||
import type { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js'; | ||
import type { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js'; | ||
import type { DelegateStateMixinClass } from '@vaadin/field-base/src/delegate-state-mixin.js'; | ||
import type { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js'; | ||
import type { InputConstraintsMixinClass } from '@vaadin/field-base/src/input-constraints-mixin.js'; | ||
import type { InputControlMixinClass } from '@vaadin/field-base/src/input-control-mixin.js'; | ||
import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js'; | ||
import type { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js'; | ||
import type { PatternMixinClass } from '@vaadin/field-base/src/pattern-mixin.js'; | ||
import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js'; | ||
import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
import type { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js'; | ||
import type { ComboBoxMixinClass } from './vaadin-combo-box-mixin.js'; | ||
import type { ComboBoxDefaultItem } from './vaadin-combo-box-mixin.js'; | ||
export { | ||
@@ -69,2 +69,7 @@ ComboBoxDataProvider, | ||
/** | ||
* Fired whenever the field is validated. | ||
*/ | ||
export type ComboBoxValidatedEvent = CustomEvent<{ valid: boolean }>; | ||
export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap { | ||
@@ -84,2 +89,4 @@ change: ComboBoxChangeEvent<TItem>; | ||
'selected-item-changed': ComboBoxSelectedItemChangedEvent<TItem>; | ||
validated: ComboBoxValidatedEvent; | ||
} | ||
@@ -171,2 +178,3 @@ | ||
* `--vaadin-field-default-width` | Default width of the field | `12em` | ||
* `--vaadin-combo-box-overlay-width` | Width of the overlay | `auto` | ||
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh` | ||
@@ -214,2 +222,3 @@ * | ||
* @fires {CustomEvent} value-changed - Fired when the `value` property changes. | ||
* @fires {CustomEvent} validated - Fired whenever the field is validated. | ||
*/ | ||
@@ -216,0 +225,0 @@ declare class ComboBox<TItem = ComboBoxDefaultItem> extends HTMLElement { |
@@ -107,2 +107,3 @@ /** | ||
* `--vaadin-field-default-width` | Default width of the field | `12em` | ||
* `--vaadin-combo-box-overlay-width` | Width of the overlay | `auto` | ||
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh` | ||
@@ -150,2 +151,3 @@ * | ||
* @fires {CustomEvent} value-changed - Fired when the `value` property changes. | ||
* @fires {CustomEvent} validated - Fired whenever the field is validated. | ||
* | ||
@@ -152,0 +154,0 @@ * @extends HTMLElement |
137279
3432
+ Added@vaadin/component-base@23.2.0-alpha3(transitive)
+ Added@vaadin/field-base@23.2.0-alpha3(transitive)
+ Added@vaadin/icon@23.2.0-alpha3(transitive)
+ Added@vaadin/input-container@23.2.0-alpha3(transitive)
+ Added@vaadin/item@23.2.0-alpha3(transitive)
+ Added@vaadin/lit-renderer@23.2.0-alpha3(transitive)
+ Added@vaadin/vaadin-lumo-styles@23.2.0-alpha3(transitive)
+ Added@vaadin/vaadin-material-styles@23.2.0-alpha3(transitive)
+ Added@vaadin/vaadin-overlay@23.2.0-alpha3(transitive)
+ Added@vaadin/vaadin-themable-mixin@23.2.0-alpha3(transitive)
- Removed@vaadin/component-base@23.2.0-alpha2(transitive)
- Removed@vaadin/field-base@23.2.0-alpha2(transitive)
- Removed@vaadin/icon@23.2.0-alpha2(transitive)
- Removed@vaadin/input-container@23.2.0-alpha2(transitive)
- Removed@vaadin/item@23.2.0-alpha2(transitive)
- Removed@vaadin/lit-renderer@23.2.0-alpha2(transitive)
- Removed@vaadin/vaadin-lumo-styles@23.2.0-alpha2(transitive)
- Removed@vaadin/vaadin-material-styles@23.2.0-alpha2(transitive)
- Removed@vaadin/vaadin-overlay@23.2.0-alpha2(transitive)
- Removed@vaadin/vaadin-themable-mixin@23.2.0-alpha2(transitive)
Updated@vaadin/item@23.2.0-alpha3