# Summary
Without the `maskUnits` attribute, masks may not render correctly, as
seen in issue #2449. This pull request adds support for `maskUnits` and
ensures proper cropping within the mask boundaries.
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| MacOS | ✅ |
| Android | ✅ |
# Summary
Implement proper handling for filter region according to the specs:
*
[FilterEffectsRegion](https://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion)
*
[FilterPrimitiveSubRegion](https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveSubRegion)
enabling user to specify
* `filterUnits`
* `primitiveUnits`
* `x`
* `y`
* `width`
* `height`
on `Filter` element and the last four on filter primitives.
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| MacOS | ✅ |
| Android | ✅ |
| Web | ✅ |
# Summary
Since `RNSVGPlatformView` on macOS old arch is just `RCTUIView`, we need
to add `updateReactTransformInternal` to `RNSVGSvgView`.
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| MacOS | ✅ |
# Summary
Explain the **motivation** for making this change: here are some points
to help you:
* What issues does the pull request solve? Please tag them so that they
will get automatically closed once the PR is merged
* What is the feature? (if applicable)
* How did you implement the solution?
* What areas of the library does it impact?
## Test Plan
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes UI.
### What's required for testing (prerequisites)?
### What are the steps to reproduce (after prerequisites)?
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| MacOS | ✅❌ |
| Android | ✅ |
| Web | ✅❌ |
# Summary
Closes#2233
in iOS and old Arch, a callback on `toDataURL` method will only be
called the second time of asking.
Based on that
[PR](https://github.com/software-mansion/react-native-svg/pull/2234)
format `RNSVGSvgViewModule` file.
## Test Plan
We can easily test that fix by running the `Test2233`, we have an
example of the problem.
### What are the steps to reproduce (after prerequisites)?
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
# Summary
When there is no content of CGImage, ref will return `nil` instead of
empty image and crash, we should ignore that results and continue
applying filters.
## Example
```tsx
<svg width="200" height="200">
<filter id="offset">
<feOffset dx="1000" dy="1000" />
</filter>
<rect
x="0"
y="0"
width="100"
height="100"
fill="green"
filter="url(#offset)" />
</svg>
```
# Summary
Continuation of #2316
Introducing new filter `FeOffset`.
## Test Plan
Example app -> Filters -> FeOffset
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
## Checklist
- [x] I have tested this on a device and a simulator
- [x] I added documentation in `README.md`
- [x] I updated the typed files (typescript)
# Summary
Continuation of #2316
Introducing new filter `FeGaussianBlur`.
### Implementation notes
On Android there is no easy way to fully implement Gaussian blur, as
there is no native api for this. While a basic implementation is
possible with `RenderScript`, it does not allow for blur in one axis and
greater than `25`
## Test Plan
Example app -> Filters -> FeGaussianBlur
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
# Summary
Applying multiple `FeColorFilter` instances can cause unexpected
behavior on iOS, likely due to a bug in `CoreImage` where the `CIImage`
recipe isn't applied step by step as it should be. This fix ensures that
the filter result is rendered after each application by converting the
image to `CGImage` and then back to `CIImage`.
## Test Plan
With this simple test, we can prove that these changes are working
```tsx
<Svg height="200" width="200">
<Filter id="filter">
<FeColorMatrix type="matrix" values="78 -70 -7 0 0 -21 29 -7 0 0 -21 -70 0 0 0 0 0 0 1 0"/>
<FeColorMatrix type="matrix" values="0.2126, 0.7152, 0.0722, 0, 0, 0.2126, 0.7152, 0.0722, 0, 0, 0.2126, 0.7152, 0, 0, 0, 0, 0, 0, 1, 0"/>
</Filter>
<Rect width="200" height="200" fill="red" filter="url(#filter)"/>
</Svg>
```
| Web | iOS before changes | iOS after changes |
| --- | --- | --- |
| <img width="242" alt="image"
src="https://github.com/user-attachments/assets/dc683341-b3ca-4fab-86d8-cf72b15c13d4">
| <img width="237" alt="image"
src="https://github.com/user-attachments/assets/d4a1af5d-ae67-4ed9-9dbd-d03540b2c63c">
| <img width="249" alt="image"
src="https://github.com/user-attachments/assets/83e856a6-5bcc-4534-ad7b-a1f188434e1c">
|
# Summary
Closes#2356
Currently, when `filter` prop is defined, but there is no equivalent
`<Filter>` component, on iOS nothing is rendered, with this fix this
prop would be ignored, and the component should render as expected.
## Test Plan
```tsx
<Svg width="400" height="400" viewBox="0 0 124 124" fill="none">
<Rect width="124" height="124" rx="24" fill="red" filter="url(#nonExistingFilterId)"/>
</Svg>
```
## Affected platforms
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
# Summary
Introducing the long-awaited **Filters** in `react-native-svg` 🎉
### Motivation
This PR is the beginning of bringing support of SVG Filters into
`react-native-svg`.
* **related issues**: This PR series will address the following issues:
#150, #176, #635, #883, #994, #996, #1216
* **feature overview**: This PR is a boilerplate for Filters
* introducing `Filter` component and `FeColorMatrix` as a start.
* It also introduces a new subdirectory called
`react-native-svg/filter-image` with a `FilterImage` component.
# Usage
## Filter and Fe...
Filters are compatible with the web familiar standard, so most things
should be compatible out-of-the-box and changes will be limited to using
a capital letter as it's component.
### Example
```tsx
import React from 'react';
import { FeColorMatrix, Filter, Rect, Svg } from 'react-native-svg';
export default () => {
return (
<Svg height="300" width="300">
<Filter id="myFilter">
<FeColorMatrix type="saturate" values="0.2" />
</Filter>
<Rect
x="0"
y="0"
width="300"
height="300"
fill="red"
filter="url(#myFilter)"
/>
</Svg>
);
};
```

## Filter Image
`FilterImage` is a new component that is not strictly related to SVG.
Its behavior should be the same as a regular `Image` component from
React Native with one exception - the additional prop `filters`, which
accepts an array of filters to apply to the image.
### Example
```tsx
import React from 'react';
import { StyleSheet } from 'react-native';
import { FilterImage } from 'react-native-svg/filter-image';
const myImage = require('./myImage.jpg');
export default () => {
return (
<FilterImage
style={styles.image}
source={myImage}
filters={[
{ name: 'colorMatrix', type: 'saturate', values: 0.2 },
{
name: 'colorMatrix',
type: 'matrix',
values: [
0.2, 0.2, 0.2, 0, 0, 0.2, 0.2, 0.2, 0, 0, 0.2, 0.2, 0.2, 0, 0, 0, 0,
0, 1, 0,
],
},
]}
/>
);
};
const styles = StyleSheet.create({
image: {
width: 200,
height: 200,
},
});
```

## Test Plan
**Example App**: Updated the example app with various filter effects,
showcasing real-world usage.
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
## Checklist
- [x] I have tested this on a device and a simulator
- [x] I added documentation in `README.md` and `USAGE.md`
- [x] I updated the typed files (typescript)
<!-- Thanks for submitting a pull request! We appreciate you spending
the time to work on these changes. Please follow the template so that
the reviewers can easily understand what the code changes affect -->
# Summary
This is a sibling PR to:
https://github.com/software-mansion/react-native-svg/pull/2318 which
fixed missing mount/unmount methods to correctly display SVG.
This PR overrides the same `mountChildComponentView` and
`unmountChildComponentView` methods but for `RNSVGSvgView` component.
This will make the components and their behaviour aligned and more
predictable.
I included the test that specifically tests for attaching another
external svg into and already existing SVG, should catch any edge cases
with invalidation/redrawing.
## Test Plan
`TestExample` app -> `TestSvgUriUpdating` example.
https://github.com/software-mansion/react-native-svg/assets/3929868/49499914-7037-4ab0-a9a9-1e139d460117
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
## Checklist
<!-- Check completed item, when applicable, via: [X] -->
- [x] I have tested this on a device and a simulator
- [ ] I added documentation in `README.md`
- [ ] I updated the typed files (typescript)
- [ ] I added a test for the API in the `__tests__` folder
# Summary
Change data structure returned from the Image onLoad event.
Add fix in new arch for returned sizes.
## Test Plan
Manually test in both architectures and platforms.
### What's required for testing (prerequisites)?
### What are the steps to reproduce (after prerequisites)?
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
---------
Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
# Summary
On iOS with the new architecture, when mounting or unmounting a
component, changes were not visible because `invalidate` wasn't called.
These changes override `mountChildComponentView` and
`unmountChildComponentView` to ensure that invalidate is called when
`RNSVGNode` is mounted or unmounted.
## Test Plan
`TestExample` app -> `MountUnmount` example
```tsx
import React from 'react';
import {Button, Text, View} from 'react-native';
import {Rect, Svg} from 'react-native-svg';
export default () => {
const [show, setShow] = React.useState(true);
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Blue rect is mounted: {show ? 'true' : 'false'}</Text>
<Svg height="300" width="300">
{show ? (
<Rect x="100" y="100" width="100" height="100" fill="blue" />
) : null}
</Svg>
<Button title="Toggle" onPress={() => setShow(!show)} />
</View>
);
};
```
https://github.com/software-mansion/react-native-svg/assets/39670088/0eaf9a61-b47b-4f89-a7c7-a67375e2e63ehttps://github.com/software-mansion/react-native-svg/assets/39670088/709feedf-63c1-47d7-b799-f3899278fe77
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
# Summary
Closes#1442
We want to add new props to the Image Component.
## Test Plan
Added the Test component.
Manually test that in Android and IOS platforms on new and old
Architectures.
### What are the steps to reproduce (after prerequisites)?
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
# Summary
This PR resolves an issue raised in #1451.
Currently, when a mask is used, we render the element as a bitmap (or
platform equivalent), but the bitmap's size does not update accordingly
with transformations. With these changes, the problem is addressed as
follows:
* **Android**: We utilize the original canvas layers to render the mask
and element with the appropriate blending mode.
* **iOS**: We create an offscreen context with the size multiplied by
the screen scale and apply the original UIGraphics CTM (current
transformation matrix) to the offscreen context. This ensures that the
same transformations are applied as on the original context.
Additionally, there is a significant performance improvement on Android
as we are not creating three new Bitmaps and three new Canvases.
## Test Plan
There are many ways for testing these changes, but the required ones
are:
* `TestsExample` app -> `Test1451.tsx`
* `Example` app -> Mask section
* `FabricExample` app -> Mask section
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| Android | ✅ |
| iOS | ✅ |
## Preview
<img width="337" alt="image"
src="https://github.com/software-mansion/react-native-svg/assets/39670088/93dbae85-edbd-452a-84b0-9a50107b1361">
<img width="337" alt="image"
src="https://github.com/software-mansion/react-native-svg/assets/39670088/07838dff-cb2d-4072-a2fc-5c16a76f6c33">
# Summary
This PR removes the flag to include custom line breaks on `toDataUrl`
method. Some software could not read base64 with additional line break
characters, so it could lead to corrupting the image (like in
react-native-share). Fixes#1986.
## Test Plan
`TestsExample` -> `Test1986`
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
# Summary
* Fixed crash on Android when `<RadialGradient r={0}>`.
* Fixed render issue on Android and iOS when radius is zero. According
to [MDN
Docs](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/r#radialgradient)
> A value of lower or equal to zero will cause the area to be painted as
a single color using the color and opacity of the last gradient
`<stop>`.
## Test Plan
Test is available in `TestsExample` as `Test2170`
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
Fixes#2170
# Summary
PR bringing proper support for react-native-reanimated in the library by using dynamics instead of strings for props that can be either string or number.
React Native no longer allows implicit copying of Props, since they're large data-structures and copies are often accidental (bbc517c8c8). This updates react-native-svg to be compatible with this change, and will provide a small perf win.
Apple made a breaking change in Xcode 15 / macOS Sonoma which breaks usages of drawRect:. You can no longer trust that the OS will provide you a dirtyRect will be within the bounds of your view. Specifically (from the appkit release notes):
Filling the dirty rect of a view inside of -drawRect. A fairly common pattern is to simply rect fill the dirty rect passed into an override of NSView.draw(). The dirty rect can now extend outside of your view’s bounds. This pattern can be adjusted by filling the bounds instead of the dirty rect, or by setting clipsToBounds = true.
This led to an unfortunate bug where any SVG drawn took up the full width/height of your window. Let's follow Apple's advice and draw using [self bounds] instead of dirtyRect.
PR restoring macos CI job and restoring usage of UIGraphicsBeginImageContextWithOptions on macos since there is no implementation for UIGraphicsImageRendererFormat there yet.
Since UIGraphicsBeginImageContextWithOptions will be depracated in iOS 17 (developer.apple.com/documentation/uikit/1623912-uigraphicsbeginimagecontextwitho), I changed the implementation to not use it and use UIGraphicsImageRenderer instead.
Also added Mask examples to be able to test it.
PR adding the proper handling of strokeDasharray prop for when used with Animated and Reanimated. Code based on #1464 by @bardliu, but with the newest state of the repository.
PR removing methods that seem unnecessary for the accessibility props since they are provided by superclasses. It was necessary to update fabric updateProps method though, since we don't call super there. Also added proper type definitions and removed unnecessary casts.
PR adding accessibility and testId props and virtual nodes to support e2e tests tools and provide general accessibility support.
Co-authored-by: yonatan.altaraz <yonatan.altaraz@khealth.ai>
Co-authored-by: galkahana <gal.kahana@hotmail.com>
PR changing the custom transform prop parsing algorithm to the one from RN core (facebook/react-native@2eccd59/React/Views/RCTConvert%2BTransform.m), which the current one was most probably taken from.
PR restoring backwards compatibility due to braking changes in method signatures of getViewManagerNames and setHitSlop, lambda expression being available for RN > 0.64(?). Since viewRegistry_DEPRECATED is available from RN 0.65, and its addUIBlock method is available from RN 0.69, and both those things are only really needed on new architecture, we use them only there and stick to the old impl for old arch.
Changed `requireNativeComponent` to `codegenNativeComponent` so that upcoming changes (Static View Configs, Bridgeless Mode and idk what more) in `react-native` are available in the library. Also, types and native components are now taken directly from `fabric` folder to make sure the values passed to the native components are the ones defined in props. It should work on all supported versions since `codegenNativeComponent` function exists from RN v. 0.61.0. Suggested by @RSNara and @cipolleschi
Reason for [`5394bbb` (#1847)](5394bbbced):
- on `Paper`, `Animated` uses `setNativeProps` method when we set `useNativeDriver` to `false`, and does not rerender the component. Therefore, new transform lands only in `SvgView` and is parsed in `RCTViewManager.m` .
- on `Fabric`, the same code makes the components rerender. Due to this, information about new transform is passed to the `SvgView` child: `G` , making it apply translations from the transform in its `updateProps` method.
- other than `Animated` use-case, on both archs, if we just passed `transform` prop to `Svg` component, it would end up in double transformations now as well. All of those changes are due to https://github.com/software-mansion/react-native-svg/pull/1895, which added proper parsing of RN style `transform` prop (array of transformations objects) therefore making `G` properly handle `transform` prop passed from `Svg`.
Reason for [`19bcb24` (#1847)](19bcb2464b): Same as https://github.com/software-mansion/react-native-screens/pull/1624