diff --git a/src/Autocomplete/CHANGELOG.md b/src/Autocomplete/CHANGELOG.md
index 03022e74226..41dd6e8a55c 100644
--- a/src/Autocomplete/CHANGELOG.md
+++ b/src/Autocomplete/CHANGELOG.md
@@ -1,5 +1,33 @@
# CHANGELOG
+## 2.28.0
+
+- Default plugins like `clear_button` or `remove_button` can now be removed when setting their value to `false` in the `tom_select_options.plugins` option, for example:
+```php
+setDefaults([
+ 'class' => Ingredient::class,
+ 'tom_select_options' => [
+ 'plugins' => [
+ 'clear_button' => false, // Disable the clear button
+ 'remove_button' => false, // Disable the remove button
+ ],
+ ],
+ ]);
+ }
+
+ public function getParent(): string
+ {
+ return BaseEntityAutocompleteType::class;
+ }
+}
+```
+
## 2.25.0
- Escape `querySelector` dynamic selector with `CSS.escape()` #2663
diff --git a/src/Autocomplete/assets/dist/controller.js b/src/Autocomplete/assets/dist/controller.js
index 62ca5d44b47..c68b7bd3015 100644
--- a/src/Autocomplete/assets/dist/controller.js
+++ b/src/Autocomplete/assets/dist/controller.js
@@ -29,7 +29,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
-var _default_1_instances, _default_1_getCommonConfig, _default_1_createAutocomplete, _default_1_createAutocompleteWithHtmlContents, _default_1_createAutocompleteWithRemoteData, _default_1_stripTags, _default_1_mergeConfigs, _default_1_normalizePluginsToHash, _default_1_createTomSelect;
+var _default_1_instances, _default_1_getCommonConfig, _default_1_createAutocomplete, _default_1_createAutocompleteWithHtmlContents, _default_1_createAutocompleteWithRemoteData, _default_1_stripTags, _default_1_mergeConfigs, _default_1_normalizePluginsToHash, _default_1_normalizePlugins, _default_1_createTomSelect;
class default_1 extends Controller {
constructor() {
super(...arguments);
@@ -382,11 +382,18 @@ _default_1_normalizePluginsToHash = new WeakMap(), _default_1_instances = new We
return {
...config1,
...config2,
- plugins: {
+ plugins: __classPrivateFieldGet(this, _default_1_instances, "m", _default_1_normalizePlugins).call(this, {
...__classPrivateFieldGet(this, _default_1_normalizePluginsToHash, "f").call(this, config1.plugins || {}),
...__classPrivateFieldGet(this, _default_1_normalizePluginsToHash, "f").call(this, config2.plugins || {}),
- },
+ }),
};
+}, _default_1_normalizePlugins = function _default_1_normalizePlugins(plugins) {
+ return Object.entries(plugins).reduce((acc, [pluginName, pluginOptions]) => {
+ if (pluginOptions !== false) {
+ acc[pluginName] = pluginOptions;
+ }
+ return acc;
+ }, {});
}, _default_1_createTomSelect = function _default_1_createTomSelect(options) {
const preConnectPayload = { options };
this.dispatchEvent('pre-connect', preConnectPayload);
diff --git a/src/Autocomplete/assets/src/controller.ts b/src/Autocomplete/assets/src/controller.ts
index d0b7db8282d..8be9ab53594 100644
--- a/src/Autocomplete/assets/src/controller.ts
+++ b/src/Autocomplete/assets/src/controller.ts
@@ -330,10 +330,10 @@ export default class extends Controller {
...config1,
...config2,
// Plugins from both configs should be merged together.
- plugins: {
+ plugins: this.#normalizePlugins({
...this.#normalizePluginsToHash(config1.plugins || {}),
...this.#normalizePluginsToHash(config2.plugins || {}),
- },
+ }),
};
}
@@ -358,6 +358,16 @@ export default class extends Controller {
return plugins;
};
+ #normalizePlugins(plugins: TPluginHash): TPluginHash {
+ return Object.entries(plugins).reduce((acc, [pluginName, pluginOptions]) => {
+ if (pluginOptions !== false) {
+ acc[pluginName] = pluginOptions;
+ }
+
+ return acc;
+ }, {} as TPluginHash);
+ }
+
/**
* Returns the element, but only if it's a select element.
*/
diff --git a/src/Autocomplete/assets/test/controller.test.ts b/src/Autocomplete/assets/test/controller.test.ts
index 9c02e4b0113..ae6bf5eea76 100644
--- a/src/Autocomplete/assets/test/controller.test.ts
+++ b/src/Autocomplete/assets/test/controller.test.ts
@@ -994,4 +994,123 @@ describe('AutocompleteController', () => {
await shortDelay(10);
expect(wasReset).toBe(false);
});
+
+ it('must disable default plugin "clear_button"', async () => {
+ const { tomSelect } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect.plugins.names, 'The plugin "clear_button" must be present by default.').toEqual([
+ 'clear_button',
+ ]);
+
+ const { tomSelect: tomSelect2 } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect2.plugins.names, 'The plugin "clear_button" must not be present.').toEqual([]);
+ });
+
+ it('must disable default plugin "remove_button"', async () => {
+ const { tomSelect } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect.plugins.names, 'The plugin "remove_button" must be present by default.').toEqual([
+ 'remove_button',
+ ]);
+
+ const { tomSelect: tomSelect2 } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect2.plugins.names, 'The plugin "remove_button" must not be present.').toEqual([]);
+ });
+
+ it('adding a plugin should merge it with the common plugins list', async () => {
+ const { tomSelect } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect.plugins.names, 'The plugin "remove_button" must be present by default.').toEqual([
+ 'clear_button',
+ ]);
+
+ const { tomSelect: tomSelect2 } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect2.plugins.names, 'The plugin "input_autogrow" must be present too.').toEqual([
+ 'clear_button',
+ 'input_autogrow',
+ ]);
+ });
+
+ it('adding a plugin (with configuration) should merge it with the common plugins list', async () => {
+ const { tomSelect } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect.plugins.names, 'The plugin "remove_button" must be present by default.').toEqual([
+ 'clear_button',
+ ]);
+
+ const { tomSelect: tomSelect2 } = await startAutocompleteTest(`
+
+ `);
+
+ expect(tomSelect2.plugins.names, 'The plugin "input_autogrow" must be present too.').toEqual([
+ 'clear_button',
+ 'input_autogrow',
+ ]);
+ });
});