diff --git a/USAGE.md b/USAGE.md
index 6e9b21557..250a1f7ec 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -92,14 +92,15 @@ If remote SVG file contains CSS in `
+
+ CSS Styled
+
+`);
+
+const calculateWidth = (svgProps: SvgProps, desiredHeight: number) => {
+ let originalHeight = svgProps.height;
+ let originalWidth = svgProps.width;
+ if (originalWidth && originalHeight) {
+ return (Number(originalWidth) / Number(originalHeight)) * desiredHeight;
+ }
+};
+
+const ExampleWithSvgUri = () => {
+ const [width, setWidth] = useState(0);
+ const height = 12;
+
+ const handleLoad = (svgProps: SvgProps) => {
+ const calculatedWidth = calculateWidth(svgProps, height);
+ if (calculatedWidth) {
+ setWidth(calculatedWidth);
+ }
+ };
+ return (
+
+ SvgUri component
+
+ Original Size ✅
+
+
+
+ Set different height ❌
+
+
+
+
+ Preserve Aspect Ratio Meet ❌
+
+
+
+
+ Preserve Aspect Ratio Slice ❌
+
+
+
+
+ Preserve Aspect Ratio None ❌
+
+
+
+
+ Auto calculate width ✅
+
+
+
+ );
+};
+
+const ExampleWithSvgCssUri = () => {
+ const [width, setWidth] = useState(0);
+ const height = 25;
+ const handleLoad = (svgProps: SvgProps) => {
+ const calculatedWidth = calculateWidth(svgProps, height);
+ if (calculatedWidth) {
+ setWidth(calculatedWidth);
+ }
+ };
+
+ return (
+
+ SvgCssUri component
+
+ Original Size ✅
+
+
+
+ Set different height ❌
+
+
+
+
+ Preserve Aspect Ratio Meet ❌
+
+
+
+
+ Preserve Aspect Ratio Slice ❌
+
+
+
+
+ Preserve Aspect Ratio None ❌
+
+
+
+
+ Auto calculate width ✅
+
+
+
+ );
+};
+
+export default () => {
+ return (
+
+
+
+
+ );
+};
diff --git a/apps/common/test/index.tsx b/apps/common/test/index.tsx
index 2c1954cc9..1781c86d5 100644
--- a/apps/common/test/index.tsx
+++ b/apps/common/test/index.tsx
@@ -35,6 +35,7 @@ import Test2417 from './Test2417';
import Test2455 from './Test2455';
import Test2471 from './Test2471';
import Test2520 from './Test2520';
+import Test2540 from './SvgUriOnLoad';
import Test2670 from './Test2670';
export default function App() {
diff --git a/src/css/css.tsx b/src/css/css.tsx
index fba0e416c..83fafa0d4 100644
--- a/src/css/css.tsx
+++ b/src/css/css.tsx
@@ -766,17 +766,29 @@ export const inlineStyles: Middleware = function inlineStyles(
};
export function SvgCss(props: XmlProps) {
- const { xml, override, fallback, onError = err } = props;
- try {
- const ast = useMemo(
- () => (xml !== null ? parse(xml, inlineStyles) : null),
- [xml]
- );
- return ;
- } catch (error) {
- onError(error);
+ const { xml, override, fallback, onError = err, onLoad } = props;
+
+ const [ast, error] = useMemo<[JsxAST | null, unknown]>(() => {
+ try {
+ const parsed = xml !== null ? parse(xml, inlineStyles) : null;
+ return [parsed, null];
+ } catch (exc) {
+ return [null, exc];
+ }
+ }, [xml]);
+
+ useEffect(() => {
+ if (!error && ast?.props) {
+ onLoad?.(ast.props);
+ } else if (error) {
+ onError(error as Error);
+ }
+ }, [ast, error, onLoad, onError]);
+
+ if (error) {
return fallback ?? null;
}
+ return ;
}
export function SvgCssUri(props: UriProps) {
@@ -788,7 +800,6 @@ export function SvgCssUri(props: UriProps) {
? fetchText(uri)
.then((data) => {
setXml(data);
- onLoad?.();
})
.catch((e) => {
onError(e);
@@ -799,7 +810,9 @@ export function SvgCssUri(props: UriProps) {
if (isError) {
return fallback ?? null;
}
- return ;
+ return (
+
+ );
}
// Extending Component is required for Animated support.
diff --git a/src/xml.tsx b/src/xml.tsx
index 073888c13..d46dad4b7 100644
--- a/src/xml.tsx
+++ b/src/xml.tsx
@@ -35,7 +35,7 @@ export interface JsxAST extends AST {
export type AdditionalProps = {
onError?: (error: Error) => void;
override?: object;
- onLoad?: () => void;
+ onLoad?: (svgProps: SvgProps) => void;
fallback?: JSX.Element;
};
@@ -65,18 +65,29 @@ export function SvgAst({ ast, override }: AstProps) {
const err = console.error.bind(console);
export function SvgXml(props: XmlProps) {
- const { onError = err, xml, override, fallback } = props;
+ const { onError = err, xml, override, fallback, onLoad } = props;
- try {
- const ast = useMemo(
- () => (xml !== null ? parse(xml) : null),
- [xml]
- );
- return ;
- } catch (error) {
- onError(error);
+ const [ast, error] = useMemo<[JsxAST | null, unknown]>(() => {
+ try {
+ const parsed = xml !== null ? parse(xml) : null;
+ return [parsed, null];
+ } catch (exc) {
+ return [null, exc];
+ }
+ }, [xml]);
+
+ useEffect(() => {
+ if (!error && ast?.props) {
+ onLoad?.(ast.props);
+ } else if (error) {
+ onError(error as Error);
+ }
+ }, [ast, error, onError, onLoad]);
+
+ if (error) {
return fallback ?? null;
}
+ return ;
}
export function SvgUri(props: UriProps) {
@@ -89,7 +100,6 @@ export function SvgUri(props: UriProps) {
.then((data) => {
setXml(data);
isError && setIsError(false);
- onLoad?.();
})
.catch((e) => {
onError(e);
@@ -101,7 +111,9 @@ export function SvgUri(props: UriProps) {
if (isError) {
return fallback ?? null;
}
- return ;
+ return (
+
+ );
}
// Extending Component is required for Animated support.