diff --git a/src/components/Episode/Header/Episode.Channels.tsx b/src/components/Episode/Header/Episode.Channels.tsx index 49e32c2..22122e5 100644 --- a/src/components/Episode/Header/Episode.Channels.tsx +++ b/src/components/Episode/Header/Episode.Channels.tsx @@ -53,6 +53,7 @@ const EpisodeChannelContainer = styled.div` align-items: center; margin-top: 32px; margin-bottom: 32px; + flex-wrap: wrap; ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 24px; diff --git a/src/components/SearchBox/SearchBox.tsx b/src/components/SearchBox/SearchBox.tsx index 0fe2ad1..1ab04d9 100644 --- a/src/components/SearchBox/SearchBox.tsx +++ b/src/components/SearchBox/SearchBox.tsx @@ -66,6 +66,8 @@ const SearchBox = (props: SearchBoxProps) => { showModeSwitch = true, } = props + const hydrated = useHydrated() + const [filterTags, setFilterTags] = useQueryParam( 'topic', withDefault(ArrayParam, []), @@ -96,14 +98,9 @@ const SearchBox = (props: SearchBoxProps) => { const [whereResultsStick, setWhereResultsStick] = useState(0) const [showDetails, setShowDetails] = useState(false) const [detailsTop, setDetailsTop] = useState(0) - const [mounted, setMounted] = useState(false) const [focused, setFocused] = useState(false) const [showClear, setShowClear] = useState(false) - useEffect(() => { - setMounted(true) - return () => setMounted(false) - }, []) const handleViewChange = async (n: string) => { setView(n) onViewChange(n) @@ -185,8 +182,6 @@ const SearchBox = (props: SearchBoxProps) => { // if (query !== queryInput) setQuery(queryInput) // }, [focused, query, queryInput]) - const hydrated = useHydrated() - return ( data.__typename === 'TextBlock', transform: (helpers, data, original, root) => { - const { text = '', html = '' } = data + let { text = '', html = '' } = data const labels: LPE.Post.ContentBlockLabel[] = [] let embed: LPE.Post.TextBlockEmbed | null = null @@ -67,10 +68,23 @@ export const TextBlockDataType: UnbodyDataTypeConfig< } } + // set target="_blank" on anchor elements + { + const matches = Array.from( + html.matchAll(/]*href="http[^>]*"[^>]*>/gi), + ) + + for (const match of matches) { + const [anchorHTML] = match + const newAnchorHTML = setAttributeOnHTML(anchorHTML, 'target', '_blank') + html = html.replace(anchorHTML, newAnchorHTML) + } + } + return { id: data?._additional?.id || `${data.order}`, type: 'text', - html: data.html, + html, text: data.text || '', classNames: data.classNames, footnotes: data.footnotesObj, diff --git a/src/utils/html.utils.ts b/src/utils/html.utils.ts index 7934e79..b2f3ee5 100644 --- a/src/utils/html.utils.ts +++ b/src/utils/html.utils.ts @@ -38,6 +38,30 @@ export function extractAttributeFromHTML( ) } +export const setAttributeOnHTML = ( + html: string, + attribute: string, + value: string, +) => { + let result = html.trim() + const tagName = html.match(/^<([\w])+/)?.[0]?.slice(1)! + const current = extractAttributeFromHTML(html, attribute) + + if (current) { + const currentAttribute = `${attribute}="${current}"` + const index = html.indexOf(currentAttribute) + + result = + result.slice(0, index) + result.slice(index + currentAttribute.length + 1) + } + + result = `<${tagName} ${attribute}="${value}"${result.slice( + tagName.length + 1, + )}` + + return result +} + export const isAuthorsParagraph = (html: string) => { const regex = /]*href="mailto:([^"]+)"[^>]*>([^<]+)<\/a>/g const matches = html.match(regex)