Skip to content

Commit

Permalink
feat(ios): override transparent with configurable color for iOS
Browse files Browse the repository at this point in the history
iOS doesn't support transparency for icons and would otherwise default to a black background. release-npm
  • Loading branch information
tobua committed Aug 6, 2022
1 parent 782d2e3 commit 799cab9
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ Numic automatically picks up the plugin once installed and adds the various icon

The icon can be configured in `package.json` under the `numic` property. This will override default icon paths from the file system as described above.

```json
```js
{
"name": "my-app",
"numic": {
"icon-numic-plugin": {
"icon": "image/my-icon.png"
"icon": "image/my-icon.png",
// Convert transparent icons to a black background for iOS, default white.
"iOSBackground": "#000000"
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Input = {
projectPath?: string
nativePath?: string
log?: (message: string, type?: string) => void
options?: object
options?: { iOSBackground?: string; icon?: string }
}

const iconSourcePaths = (projectPath: string) => [
Expand Down Expand Up @@ -123,7 +123,11 @@ export default async ({
if (!existsSync(directory)) {
mkdirSync(directory, { recursive: true })
}
return sharp(inputFile).resize(icon.size, icon.size).toFile(destinationFile)
// iOS doesn't support transparent icons and will add a black background, this plugin by default adds a white background.
return sharp(inputFile)
.flatten({ background: options.iOSBackground ?? '#FFFFFF' })
.resize(icon.size, icon.size)
.toFile(destinationFile)
})

await Promise.all(iosPromises)
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@
"react-native"
],
"devDependencies": {
"@types/get-pixels": "^3.3.2",
"@types/sharp": "^0.30.4",
"get-pixels": "^3.3.3",
"jest-fixture": "^3.0.1",
"padua": "^0.6.1",
"vitest": "^0.16.0"
"vitest": "^0.21.0"
},
"prettier": "padua/configuration/.prettierrc.json",
"eslintConfig": {
Expand Down
62 changes: 62 additions & 0 deletions test/logo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { cpSync, existsSync, mkdirSync } from 'fs'
import { join } from 'path'
import { expect, test, beforeEach, afterEach, vi } from 'vitest'
import { prepare, environment, packageJson, listFilesMatching, readFile } from 'jest-fixture'
import getPixels from 'get-pixels'
import plugin from '../index'

const initialCwd = process.cwd()
Expand Down Expand Up @@ -126,3 +127,64 @@ test('Automatically finds svg in default paths.', async () => {
expect(files.includes('android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png')).toBe(true)
expect(files.includes('ios/numic/Images.xcassets/AppIcon.appiconset/Icon-80.png')).toBe(true)
})

test('iOS background transparency can be configured.', async () => {
prepare([packageJson('logo-ios-background')])

const white = '#FFFFFF'
const black = '#000000'

const logoPath = join(process.cwd(), 'icon.png')

cpSync(join(initialCwd, 'test/logo.png'), logoPath)
mkdirSync(join(process.cwd(), 'ios/numic/Images.xcassets'), { recursive: true })

expect(existsSync(logoPath)).toBe(true)

await plugin({})

const someIOSIcon = join(
process.cwd(),
'ios/numic/Images.xcassets/AppIcon.appiconset/Icon-80.png'
)

expect(existsSync(someIOSIcon)).toBe(true)
let pixels = await new Promise<number[]>((done) =>
getPixels(someIOSIcon, (_, pixels: any) => done(pixels.data))
)

expect(pixels[0]).toBe(255) // Red
expect(pixels[1]).toBe(255) // Green
expect(pixels[2]).toBe(255) // Blue
expect(pixels[3]).toBe(255) // Alpha (transparency)

await plugin({
options: {
iOSBackground: black,
},
})

pixels = await new Promise<number[]>((done) =>
getPixels(someIOSIcon, (_, pixels: any) => done(pixels.data))
)

expect(pixels[0]).toBe(0) // Red
expect(pixels[1]).toBe(0) // Green
expect(pixels[2]).toBe(0) // Blue
expect(pixels[3]).toBe(255) // Alpha (transparency)

await plugin({
options: {
iOSBackground: white,
},
})

pixels = await new Promise<number[]>((done) =>
getPixels(someIOSIcon, (_, pixels: any) => done(pixels.data))
)

expect(pixels[0]).toBe(255) // Red
expect(pixels[1]).toBe(255) // Green
expect(pixels[2]).toBe(255) // Blue
expect(pixels[3]).toBe(255) // Alpha (transparency)
})

0 comments on commit 799cab9

Please sign in to comment.