Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: Tests

on:
- push
- pull_request
push:
branches:
- main
pull_request:

jobs:
unit:
Expand All @@ -19,8 +21,10 @@ jobs:
node-version-file: '.node-version'
- name: Install dependencies
run: yarn --frozen-lockfile --non-interactive --silent --ignore-scripts
- name: Run tests
- name: Run unit tests
run: yarn test
- name: Run plugin tests
run: yarn test:plugin

ios:
name: iOS integration tests
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ node_modules/

# Logs
*.log

plugin/build/
4 changes: 2 additions & 2 deletions Example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"postinstall": "DESTINATION='node_modules/react-native-vector-image' LIB_FILE=`cd .. && echo \\`pwd\\`/\\`npm pack\\`` && (rm -rf $DESTINATION || true) && mkdir -p $DESTINATION && tar -xvzf $LIB_FILE -C $DESTINATION --strip-components 1 && rm $LIB_FILE",
"postinstall": "(cd .. && npm pack) && DESTINATION='node_modules/react-native-vector-image' LIB_FILE=`ls ../*.tgz` && (rm -rf $DESTINATION || true) && mkdir -p $DESTINATION && tar -xvzf $LIB_FILE -C $DESTINATION --strip-components 1 && rm $LIB_FILE",
"assets": "react-native-vector-image generate",
"test": "jest"
},
"dependencies": {
"react": "19.1.1",
"react-native": "0.82.0",
"react-native-vector-image": "^0.4.5"
"react-native-vector-image": "^0.5.1"
},
"devDependencies": {
"@babel/core": "^7.25.2",
Expand Down
8 changes: 4 additions & 4 deletions Example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5564,10 +5564,10 @@ react-is@^19.1.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.0.tgz#ddc3b4a4e0f3336c3847f18b806506388d7b9973"
integrity sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==

react-native-vector-image@^0.4.5:
version "0.4.5"
resolved "https://registry.yarnpkg.com/react-native-vector-image/-/react-native-vector-image-0.4.5.tgz#910a6e537d180c2082c85d91951aea6ba87e6d2f"
integrity sha512-19B9a+CXvIfTCCOG58lttULtG9/3BfBO5VBdvnElKmXov/V3mBbtAPBNwC+tmqu3cWKkAMzq8jeBwG7FxN9OAA==
react-native-vector-image@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/react-native-vector-image/-/react-native-vector-image-0.5.1.tgz#642462da775d4ae4b64f7eed5862cefd6a4fd20c"
integrity sha512-ik2ZwzLkSPf0/PpbMBt+kaMsgewc/VqHeKDRzAa4vZeZ+WCVEAj+++yVTm/XB2QV2z3gz4nfW5TEwUM0bWhTag==
dependencies:
chalk "^4.1.1"
chroma-js "^2.1.1"
Expand Down
66 changes: 53 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
- Faster render – ~5x faster than `react-native-svg`.
- Smaller JS bundle = faster startup.
- Native support for dark mode.
- Web support for Expo.

## Installation

```sh
yarn add react-native-vector-image
```

For expo, see [`@zamplyy/react-native-vector-image-plugin`](https://github.com/zamplyy/react-native-vector-image-plugin).

### Android

Edit `android/app/build.gradle` to look like this (without the +):
Expand Down Expand Up @@ -44,6 +43,44 @@ REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"

<img width="1212" alt="" src="https://user-images.githubusercontent.com/378279/115999935-544c0600-a5ee-11eb-9c59-6fb50e434ed0.png">

### Expo

After installing this npm package, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js`:

```json
{
"expo": {
"plugins": ["react-native-vector-image"]
}
}
```

Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/) guide.

#### Options

```json
{
"expo": {
"plugins": [
[
"react-native-vector-image",
{
// These are default options, change if you want a different value:
"stripSvgs": false, // if true, svgs will be removed from bundle. expo-updates package crashes when svgs it expects in the bundle are not there
"metroConfigFile": "metro.config.js",
"resetCache": false,
"bundleWithExpo": true,
"entryFile": "index.ts"
}
]
]
}
}
```

Shout out to [zamplyy](https://github.com/zamplyy) for making the first version of the Expo plugin.

## Usage

Since native vector assets cannot be served over http via metro dev server, they must be generated and compiled into the app bundle.
Expand All @@ -62,21 +99,24 @@ To add dark mode to your image, create a new file with an `.dark.svg` extension,

This takes a while as metro has to go through all the code to find the imported SVGs.

_Note: for Expo just use the plugin and `npx expo prebuild`._

```sh
yarn react-native-vector-image generate
```

| Argument | Description | Default |
| ---------------------- | ---------------------------------------------------------------- | ----------------------------- |
| `--entry-file` | Path to the app entrypoint file. | `index.js` |
| `--config` | Path to the metro config file. | `metro.config.js` |
| `--reset-cache` | Reset metro cache before extracting SVG assets. | `false` |
| `--ios-output` | Path to an iOS `.xcassets` folder. | `ios/AppName/Images.xcassets` |
| `--no-ios-output` | Disable iOS output. | `false` |
| `--android-output` | Path to an Android `res` folder. | `android/app/src/main/res` |
| `--no-android-output` | Disable Android output. | `false` |
| `--current-color` | Replace any `currentColor` color references in SVGs. | `#000000` |
| `--current-color-dark` | Replace any `currentColor` color references in `.dark.svg` SVGs. | `#ffffff` |
| Argument | Description | Default |
| ---------------------- | -------------------------------------------------------------------- | ----------------------------- |
| `--entry-file` | Path to the app entrypoint file. | `index.js` |
| `--config` | Path to the metro config file. | `metro.config.js` |
| `--reset-cache` | Reset metro cache before extracting SVG assets. | `false` |
| `--bundle-with-expo` | Whether to bundle the app with Expo presets or using metro directly. | `false` |
| `--ios-output` | Path to an iOS `.xcassets` folder. | `ios/AppName/Images.xcassets` |
| `--no-ios-output` | Disable iOS output. | `false` |
| `--android-output` | Path to an Android `res` folder. | `android/app/src/main/res` |
| `--no-android-output` | Disable Android output. | `false` |
| `--current-color` | Replace any `currentColor` color references in SVGs. | `#000000` |
| `--current-color-dark` | Replace any `currentColor` color references in `.dark.svg` SVGs. | `#ffffff` |

### Step 3: recompile

Expand Down
1 change: 1 addition & 0 deletions app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./plugin/build/withVectorImage');
3 changes: 3 additions & 0 deletions expo-module.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"platforms": ["apple", "android", "web"]
}
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,21 @@
"url": "git+https://github.com/oblador/react-native-vector-image.git"
},
"scripts": {
"test": "jest src"
"test": "jest src",
"build:plugin": "expo-module build plugin",
"test:plugin": "expo-module test plugin",
"prepare": "expo-module prepare plugin",
"prepublishOnly": "expo-module prepublishOnly plugin"
},
"bin": {
"react-native-vector-image": "bin/react-native-vector-image.js"
},
"files": [
"bin",
"src",
"app.plugin.js",
"expo-module.config.json",
"plugin/build",
"strip_svgs.sh",
"strip_svgs.gradle",
"!*.spec.js",
Expand Down Expand Up @@ -51,7 +58,10 @@
}
},
"devDependencies": {
"jest": "^26.6.3",
"expo-module-scripts": "^5.0.7",
"expo": "^54.0.12",
"react-native": "0.81.4",
"jest": "^29.6.3",
"metro": ">=0.83.3",
"metro-config": ">=0.83.3",
"prettier": "^2.2.1"
Expand Down
5 changes: 5 additions & 0 deletions plugin/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
root: true,
extends: ['universe/native', 'universe/web'],
ignorePatterns: ['build'],
};
17 changes: 17 additions & 0 deletions plugin/__tests__/android/withVectorImage-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as fs from 'fs/promises';
import { resolve } from 'path';

import { addStripSvgsImplementation } from '../../src/withVectorImage';

describe('addStripSvgsImplementation', () => {
it(`adds string`, async () => {
const sampleBuildGradle = await fs.readFile(
resolve(__dirname, '../fixtures/build.gradle'),
'utf8'
);
const buildGradle = await addStripSvgsImplementation(sampleBuildGradle);
const addString =
'apply from: "../../node_modules/react-native-vector-image/strip_svgs.gradle"';
expect(buildGradle.includes(addString)).toEqual(true);
});
});
37 changes: 37 additions & 0 deletions plugin/__tests__/both/withVectorImage-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { GenerateCommands, getCommands } from '../../src/withVectorImage';

describe('command generation', () => {
it('generates list of commands correct', async () => {
const defaultCommands = getCommands();
const customCommands1 = getCommands([
{ command: GenerateCommands.Config, input: 'metro2.config.js' },
]);
const customCommands2 = getCommands([
{ command: GenerateCommands.EntryFile, input: 'app.js' },
]);
const customCommands3 = getCommands([
{ command: GenerateCommands.ResetCache, input: 'true' },
]);
const customCommands4 = getCommands([
{ command: GenerateCommands.ResetCache, input: 'true' },
{ command: GenerateCommands.EntryFile, input: 'app.js' },
{ command: GenerateCommands.Config, input: 'metro2.config.js' },
{ command: GenerateCommands.BundleWithExpo, input: 'false' },
]);
expect(defaultCommands).toEqual(
'--entry-file index.ts --bundle-with-expo true'
);
expect(customCommands1).toEqual(
'--config metro2.config.js --entry-file index.ts --bundle-with-expo true'
);
expect(customCommands2).toEqual(
'--entry-file app.js --bundle-with-expo true'
);
expect(customCommands3).toEqual(
'--reset-cache true --entry-file index.ts --bundle-with-expo true'
);
expect(customCommands4).toEqual(
'--reset-cache true --entry-file app.js --config metro2.config.js --bundle-with-expo false'
);
});
});
Loading