diff --git a/packages/dev/package.json b/packages/dev/package.json index 369f6127..94349359 100644 --- a/packages/dev/package.json +++ b/packages/dev/package.json @@ -9,7 +9,7 @@ "serve": "serve public" }, "dependencies": { - "@patternfly/quickstarts": "1.0.0-rc.20", + "@patternfly/quickstarts": "1.0.0-rc.21", "@patternfly/react-core": "^4.101.3", "asciidoctor": "^2.2.1", "react": "^16.14.0", diff --git a/packages/module/package.json b/packages/module/package.json index acac100f..8d841aa5 100644 --- a/packages/module/package.json +++ b/packages/module/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/quickstarts", - "version": "1.0.0-rc.20", + "version": "1.0.0-rc.21", "description": "PatternFly quick starts", "files": [ "dist" diff --git a/packages/module/src/ConsoleInternal/components/markdown-view.tsx b/packages/module/src/ConsoleInternal/components/markdown-view.tsx index a81044ad..c91b5941 100644 --- a/packages/module/src/ConsoleInternal/components/markdown-view.tsx +++ b/packages/module/src/ConsoleInternal/components/markdown-view.tsx @@ -1,9 +1,8 @@ import * as React from 'react'; import { Converter } from 'showdown'; import { QuickStartContext, QuickStartContextValues } from '../../utils/quick-start-context'; -// import _truncate from 'lodash-es/truncate.js'; -// import _uniqueId from 'lodash-es/uniqueId.js'; import cx from 'classnames'; +import { useForceRender } from '@console/shared'; import './_markdown-view.scss'; @@ -97,18 +96,11 @@ export const SyncMarkdownView: React.FC = ({ }) => { const { getResource } = React.useContext(QuickStartContext); const markup = React.useMemo(() => { - const truncatedContent = /*truncateContent - ? _truncate(content, { - length: 256, - separator: ' ', - omission: '\u2026', - }) - : */ content; return markdownConvert( - truncatedContent || emptyMsg || getResource('Not available'), + content || emptyMsg || getResource('Not available'), extensions, ); - }, [content, emptyMsg, extensions, getResource /*, truncateContent*/]); + }, [content, emptyMsg, extensions, getResource]); const innerProps: InnerSyncMarkdownProps = { renderExtension: extensions?.length > 0 ? renderExtension : undefined, exactHeight, @@ -128,6 +120,43 @@ const uniqueId = (function () { }; })(); +type RenderExtensionProps = { + renderExtension: (contentDocument: HTMLDocument, rootSelector: string) => React.ReactNode; + selector: string; + markup: string; + docContext?: HTMLDocument; +}; + +const RenderExtension: React.FC = ({ + renderExtension, + selector, + markup, + docContext, +}) => { + const forceRender = useForceRender(); + const markupRef = React.useRef(null); + const shouldRenderExtension = React.useCallback(() => { + if (markupRef.current === markup) { + return true; + } + markupRef.current = markup; + return false; + }, [markup]); + /** + * During a render cycle in which markup changes, renderExtension receives an old copy of document + * because react is still updating the dom using `dangerouslySetInnerHTML` with latest markdown markup + * which causes the component rendered by renderExtension to receive old copy of document + * use forceRender to delay the rendering of extension by one render cycle + */ + React.useEffect(() => { + renderExtension && forceRender(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [markup]); + return ( + <>{shouldRenderExtension() ? renderExtension?.(docContext ?? document, selector) : null} + ); +}; + const InlineMarkdownView: React.FC = ({ markup, isEmpty, @@ -138,7 +167,7 @@ const InlineMarkdownView: React.FC = ({ return (
- {renderExtension && renderExtension(document, `#${id}`)} + {renderExtension && }
); }; @@ -232,7 +261,14 @@ const IFrameMarkdownView: React.FC = ({ onLoad={() => onLoad()} className={className} /> - {loaded && frame && renderExtension && renderExtension(frame.contentDocument, '')} + {loaded && frame && renderExtension && ( + + )} ); }; diff --git a/packages/module/src/ConsoleShared/src/hooks/index.ts b/packages/module/src/ConsoleShared/src/hooks/index.ts index 79e12449..15cbaff6 100644 --- a/packages/module/src/ConsoleShared/src/hooks/index.ts +++ b/packages/module/src/ConsoleShared/src/hooks/index.ts @@ -2,3 +2,4 @@ export * from './scroll'; export * from './useResizeObserver'; export * from './useScrollShadows'; export * from './useBoundingClientRect'; +export * from './useForceRender'; diff --git a/packages/module/src/ConsoleShared/src/hooks/useForceRender.ts b/packages/module/src/ConsoleShared/src/hooks/useForceRender.ts new file mode 100644 index 00000000..7633a9e9 --- /dev/null +++ b/packages/module/src/ConsoleShared/src/hooks/useForceRender.ts @@ -0,0 +1,6 @@ +import * as React from 'react'; + +/** + * React hook that forces component render. + */ +export const useForceRender = () => React.useReducer((s: boolean) => !s, false)[1] as VoidFunction;