Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Image Symbol Names (e.g. SF Symbols) #763

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
67 changes: 67 additions & 0 deletions proposals/0000-support-image-symbol-names.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Support Image Symbol Names
author:
- Aaron Brager
date: 2024-02-11
---

# RFC0000: Support Image Symbol Names

## Summary

This proposal suggests adding support for custom symbol images in React Native's `Image` component. Currently, React Native supports loading images from local files and network URLs. However, there's no direct support for using custom symbol images on iOS/macOS/tvOS. This feature would improve developers' ability to use React Native to create a native look and feel without relying on third-party libraries.

If you're not familiar with this iOS feature there's more info here: https://developer.apple.com/documentation/uikit/uiimage/configuring_and_displaying_symbol_images_in_your_ui

## Basic example

There's a few different approaches for the API and I'm not married to this one, but it'd look something like this:

```javascript
import React from 'react';
import { View, Image } from 'react-native';

const CustomSymbolImageExample = () => (
<View>
<Image source={{ systemSymbol: { name: 'custom.multiply.circle', configuration: {
weight: 'thin',
scale: 'large'
}}} />
</View>
);

export default CustomSymbolImageExample;
```

## Motivation

Currently, developers resort to workarounds like using third-party libraries such as `react-native-sfsymbols` to do what should be built-in. This change would reduce dependencies on external packages and provide a more cohesive ecosystem.

## Detailed design

Extend React Native's `Image` component to accept system symbol names. This component would bridge to e.g. `UIImage(systemName: "multiply.circle.fill")` to load the correct symbol, then render it in a `UIImageView`, which is similar to how the current implementation works, except with a different initializer.

Android doesn't support an equivalent.

## Drawbacks

- Implementation cost: Adding support for custom symbol images may introduce additional complexity to the `Image` component implementation.
- Platform specificity: This would only be available on Apple platforms which would exacerbate platform disparities in React Native apps.

## Alternatives

- Use `react-native-sfsymbols`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another good option: https://docs.expo.dev/versions/v51.0.0/sdk/symbols/

imo this is sufficient, in particular given #759 - which will see React Native move towards recommending using a React Native Framework like Expo and keeping a focused core. note that any platform-specific APIs in React Native core increase the surface area for out of tree platforms.

further, I'm not convinced that the Image component from react-native is actually the best tool to use for most apps. there is a greater discussion to be had about this, but in general most folks building larger apps will use expo-image or react-native-fast-image instead due to the better perceived "feel" and objective performance.

- Handwrite a bridge

## Adoption strategy

It's not a breaking change. We could optionally coordinate with `react-native-sfsymbols` to use the new functionality under the hood in their library. We could also invite them to contribute their source code to the core React Native project.

## How we teach this

Nothing major would change about teaching this, just some additions to the docs.

## Unresolved questions

- Should we support a bunch of separate props to compose the system symbol names, have typescript enums, etc? (In my example above I just used strings.)
- Some symbols support animations, what should the API interface be for that? (I think we could still use `Image` for this.)