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

FontAwesome 5 #776

Merged
merged 23 commits into from
Jul 20, 2018
Merged

FontAwesome 5 #776

merged 23 commits into from
Jul 20, 2018

Conversation

hampustagerud
Copy link
Collaborator

@hampustagerud hampustagerud commented Jul 17, 2018

I have implemented a way to use FontAwesome 5, both Free and Pro versions (see instructions included in FONTAWESOME5.md). This should resolve #613, close #695, close #713 and close #771. I have tested regular icons on both Android and iOS. Button and similar extra classes currently only works properly on Android (defaults to Regular on iOS) but should be easily fixed with some more time. People just seemed really interested in this feature so I wanted to make it available as soon as possible 😃

Also, there is no breaking changes for those using FA4. There is a separate glyphmap and new classes using it 👍🏻

I have now automated the upgrading and building, added it to the directory and IconExplorer (it's not a 100% functional due to how FontAwesome5 is built and the directories are built but most icons are visible). It should also be fully functional with Buttons and TabBarItems (I have only tested Button though) on both Android and iOS, be sure to read the manual on how to access these since it is not really the same as with the standard fonts.

@hampustagerud hampustagerud force-pushed the fontawesome5 branch 2 times, most recently from 82dcf01 to 3449bc1 Compare July 17, 2018 14:48
+ GlyphMap for FontAwesome 5.1.0 Pro
+ Font files for FontAwesome 5.1.0 Free
+ Implementation enabling FontAwesome5 icons

Handles the copying and renaming of FontAwesome5 Pro font files

Removed debug code
Now a default import from a separate file, instead of
creating it using FA5iconSet(bool).
Fixes to pass tests
@@ -38,11 +43,13 @@ export default function createIconSet(glyphMap, fontFamily, fontFile) {
color: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
children: PropTypes.node,
style: PropTypes.any, // eslint-disable-line react/forbid-prop-types
extraStyle: PropTypes.any, // eslint-disable-line react/forbid-prop-types
Copy link
Owner

Choose a reason for hiding this comment

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

What is this extraStyle used for? Can't see it referenced elsewhere.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was part of an earlier solution which I seemed to have missed when cleaning up the code, on it!


echo "Creating glyphmaps"

mkdir -p temp
Copy link
Owner

Choose a reason for hiding this comment

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

Can you do the following like the other build scripts instead?

TEMP_DIR=`mktemp -d -t rnvi`
mkdir $TEMP_DIR


echo "Installing FontAwesome5"

npm install @fortawesome/fontawesome-free --no-shrinkwrap
Copy link
Owner

Choose a reason for hiding this comment

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

Think we can do npm pack instead to avoid polluting the node_modules folder

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

npm pack is probably better yea...

echo "Copying font files"

cp ./node_modules/@fortawesome/fontawesome-pro/webfonts/fa-brands-400.ttf Fonts/FontAwesome5_Brands.ttf
cp ./node_modules/@fortawesome/fontawesome-pro/webfonts/fa-light-300.ttf Fonts/FontAwesome5_Light.ttf
Copy link
Owner

Choose a reason for hiding this comment

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

It's not ideal to install these to the node_modules folder IMHO as it is usually not checked in to git and thus wouldn't work out of the box if you're more than one dev. Would it be possible to either use the fonts from the @fortawesome/fontawesome-pro package directly or output them to the main project's directory?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure, the API requires direct access to the files but maybe the FontAwesome5Pro module could point backwards? I'll look into it!

package.json Outdated
"build-feather": "./scripts/feather.sh",
"build-foundation": "./scripts/foundation.sh",
"build-ionicons": "./scripts/ionicons.sh",
"build-materialicons": "./scripts/materialicons.sh",
"build-materialcommunityicons": "./scripts/materialcommunityicons.sh",
"build-octicons": "./scripts/octicons.sh",
"build-zocial": "./scripts/zocial.sh",
"build-simplelineicons": "./scripts/simplelineicons.sh"
"build-simplelineicons": "./scripts/simplelineicons.sh",
"fa5upgrade": "./scripts/fa5upgrade.sh"
Copy link
Owner

Choose a reason for hiding this comment

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

This should probably exported as a bin instead of as a script.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not too familiar with this aspect of npm so I took a shot. Would adding it to bin make it runnable from the app folder (instead of navigating into the library folder for upgrading)? My original though was that you could just run something like npm run fa5upgrade from the top folder which would be easier (and cleaner).

Copy link
Owner

Choose a reason for hiding this comment

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

Yep, exactly :-)

FontAwesome5.js Outdated
};

static defaultProps = {
size: DEFAULT_ICON_SIZE,
Copy link
Owner

Choose a reason for hiding this comment

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

Do we have to duplicate the defaults here? Should be enough if they are applied later.

FontAwesome5.js Outdated
static Light = LightSet;
static Regular = RegularSet;
static Solid = SolidSet;

Copy link
Owner

Choose a reason for hiding this comment

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

Have you thought about implementing getImageSource or would one go directly for the specific sets?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I could probably fix this when I am implementing the Button class!

FontAwesome5.js Outdated
}

const iconSet = FA5iconSet(false);
export default iconSet;
Copy link
Owner

Choose a reason for hiding this comment

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

The other icon sets also export Button, TabBarItem, TabBarItemIOS, ToolbarAndroid. Would it be possible to use these specialized components with FA5?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For now it is possible to use through the iconSets in the FontAwesome5 class but I think implementing it should be fairly easy.

* Usage: <FontAwesome5Pro name="icon-name" size={20} color="#4F8EF7" />
*/

import {FA5iconSet} from './FontAwesome5';
Copy link
Owner

Choose a reason for hiding this comment

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

Not sure if the linter caught it but, should be spaces around the curly braces like this: `{ FA5iconSet }

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, I didn't get a warning but I'll fix it 👍🏻

@@ -12,7 +12,7 @@ Pod::Spec.new do |s|
s.platform = :ios, "7.0"
s.source = { :git => "https://github.com/oblador/react-native-vector-icons.git", :tag => "v#{s.version}" }
s.source_files = 'RNVectorIconsManager/**/*.{h,m}'
s.resources = "Fonts/*.ttf"
s.resources = "Fonts/*.(o|t)tf"
Copy link
Owner

Choose a reason for hiding this comment

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

Is this change needed? Seems like FA5 uses .ttf too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is true, my first design was using the desktop version of the font (which is .otf) but I later moved to the npm hosted version and just forgot about this but I can change it.

@oblador
Copy link
Owner

oblador commented Jul 17, 2018

So awesome, thanks a bunch! This is a big PR with some new API considerations, so added some comments relating to this.

@oblador
Copy link
Owner

oblador commented Jul 17, 2018

Btw I’m originally from and on my way to Malmö right now haha.

@hampustagerud
Copy link
Collaborator Author

I had to make a few changes to the API in order to be able to select style but they don't break anything so I felt it was worth it. Also, I am mainly a C/C++ (at least native) developer so this whole npm ecosystem is quite new to me and sometimes it feels like it´s messing with me on purpose which is why it may not be the cleanest solutions possible. I´ll look into the things you commented on and try to fix it (and maybe learn something 🙃).

Haha it´s a small world (or at least country)! I feel sorry for you that you had to leave the best part of Sweden but I hope you feel welcome when you return 😉 Work or pleasure?

@hampustagerud
Copy link
Collaborator Author

hampustagerud commented Jul 18, 2018

I have updated the code quite a lot now:

+ iconSets are now generated via a factory
+ iconSets support all features that "classic" iconSets do (Button, TabBarItem etc.) and in the same way they do.
+ getImageSource() works
+ Fixed the IconExplorer project
+ Building uses a temporary folder and npm pack
+ Upgrading occurs locally to the project (not in the library folder) and requires no additional steps after the script is finished. It can be run using just fa5-upgrade from the project folder, much cleaner and easier!
+ Docs update

- Library doesn't have to be manually implemented on iOS, it is done automatically the first time an iconSet is generated

I think that is all the changes, the code looks and works better at least 🙃

echo "Downloading FontAwesome5 Pro"

npm pack @fortawesome/fontawesome-pro
tar -xzf fortawesome-fontawesome-pro*
Copy link
Owner

Choose a reason for hiding this comment

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

AFAIK npm pack will output the file name, so you can use that instead of globing.

echo "Setting up npm config"

npm config set "@fortawesome:registry" https://npm.fontawesome.com/
npm config set "//npm.fontawesome.com/:_authToken" $fa5_token
Copy link
Owner

Choose a reason for hiding this comment

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

I'm assuming that this might already have been done before. Maybe we should check whether the setting already exists and not ask for token in that case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure how to implement this, I can read the first variable and only set it to a new value if it is undefined. However, the second one is secret and I can't read anything from checking npm config get "//npm.fontawesome.com/:_authToken". Is there a way to extract the value? The documentation doesn't seem to mention anything about it or the error thrown ("--- sekretz ---").


echo "Modifying package.json"

add-font-assets
Copy link
Owner

Choose a reason for hiding this comment

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

This assumes $PATH variable to include ./node_modules/.bin correct? Maybe better to be explicit here.


echo "Linking project"

react-native link
Copy link
Owner

Choose a reason for hiding this comment

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

This is potentially dangerous, can we be explicit with only linking the current project? Didn't try but was thinking like this:

react-native link `basename "$PWD"`

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I ran with react-native link react-native-vector-icons which I intended first but I guess I forgot it later.

@@ -43,6 +61,7 @@ export default function createIconSet(glyphMap, fontFamily, fontFile) {
static defaultProps = {
size: DEFAULT_ICON_SIZE,
allowFontScaling: false,
extraStyle: {},
Copy link
Owner

Choose a reason for hiding this comment

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

Think you forgot this one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure did!

package.json Outdated
@@ -4,6 +4,8 @@
"description": "Customizable Icons for React Native with support for NavBar/TabBar/ToolbarAndroid, image source and full styling.",
"main": "dist/index.js",
"bin": {
"add-font-assets": "./bin/add-font-assets.js",
"fa5-upgrade": "./bin/fa5-upgrade.sh",
Copy link
Owner

@oblador oblador Jul 19, 2018

Choose a reason for hiding this comment

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

Does it make sense to prefix this somehow? I know generate-icon doesn't, but that doesn't mean it's correct hehe.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't know, looking through some .bin folders it doesn't seem conventional to have some common prefix.

FONTAWESOME5.md Outdated
Use this to select which style the generated image should have:

```javascript
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
Copy link
Owner

Choose a reason for hiding this comment

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

Should say import FontAwesome5, { FA5Style } ...

FONTAWESOME5.md Outdated
You need your FontAwesome npm token which can be obtained by logging into your
account and then access the ```Services``` tab.

Run ```fa5upgrade``` and enter the token when asked to in order to
Copy link
Owner

Choose a reason for hiding this comment

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

npm run fa5-upgrade or ./node_modules/.bin/fa5-upgrade, yeah?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

npm run fa5-upgrade results in npm ERR! missing script: fa5-upgrade for me. ./node_modules/.bin/fa5-upgrade works but so does fa5-upgrade?

Copy link
Owner

Choose a reason for hiding this comment

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

Maybe that only works with yarn, let’s change to full bin path (current name is wrong now anyway). Not everybody has set up their path to include node_modules.

package.json Outdated
@@ -4,6 +4,8 @@
"description": "Customizable Icons for React Native with support for NavBar/TabBar/ToolbarAndroid, image source and full styling.",
"main": "dist/index.js",
"bin": {
"add-font-assets": "./bin/add-font-assets.js",
Copy link
Owner

Choose a reason for hiding this comment

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

Do we need to expose this script to the user? If so maybe document it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not really, it is only useful when running fa5-upgrade.

fonts.gradle Outdated
@@ -5,7 +5,7 @@
def config = project.hasProperty("vectoricons") ? project.vectoricons : [];

def iconFontsDir = config.iconFontsDir ?: "../../node_modules/react-native-vector-icons/Fonts";
def iconFontNames = config.iconFontNames ?: [ "*.ttf" ];
def iconFontNames = config.iconFontNames ?: [ "*.ttf", "*.otf" ];
Copy link
Owner

Choose a reason for hiding this comment

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

Revert this one too to be consistent across platforms.

tar -xzf fortawesome-fontawesome-pro*
mv package pro

popd
Copy link
Owner

Choose a reason for hiding this comment

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

Learned a new command today, thanks!

}

for (let i = 0; i < pack.rnpm.assets.length; i += 1)
if (pack.rnpm.assets[i] === './assets/fonts') process.exit();
Copy link
Owner

Choose a reason for hiding this comment

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

Feels like includes() or an old school pack.rnpm.assets.indexOf('./assets/fonts') !== -1 would be prettier somehow

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Total blackout here, of course that's what it should be!


const json = fs.readFileSync('package.json', 'utf8');

const pack = JSON.parse(json);
Copy link
Owner

Choose a reason for hiding this comment

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

Not sure if it's better but I would do a require('package.json') to save me some typing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried it at first because it does look a lot cleaner but then node can't seem to find the file, it only works when I use the fs module. Maybe there is something wrong with my env?

Copy link
Owner

Choose a reason for hiding this comment

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

Think fs is relative to pwd and require to the file. Try require(path.resolve(’package.json’))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, require is relative to the file... I forgot about that!


pack.rnpm.assets.push('./assets/fonts');

fs.writeFileSync('package.json', JSON.stringify(pack, null, 2), 'utf8');
Copy link
Owner

Choose a reason for hiding this comment

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

Very small detail, but most prefer files ending with a new line and many editors will add it by just saving. To avoid diffs, could you add one?

Copy link
Collaborator Author

@hampustagerud hampustagerud Jul 19, 2018

Choose a reason for hiding this comment

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

I do too, I don't know if it's git or my editor (currently JetBrains) but I have to have two blank lines at the end to make one blank line in the saved file.

It seems like yarn test complains on the blank line though?

Copy link
Owner

Choose a reason for hiding this comment

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

I meant in the generated package.json

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, got it!

@oblador
Copy link
Owner

oblador commented Jul 19, 2018

So awesome man! PR of the year for sure 😄 Really close now, added a few comments, mostly minor things. Thank you for your patience! 🙇

@hampustagerud
Copy link
Collaborator Author

Should be a little closer to the finish line now 😊

@oblador oblador merged commit 45e8617 into oblador:master Jul 20, 2018
@oblador
Copy link
Owner

oblador commented Jul 20, 2018

@hampustagerud I merged this perhaps a bit prematurely. Was checking out the IconExplorer project and most of the icons are just question marks on iOS:

simulator screen shot - iphone 6 - 2018-07-20 at 09 19 32

@beausmith
Copy link

Ha! Random… I'm eagerly watching this PR, and noticed the Sweden references… just flew into CPH yesterday (from SF), and now chilling in Åhus with my in-laws for the next month. ❤️

@oblador
Copy link
Owner

oblador commented Jul 20, 2018

Also @hampustagerud, would you mind sharing your fontawsome token so I can play around with it a bit? DM me on https://twitter.com/trastknast

@hampustagerud
Copy link
Collaborator Author

I can send it soon!

The bug in the icon list is that the icons default to regular which does not even contain all free icons. I have changed to code in IconList.js to always set the solid prop to true and then all icon renders properly, also this shouldn't interfere with the other icon sets.

Should I create a PR or just commit it?

@oblador
Copy link
Owner

oblador commented Jul 20, 2018

Please make a PR! 👍

@hampustagerud
Copy link
Collaborator Author

Will do that!

Also, realised that the brands icons are not showing since they are a different font but in the same glyphmap... Maybe the best thing would be to have a custom IconList for FA5 which could show all free versions of the icons? Some would probably be question marks still but there should be a some icons in every ListItem (either Brand, Regular or Solid).

@oblador
Copy link
Owner

oblador commented Jul 20, 2018

Hmm, would be cool if we could tell by the glyph which font to use so you didn’t have to do the brand prop. Think I actually saw that somewhere that they have different ranges.

@hampustagerud
Copy link
Collaborator Author

That would be interesting for sure, then there could be some automatic fallback as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants