UNPKG

react-inlinesvg

Version:
1 lines 19.3 kB
{"version":3,"file":"index.mjs","names":[],"sources":["../src/modules/hooks.tsx","../src/modules/utils.ts","../src/modules/useInlineSVG.ts","../src/index.tsx"],"sourcesContent":["import { EffectCallback, useEffect, useRef } from 'react';\n\nexport function useMount(effect: EffectCallback) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(effect, []);\n}\n\nexport function usePrevious<T>(state: T): T | undefined {\n const ref = useRef<T>(undefined);\n\n useEffect(() => {\n ref.current = state;\n });\n\n return ref.current;\n}\n","import convert from 'react-from-dom';\n\nimport { Props, State } from '../types';\n\ninterface GetNodeOptions extends Props, Pick<State, 'content'> {\n handleError: (error: Error) => void;\n hash: string;\n}\n\ninterface UpdateSVGAttributesOptions extends Pick<Props, 'baseURL' | 'uniquifyIDs'> {\n hash: string;\n}\n\nfunction uniquifyStyleIds(svgText: string, hash: string, baseURL: string): string {\n const idMatches = svgText.matchAll(/\\bid=([\"'])([^\"']+)\\1/g);\n const ids = [...new Set([...idMatches].map(m => m[2]))];\n\n if (!ids.length) {\n return svgText;\n }\n\n ids.sort((a, b) => b.length - a.length);\n\n return svgText.replace(/<style[^>]*>([\\S\\s]*?)<\\/style>/gi, (fullMatch, cssContent) => {\n let modified = cssContent as string;\n\n for (const id of ids) {\n const escaped = id.replace(/[$()*+.?[\\\\\\]^{|}]/g, '\\\\$&');\n\n modified = modified.replace(\n new RegExp(`url\\\\((['\"]?)#${escaped}\\\\1\\\\)`, 'g'),\n `url($1${baseURL}#${id}__${hash}$1)`,\n );\n modified = modified.replace(\n new RegExp(`#${escaped}(?![a-zA-Z0-9_-])`, 'g'),\n `#${id}__${hash}`,\n );\n }\n\n return fullMatch.replace(cssContent, modified);\n });\n}\n\nexport function getNode(options: GetNodeOptions) {\n const {\n baseURL,\n content,\n description,\n handleError,\n hash,\n preProcessor,\n title,\n uniquifyIDs = false,\n } = options;\n\n try {\n let svgText = preProcessor ? preProcessor(content) : content;\n\n if (uniquifyIDs) {\n svgText = uniquifyStyleIds(svgText, hash, baseURL ?? '');\n }\n\n const node = convert(svgText, { nodeOnly: true });\n\n if (!node || !(node instanceof SVGSVGElement)) {\n throw new Error('Could not convert the src to a DOM Node');\n }\n\n const svg = updateSVGAttributes(node, { baseURL, hash, uniquifyIDs });\n\n if (description) {\n const originalDesc = svg.querySelector('desc');\n\n if (originalDesc?.parentNode) {\n originalDesc.parentNode.removeChild(originalDesc);\n }\n\n const descElement = document.createElementNS('http://www.w3.org/2000/svg', 'desc');\n\n descElement.innerHTML = description;\n svg.prepend(descElement);\n }\n\n if (typeof title !== 'undefined') {\n const originalTitle = svg.querySelector('title');\n\n if (originalTitle?.parentNode) {\n originalTitle.parentNode.removeChild(originalTitle);\n }\n\n if (title) {\n const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');\n\n titleElement.innerHTML = title;\n svg.prepend(titleElement);\n }\n }\n\n return svg;\n } catch (error: any) {\n return handleError(error);\n }\n}\n\nexport function updateSVGAttributes(\n node: SVGSVGElement,\n options: UpdateSVGAttributesOptions,\n): SVGSVGElement {\n const { baseURL = '', hash, uniquifyIDs } = options;\n const replaceableAttributes = ['id', 'href', 'xlink:href', 'xlink:role', 'xlink:arcrole'];\n const linkAttributes = ['href', 'xlink:href'];\n const isDataValue = (name: string, value: string) =>\n linkAttributes.includes(name) && (value ? !value.includes('#') : false);\n\n if (!uniquifyIDs) {\n return node;\n }\n\n [...node.children].forEach(d => {\n if (d.attributes?.length) {\n const attributes = Object.values(d.attributes).map(a => {\n const attribute = a;\n const match = /url\\((.*?)\\)/.exec(a.value);\n\n if (match?.[1]) {\n attribute.value = a.value.replace(match[0], `url(${baseURL}${match[1]}__${hash})`);\n }\n\n return attribute;\n });\n\n replaceableAttributes.forEach(r => {\n const attribute = attributes.find(a => a.name === r);\n\n if (attribute && !isDataValue(r, attribute.value)) {\n attribute.value = `${attribute.value}__${hash}`;\n }\n });\n }\n\n if (d.children.length) {\n return updateSVGAttributes(d as SVGSVGElement, options);\n }\n\n return d;\n });\n\n return node;\n}\n","import { isValidElement, useCallback, useEffect, useReducer, useRef } from 'react';\nimport convert from 'react-from-dom';\n\nimport { STATUS } from '../config';\nimport type { FetchError, Props, State } from '../types';\n\nimport type CacheStore from './cache';\nimport { canUseDOM, isSupportedEnvironment, randomString, request } from './helpers';\nimport { useMount, usePrevious } from './hooks';\nimport { getNode } from './utils';\n\nexport default function useInlineSVG(props: Props, cacheStore: CacheStore) {\n const {\n baseURL,\n cacheRequests = true,\n description,\n fetchOptions,\n onError,\n onLoad,\n preProcessor,\n src,\n title,\n uniqueHash,\n uniquifyIDs,\n } = props;\n\n const hash = useRef(uniqueHash ?? randomString(8));\n const fetchOptionsRef = useRef(fetchOptions);\n const onErrorRef = useRef(onError);\n const onLoadRef = useRef(onLoad);\n const preProcessorRef = useRef(preProcessor);\n\n fetchOptionsRef.current = fetchOptions;\n onErrorRef.current = onError;\n onLoadRef.current = onLoad;\n preProcessorRef.current = preProcessor;\n\n const [state, setState] = useReducer(\n (previousState: State, nextState: Partial<State>) => ({\n ...previousState,\n ...nextState,\n }),\n {\n content: '',\n element: null,\n isCached: false,\n status: STATUS.IDLE,\n },\n (initial): State => {\n const cached = cacheRequests && cacheStore.isCached(src);\n\n if (!cached) {\n return initial;\n }\n\n const cachedContent = cacheStore.getContent(src);\n\n try {\n const node = getNode({\n ...props,\n handleError: () => {},\n hash: hash.current,\n content: cachedContent,\n });\n\n if (!node) {\n return { ...initial, content: cachedContent, isCached: true, status: STATUS.LOADED };\n }\n\n const convertedElement = convert(node as Node);\n\n if (convertedElement && isValidElement(convertedElement)) {\n return {\n content: cachedContent,\n element: convertedElement,\n isCached: true,\n status: STATUS.READY,\n };\n }\n } catch {\n // Fall through to effect-driven flow\n }\n\n return {\n ...initial,\n content: cachedContent,\n isCached: true,\n status: STATUS.LOADED,\n };\n },\n );\n const { content, element, isCached, status } = state;\n const previousProps = usePrevious(props);\n const previousState = usePrevious(state);\n const isActive = useRef(false);\n const isInitialized = useRef(false);\n\n const handleError = useCallback((error: Error | FetchError) => {\n if (isActive.current) {\n setState({\n status:\n error.message === 'Browser does not support SVG' ? STATUS.UNSUPPORTED : STATUS.FAILED,\n });\n\n onErrorRef.current?.(error);\n }\n }, []);\n\n const getElement = useCallback(() => {\n try {\n const node = getNode({\n baseURL,\n content,\n description,\n handleError,\n hash: hash.current,\n preProcessor: preProcessorRef.current,\n src,\n title,\n uniquifyIDs,\n }) as Node;\n const convertedElement = convert(node);\n\n if (!convertedElement || !isValidElement(convertedElement)) {\n throw new Error('Could not convert the src to a React element');\n }\n\n setState({\n element: convertedElement,\n status: STATUS.READY,\n });\n } catch (error: any) {\n handleError(error);\n }\n }, [baseURL, content, description, handleError, src, title, uniquifyIDs]);\n\n // Mount\n useMount(() => {\n isActive.current = true;\n\n if (!canUseDOM() || isInitialized.current) {\n return undefined;\n }\n\n try {\n if (status === STATUS.READY) {\n onLoadRef.current?.(src, isCached);\n } else if (status === STATUS.IDLE) {\n if (!isSupportedEnvironment()) {\n throw new Error('Browser does not support SVG');\n }\n\n if (!src) {\n throw new Error('Missing src');\n }\n\n setState({ content: '', element: null, isCached: false, status: STATUS.LOADING });\n }\n } catch (error: any) {\n handleError(error);\n }\n\n isInitialized.current = true;\n\n return () => {\n isActive.current = false;\n };\n });\n\n // Src changes\n useEffect(() => {\n if (!canUseDOM() || !previousProps) {\n return;\n }\n\n if (previousProps.src !== src) {\n if (!src) {\n handleError(new Error('Missing src'));\n\n return;\n }\n\n setState({ content: '', element: null, isCached: false, status: STATUS.LOADING });\n }\n }, [handleError, previousProps, src]);\n\n // Fetch content when status is LOADING\n useEffect(() => {\n if (status !== STATUS.LOADING) {\n return undefined;\n }\n\n const controller = new AbortController();\n let active = true;\n\n (async () => {\n try {\n const dataURI = /^data:image\\/svg[^,]*?(;base64)?,(.*)/.exec(src);\n let inlineSrc;\n\n if (dataURI) {\n inlineSrc = dataURI[1] ? window.atob(dataURI[2]) : decodeURIComponent(dataURI[2]);\n } else if (src.includes('<svg')) {\n inlineSrc = src;\n }\n\n if (inlineSrc) {\n if (active) {\n setState({ content: inlineSrc, isCached: false, status: STATUS.LOADED });\n }\n\n return;\n }\n\n const fetchParameters = { ...fetchOptionsRef.current, signal: controller.signal };\n let loadedContent: string;\n let hasCache = false;\n\n if (cacheRequests) {\n hasCache = cacheStore.isCached(src);\n loadedContent = await cacheStore.get(src, fetchParameters);\n } else {\n loadedContent = await request(src, fetchParameters);\n }\n\n if (active) {\n setState({ content: loadedContent, isCached: hasCache, status: STATUS.LOADED });\n }\n } catch (error: any) {\n if (active && error.name !== 'AbortError') {\n handleError(error);\n }\n }\n })();\n\n return () => {\n active = false;\n controller.abort();\n };\n }, [cacheRequests, cacheStore, handleError, src, status]);\n\n // LOADED -> READY\n useEffect(() => {\n if (status === STATUS.LOADED && content) {\n getElement();\n }\n }, [content, getElement, status]);\n\n // Title and description changes\n useEffect(() => {\n if (!canUseDOM() || !previousProps || previousProps.src !== src) {\n return;\n }\n\n if (previousProps.title !== title || previousProps.description !== description) {\n getElement();\n }\n }, [description, getElement, previousProps, src, title]);\n\n // READY -> onLoad\n useEffect(() => {\n if (!previousState) {\n return;\n }\n\n if (status === STATUS.READY && previousState.status !== STATUS.READY) {\n onLoadRef.current?.(src, isCached);\n }\n }, [isCached, previousState, src, status]);\n\n return { element, status };\n}\n","import { cloneElement, ReactElement, ReactNode, SVGProps } from 'react';\n\nimport { STATUS } from './config';\nimport CacheStore from './modules/cache';\nimport { canUseDOM, omit } from './modules/helpers';\nimport useInlineSVG from './modules/useInlineSVG';\nimport { useCacheStore } from './provider';\nimport { Props, Status } from './types';\n\nexport const cacheStore = new CacheStore();\n\nexport default function InlineSVG(props: Props): ReactNode {\n const { children = null, innerRef, loader = null } = props;\n const contextStore = useCacheStore();\n const store = contextStore ?? cacheStore;\n\n const { element, status } = useInlineSVG(props, store);\n\n if (!canUseDOM()) {\n return loader;\n }\n\n if (element) {\n return cloneElement(element as ReactElement<SVGProps<SVGElement>>, {\n ref: innerRef,\n ...omit(\n props,\n 'baseURL',\n 'cacheRequests',\n 'children',\n 'description',\n 'fetchOptions',\n 'innerRef',\n 'loader',\n 'onError',\n 'onLoad',\n 'preProcessor',\n 'src',\n 'title',\n 'uniqueHash',\n 'uniquifyIDs',\n ),\n });\n }\n\n if (([STATUS.UNSUPPORTED, STATUS.FAILED] as Status[]).includes(status)) {\n return children;\n }\n\n return loader;\n}\n\nexport * from './types';\n"],"mappings":"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"}