235 Commits

Author SHA1 Message Date
Jakub Grzywacz
e79a6c198e fix: FeDropShadow results and import react (#2625)
# Summary

* Add results alias in `FeDropShadow`
* Import React in every tsx filter file to satisfy typescript/eslint
* Replace `<>` with `<React.Fragment>` in `FeDropShadow`
2025-01-24 16:34:33 +01:00
Jakub Grzywacz
d888de904e refactor: update eslint disable comments after config changes (#2602)
# Summary

* update eslint-disable comments after config changes
* run bundle exec pod install in tests-example
2025-01-07 15:58:28 +01:00
Jakub Grzywacz
c7743f1a41 chore: bump react-native and other packages (#2598)
# Summary

* Bump react-native and other packages (babel, eslint, prettier,
`@types`) to resolve errors in
https://github.com/software-mansion/react-native-svg/pull/2586
* Cleanup unused/unnecessary devDependencies 

## Test Plan

Lib should work exactly the same as before.
2025-01-07 14:28:14 +01:00
Jakub Grzywacz
b4fa586ab8 feat: allow single quote ID wrapper (#2580)
# Summary  

The SVG specification does not strictly standardize linking, and most
browsers permit the use of `'` as a wrapper in `url` links. As a result,
I've added support for URLs such as `url('#id')`.

## Test Plan

`url(#id)` and `url('#id')` should do the exact same thing.


Closes #1768
2024-12-17 10:58:14 +01:00
Jakub Grzywacz
d3d61a5fc1 feat: custom shadow nodes (#2568)
# Summary

Implement custom shadow nodes for nearly all `Svg` components. While
it's a foundation for numerous upcoming changes, it currently addresses
and resolves #2544.

## Test Plan

There shouldn't be any noticeable changes, and everything should
function as before, except that `onLayout` will now be triggered only
once and with the correct dimensions.

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| MacOS   |          |
| Android |          |

---------

Co-authored-by: Jakub Piasecki <jakubpiasecki67@gmail.com>
2024-12-12 11:48:46 +01:00
Jakub Grzywacz
488613562b fix: do not parse id as number in any case (#2563)
# Summary

When using `SvgXml` or `SvgCss`, an `id` attribute gets converted into a
`number` instead of a `string`, which causes a crash because the native
side expects a string value.

```js
import {SvgXml} from 'react-native-svg';
import {SvgCss} from 'react-native-svg/css';
```

## Test Plan

This example should not crash:
```jsx
import {SvgCss} from 'react-native-svg/css';

const svgXml = `
<svg width="100" height="100" viewBox="0 0 100 100">
  <filter x="0%" y="0%" width="100" height="100" id="0123456789">
    <feFlood flood-color="red" />
  </filter>
  <circle cx="50" cy="50" r="50" filter="url(#0123456789)" />
</svg>
`;

function Example() {
  return <SvgCss xml={svgXml} />;
}
```
2024-12-05 11:15:32 +01:00
Jakub Grzywacz
1c9a553db0 fix: FeComposite add default value for k1...4 (#2557)
# Summary

Fixes #2552 by adding default value for k1, k2, k3, k4 according to the
spec: https://www.w3.org/TR/SVG11/filters.html#feCompositeElement

> If the attribute is not specified, the effect is as if a value of 0
were specified.

## Test Plan

[Repro from issue
2552](https://github.com/TomCorvus/RNSVG/blob/main/App.js)

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| MacOS   |          |
2024-12-02 13:32:51 +01:00
Andrew Coates
d02c997352 fix: react-native-windows implementation for new architecture (#2527)
# Summary
There are two main things going on with the PR. Both involve a reworking
of the new arch implementation of rn-svg for windows.
The current implementation attempts to implement a svg renderer from
scratch. There are numerous edge cases that it wasn't handling
correctly, and the performance had some serious issues. This
implementation switches to use the svg rendering path built into
Direct2D. This brings significant performance improvements.

The 2nd issue is there have been various breaking changes in
react-native-windows for how new arch native components are implemented.
This brings the rn-svg implementation in line with those latest changes.

## Test Plan

Primary testing right now is loading up the example app in the repo.
New arch on react-native-windows is still in somewhat early days - so
there are not really current users of this code. I am integrating this
code into Microsoft Office, where I have tested some scenarios. But we
will get expanded testing as we roll out the new arch. I expect there to
be some follow-ups as we expand our usage. The version of rn-svg before
this PR doesn't build with the latest new arch react-native-windows
versions. - So its hard to get worse than that.

### What's required for testing (prerequisites)?

### What are the steps to reproduce (after prerequisites)?

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |    N/A  |
| MacOS   |    N/A      |
| Android |    N/A      |
| Web     |          |

## Checklist

- [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
2024-11-15 12:17:12 +01:00
Jakub Grzywacz
d0530e4b9f fix: add default FeBlend mode (#2530)
# Summary

Fixes #2529
`FeBlend` should have default blend mode set to `normal`

## Test Plan

Test case specified in #2529

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Android |          |
2024-11-12 14:37:46 +01:00
Jakub Grzywacz
29d4c7c37b fix: update warnUnimplementedFilter list (#2525)
# Summary

Closes #2523
Since `FeBlend`, `FeComposite`, `FeDropShadow` and `FeFlood` is already
supported (see: #2362) we should remove it from
`warnUnimplementedFilter` list
2024-11-04 13:12:37 +01:00
Jakub Grzywacz
2a58016ec1 feat: get currentColor from caller instead of parent (#2521)
# Summary

Fixes #2520
When an element uses `currentColor`, it should look for color in its
caller, not in its parent.
Example: 
```svg
<Svg width="100" height="100" viewBox="0 0 100 100" color="red">
  <Defs color="blue">
    <G color="green">
      <Rect id="a" x="0" y="0" width="50" height="50" fill="currentColor"/>
    </G>
  </Defs>
  <G color="pink">
    <Use href="#a"/>												<!-- #1 -->
  </G>
  <Use href="#a" transform="translate(25 25)"/>						<!-- #2 -->
  <G color="green">
    <Use href="#a" transform="translate(50 50)"/>					<!-- #3 -->
  </G>
</Svg>
```

* `#1` should be **pink**
* `#2` should be **red**
* `#3` should be **green**


![image](https://github.com/user-attachments/assets/b7ba2ec6-ea05-4bcb-9f40-0cf024e5c749)

## Test Plan

Example app -> test -> Test2520

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| MacOS   |          |
| Android |          |
2024-10-31 16:00:36 +01:00
Jakub Grzywacz
e6a27f8a3d feat: FeDropShadow (#2514)
# Summary

Continuation of #2362 introducing highly requested  `FeDropShadow` 
filter. This addition is straightforward since it's essentially a
shorthand (as specified in the spec) for filters that are already
implemented: https://www.w3.org/TR/filter-effects-1/#feDropShadowElement

<img width="532" alt="image"
src="https://github.com/user-attachments/assets/b221ee4c-d8b0-469b-acb0-71224fb2b1e0">

## Test Plan

Example app -> Filters -> FeDropShadow

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| macOS   |          |
| Android |          |
| Web     |          |
2024-10-28 14:44:36 +01:00
Jakub Grzywacz
4637dee1e4 feat: FeComposite filter (#2433)
# Summary

<img width="324" alt="image"
src="https://github.com/user-attachments/assets/0a9b4a56-d093-49f7-aacd-c198ee00f256">

## Test Plan

Examples app -> Filters -> FeComposite

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| macOS   |    *      |
| Android |          |
| Web     |          |

_*_ macOS isn't working as:
* `CGBitmapContextCreateImage` always returns null
* FeFlood isn't aligned properly (will be fixed in the following PR)
2024-10-25 11:18:07 +02:00
Evan Bacon
69d25622b8 feat: add basic React Server Component support (#2287)
# Summary

Add basic support for React Server Components support. This package
could surely be improved (at least on web) but there are a lot of class
components (unsupported in RSC) which need to be rewritten to function
components in order to compile down further. For now, I'm opting the
entire package.

Related PRs for more context:

- https://github.com/necolas/react-native-web/pull/2678
- https://github.com/th3rdwave/react-native-safe-area-context/pull/502
- I've added more support for mixing export types, but it isn't perfect
https://github.com/expo/expo/pull/29426

## Test Plan

- It's kinda hard to test this E2E. I wrote a small jest runner in
jest-expo which executes in RSC mode, but it requires React 19 to work.
Here's where I tested this patch https://github.com/expo/expo/pull/29404
2024-10-18 10:53:43 +02:00
Jakub Grzywacz
096fdc22a5 feat: FeBlend (#2489)
# Summary

Continuation of #2362 implementing `FeBlend` filter
https://www.w3.org/TR/SVG11/filters.html#feBlendElement

## Test Plan

Example app → Filters → `FeBlend`

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| macOS   |     _*_      |
| Android |          |
| Web     |          |
2024-10-16 11:45:44 +02:00
Jakub Grzywacz
ba54b15799 feat: FeFlood (#2487)
# Summary

Continuation of #2362 implementing `FeFlood` filter
https://www.w3.org/TR/SVG11/filters.html#feFloodElement

## Test Plan

Example app → Filters → `FeFlood`

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| macOS   |     _*_      |
| Android |          |
| Web     |          |

_* `canvasWidth/canvasHeight` is incorrect on macOS, so there might be
some problems_
2024-10-15 09:35:13 +02:00
Jakub Grzywacz
8fed77476b feat: properly implement filter region unit USER_SPACE_ON_USE (#2486)
# Summary

After deep dive into the specification, I found out that the default
filter subregion is not equal to `0% 0% 100% 100%`, rather the size of
the parent filter region.

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| MacOS   |          |
| Android |          |
2024-10-14 15:35:16 +02:00
Jakub Grzywacz
690cddd2f7 feat: improve animating colors (#2471)
# Summary

Currently on Fabric, you cannot animate color properties like `fill` or
`stroke` using Animated with `useNativeDriver: true` or Reanimated.
That's because we have custom structure that needs to be parsed on `JS`
and looks like:

```ts
type ColorStruct = Readonly<{
  type?: WithDefault<Int32, -1>;
  payload?: ColorValue;
  brushRef?: string;
}>;
```

However, special values like `currentColor` / `context-fill` /
`context-stroke` / `/^url\(#(.+)\)$/` can not be animated anyway.
Instead, we should allow passing `ColorValue` directly and detect on the
native side if its ColorValue or ColorStruct.

## Test Plan

Example app -> TestX

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| MacOS   |          |
| Android |          |

## Checklist

- [x] I have tested this on a device and a simulator
- [ ] I added documentation in `README.md`
2024-10-04 14:20:54 +02:00
Bohdan Artiukhov
b4dc9756df feat: support css variables for SvgCss (#2459)
# Summary
Feature #2380 

We want to add support for CSS variables when passing them to parse the
SVG XML source function.

## Test Plan
Test app -> src -> Test2380

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |         		 |
| MacOS   |            |
| Android |         	|
| Web     |    		    |

---------

Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
2024-10-02 09:23:34 +02:00
Jakub Grzywacz
9d9958264b feat: properly implement currentColor (#2466)
# Summary

Motivated by issue #2455, I decided to implement the `currentColor`
property in line with the specs
(https://www.w3.org/TR/SVG11/color.html#ColorProperty). This involves
adding the `color` property to all renderable nodes.

## Test Plan

Example app -> `Test2455`

<img width="344" alt="image"
src="https://github.com/user-attachments/assets/ccaf5a79-4097-49f8-8948-0158d9d9274c">

```svg
<Svg color="red" width="60" height="60" viewBox="0 0 24 24" fill="none">
  <Path d="M22.7927 11.1242C21.359 18.5187 12.0003 22.7782 12.0003 22.7782C12.0003 22.7782 2.64153 18.5187 1.20661 11.1242C0.326598 6.58719 2.24925 2.02329 7.13701 2.00007C10.7781 1.98296 12.0003 5.65211 12.0003 5.65211C12.0003 5.65211 13.2226 1.98173 16.8624 2.00007C21.7612 2.02329 23.6727 6.58841 22.7927 11.1242Z" fill="currentColor"/>
  <G color="green" fill="purple">
    <G>
      <Rect x="16" y="16" width="8" height="8" fill="currentColor"/>
      <G color="pink">
        <Rect x="0" y="16" width="8" height="8" color="gold" fill="currentColor"/>
        <Circle cx="12" cy="20" r="4" fill="currentColor"/>
      </G>
    </G>
  </G>
</Svg>
```
## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| MacOS   |          |
| Android |          |
2024-09-30 15:50:37 +02:00
Jakub Grzywacz
cc961774e7 fix: do not crash when borderRadius is set on Android (#2415)
# Summary

Fixes #2462
Currently, on Android, when `borderRadius` style is applied to a `Svg`
component an error occurs, stating `Cannot cast Double to Float`

This PR updates the codegen types, changing them from Double to Dynamic,
aligning with the implementation with the ViewProps.

## Test

### Tested on

- [x] react-native@0.76.0-rc.1
- [x] react-native@0.75.1
- [x] react-native@0.74.2
- [x] react-native@0.73.9

### Test case
```jsx
<Svg
  width="60"
  height="60"
  viewBox="0 0 24 24"
  style={{
    borderRadius: 16.2,
    borderTopLeftRadius: 16.2,
    borderBottomRightRadius: 16.2,
    borderStartStartRadius: 16.2,
    borderStartEndRadius: 16.2,
    borderTopRightRadius: 16.2,
    borderBottomLeftRadius: 16.2,
    borderTopStartRadius: 16.2,
    borderTopEndRadius: 16.2,
    borderBottomStartRadius: 16.2,
    borderBottomEndRadius: 16.2,
    borderEndEndRadius: 16.2,
    borderEndStartRadius: 16.2,
  }}>
  <Rect x="0" y="0" width="24" height="24" fill="red" />
</Svg>
```

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Android |          |
2024-09-30 13:02:40 +02:00
Bohdan Artiukhov
14a131c5d8 feat: add support base64 uri type in SvgUri component (#2444)
# Summary
Feature #2142 

Add support for data: image/svg+XML; Base64 format.

## Test Plan
TestExample app -> src -> Test2142

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
| MacOS   |          |
| Android |          |
| Web     |          |

---------

Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
2024-09-24 10:23:14 +02:00
Jakub Grzywacz
85be1d0bac feat: implement filter region (#2441)
# 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     |          |
2024-09-12 12:13:05 +02:00
Jakub Grzywacz
49a99d83b7 fix: do not resolve asset url for every object on web. (#2419)
# Summary

Do not resolve asset url for every object when href is undefined on
WebShape.
2024-08-21 11:12:35 +02:00
hryhoriiK97
09a9d2e86f Support-rgb(R%,G%,B%)-percentage (#2363)
<!-- 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

Closes #1897 

In our project, we encountered a problem with SVGs that include RGB/RGBA
color values in percentage format. To address this, I've decided to
handle it within the react-native-svg library.

Also, I found an open issue for this -
https://github.com/software-mansion/react-native-svg/issues/1897

`percentTo255`: Converts a percentage string (e.g., 50%) to its
corresponding integer value on a scale of 0-255. This is done by parsing
the percentage as a float and multiplying by 2.55 (since 100% equals 255
in RGB).

`parseAlpha`: Converts the alpha component to a float between 0 and 1.
If the alpha is a percentage, it divides by 100; otherwise, it parses it
as a float directly.

`parsePercentageRGBColor`: This function takes a color string as input
and attempts to match it against the RGB_PATTERN or RGBA_PATTERN. If a
match is found, it extracts the red, green, blue, and optional alpha
components. It then converts these components from their percentage form
to the 0-255 range (or normalized float for alpha). The function returns
the color in standard rgb(r, g, b) or rgba(r, g, b, a) format. If the
input color string does not match the patterns, it logs a warning and
returns undefined

`transformColorToPercentage`: This function checks if the given color
value (which can be of type ColorValue from React Native) is a string
matching the percentage-based RGB or RGBA patterns. It removes any
whitespace from the color string and tests it against the patterns. If
the color matches, it converts it using `parsePercentageRGBColor`. If
not, it returns the original color value unchanged.

<img width="240" alt="Screenshot 2024-07-23 at 18 45 25"
src="https://github.com/user-attachments/assets/7ba0dcb7-1daa-4f84-9771-6884de76649a">

## Test Plan

Run test-examples with Test2363

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |         |
| Android |        |

## Checklist

<!-- Check completed item, when applicable, via: [X] -->

- [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)

---------

Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
2024-08-19 10:11:43 +02:00
Jakub Grzywacz
d11d892496 feat: rewrite Svg transform (#2403)
# Summary

Currently, when applying transforms depending on the type (RN style vs
SVG style) transforms behave differently giving wrong results.

Example component
```tsx
<Svg
  height="200"
  viewBox="0 0 200 200"
  width="200"
  // transform={[{scale: 2}]}
  // transform="scale(2)"
  // transform={[{rotate: '45deg'}]}
  // transform="rotate(45)"
  // transform={[{translateX: 100}, {translateY: 100}]}
  // transform="translate(100 100)"
>
  <Mask id="myMask">
    <Rect fill="white" height="100" width="100" x="0" y="0" />
    <Path d="M10,35 A20,20,0,0,1,50,35 A20,20,0,0,1,90,35 Q90,65,50,95 Q10,65,10,35 Z" />
  </Mask>
  <Rect fill="pink" height="200" width="300" x="0" y="0" />
  <Circle cx="50" cy="50" fill="purple" mask="url(#myMask)" r="50" />
  <Rect fill="green" x="50" y="100" width="100" height="100" />
</Svg>
```
| Attribute | Before | After |
| --- | --- | --- |
| `transform={[{scale: 2}]}` | <img width="250" alt="image"
src="https://github.com/user-attachments/assets/c04d7e11-e039-4d1a-b804-e993f3877b6a">
| <img width="250" alt="image"
src="https://github.com/user-attachments/assets/bb717ae4-7c8f-410a-942d-1bd6feab273c">
|
| `transform="scale(2)"` | <img width="250" alt="image"
src="https://github.com/user-attachments/assets/85717613-ede0-44a8-8524-c9af4b37c09d">
| <img width="250" alt="image"
src="https://github.com/user-attachments/assets/f4e23bc6-8cfb-4509-a2f5-45c4f642c197">
|
| `transform={[{rotate: '45deg'}]}` | <img width="250" alt="image"
src="https://github.com/user-attachments/assets/90131401-2c52-4e8a-81ab-6cd449625953">
| <img width="250" alt="image"
src="https://github.com/user-attachments/assets/bab46300-4794-4322-bd95-d6e7e7abd30e">
|
| `transform="rotate(45)"` | <img width="250" alt="image"
src="https://github.com/user-attachments/assets/6d308022-4844-451a-b767-1c3e94e7a295">
| <img width="250" alt="image"
src="https://github.com/user-attachments/assets/553bbad5-9e37-4a52-b4e0-fa0c7b6b558e">
|
| `transform={[{translateX: 100}, {translateY: 100}]}` | <img
width="250" alt="image"
src="https://github.com/user-attachments/assets/91508d75-2b0a-4be6-9280-2ace017d9271">
| <img width="250" alt="image"
src="https://github.com/user-attachments/assets/36fb5cad-1ccf-4c99-8ffd-70ea56ba589f">
|
| `transform="translate(100 100)"` | <img width="250" alt="image"
src="https://github.com/user-attachments/assets/28fa66f2-b2f2-4b86-bb41-47bd507d6018">
| <img width="250" alt="image"
src="https://github.com/user-attachments/assets/36fb5cad-1ccf-4c99-8ffd-70ea56ba589f">
|

## Test Plan

Test example app -> `Test2403`
2024-08-19 09:16:18 +02:00
Jakub Grzywacz
ca1c35caa9 feat: introduce hitSlop prop (#2407)
# 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     |          |
2024-08-19 09:11:07 +02:00
Bohdan Artiukhov
7cf90f2f10 feat: support dataUri for android platform (#2396)
# Summary
Closes #1318 
Add support data URI in the Android platform. It already works on the iOS platform.

| Before1 | Before2 | After |
|--------|--------|--------|
|<img
src="https://github.com/user-attachments/assets/4423ae12-0e67-4ff9-9a15-76fc6b707b26"
width="300" height="600" /> | <img
src="https://github.com/user-attachments/assets/a4412e8e-d965-41e9-95f3-06bffc6ebb76"
width="300" height="600" /> | <img
src="https://github.com/user-attachments/assets/69ba40ac-de52-4edf-9850-ea870270f426"
width="300" height="600" /> |

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Android |          |
2024-08-19 08:55:03 +02:00
Bohdan Artiukhov
4320df270a feat: add support int32 color (#2397)
# Summary
When we use reanimated it's important to use createAnimatedPropAdapter
like in that
[example](https://docs.swmansion.com/react-native-reanimated/docs/core/useAnimatedProps/#adapters-),
but we didn't have support int32Color on the Web platform.

## Test Plan

When we run that
[example](https://snack.expo.dev/@bohdan.artiukhov/animation-example)
that should work on all platforms.

### What are the steps to reproduce (after prerequisites)?

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Web      |    		  	|
2024-08-13 09:43:01 +02:00
Jakub Grzywacz
3ac7914f0e fix: deconstruct filter from styles (#2389)
# Summary

Somehow deconstructing `filter` from `styles` are throwing error, when
filter does not exist. These changes ensure that `filter` is always
there (`[]` if not exists).
2024-08-05 17:08:53 +02:00
Jakub Grzywacz
e88e6403b7 refactor: unify filters types (#2394)
# Summary

Use unified SVG types for `FeColorMatrix` and `FeGaussianBlur`
2024-08-05 08:30:32 +02:00
Jakub Grzywacz
e8ed74fffa feat: placeholders for unimplemented filters and support for Web (#2392) 2024-08-01 15:29:25 +02:00
Jakub Grzywacz
acd29d7468 fix: FilterImage css filter on web (#2387) 2024-08-01 09:29:20 +02:00
Bohdan Artiukhov
15135d695b fix: change way passing onPress prop (#2386) 2024-08-01 09:28:57 +02:00
Jakub Grzywacz
7acbee41f3 fix: FeMerge on paper (#2384)
# Summary

Use empty string (`""`) instead of `undefined` for previous filter
result in `FeMergeNode`
2024-07-31 15:13:50 +02:00
Jakub Grzywacz
b8b022c31e feat: add FeMerge and FeMergeNode filters (#2369)
# Summary

As mentioned in #2362
Introduce new filters:
* `FeMerge`
* `FeMergeNode`

## Example usage

```tsx
<Svg width="200" height="200">
  <Filter id="mergeWithOffset" width="180" height="180">
    <FeOffset dx="50" dy="50" result="test" />
    <FeOffset dx="100" dy="100" in="SourceGraphic" />
    <FeMerge>
      <FeMergeNode in="SourceGraphic" />
      <FeMergeNode in="test" />
      <FeMergeNode />
    </FeMerge>
  </Filter>
  <Rect
    x="0"
    y="0"
    width="100"
    height="100"
    stroke="black"
    fill="red"
    filter="url(#mergeWithOffset)"
  />
</Svg>
```

<img width="207" alt="image"
src="https://github.com/user-attachments/assets/9cb3ded6-f939-4b2b-8ece-df54e64fe898">

## Test Plan

`Example` app -> `Filters` -> `FeMerge`

## 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)
2024-07-31 13:23:53 +02:00
Bohdan Artiukhov
a2e843bc9c feat: add web implementation SvgXml and others component (#2382)
# Summary
We want to make available SvgXml and other components in the web
platform.

## Test Plan
We can easily check how that works by opening `Test1813`.

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Web     |         |

---------

Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
2024-07-31 11:56:48 +02:00
Bohdan Artiukhov
a27e17f505 fix: circular-dependencies (#2381)
# Summary
- Require cycles are allowed, but can result in uninitialized values.
Consider refactoring to remove the need for a cycle.
- extract SVG web components.
- extract web types.
- extract utils function.

## Test Plan
You can test that problem by running a test example `Test1813`

### What are the steps to reproduce (after prerequisites)?
Without those changes, you can occur that problem by running a test
example `Test1813`

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |         |
| Android |         |

---------

Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
2024-07-31 11:45:04 +02:00
Jakub Grzywacz
bbd38fb15b fix: web example (#2376)
Fix web example by adding missing tags and importing react
2024-07-29 13:57:53 +02:00
Bohdan Artiukhov
6a563f42b6 fix: type problem ReactNativeSvg.web.ts (#2374)
# Summary

Fix type problem in `ReactNativeSvg.web.ts`
2024-07-29 13:57:19 +02:00
Joshua Yoes
360e0ee01a fix(xml): extract tags map to separate entry point for mobile & web (#1916)
# Summary

**What issues does the pull request solve? Please tag them so that they
will get automatically closed once the PR is merged**

When utilizing with `react-native-web`: SvgXml and SvgUri are not
exported in the `src/ReactNativeSVG.web.ts` extension. The logic for
SvgXml and SvgUri do not have native dependencies, so they are safe to
consume on web.

Issues:
- https://github.com/software-mansion/react-native-svg/issues/1279
- https://github.com/software-mansion/react-native-svg/issues/1742

**What is the feature? (if applicable)**

Add SvgXml and SvgUri as consumable exports for `react-native-web`

**How did you implement the solution?**

Extract `tags` to shapes map into separate `tags.tsx` file, where native
shape elements and web shape elements can be provided to their
respective envs.

**What areas of the library does it impact?**

`src` directory

## 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)?
n/a

### What are the steps to reproduce (after prerequisites)?
n/a

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |         |
| Android |         |

## Checklist

<!-- Check completed item, when applicable, via: [X] -->

- [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)
- [ ] I added a test for the API in the `__tests__` folder

---------

Co-authored-by: bohdanprog <bohdan.artiukhov@swmansion.com>
2024-07-29 13:06:19 +02:00
Jakub Grzywacz
25099ff220 refactor: small changes to filters (#2368)
# Summary

This PR contains two small refactors of filters:
* extract common props on ViewManagers on Android
* remove unnecessary extract in `FeOffset` filter
2024-07-29 08:21:17 +02:00
Jakub Grzywacz
5807f2c1a6 feat: add FeOffset filter (#2361)
# 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)
2024-07-25 12:32:15 +02:00
Jakub Grzywacz
44254df9fb feat: add FeGaussianBlur filter (#2352)
# 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 |         |
2024-07-25 11:46:45 +02:00
Jakub Grzywacz
ba7d77548f feat: support filters on web (#2346)
# Summary

* Export `Filter` and `FeColorMatrix` components on `web`
* Change filter IDs in example to be unique*
* Generate filter ID when using `FilterImage`*
* Hide `FilterImage` example on web, since it's crashing the whole site
(see #2334)

\* ID on web has to be unique, otherwise it'll use the first element
with that ID, even if they are in the separate SVG elements

## Test Plan

run `web-example` app

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Web     |         |
2024-07-25 10:45:24 +02:00
Jakub Grzywacz
52466a2564 feat: introduce CSS filter API on FilterImage (#2359)
# Summary

Provide a **CSS**-like filter API in the `FilterImage` component. 
Unlike the SVG filter API, which can be complex and challenging even for
simple tasks, the CSS API is straightforward and allows users to quickly
achieve satisfactory results.

The full API can be viewed here
https://developer.mozilla.org/en-US/docs/Web/CSS/filter
_We support all `<filter-function>` listed in the docs while we do not
support functions from `<url>` (`url()` and `src()`)._

All shorthands are implemented according to the W3 standard described
here
https://www.w3.org/TR/filter-effects-1/#ShorthandEquivalents

This PR also changes the `filters` prop behavior as it adds `fe` in
front of `name` attribute to not introduce any abstract above that
specified in the docs.
```tsx
<FilterImage
  source={myImage}
  filters={[{ name: 'colorMatrix', type: 'saturate', values: 0.2 }])
/>
```
is now 
```tsx
<FilterImage
  source={myImage}
  filters={[{ name: 'feColorMatrix', type: 'saturate', values: 0.2 }])
/>
```

## Examples
Below are the simple examples of the usage

through `StyleSheet`
```tsx
import React from 'react';
import {StyleSheet, View} from 'react-native';
import {FilterImage} from 'react-native-svg/filter-image';

export default () => {
  return (
    <FilterImage
      style={styles.image}
      source={{
        uri: 'https://cdn.pixabay.com/photo/2024/05/26/00/40/lizard-8787888_1280.jpg',
      }}
    />
  );
};
const styles = StyleSheet.create({
  image: {
    width: 200,
    height: 200,
    filter: 'saturate(100) grayscale(100%)',
  },
});
```

or directly in the `style` prop

```tsx
import React from 'react';
import {StyleSheet, View} from 'react-native';
import {FilterImage} from 'react-native-svg/filter-image';

export default () => {
  return (
    <FilterImage
      style={{
        width: 200,
        height: 200,
        filter: 'saturate(100) grayscale(100%)',
      }}
      source={{
        uri: 'https://cdn.pixabay.com/photo/2024/05/26/00/40/lizard-8787888_1280.jpg',
      }}
    />
  );
};
```

## 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)
2024-07-25 10:19:47 +02:00
Bohdan Artiukhov
2da02cf259 feat: add new resolve web asset function (#2334)
# Summary
Add a new function to resolve Image asset uri.

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Web     |         |
2024-07-19 17:12:49 +02:00
Jakub Grzywacz
657a102b5f fix: cannot set property transform of undefined (gStyle) (#2355)
# Summary

Fix bug introduced in #2189, 
if `style` is not provided, then `StyleSheet.flatten` returns
`undefined`, and we're trying to access `transform` of it.

## Test Plan

Run `example` app
2024-07-19 11:52:22 +02:00
HeeCheolKim
74445cc0fd fix: allow to array style prop (#2189)
# Summary
- Previously, styles in "Array" format were not being applied correctly.
- Therefore, now ensure that styles in "Array" format are correctly
applied using `StyleSheet.flatten.`


**Before: The `opacity` attribute is not correctly applied in
`gStyle`.** 
```tsx
const gStyle = Object.assign({}, [{ opacity: 0.5 }]);
/* { 0: {opacity: 0.5 }} */
```

**After: Now, the `opacity` attribute is correctly applied in
`gStyle`.** 
```tsx
const gStyle = StyleSheet.flatten([{ opacity: 0.5 }]);
/* { opacity: 0.5 } */
```

```tsx
const gStyle = StyleSheet.flatten([{ opacity: 0.5 }, { backgroundColor: 'red' }]);
/* { opacity: 0.5, backgroundColor: 'red' } */
```

## Test Plan

`0` key is not allow to `ViewStyle`

### What's required for testing (prerequisites)?

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |        |
| Android |         |

## Checklist

<!-- Check completed item, when applicable, via: [X] -->

- [x] I have tested this on a device and a simulator

---------

Co-authored-by: bohdanprog <bohdan.artiukhov@swmansion.com>
2024-07-18 11:25:08 +02:00
Jakub Grzywacz
08e92074b4 feat: filters support FeColorMatrix and FilterImage (#2316)
# 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>
  );
};
```

![image](https://github.com/software-mansion/react-native-svg/assets/39670088/c36fb238-95f4-455d-b0aa-2a7d4038b828)

## 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,
  },
});
```


![image](https://github.com/software-mansion/react-native-svg/assets/39670088/666ed89f-68d8-491b-b97f-1eef112b7095)

## 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)
2024-07-11 11:17:35 +02:00