From 67f3c4d824d5b0a59baf4cd49a89e36c9f01693e Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 4 May 2023 14:41:44 +0200 Subject: [PATCH] Improve control over `Menu` and `Listbox` options while searching (#2471) * add `get-text-value` helper * use `getTextValue` in `Listbox` component * use `getTextValue` in `Menu` component * update changelog * ensure we handle multiple values for `aria-labelledby` * hoist regex * drop child nodes instead of replacing its innerText This makes it a bit slower but also more correct. We can use a cache on another level to ensure that we are not creating useless work. * add `useTextValue` to improve performance of `getTextValue` This will add a cache and only if the `innerText` changes, only then will we calculate the new text value. * use better `useTextValue` hook --- jest/create-jest-config.cjs | 6 +- jest/polyfills.ts | 15 +++ packages/@headlessui-react/CHANGELOG.md | 1 + .../src/components/listbox/listbox.tsx | 4 +- .../src/components/menu/menu.tsx | 14 ++- .../src/hooks/use-text-value.ts | 25 +++++ .../src/utils/get-text-value.test.ts | 95 +++++++++++++++++++ .../src/utils/get-text-value.ts | 81 ++++++++++++++++ packages/@headlessui-vue/CHANGELOG.md | 1 + .../src/components/listbox/listbox.ts | 10 +- .../src/components/menu/menu.ts | 10 +- .../src/hooks/use-text-value.ts | 25 +++++ .../src/utils/get-text-value.test.ts | 95 +++++++++++++++++++ .../src/utils/get-text-value.ts | 81 ++++++++++++++++ 14 files changed, 447 insertions(+), 16 deletions(-) create mode 100644 jest/polyfills.ts create mode 100644 packages/@headlessui-react/src/hooks/use-text-value.ts create mode 100644 packages/@headlessui-react/src/utils/get-text-value.test.ts create mode 100644 packages/@headlessui-react/src/utils/get-text-value.ts create mode 100644 packages/@headlessui-vue/src/hooks/use-text-value.ts create mode 100644 packages/@headlessui-vue/src/utils/get-text-value.test.ts create mode 100644 packages/@headlessui-vue/src/utils/get-text-value.ts diff --git a/jest/create-jest-config.cjs b/jest/create-jest-config.cjs index 3ab2429e19..63e9394dbe 100644 --- a/jest/create-jest-config.cjs +++ b/jest/create-jest-config.cjs @@ -3,7 +3,11 @@ module.exports = function createJestConfig(root, options) { return Object.assign( { rootDir: root, - setupFilesAfterEnv: ['../../jest/custom-matchers.ts', ...setupFilesAfterEnv], + setupFilesAfterEnv: [ + '../../jest/custom-matchers.ts', + '../../jest/polyfills.ts', + ...setupFilesAfterEnv, + ], transform: { '^.+\\.(t|j)sx?$': '@swc/jest', ...transform, diff --git a/jest/polyfills.ts b/jest/polyfills.ts new file mode 100644 index 0000000000..f928491855 --- /dev/null +++ b/jest/polyfills.ts @@ -0,0 +1,15 @@ +// JSDOM Doesn't implement innerText yet: https://github.com/jsdom/jsdom/issues/1245 +// So this is a hacky way of implementing it using `textContent`. +// Real implementation doesn't use textContent because: +// > textContent gets the content of all elements, including