diff --git a/apiExamples/matchWord.html b/apiExamples/matchWord.html index 3a45af4..17dde25 100644 --- a/apiExamples/matchWord.html +++ b/apiExamples/matchWord.html @@ -4,13 +4,33 @@
Stops - Price - Duration - Departure - - Apples - Oranges - Peaches - - Arrival + Price + Duration +
+ + Apples + Oranges + Pears + Grapes + Kiwi +
+ + Person + Woman + Man + Camera + TV + +
+
+ Departure + Arrival +
+ + Cars + Trucks + Boats + Planes + Motorcycles +
diff --git a/demo/api.md b/demo/api.md index 6bb045f..feaaa96 100644 --- a/demo/api.md +++ b/demo/api.md @@ -222,15 +222,35 @@ The `auro-menu` component supports the use of the `matchWord` attribute to highl
Stops - Price - Duration - Departure - - Apples - Oranges - Peaches - - Arrival + Price + Duration +
+ + Apples + Oranges + Pears + Grapes + Kiwi +
+ + Person + Woman + Man + Camera + TV + +
+
+ Departure + Arrival +
+ + Cars + Trucks + Boats + Planes + Motorcycles +
@@ -263,15 +283,35 @@ export function auroMenuMatchWordExample() {
Stops - Price - Duration - Departure - - Apples - Oranges - Peaches - - Arrival + Price + Duration +
+ + Apples + Oranges + Pears + Grapes + Kiwi +
+ + Person + Woman + Man + Camera + TV + +
+
+ Departure + Arrival +
+ + Cars + Trucks + Boats + Planes + Motorcycles +
``` diff --git a/demo/api.min.js b/demo/api.min.js index 077d9d9..8bc1086 100644 --- a/demo/api.min.js +++ b/demo/api.min.js @@ -223,6 +223,11 @@ class AuroMenu extends LitElement { * @private */ this.runtimeUtils = new AuroLibraryRuntimeUtils(); + + /** + * @private + */ + this.nestingSpacer = ''; } static get properties() { @@ -323,20 +328,22 @@ class AuroMenu extends LitElement { * @returns {void} When called will update the DOM with visible suggest text matches. */ markOptions() { - if (this.items && this.items.length > 0) { + if (this.items && this.items.length > 0 && (this.matchWord && this.matchWord.length > 0)) { - if (this.matchWord && this.matchWord.length > 0) { + // Escape special regex characters + const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); - // Global case-insensitive matching - const regex = new RegExp(this.matchWord, 'giu'); + // Global, case-insensitive, unicode matching regex pattern + const regexWord = new RegExp(escapedWord, 'giu'); - this.items.forEach((item) => { - if (this.optionInteractive(item) && !item.hasAttribute('persistent')) { - item.innerHTML = item.textContent.replace(regex, (match) => `${match}`); - } - }); + this.items.forEach((item) => { + if (this.optionInteractive(item) && !item.hasAttribute('persistent')) { + const nested = item.querySelectorAll('.nestingSpacer'); + const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join(''); - } + item.innerHTML = nestingSpacerBundle + item.textContent.replace(regexWord, (match) => `${match}`); + } + }); } } @@ -548,7 +555,7 @@ class AuroMenu extends LitElement { const options = nestedMenu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption'); options.forEach((option) => { - option.innerHTML = ` ${option.innerHTML}`; + option.innerHTML = this.nestingSpacer + option.innerHTML; }); this.handleNestedMenus(nestedMenu); diff --git a/demo/index.min.js b/demo/index.min.js index ad99e8f..15bccb6 100644 --- a/demo/index.min.js +++ b/demo/index.min.js @@ -189,6 +189,11 @@ class AuroMenu extends LitElement { * @private */ this.runtimeUtils = new AuroLibraryRuntimeUtils(); + + /** + * @private + */ + this.nestingSpacer = ''; } static get properties() { @@ -289,20 +294,22 @@ class AuroMenu extends LitElement { * @returns {void} When called will update the DOM with visible suggest text matches. */ markOptions() { - if (this.items && this.items.length > 0) { + if (this.items && this.items.length > 0 && (this.matchWord && this.matchWord.length > 0)) { - if (this.matchWord && this.matchWord.length > 0) { + // Escape special regex characters + const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); - // Global case-insensitive matching - const regex = new RegExp(this.matchWord, 'giu'); + // Global, case-insensitive, unicode matching regex pattern + const regexWord = new RegExp(escapedWord, 'giu'); - this.items.forEach((item) => { - if (this.optionInteractive(item) && !item.hasAttribute('persistent')) { - item.innerHTML = item.textContent.replace(regex, (match) => `${match}`); - } - }); + this.items.forEach((item) => { + if (this.optionInteractive(item) && !item.hasAttribute('persistent')) { + const nested = item.querySelectorAll('.nestingSpacer'); + const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join(''); - } + item.innerHTML = nestingSpacerBundle + item.textContent.replace(regexWord, (match) => `${match}`); + } + }); } } @@ -514,7 +521,7 @@ class AuroMenu extends LitElement { const options = nestedMenu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption'); options.forEach((option) => { - option.innerHTML = ` ${option.innerHTML}`; + option.innerHTML = this.nestingSpacer + option.innerHTML; }); this.handleNestedMenus(nestedMenu); diff --git a/src/auro-menu.js b/src/auro-menu.js index caa2954..8d4eecc 100644 --- a/src/auro-menu.js +++ b/src/auro-menu.js @@ -56,6 +56,11 @@ export class AuroMenu extends LitElement { * @private */ this.runtimeUtils = new AuroLibraryRuntimeUtils(); + + /** + * @private + */ + this.nestingSpacer = ''; } static get properties() { @@ -156,20 +161,22 @@ export class AuroMenu extends LitElement { * @returns {void} When called will update the DOM with visible suggest text matches. */ markOptions() { - if (this.items && this.items.length > 0) { + if (this.items && this.items.length > 0 && (this.matchWord && this.matchWord.length > 0)) { - if (this.matchWord && this.matchWord.length > 0) { + // Escape special regex characters + const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); - // Global, case-insensitive, unicode matching - const regex = new RegExp(this.matchWord, 'giu'); + // Global, case-insensitive, unicode matching regex pattern + const regexWord = new RegExp(escapedWord, 'giu'); - this.items.forEach((item) => { - if (this.optionInteractive(item) && !item.hasAttribute('persistent')) { - item.innerHTML = item.textContent.replace(regex, (match) => `${match}`); - } - }); + this.items.forEach((item) => { + if (this.optionInteractive(item) && !item.hasAttribute('persistent')) { + const nested = item.querySelectorAll('.nestingSpacer'); + const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join(''); - } + item.innerHTML = nestingSpacerBundle + item.textContent.replace(regexWord, (match) => `${match}`); + } + }); } } @@ -383,7 +390,7 @@ export class AuroMenu extends LitElement { const options = nestedMenu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption'); options.forEach((option) => { - option.innerHTML = ` ${option.innerHTML}`; + option.innerHTML = this.nestingSpacer + option.innerHTML; }); this.handleNestedMenus(nestedMenu);