diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c236195f7b..bba7918903b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ - Added `onBlur` prop to `EuiComboBox` ([#1400](https://github.com/elastic/eui/pull/1400)) - Added `initialFocus` prop typedefs to `EuiModal` and `EuiPopover` ([#1410](https://github.com/elastic/eui/pull/1410)) +**Bug fixes** + +- Support extended characters (e.g. non-latin, unicode) in `EuiSearchBar` and `EuiQuery` ([#1415](https://github.com/elastic/eui/pull/1415)) + ## [`6.2.0`](https://github.com/elastic/eui/tree/v6.2.0) - Added `logoCodesandbox` and updated `apmApp` icons ([#1407](https://github.com/elastic/eui/pull/1407)) diff --git a/src/components/search_bar/query/default_syntax.js b/src/components/search_bar/query/default_syntax.js index 3bced52e84d..d2496088a2c 100644 --- a/src/components/search_bar/query/default_syntax.js +++ b/src/components/search_bar/query/default_syntax.js @@ -129,6 +129,16 @@ wordChar = alnum / [-_*:] / escapedChar + / extendedGlyph + +// This isn't _strictly_ correct: +// for our purposes, a non-ascii word character is considered to +// be anything above \`Latin-1 Punctuation & Symbols\`, which ends at U+00BF +// This allows any non-ascii character, including the full set of unicode characters +// even those in the supplementary planes (U+010000 → U+10FFFF) as those will be seen individually +// in their surrogate pairs which are of the format /[\uD800-\uDBFF][\uDC00-\uDFFF]/ +extendedGlyph + = [\u00C0-\uFFFF] escapedChar = "\\\\" reservedChar diff --git a/src/components/search_bar/query/default_syntax.test.js b/src/components/search_bar/query/default_syntax.test.js index 9805d5f81a2..8b2a59ea6fe 100644 --- a/src/components/search_bar/query/default_syntax.test.js +++ b/src/components/search_bar/query/default_syntax.test.js @@ -68,6 +68,28 @@ describe('defaultSyntax', () => { expect(clause.value).toBe('dash-3'); }); + test('unicode field and term values', () => { + const query = 'name:👸Queen_Elizabeth 🤴King_Henry'; + const ast = defaultSyntax.parse(query); + + expect(ast).toBeDefined(); + expect(ast.clauses).toBeDefined(); + expect(ast.clauses).toHaveLength(2); + + let clause = ast.getSimpleFieldClause('name', '👸Queen_Elizabeth'); + expect(clause).toBeDefined(); + expect(AST.Field.isInstance(clause)).toBe(true); + expect(AST.Match.isMustClause(clause)).toBe(true); + expect(clause.field).toBe('name'); + expect(clause.value).toBe('👸Queen_Elizabeth'); + + clause = ast.getTermClause('🤴King_Henry'); + expect(clause).toBeDefined(); + expect(AST.Term.isInstance(clause)).toBe(true); + expect(AST.Match.isMustClause(clause)).toBe(true); + expect(clause.value).toBe('🤴King_Henry'); + }); + test('escaped chars as default clauses', () => { const query = '-\\: \\\\'; const ast = defaultSyntax.parse(query);