From 97e1f3cf9749dbbcbd3860f26ace0a5e48e0d2c5 Mon Sep 17 00:00:00 2001 From: Micah Snyder Date: Mon, 23 Jun 2025 17:20:56 -0700 Subject: [PATCH] Convert useMutationAwareAnchor to use Sizzle --- packages/react/package.json | 2 + .../components/Hint/useMutationAwareAnchor.ts | 37 ++++++++++--------- packages/react/src/index.ts | 1 + yarn.lock | 16 ++++++++ 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/packages/react/package.json b/packages/react/package.json index 7a767a38..b0d906ab 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -65,6 +65,7 @@ "known-css-properties": "^0.29.0", "react-hook-form": "^7.49.3", "react-remove-scroll": "^2.5.10", + "sizzle": "^2.3.10", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { @@ -77,6 +78,7 @@ "@types/node": "^20.10.5", "@types/react": "^18.2.34", "@types/react-dom": "^18.2.14", + "@types/sizzle": "^2", "@types/use-sync-external-store": "^0.0.6", "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", diff --git a/packages/react/src/components/Hint/useMutationAwareAnchor.ts b/packages/react/src/components/Hint/useMutationAwareAnchor.ts index 02a2e036..a997fbe5 100644 --- a/packages/react/src/components/Hint/useMutationAwareAnchor.ts +++ b/packages/react/src/components/Hint/useMutationAwareAnchor.ts @@ -1,15 +1,16 @@ import { useEffect, useState } from 'react' +import Sizzle from 'sizzle' -function checkElementForAnchor(element: Element, anchor: string) { +function checkElementForAnchor(element: Element, anchorSelector: string) { try { - if (element.matches(anchor) && isVisible(element)) { + if (Sizzle.matchesSelector(element, anchorSelector) && isVisible(element)) { return element } - const anchorSelector = element.querySelectorAll(anchor) + const anchorElements = Sizzle(anchorSelector, element) - if (anchorSelector.length > 0 && isVisible(anchorSelector[0])) { - return anchorSelector[0] + if (anchorElements.length > 0 && isVisible(anchorElements[0])) { + return anchorElements[0] } } catch (invalidSelector) { return null @@ -24,30 +25,30 @@ function isVisible(element: Element) { return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length) } -export function useMutationAwareAnchor(anchor: string) { +export function useMutationAwareAnchor(anchorSelector: string) { const [anchorElement, setAnchorElement] = useState(null) useEffect(() => { - if (typeof anchor !== 'string') { + if (typeof anchorSelector !== 'string') { return } try { - const element = document.querySelector(anchor) + const element = Sizzle(anchorSelector)[0] if (element != null) { - console.debug(`[frigade] Found anchor: ${anchor}`) + console.debug(`[frigade] Found anchor: ${anchorSelector}`) setAnchorElement(element) } else { - console.debug(`[frigade] No anchor found for selector: ${anchor}`) + console.debug(`[frigade] No anchor found for selector: ${anchorSelector}`) } } catch (invalidSelector) { - console.debug(`[frigade] Invalid selector for anchor: ${anchor}`) + console.debug(`[frigade] Invalid selector for anchor: ${anchorSelector}`) } - }, [anchor]) + }, [anchorSelector]) useEffect(() => { - if (typeof anchor !== 'string') { + if (typeof anchorSelector !== 'string') { return } @@ -62,10 +63,10 @@ export function useMutationAwareAnchor(anchor: string) { continue } - const maybeAnchor = checkElementForAnchor(node as Element, anchor) + const maybeAnchor = checkElementForAnchor(node as Element, anchorSelector) if (maybeAnchor != null) { - console.debug(`[frigade] Found anchor: ${anchor}`) + console.debug(`[frigade] Found anchor: ${anchorSelector}`) setAnchorElement(maybeAnchor) break } @@ -76,10 +77,10 @@ export function useMutationAwareAnchor(anchor: string) { continue } - const maybeAnchor = checkElementForAnchor(node as Element, anchor) + const maybeAnchor = checkElementForAnchor(node as Element, anchorSelector) if (maybeAnchor != null) { - console.debug(`[frigade] Removed anchor: ${anchor}`) + console.debug(`[frigade] Removed anchor: ${anchorSelector}`) setAnchorElement(null) break } @@ -90,7 +91,7 @@ export function useMutationAwareAnchor(anchor: string) { observer.observe(document.querySelector('body'), { childList: true, subtree: true }) return () => observer.disconnect() - }, [anchor]) + }, [anchorSelector]) return { anchorElement, diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 822c32f7..0a7adccc 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -65,6 +65,7 @@ export { export { useFrigade } from './hooks/useFrigade' export { useUser } from './hooks/useUser' export { useGroup } from './hooks/useGroup' +export { useFloating } from './hooks/useFloating' // TEMP: Remove this, used for testing Storybook export * as FloatingUI from '@floating-ui/react' diff --git a/yarn.lock b/yarn.lock index 30f3346f..fb5cf429 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3834,6 +3834,7 @@ __metadata: "@types/node": "npm:^20.10.5" "@types/react": "npm:^18.2.34" "@types/react-dom": "npm:^18.2.14" + "@types/sizzle": "npm:^2" "@types/use-sync-external-store": "npm:^0.0.6" "@typescript-eslint/eslint-plugin": "npm:^6.20.0" "@typescript-eslint/parser": "npm:^6.20.0" @@ -3852,6 +3853,7 @@ __metadata: react-hook-form: "npm:^7.49.3" react-remove-scroll: "npm:^2.5.10" rimraf: "npm:^4.1.2" + sizzle: "npm:^2.3.10" ts-jest: "npm:^29.1.0" tsup: "npm:^6.7.0" typedoc: "npm:^0.25.12" @@ -7867,6 +7869,13 @@ __metadata: languageName: node linkType: hard +"@types/sizzle@npm:^2": + version: 2.3.9 + resolution: "@types/sizzle@npm:2.3.9" + checksum: 10/413811a79e7e9f1d8f47e6047ae0aea1530449d612304cdda1c30018e3d053b8544861ec2c70bdeca75a0a010192e6bb78efc6fb4caaafdd65c4eee90066686a + languageName: node + linkType: hard + "@types/stack-utils@npm:^2.0.0": version: 2.0.3 resolution: "@types/stack-utils@npm:2.0.3" @@ -18477,6 +18486,13 @@ __metadata: languageName: node linkType: hard +"sizzle@npm:^2.3.10": + version: 2.3.10 + resolution: "sizzle@npm:2.3.10" + checksum: 10/c68b99ab7bb904655671068d959c1c4bee6b818514f04e3027f23650d2c85e6895d6a01304dd5cf8529c2cbe58cd926aad44a37396003c6a097b91ba5b9e4904 + languageName: node + linkType: hard + "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0"