+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/demo/src/examples/example09.ts b/packages/demo/src/examples/example09.ts
index c0ad91d6..7c6aabe7 100644
--- a/packages/demo/src/examples/example09.ts
+++ b/packages/demo/src/examples/example09.ts
@@ -1,39 +1,52 @@
-import { MultipleSelectInstance, multipleSelect } from 'multiple-select-vanilla';
+import { type LocaleKey, type MultipleSelectInstance, multipleSelect } from 'multiple-select-vanilla';
-// 1. load every locale individually
-// import 'multiple-select-vanilla/dist/locales/multiple-select-fr-FR';
-// import 'multiple-select-vanilla/dist/locales/multiple-select-es-ES';
+// 1. load every locale individually, it could be import in 2 ways (named import OR import on window object)
+import { Spanish } from 'multiple-select-vanilla/dist/locales/multiple-select-es-ES'; // named import
+// import 'multiple-select-vanilla/dist/locales/multiple-select-es-ES'; // locale on window object
// 2. or load all locales at once
import 'multiple-select-vanilla/dist/locales/multiple-select-all-locales';
export default class Example {
+ ms0?: MultipleSelectInstance;
ms1?: MultipleSelectInstance;
ms2?: MultipleSelectInstance;
mount() {
const elm = document.querySelector('#locale') as HTMLSelectElement;
elm.addEventListener('change', ((event: KeyboardEvent & { target: HTMLSelectElement }) => {
- this.updateLocale(event.target.value);
+ this.updateLocale(event.target.value as LocaleKey);
}) as EventListener);
- this.ms1 = multipleSelect(elm) as MultipleSelectInstance;
- this.ms2 = multipleSelect('#select', {
+ this.ms0 = multipleSelect(elm) as MultipleSelectInstance;
+ this.ms1 = multipleSelect('#dynamic-select', {
filter: true,
showOkButton: true,
+ dataTest: 'select1',
+ }) as MultipleSelectInstance;
+
+ this.ms2 = multipleSelect('#fixed-import', {
+ filter: true,
+ showOkButton: true,
+ dataTest: 'select2',
+
+ // when using named import
+ locale: Spanish,
}) as MultipleSelectInstance;
}
unmount() {
// destroy ms instance(s) to avoid DOM leaks
+ this.ms0?.destroy();
this.ms1?.destroy();
this.ms2?.destroy();
+ this.ms0 = undefined;
this.ms1 = undefined;
this.ms2 = undefined;
}
- updateLocale(locale: string) {
- this.ms2?.destroy();
- this.ms2?.refreshOptions({ locale });
+ updateLocale(locale: LocaleKey) {
+ this.ms1?.destroy();
+ this.ms1?.refreshOptions({ locale });
}
}
diff --git a/packages/demo/src/i18n/i18n.ts b/packages/demo/src/i18n/i18n.ts
index 2585b240..65e24c61 100644
--- a/packages/demo/src/i18n/i18n.ts
+++ b/packages/demo/src/i18n/i18n.ts
@@ -1,4 +1,4 @@
-import { MultipleSelectInstance, multipleSelect } from 'multiple-select-vanilla';
+import { type MultipleSelectInstance, multipleSelect } from 'multiple-select-vanilla';
export default class Example {
ms1?: MultipleSelectInstance;
@@ -26,11 +26,13 @@ export default class Example {
},
// 2. OR you could also use string pattern instead of the callback functions
- // allSelectedText: 'Tous sélectionnés',
- // countSelectedText: '# de % selectionnés',
- // noMatchesFoundText: 'Aucun résultat',
- // okButtonText: 'Fermer',
- // selectAllText: 'Tout sélectionner',
+ /*
+ allSelectedText: 'Tous sélectionnés',
+ countSelectedText: '# de % selectionnés',
+ noMatchesFoundText: 'Aucun résultat',
+ okButtonText: 'Fermer',
+ selectAllText: 'Tout sélectionner',
+ */
}) as MultipleSelectInstance;
}
diff --git a/packages/multiple-select-vanilla/index.d.ts b/packages/multiple-select-vanilla/index.d.ts
index f3fcf484..58e7e130 100644
--- a/packages/multiple-select-vanilla/index.d.ts
+++ b/packages/multiple-select-vanilla/index.d.ts
@@ -8,14 +8,7 @@ declare global {
config?: Partial
>,
): MultipleSelectInstance | MultipleSelectInstance[];
defaults: Partial;
- locales: {
- [localeKey: string]: {
- formatSelectAll: () => string;
- formatAllSelected: () => string;
- formatCountSelected: (count: number, total: number) => string;
- formatNoMatchesFound: () => string;
- };
- };
+ locales: Record;
methods: string[];
};
}
diff --git a/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts b/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts
index f0d94e01..402b67dc 100644
--- a/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts
+++ b/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts
@@ -59,7 +59,7 @@ export class MultipleSelectInstance {
protected _currentHighlightIndex = -1;
protected _currentSelectedElm?: HTMLLIElement | HTMLDivElement;
protected isMoveUpRecalcRequired = false;
- locales: MultipleSelectLocales = {};
+ locales = {} as MultipleSelectLocales;
get isRenderAsHtml() {
return this.options.renderOptionLabelAsHtml || this.options.useSelectOptionLabelToHtml;
@@ -120,6 +120,11 @@ export class MultipleSelectInstance {
protected initLocale() {
if (this.options.locale) {
+ if (typeof this.options.locale === 'object') {
+ Object.assign(this.options, this.options.locale);
+ return;
+ }
+
const locales = window.multipleSelect.locales;
const parts = this.options.locale.split(/-|_/);
diff --git a/packages/multiple-select-vanilla/src/interfaces/index.ts b/packages/multiple-select-vanilla/src/interfaces/index.ts
index 7ca7802f..c6187e1c 100644
--- a/packages/multiple-select-vanilla/src/interfaces/index.ts
+++ b/packages/multiple-select-vanilla/src/interfaces/index.ts
@@ -1,2 +1,3 @@
export * from './interfaces';
+export * from './locale.interface';
export * from './multipleSelectOption.interface';
diff --git a/packages/multiple-select-vanilla/src/interfaces/interfaces.ts b/packages/multiple-select-vanilla/src/interfaces/interfaces.ts
index c9ed9bcf..143fb06f 100644
--- a/packages/multiple-select-vanilla/src/interfaces/interfaces.ts
+++ b/packages/multiple-select-vanilla/src/interfaces/interfaces.ts
@@ -51,27 +51,6 @@ export interface VirtualScrollOption {
sanitizer?: (html: string) => string | TrustedHTML;
}
-export interface MultipleSelectLocale {
- /** Customize the formatted text "All Selected" when using custom locale. */
- formatAllSelected(): string;
-
- /** Customize the formatted text "x of y selected" when using custom locale. */
- formatCountSelected(selectedCount: number, totalCount: number): string;
-
- /** For the "No Matches Found" text when nothing is found while filtering the dropdown */
- formatNoMatchesFound(): string;
-
- /** Customize the formatted text "OK" showing at the bottom of the drop. */
- formatOkButton(): string;
-
- /** For the "Select All" checkbox text */
- formatSelectAll(): string;
-}
-
-export interface MultipleSelectLocales {
- [localeKey: string]: MultipleSelectLocale;
-}
-
export interface LabelFilter {
label: string;
search: string;
diff --git a/packages/multiple-select-vanilla/src/interfaces/locale.interface.ts b/packages/multiple-select-vanilla/src/interfaces/locale.interface.ts
new file mode 100644
index 00000000..f236e239
--- /dev/null
+++ b/packages/multiple-select-vanilla/src/interfaces/locale.interface.ts
@@ -0,0 +1,34 @@
+/** Locale I18N key (string) that currently exists in the project */
+export type LocaleKey =
+ | 'cz-CS'
+ | 'da-DK'
+ | 'en-US'
+ | 'es-ES'
+ | 'fr-FR'
+ | 'hu-HU'
+ | 'it-IT'
+ | 'ja-JP'
+ | 'pt-BR'
+ | 'ru-RU'
+ | 'vi-VN'
+ | 'zh-CN'
+ | 'zh-TW';
+
+export interface MultipleSelectLocale {
+ /** Customize the formatted text "All Selected" when using custom locale. */
+ formatAllSelected(): string;
+
+ /** Customize the formatted text "x of y selected" when using custom locale. */
+ formatCountSelected(selectedCount: number, totalCount: number): string;
+
+ /** For the "No Matches Found" text when nothing is found while filtering the dropdown */
+ formatNoMatchesFound(): string;
+
+ /** Customize the formatted text "OK" showing at the bottom of the drop. */
+ formatOkButton(): string;
+
+ /** For the "Select All" checkbox text */
+ formatSelectAll(): string;
+}
+
+export type MultipleSelectLocales = Record;
diff --git a/packages/multiple-select-vanilla/src/interfaces/multipleSelectOption.interface.ts b/packages/multiple-select-vanilla/src/interfaces/multipleSelectOption.interface.ts
index 93fbf34d..bfba7e95 100644
--- a/packages/multiple-select-vanilla/src/interfaces/multipleSelectOption.interface.ts
+++ b/packages/multiple-select-vanilla/src/interfaces/multipleSelectOption.interface.ts
@@ -1,4 +1,5 @@
-import { LabelFilter, MultipleSelectLocale, OptGroupRowData, OptionRowData, OptionRowDivider, TextFilter } from './interfaces';
+import type { LabelFilter, OptGroupRowData, OptionRowData, OptionRowDivider, TextFilter } from './interfaces';
+import type { LocaleKey, MultipleSelectLocale } from './locale.interface';
export interface MultipleSelectView {
label: string;
@@ -97,7 +98,7 @@ export interface MultipleSelectOption extends MultipleSelectLocale {
keepOpen?: boolean;
/** Optional Locale */
- locale?: string;
+ locale?: LocaleKey | MultipleSelectLocale;
/** Defaults to 250, define the maximum height property of the dropdown list. */
maxHeight: number;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-cz-CS.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-cz-CS.ts
index 7e9b0a59..db1d876e 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-cz-CS.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-cz-CS.ts
@@ -3,11 +3,15 @@
* Author: Matej Puhony
*/
+import { MultipleSelectInstance } from '../MultipleSelectInstance';
import { MultipleSelectLocale, MultipleSelectLocales } from '../interfaces';
-const ms = window.multipleSelect;
+const ms =
+ typeof window !== 'undefined' && window.multipleSelect !== undefined
+ ? window.multipleSelect
+ : ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['cz-CS'] = {
+export const Czech = {
formatSelectAll() {
return '[Vybrat vše]';
},
@@ -25,4 +29,6 @@ const ms = window.multipleSelect;
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['cz-CS'] = Czech;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-da-DK.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-da-DK.ts
index d9ffd5fa..bc84a124 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-da-DK.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-da-DK.ts
@@ -3,11 +3,15 @@
* Author: HThuren
*/
+import { MultipleSelectInstance } from '../MultipleSelectInstance';
import { MultipleSelectLocale, MultipleSelectLocales } from '../interfaces';
-const ms = window.multipleSelect;
+const ms =
+ typeof window !== 'undefined' && window.multipleSelect !== undefined
+ ? window.multipleSelect
+ : ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['da-DK'] = {
+export const Danish = {
formatSelectAll() {
return '[Vælg alle]';
},
@@ -25,4 +29,6 @@ const ms = window.multipleSelect;
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['da-DK'] = Danish;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-en-US.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-en-US.ts
index cbafc4c4..13f076e9 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-en-US.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-en-US.ts
@@ -11,24 +11,24 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales) = {
- 'en-US': {
- formatSelectAll() {
- return '[Select all]';
- },
- formatAllSelected() {
- return 'All selected';
- },
- formatCountSelected(count: number, total: number) {
- return `${count} of ${total} selected`;
- },
- formatNoMatchesFound() {
- return 'No matches found';
- },
- formatOkButton() {
- return 'OK';
- },
- } as MultipleSelectLocale,
-};
+export const English = {
+ formatSelectAll() {
+ return '[Select all]';
+ },
+ formatAllSelected() {
+ return 'All selected';
+ },
+ formatCountSelected(count: number, total: number) {
+ return `${count} of ${total} selected`;
+ },
+ formatNoMatchesFound() {
+ return 'No matches found';
+ },
+ formatOkButton() {
+ return 'OK';
+ },
+} as MultipleSelectLocale;
+
+(ms.locales as MultipleSelectLocales)['en-US'] = English;
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-es-ES.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-es-ES.ts
index 626cfdef..053ae6c1 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-es-ES.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-es-ES.ts
@@ -3,11 +3,15 @@
* Author: Zhixin Wen
*/
+import { MultipleSelectInstance } from '../MultipleSelectInstance';
import { MultipleSelectLocale, MultipleSelectLocales } from '../interfaces';
-const ms = window.multipleSelect;
+const ms =
+ typeof window !== 'undefined' && window.multipleSelect !== undefined
+ ? window.multipleSelect
+ : ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['es-ES'] = {
+export const Spanish = {
formatSelectAll() {
return '[Seleccionar todo]';
},
@@ -25,4 +29,6 @@ const ms = window.multipleSelect;
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['es-ES'] = Spanish;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-fr-FR.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-fr-FR.ts
index 9e756d10..3e2a610f 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-fr-FR.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-fr-FR.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['fr-FR'] = {
+export const French = {
formatSelectAll() {
return '[Tout sélectionner]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['fr-FR'] = French;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-hu-HU.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-hu-HU.ts
index 73acde15..32a70542 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-hu-HU.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-hu-HU.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['hu-HU'] = {
+export const Hungarian = {
formatSelectAll() {
return '[Összes kiválasztása]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['hu-HU'] = Hungarian;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-it-IT.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-it-IT.ts
index 08713fb0..b2807a20 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-it-IT.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-it-IT.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['it-IT'] = {
+export const Italian = {
formatSelectAll() {
return '[Seleziona tutti]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['it-IT'] = Italian;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-ja-JP.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-ja-JP.ts
index 5dafa878..ee30dd19 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-ja-JP.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-ja-JP.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['ja-JP'] = {
+export const Japanese = {
formatSelectAll() {
return '[すべて選択]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['ja-JP'] = Japanese;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-pt-BR.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-pt-BR.ts
index 73466cc0..6dc15b3a 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-pt-BR.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-pt-BR.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['pt-BR'] = {
+export const Portuguese = {
formatSelectAll() {
return '[Selecionar todos]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['pt-BR'] = Portuguese;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-ru-RU.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-ru-RU.ts
index 0e85bd4a..56f925d7 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-ru-RU.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-ru-RU.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['ru-RU'] = {
+export const Russian = {
formatSelectAll() {
return '[Выбрать все]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['ru-RU'] = Russian;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-vi-VN.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-vi-VN.ts
index 9378bd70..44088160 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-vi-VN.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-vi-VN.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['vi-VN'] = {
+export const Vietnamese = {
formatSelectAll() {
return '[Tất cả]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['vi-VN'] = Vietnamese;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-zh-CN.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-zh-CN.ts
index a93e38b9..9d5a2a31 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-zh-CN.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-zh-CN.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['zh-CN'] = {
+export const Mandarin = {
formatSelectAll() {
return '[全选]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['zh-CN'] = Mandarin;
+
export default ms.locales;
diff --git a/packages/multiple-select-vanilla/src/locales/multiple-select-zh-TW.ts b/packages/multiple-select-vanilla/src/locales/multiple-select-zh-TW.ts
index d65a0417..f949ed5a 100644
--- a/packages/multiple-select-vanilla/src/locales/multiple-select-zh-TW.ts
+++ b/packages/multiple-select-vanilla/src/locales/multiple-select-zh-TW.ts
@@ -11,7 +11,7 @@ const ms =
? window.multipleSelect
: ({ locales: {} as MultipleSelectLocales } as Partial);
-(ms.locales as MultipleSelectLocales)['zh-TW'] = {
+export const MandarinTraditional = {
formatSelectAll() {
return '[全選]';
},
@@ -29,4 +29,6 @@ const ms =
},
} as MultipleSelectLocale;
+(ms.locales as MultipleSelectLocales)['zh-TW'] = MandarinTraditional;
+
export default ms.locales;
diff --git a/playwright/e2e/example09.spec.ts b/playwright/e2e/example09.spec.ts
index f4ed2e95..cd41b19e 100644
--- a/playwright/e2e/example09.spec.ts
+++ b/playwright/e2e/example09.spec.ts
@@ -1,4 +1,4 @@
-import { test } from '@playwright/test';
+import { expect, test } from '@playwright/test';
test.describe('Example 09 - Locale', () => {
test('changing locale should be reflected in dropdown & selected text', async ({ page }) => {
@@ -23,5 +23,17 @@ test.describe('Example 09 - Locale', () => {
await page.getByRole('button', { name: 'Chọn tất cả' }).click();
await page.getByText('[Tất cả]').click();
await page.getByRole('button', { name: 'Đóng' }).click();
+ await page.locator('div[data-test=select1].ms-parent').click();
+ });
+
+ test('fixed named Locale import', async ({ page }) => {
+ await page.goto('#/example09');
+ await page.locator('div[data-test=select2].ms-parent').click();
+ await page.getByText('[Seleccionar todo]').click();
+ await page.getByRole('button', { name: 'Todos seleccionados' });
+ await page.getByRole('button', { name: 'Cerrar' }).click();
+
+ const parentLoc = await page.locator('div[data-test=select2].ms-parent');
+ await expect(parentLoc).not.toHaveClass('ms-parent-open');
});
});