Merge pull request #25422 from backstage/shadow-root-mutation-listener

Shadow Root MutationObserver
This commit is contained in:
Jackson Chen
2024-06-28 08:50:30 -04:00
committed by GitHub
5 changed files with 24 additions and 17 deletions
+1 -2
View File
@@ -1,6 +1,5 @@
---
'@backstage/plugin-techdocs-react': patch
'@backstage/plugin-techdocs': patch
---
Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation.
Resolved the issue where changes in TechDoc add-ons, including the TextSize add-on, were not reapplying during navigation
-2
View File
@@ -116,8 +116,6 @@ export type TechDocsReaderPageValue = {
entityMetadata: AsyncState<TechDocsEntityMetadata>;
shadowRoot?: ShadowRoot;
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
shadowRootVersion: number;
incShadowRootVersion: () => void;
title: string;
setTitle: Dispatch<SetStateAction<string>>;
subtitle: string;
+1 -8
View File
@@ -25,7 +25,6 @@ import React, {
} from 'react';
import useAsync, { AsyncState } from 'react-use/esm/useAsync';
import useAsyncRetry from 'react-use/esm/useAsyncRetry';
import useCounter from 'react-use/esm/useCounter';
import {
CompoundEntityRef,
@@ -65,8 +64,6 @@ export type TechDocsReaderPageValue = {
entityMetadata: AsyncState<TechDocsEntityMetadata>;
shadowRoot?: ShadowRoot;
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
shadowRootVersion: number;
incShadowRootVersion: () => void;
title: string;
setTitle: Dispatch<SetStateAction<string>>;
subtitle: string;
@@ -83,8 +80,6 @@ const defaultTechDocsReaderPageValue: TechDocsReaderPageValue = {
setTitle: () => {},
setSubtitle: () => {},
setShadowRoot: () => {},
shadowRootVersion: 0,
incShadowRootVersion: () => {},
metadata: { loading: true },
entityMetadata: { loading: true },
entityRef: { kind: '', name: '', namespace: '' },
@@ -139,7 +134,6 @@ export const TechDocsReaderPageProvider = memo(
const [shadowRoot, setShadowRoot] = useState<ShadowRoot | undefined>(
defaultTechDocsReaderPageValue.shadowRoot,
);
const [shadowRootVersion, { inc: incShadowRootVersion }] = useCounter(0);
useEffect(() => {
if (shadowRoot && !metadata.value && !metadata.loading) {
@@ -159,8 +153,6 @@ export const TechDocsReaderPageProvider = memo(
entityMetadata,
shadowRoot,
setShadowRoot,
shadowRootVersion,
incShadowRootVersion,
title,
setTitle,
subtitle,
@@ -198,5 +190,6 @@ export const useTechDocsReaderPage = () => {
if (context === undefined) {
throw new Error('No context found for version 1.');
}
return context;
};
+21 -2
View File
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useState, useEffect, useMemo } from 'react';
import { useEffect, useMemo, useState } from 'react';
import debounce from 'lodash/debounce';
import { useTechDocsReaderPage } from './context';
@@ -39,9 +39,28 @@ export const useShadowRootElements = <
selectors: string[],
): TReturnedElement[] => {
const shadowRoot = useShadowRoot();
const [render, rerender] = useState(false);
useEffect(() => {
let observer: MutationObserver;
if (shadowRoot) {
observer = new MutationObserver(() => {
rerender(!render);
});
observer.observe(shadowRoot, {
attributes: true,
characterData: true,
childList: true,
subtree: true,
});
}
return () => observer?.disconnect();
}, [shadowRoot, render, rerender]);
if (!shadowRoot) return [];
return selectors
.map(selector => shadowRoot?.querySelectorAll<TReturnedElement>(selector))
.map(selector => shadowRoot.querySelectorAll<TReturnedElement>(selector))
.filter(nodeList => nodeList.length)
.map(nodeList => Array.from(nodeList))
.flat();
@@ -80,7 +80,6 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider(
entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },
entityRef,
setShadowRoot,
incShadowRootVersion,
} = useTechDocsReaderPage();
const dom = useTechDocsReaderDom(entityRef);
const path = window.location.pathname;
@@ -103,12 +102,11 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider(
const handleAppend = useCallback(
(newShadowRoot: ShadowRoot) => {
setShadowRoot(newShadowRoot);
incShadowRootVersion();
if (onReady instanceof Function) {
onReady();
}
},
[setShadowRoot, incShadowRootVersion, onReady],
[setShadowRoot, onReady],
);
// No entity metadata = 404. Don't render content at all.