@grafana/scenes 7.4.1 → 7.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # v7.4.2 (Thu Apr 23 2026)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - Variables: Fix options search to be case-insensitive [#1433](https://github.com/grafana/scenes/pull/1433) ([@mdvictor](https://github.com/mdvictor))
6
+
7
+ #### Authors: 1
8
+
9
+ - Victor Marin ([@mdvictor](https://github.com/mdvictor))
10
+
11
+ ---
12
+
1
13
  # v7.4.1 (Wed Apr 22 2026)
2
14
 
3
15
  #### 🐛 Bug Fix
@@ -1,3 +1,4 @@
1
+ import { escapeRegex } from '@grafana/data';
1
2
  import uFuzzy from '@leeoniya/ufuzzy';
2
3
 
3
4
  const REGEXP_NON_ASCII = /[^ -~]/m;
@@ -22,9 +23,10 @@ function fuzzyFind(options, haystack, needle) {
22
23
  terms.length > maxFuzzyTerms || // if these differ then special chars exist in the input
23
24
  keptChars !== inputChars
24
25
  ) {
26
+ const needleRegex = new RegExp(escapeRegex(needle), "i");
25
27
  for (let i = 0; i < haystack.length; i++) {
26
28
  let item = haystack[i];
27
- if (item.includes(needle)) {
29
+ if (needleRegex.test(item)) {
28
30
  matches.push(options[i]);
29
31
  }
30
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"filter.js","sources":["../../../src/variables/filter.ts"],"sourcesContent":["import { SelectableValue } from '@grafana/data';\nimport uFuzzy from '@leeoniya/ufuzzy';\nimport { VariableValueOption } from './types';\n\n// https://catonmat.net/my-favorite-regex :)\nconst REGEXP_NON_ASCII = /[^ -~]/m;\n// https://www.asciitable.com/\n// matches only these: `~!@#$%^&*()_+-=[]\\{}|;':\",./<>?\nconst REGEXP_ONLY_SYMBOLS = /^[\\x21-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7B-\\x7E]+$/m;\n// limit max terms in needle that qualify for re-ordering\nconst outOfOrderLimit = 5;\n// beyond 25 chars fall back to substring search\nconst maxNeedleLength = 25;\n// beyond 5 terms fall back to substring match\nconst maxFuzzyTerms = 5;\n// when number of matches <= 1e4, do ranking + sorting by quality\nconst rankThreshold = 1e4;\n\n// typo tolerance mode\nconst uf = new uFuzzy({ intraMode: 1 });\n\nexport function fuzzyFind<T extends SelectableValue | VariableValueOption>(\n options: T[],\n haystack: string[],\n needle: string\n) {\n let matches: T[] = [];\n\n const terms = uf.split(needle);\n // chars maintained by ufuzzy after stripping special chars\n const keptChars = terms.join('').length;\n // overall input chars without whitespace\n const inputChars = needle.replace(/\\s/g, '').length;\n\n if (needle === '') {\n matches = options;\n }\n // fallback to substring matches to avoid badness\n else if (\n // contains non-ascii\n REGEXP_NON_ASCII.test(needle) ||\n // is only ascii symbols (operators)\n REGEXP_ONLY_SYMBOLS.test(needle) ||\n // too long (often copy-paste from somewhere)\n needle.length > maxNeedleLength ||\n // skip fuzzy searching if too many terms\n terms.length > maxFuzzyTerms ||\n // if these differ then special chars exist in the input\n keptChars !== inputChars\n ) {\n for (let i = 0; i < haystack.length; i++) {\n let item = haystack[i];\n\n if (item.includes(needle)) {\n matches.push(options[i]);\n }\n }\n }\n // fuzzy search\n else {\n const [idxs, info, order] = uf.search(haystack, needle, outOfOrderLimit, rankThreshold);\n\n if (idxs?.length) {\n if (info && order) {\n matches = order.map((idx) => options[info.idx[idx]]);\n } else {\n matches = idxs.map((idx) => options[idx]);\n }\n }\n }\n\n return matches;\n}\n"],"names":[],"mappings":";;AAKA,MAAM,gBAAmB,GAAA,SAAA;AAGzB,MAAM,mBAAsB,GAAA,4CAAA;AAE5B,MAAM,eAAkB,GAAA,CAAA;AAExB,MAAM,eAAkB,GAAA,EAAA;AAExB,MAAM,aAAgB,GAAA,CAAA;AAEtB,MAAM,aAAgB,GAAA,GAAA;AAGtB,MAAM,KAAK,IAAI,MAAA,CAAO,EAAE,SAAA,EAAW,GAAG,CAAA;AAEtB,SAAA,SAAA,CACd,OACA,EAAA,QAAA,EACA,MACA,EAAA;AACA,EAAA,IAAI,UAAe,EAAC;AAEpB,EAAM,MAAA,KAAA,GAAQ,EAAG,CAAA,KAAA,CAAM,MAAM,CAAA;AAE7B,EAAA,MAAM,SAAY,GAAA,KAAA,CAAM,IAAK,CAAA,EAAE,CAAE,CAAA,MAAA;AAEjC,EAAA,MAAM,UAAa,GAAA,MAAA,CAAO,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAE,CAAA,MAAA;AAE7C,EAAA,IAAI,WAAW,EAAI,EAAA;AACjB,IAAU,OAAA,GAAA,OAAA;AAAA,GACZ,MAAA;AAAA;AAAA,IAIE,gBAAA,CAAiB,KAAK,MAAM,CAAA;AAAA,IAE5B,mBAAA,CAAoB,KAAK,MAAM,CAAA;AAAA,IAE/B,OAAO,MAAS,GAAA,eAAA;AAAA,IAEhB,MAAM,MAAS,GAAA,aAAA;AAAA,IAEf,SAAc,KAAA;AAAA,IACd;AACA,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,QAAA,CAAS,QAAQ,CAAK,EAAA,EAAA;AACxC,MAAI,IAAA,IAAA,GAAO,SAAS,CAAC,CAAA;AAErB,MAAI,IAAA,IAAA,CAAK,QAAS,CAAA,MAAM,CAAG,EAAA;AACzB,QAAQ,OAAA,CAAA,IAAA,CAAK,OAAQ,CAAA,CAAC,CAAC,CAAA;AAAA;AACzB;AACF,GAGG,MAAA;AACH,IAAM,MAAA,CAAC,IAAM,EAAA,IAAA,EAAM,KAAK,CAAA,GAAI,GAAG,MAAO,CAAA,QAAA,EAAU,MAAQ,EAAA,eAAA,EAAiB,aAAa,CAAA;AAEtF,IAAA,IAAI,6BAAM,MAAQ,EAAA;AAChB,MAAA,IAAI,QAAQ,KAAO,EAAA;AACjB,QAAU,OAAA,GAAA,KAAA,CAAM,IAAI,CAAC,GAAA,KAAQ,QAAQ,IAAK,CAAA,GAAA,CAAI,GAAG,CAAC,CAAC,CAAA;AAAA,OAC9C,MAAA;AACL,QAAA,OAAA,GAAU,KAAK,GAAI,CAAA,CAAC,GAAQ,KAAA,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA;AAC1C;AACF;AAGF,EAAO,OAAA,OAAA;AACT;;;;"}
1
+ {"version":3,"file":"filter.js","sources":["../../../src/variables/filter.ts"],"sourcesContent":["import { escapeRegex, SelectableValue } from '@grafana/data';\nimport uFuzzy from '@leeoniya/ufuzzy';\nimport { VariableValueOption } from './types';\n\n// https://catonmat.net/my-favorite-regex :)\nconst REGEXP_NON_ASCII = /[^ -~]/m;\n// https://www.asciitable.com/\n// matches only these: `~!@#$%^&*()_+-=[]\\{}|;':\",./<>?\nconst REGEXP_ONLY_SYMBOLS = /^[\\x21-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7B-\\x7E]+$/m;\n// limit max terms in needle that qualify for re-ordering\nconst outOfOrderLimit = 5;\n// beyond 25 chars fall back to substring search\nconst maxNeedleLength = 25;\n// beyond 5 terms fall back to substring match\nconst maxFuzzyTerms = 5;\n// when number of matches <= 1e4, do ranking + sorting by quality\nconst rankThreshold = 1e4;\n\n// typo tolerance mode\nconst uf = new uFuzzy({ intraMode: 1 });\n\nexport function fuzzyFind<T extends SelectableValue | VariableValueOption>(\n options: T[],\n haystack: string[],\n needle: string\n) {\n let matches: T[] = [];\n\n const terms = uf.split(needle);\n // chars maintained by ufuzzy after stripping special chars\n const keptChars = terms.join('').length;\n // overall input chars without whitespace\n const inputChars = needle.replace(/\\s/g, '').length;\n\n if (needle === '') {\n matches = options;\n }\n // fallback to substring matches to avoid badness\n else if (\n // contains non-ascii\n REGEXP_NON_ASCII.test(needle) ||\n // is only ascii symbols (operators)\n REGEXP_ONLY_SYMBOLS.test(needle) ||\n // too long (often copy-paste from somewhere)\n needle.length > maxNeedleLength ||\n // skip fuzzy searching if too many terms\n terms.length > maxFuzzyTerms ||\n // if these differ then special chars exist in the input\n keptChars !== inputChars\n ) {\n const needleRegex = new RegExp(escapeRegex(needle), 'i');\n\n for (let i = 0; i < haystack.length; i++) {\n let item = haystack[i];\n\n if (needleRegex.test(item)) {\n matches.push(options[i]);\n }\n }\n }\n // fuzzy search\n else {\n const [idxs, info, order] = uf.search(haystack, needle, outOfOrderLimit, rankThreshold);\n\n if (idxs?.length) {\n if (info && order) {\n matches = order.map((idx) => options[info.idx[idx]]);\n } else {\n matches = idxs.map((idx) => options[idx]);\n }\n }\n }\n\n return matches;\n}\n"],"names":[],"mappings":";;;AAKA,MAAM,gBAAmB,GAAA,SAAA;AAGzB,MAAM,mBAAsB,GAAA,4CAAA;AAE5B,MAAM,eAAkB,GAAA,CAAA;AAExB,MAAM,eAAkB,GAAA,EAAA;AAExB,MAAM,aAAgB,GAAA,CAAA;AAEtB,MAAM,aAAgB,GAAA,GAAA;AAGtB,MAAM,KAAK,IAAI,MAAA,CAAO,EAAE,SAAA,EAAW,GAAG,CAAA;AAEtB,SAAA,SAAA,CACd,OACA,EAAA,QAAA,EACA,MACA,EAAA;AACA,EAAA,IAAI,UAAe,EAAC;AAEpB,EAAM,MAAA,KAAA,GAAQ,EAAG,CAAA,KAAA,CAAM,MAAM,CAAA;AAE7B,EAAA,MAAM,SAAY,GAAA,KAAA,CAAM,IAAK,CAAA,EAAE,CAAE,CAAA,MAAA;AAEjC,EAAA,MAAM,UAAa,GAAA,MAAA,CAAO,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAE,CAAA,MAAA;AAE7C,EAAA,IAAI,WAAW,EAAI,EAAA;AACjB,IAAU,OAAA,GAAA,OAAA;AAAA,GACZ,MAAA;AAAA;AAAA,IAIE,gBAAA,CAAiB,KAAK,MAAM,CAAA;AAAA,IAE5B,mBAAA,CAAoB,KAAK,MAAM,CAAA;AAAA,IAE/B,OAAO,MAAS,GAAA,eAAA;AAAA,IAEhB,MAAM,MAAS,GAAA,aAAA;AAAA,IAEf,SAAc,KAAA;AAAA,IACd;AACA,IAAA,MAAM,cAAc,IAAI,MAAA,CAAO,WAAY,CAAA,MAAM,GAAG,GAAG,CAAA;AAEvD,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,QAAA,CAAS,QAAQ,CAAK,EAAA,EAAA;AACxC,MAAI,IAAA,IAAA,GAAO,SAAS,CAAC,CAAA;AAErB,MAAI,IAAA,WAAA,CAAY,IAAK,CAAA,IAAI,CAAG,EAAA;AAC1B,QAAQ,OAAA,CAAA,IAAA,CAAK,OAAQ,CAAA,CAAC,CAAC,CAAA;AAAA;AACzB;AACF,GAGG,MAAA;AACH,IAAM,MAAA,CAAC,IAAM,EAAA,IAAA,EAAM,KAAK,CAAA,GAAI,GAAG,MAAO,CAAA,QAAA,EAAU,MAAQ,EAAA,eAAA,EAAiB,aAAa,CAAA;AAEtF,IAAA,IAAI,6BAAM,MAAQ,EAAA;AAChB,MAAA,IAAI,QAAQ,KAAO,EAAA;AACjB,QAAU,OAAA,GAAA,KAAA,CAAM,IAAI,CAAC,GAAA,KAAQ,QAAQ,IAAK,CAAA,GAAA,CAAI,GAAG,CAAC,CAAC,CAAA;AAAA,OAC9C,MAAA;AACL,QAAA,OAAA,GAAU,KAAK,GAAI,CAAA,CAAC,GAAQ,KAAA,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA;AAC1C;AACF;AAGF,EAAO,OAAA,OAAA;AACT;;;;"}
package/dist/index.js CHANGED
@@ -5521,9 +5521,10 @@ function fuzzyFind(options, haystack, needle) {
5521
5521
  terms.length > maxFuzzyTerms || // if these differ then special chars exist in the input
5522
5522
  keptChars !== inputChars
5523
5523
  ) {
5524
+ const needleRegex = new RegExp(data.escapeRegex(needle), "i");
5524
5525
  for (let i = 0; i < haystack.length; i++) {
5525
5526
  let item = haystack[i];
5526
- if (item.includes(needle)) {
5527
+ if (needleRegex.test(item)) {
5527
5528
  matches.push(options[i]);
5528
5529
  }
5529
5530
  }