WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Support Word-Boundary Matching in Menu Typeahead Search #2887

@SiqiLu

Description

@SiqiLu

Feature Request: Support Word-Boundary Matching in Menu Typeahead Search

🎯 Current Behavior

The typeahead search feature in the Menu component currently only matches characters at the beginning of the entire
string
. It doesn't support matching at word boundaries within the search text.

Example

Given these menu items:

<!-- 
  Chinese: English name + Pinyin romanization
  - "Chinese" - allows typing 'c'
  - "Zhongwen" (拼音) - should allow typing 'z'
-->
<div data-value="zh-CN" data-valuetext="Chinese Zhongwen">简体中文</div>

<!-- 
  Japanese: English name + Romaji
  - "Japanese" - allows typing 'j'
  - "Nihongo" (ローマ字) - should allow typing 'n'
-->
<div data-value="ja" data-valuetext="Japanese Nihongo">日本語</div>

<!-- 
  Spanish: English name + Native name
  - "Spanish" - allows typing 's'
  - "Español" - should allow typing 'e'
-->
<div data-value="es" data-valuetext="Spanish Español">Español</div>

<!-- 
  German: English name + Native name
  - "German" - allows typing 'g'
  - "Deutsch" - should allow typing 'd'
-->
<div data-value="de" data-valuetext="German Deutsch">Deutsch</div>

Current behavior:

  • Typing c ✅ matches "Chinese"
  • Typing z ❌ doesn't match "Zhongwen" (even though it exists in the text)
  • Typing n ❌ doesn't match "Nihongo"
  • Typing e ❌ doesn't match "Español"
  • Typing d ❌ doesn't match "Deutsch"

💡 Use Case

This limitation creates poor UX for international/multi-language applications, where users naturally expect to
search using their native language terminology.

Real-World Scenario: Language Switcher

In a language selection menu, users from different regions have different mental models:

User's Language Menu Display English Name Native Name Expected Keys
Chinese 🇨🇳 简体中文 Chinese Zhongwen (拼音) c OR z
Japanese 🇯🇵 日本語 Japanese Nihongo (ローマ字) j OR n
Korean 🇰🇷 한국어 Korean Hangugeo (한글) k OR h
Spanish 🇪🇸 Español Spanish Español s OR e
German 🇩🇪 Deutsch German Deutsch g OR d

User expectation:

  • A Chinese user might think "I want Chinese (中文)" and type z (for Zhongwen/拼音)
  • A Japanese user might think "日本語が欲しい" and type n (for Nihongo/ローマ字)
  • A Spanish user might think "Quiero Español" and type e (for Español)
  • A German user might think "Ich möchte Deutsch" and type d (for Deutsch)

Current limitation: Only the first letter of the entire string works, forcing us to always put the English name
first, which feels unnatural for non-English speakers.

✅ Proposed Solution

Enhance the match function in packages/utilities/dom-query/src/searchable.ts to support word-boundary matching:

Current Implementation

const match = (valueText: string, query: string) => {
  return valueText.trim().toLowerCase().startsWith(query.toLowerCase())
}

Proposed Implementation

const match = (valueText: string, query: string) => {
  const text = valueText.trim().toLowerCase()
  const search = query.toLowerCase()

  // First, try matching the beginning of the entire string (backward compatible)
  if (text.startsWith(search)) return true

  // Then, try matching the beginning of each word
  const words = text.split(/\s+/)
  return words.some((word) => word.startsWith(search))
}

How It Works

Given data-valuetext="Chinese Zhongwen":

  1. Split by whitespace: ["Chinese", "Zhongwen"]
  2. Check if query matches the start of any word:
    • c → matches "Chinese" ✅
    • z → matches "Zhongwen" ✅
    • zh → matches "Zhongwen" ✅
    • chi → matches "Chinese" ✅

🎨 Configuration Example

With this change, developers can configure menu items like this:

<!-- Chinese user can type 'c' or 'z' -->
<div data-value="zh-CN" data-valuetext="Chinese Zhongwen">简体中文</div>

<!-- Japanese user can type 'j' or 'n' -->
<div data-value="ja" data-valuetext="Japanese Nihongo">日本語</div>

<!-- Korean user can type 'k' or 'h' -->
<div data-value="ko" data-valuetext="Korean Hangugeo">한국어</div>

<!-- Spanish user can type 's' or 'e' -->
<div data-value="es" data-valuetext="Spanish Español">Español</div>

<!-- German user can type 'g' or 'd' -->
<div data-value="de" data-valuetext="German Deutsch">Deutsch</div>

✨ Benefits

  1. ✅ Backward Compatible: Existing behavior is preserved (still matches string start)
  2. ✅ Better I18n/L10n Support: Native speakers can use their preferred terminology
  3. ✅ Improved Accessibility: More intuitive for global users
  4. ✅ Minimal Performance Impact: Simple string split and iteration
  5. ✅ No Breaking Changes: Existing applications continue to work as before

🔍 Technical Details

Affected File

packages/utilities/dom-query/src/searchable.ts - The match function around line 28

Build Output

  • packages/utilities/dom-query/dist/index.js (CommonJS)
  • packages/utilities/dom-query/dist/index.mjs (ESM)

Testing Considerations

  • Verify backward compatibility with existing single-word searches
  • Test with multi-word data-valuetext attributes
  • Ensure Unicode/non-ASCII characters in search terms work correctly
  • Test with multiple spaces between words

📊 Impact Assessment

Who Benefits

  • International applications (especially language switchers)
  • Applications with long descriptive menu items
  • Accessibility-focused applications

Who Is Affected

  • No breaking changes expected
  • Existing applications continue to work identically
  • Only applications that add multi-word data-valuetext will see new behavior

🚀 Demo

I've implemented and tested this solution in my local fork with a working language switcher that includes 11 languages
(English, Chinese, Japanese, Korean, Spanish, German, French, Portuguese, Italian, Dutch, and Polish). The word-boundary
matching works seamlessly across all these languages.

💪 Contribution

I'm happy to contribute a PR if this feature aligns with the project's goals.


Thank you for considering this enhancement! This would significantly improve UX for international users. 🌍

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions