Skip to content

Commit

Permalink
Release 0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
robmadole committed Jun 7, 2022
1 parent f901ef3 commit 2b938fb
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 86 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,29 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

---

## [0.3.0](https://github.com/FortAwesome/react-native-fontawesome/releases/tag/0.3.0) - 2022-06-07

**This release has a couple of breaking changes.**

1. Minimum supported version of React Native is 0.67
1. Minimum supported react-native-svg is 11.x
1. Using `width` or `height` props are not allowed (they were deprecated in 0.2.x)
1. The `secondaryOpacity` will default to 40% (0.4) instead of 100% to match other Font Awesome implementations

### Added

- Support for specifying icons as strings like `icon="fa-solid fa-mug-empty"`
- Optional testId to TypeScript .d.ts file
- Prop `maskId` allows Jest snapshot testing to have consistent results when using masks

### Fixed

- Full support for version 6 of Font Awesome
- Using icons with masks should now be fully functional
- Duotone icons have also been fixed

---

## [0.2.7](https://github.com/FortAwesome/react-native-fontawesome/releases/tag/0.2.7) - 2021-07-22

### Changed
Expand Down
14 changes: 7 additions & 7 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ to get your environment set up in your OS. For Mac OS X, that would look like:

## Launch the Example App

In the `examples/Hello` subdirectory, the following script commands are available:
In the `examples/react-native-expo` subdirectory, the following script commands are available:

| Command | Purpose |
| ------- | ------------------------------------- |
Expand All @@ -34,15 +34,15 @@ In the `examples/Hello` subdirectory, the following script commands are availabl
| clean | clean out build cache. Useful when the build isn't working and you're pretty sure it should be |

In one terminal tab:
1. `cd examples/Hello`
1. `cd examples/react-native-expo`
1. `npm install`
1. `npm run start`

This will get the JavaScript bundler running and listening for connections from a device or iOS Simulator.

In another terminal tab:
1 `cd examples/Hello`
1. `react-native link react-native-svg` # to link the native components in the ios project
1 `cd examples/react-native-expo`
1. `react-native link react-native-svg` # to link the native components in the ios project
1. `npm run ios`

This will build the project via XCode, launch the iOS Simulator, and when the project builds successfully,
Expand All @@ -56,7 +56,7 @@ Seems like things don't always go smoothly and you have to [use some hackery](ht
Try this:
1. shutdown any instances of the bundler you have running.
1. `npm run clean`
1. `npm run start-with-cache-reset` # from the examples/Hello directory
1. `npm run start-with-cache-reset` # from the examples/react-native-expo directory

From another terminal tab:
1. `npm run ios`
Expand All @@ -67,13 +67,13 @@ For now, we're just using the GitHub repo as our source for development versions
test changes to the component using the example app, you'll have to push the component changes to a development branch
and then update the `package.json` of the example app to pull the component from that branch.

Here's the step-by-step:
Here's the step-by-step:

1. make changes to this component
1. `npm run dist` # to transpile via babel into `dist/`
1. `git commit` # whatever changes you're trying to commit
1. `git push origin my-dev` # to whatever topic branch you're working on, say "my-dev"
1. Modify `examples/Hello/package.json` and find the line that looks like this:
1. Modify `examples/react-native-expo/package.json` and find the line that looks like this:
`"@fortawesome/react-native-fontawesome": "^0.0.1"`
And change it to something like this:
`"@fortawesome/react-native-fontawesome": "https://github.com/FortAwesome/react-native-fontawesome#my-dev"`
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

[![npm](https://img.shields.io/npm/v/@fortawesome/react-native-fontawesome.svg?style=flat-square)](https://www.npmjs.com/package/@fortawesome/react-native-fontawesome)

> Font Awesome 5 React Native component using SVG with JS
> Font Awesome React Native component using SVG with JS
<!-- toc -->

Expand Down Expand Up @@ -126,7 +126,7 @@ You can use Font Awesome icons in your React Native components as simply as this
That simple usage is made possible when you add the `"mug-saucer"` icon, to the
_library_.

This is one of the two ways you can use Font Awesome 5 with React Native. We'll
This is one of the two ways you can use Font Awesome with React Native. We'll
summarize both ways briefly and then get into the details of each below.

1. **Explicit Import**
Expand Down
113 changes: 65 additions & 48 deletions dist/components/FontAwesomeIcon.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DEFAULT_SIZE = exports.DEFAULT_SECONDARY_OPACITY = exports.DEFAULT_COLOR = void 0;
exports["default"] = FontAwesomeIcon;
exports.DEFAULT_SECONDARY_OPACITY = exports.DEFAULT_COLOR = exports.DEFAULT_SIZE = void 0;

var _react = _interopRequireDefault(require("react"));

Expand All @@ -18,45 +18,44 @@ var _fontawesomeSvgCore = require("@fortawesome/fontawesome-svg-core");

var _logger = _interopRequireDefault(require("../logger"));

var _excluded = ["color"];

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var _Dimensions$get = _reactNative.Dimensions.get('window'),
windowWidth = _Dimensions$get.width,
windowHeight = _Dimensions$get.height;

var DEFAULT_SIZE = 16;
exports.DEFAULT_SIZE = DEFAULT_SIZE;
var DEFAULT_COLOR = '#000';
exports.DEFAULT_COLOR = DEFAULT_COLOR;
var DEFAULT_SECONDARY_OPACITY = 0.4; // Deprecated height and width defaults

var DEFAULT_SECONDARY_OPACITY = 0.4;
exports.DEFAULT_SECONDARY_OPACITY = DEFAULT_SECONDARY_OPACITY;
var DEFAULT_HEIGHT = windowHeight * 0.1;
var DEFAULT_WIDTH = windowWidth * 0.1;

function objectWithKey(key, value) {
return Array.isArray(value) && value.length > 0 || !Array.isArray(value) && value ? _defineProperty({}, key, value) : {};
}

function normalizeIconArgs(icon) {
if (icon === null) {
return null;
if (icon && _typeof(icon) === 'object' && icon.prefix && icon.iconName && icon.icon) {
return icon;
}

if (_typeof(icon) === 'object' && icon.prefix && icon.iconName) {
return icon;
if (_fontawesomeSvgCore.parse.icon) {
return _fontawesomeSvgCore.parse.icon(icon);
}

if (icon === null) {
return null;
}

if (Array.isArray(icon) && icon.length === 2) {
Expand All @@ -77,6 +76,7 @@ function normalizeIconArgs(icon) {
function FontAwesomeIcon(props) {
var iconArgs = props.icon,
maskArgs = props.mask,
maskId = props.maskId,
height = props.height,
width = props.width,
size = props.size;
Expand All @@ -86,10 +86,12 @@ function FontAwesomeIcon(props) {
var iconLookup = normalizeIconArgs(iconArgs);
var transform = objectWithKey('transform', typeof props.transform === 'string' ? _fontawesomeSvgCore.parse.transform(props.transform) : props.transform);
var mask = objectWithKey('mask', normalizeIconArgs(maskArgs));
var renderedIcon = (0, _fontawesomeSvgCore.icon)(iconLookup, _objectSpread(_objectSpread({}, transform), mask));
var renderedIcon = (0, _fontawesomeSvgCore.icon)(iconLookup, _objectSpread(_objectSpread(_objectSpread({}, transform), mask), {}, {
maskId: maskId
}));

if (!renderedIcon) {
(0, _logger["default"])("ERROR: icon not found for icon = ", iconArgs);
(0, _logger["default"])('ERROR: icon not found for icon = ', iconArgs);
return null;
}

Expand All @@ -98,44 +100,29 @@ function FontAwesomeIcon(props) {
var color = props.color || style.color || DEFAULT_COLOR; // This is the color that will be passed to the "fill" prop of the secondary Path element child (in Duotone Icons)
// `null` value will result in using the primary color, at 40% opacity

var secondaryColor = props.secondaryColor || null; // Secondary layer opacity should default to 0.4, unless a specific opacity value or a specific secondary color was given
var secondaryColor = props.secondaryColor || color; // Secondary layer opacity should default to 0.4, unless a specific opacity value or a specific secondary color was given

var secondaryOpacity = props.secondaryOpacity || (secondaryColor ? 1 : DEFAULT_SECONDARY_OPACITY); // To avoid confusion down the line, we'll remove properties from the StyleSheet, like color, that are being overridden
var secondaryOpacity = props.secondaryOpacity || DEFAULT_SECONDARY_OPACITY; // To avoid confusion down the line, we'll remove properties from the StyleSheet, like color, that are being overridden
// or resolved in other ways, to avoid ambiguity as to which inputs cause which outputs in the underlying rendering process.
// In other words, we don't want color (for example) to be specified via two different inputs.

var styleColor = style.color,
modifiedStyle = _objectWithoutProperties(style, ["color"]);
modifiedStyle = _objectWithoutProperties(style, _excluded);

var resolvedHeight, resolvedWidth;

if (height || width) {
if (size) {
console.warn("DEPRECATION: height and width props on ".concat(FontAwesomeIcon.displayName, " have been deprecated. ") + "Since you've also provided a size prop, we'll use it to override the height and width props given. " + "You should probably go ahead and remove the height and width props to avoid confusion and resolve this warning.");
resolvedHeight = resolvedWidth = size;
} else {
console.warn("DEPRECATION: height and width props on ".concat(FontAwesomeIcon.displayName, " have been deprecated. ") + "Use the size prop instead.");
resolvedHeight = height || DEFAULT_HEIGHT;
resolvedWidth = width || DEFAULT_WIDTH;
}
throw new Error("Prop height and width for component ".concat(FontAwesomeIcon.displayName, " have been deprecated. ") + "Use the size prop instead like <".concat(FontAwesomeIcon.displayName, " size={").concat(width, "} />."));
} else {
resolvedHeight = resolvedWidth = size || DEFAULT_SIZE;
}

var extraProps = {
height: resolvedHeight,
width: resolvedWidth,
fill: color,
secondaryFill: secondaryColor,
secondaryOpacity: secondaryOpacity,
style: modifiedStyle
};
Object.keys(props).forEach(function (key) {
if (!FontAwesomeIcon.defaultProps.hasOwnProperty(key)) {
extraProps[key] = props[key];
}
});
return convertCurry(_abstract[0], extraProps);
var rootAttributes = _abstract[0].attributes;
rootAttributes.height = resolvedHeight;
rootAttributes.width = resolvedWidth;
rootAttributes.style = modifiedStyle;
replaceCurrentColor(_abstract[0], color, secondaryColor, secondaryOpacity);
return convertCurry(_abstract[0]);
}

FontAwesomeIcon.displayName = 'FontAwesomeIcon';
Expand All @@ -151,20 +138,50 @@ FontAwesomeIcon.propTypes = {
}), _propTypes["default"].array]),
icon: _propTypes["default"].oneOfType([_propTypes["default"].object, _propTypes["default"].array, _propTypes["default"].string]),
mask: _propTypes["default"].oneOfType([_propTypes["default"].object, _propTypes["default"].array, _propTypes["default"].string]),
maskId: _propTypes["default"].string,
transform: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].object])
};
FontAwesomeIcon.defaultProps = {
icon: null,
mask: null,
maskId: null,
transform: null,
style: {},
color: null,
secondaryColor: null,
secondaryOpacity: null,
height: undefined,
width: undefined // Once the deprecation of height and width props is complete, let's put the real default prop value for size here.
// For now, adding it breaks the default/override logic for height/width/size.

size: DEFAULT_SIZE
};

var convertCurry = _converter["default"].bind(null, _react["default"].createElement);
var convertCurry = _converter["default"].bind(null, _react["default"].createElement);

function replaceCurrentColor(obj, primaryColor, secondaryColor, secondaryOpacity) {
obj.children.forEach(function (child, childIndex) {
replaceFill(child, primaryColor, secondaryColor, secondaryOpacity);

if (Object.prototype.hasOwnProperty.call(child, 'attributes')) {
replaceFill(child.attributes, primaryColor, secondaryColor, secondaryOpacity);
}

if (Array.isArray(child.children) && child.children.length > 0) {
replaceCurrentColor(child, primaryColor, secondaryColor, secondaryOpacity);
}
});
}

function replaceFill(obj, primaryColor, secondaryColor, secondaryOpacity) {
if (hasPropertySetToValue(obj, 'fill', 'currentColor')) {
if (hasPropertySetToValue(obj, 'class', 'fa-primary')) {
obj.fill = primaryColor;
} else if (hasPropertySetToValue(obj, 'class', 'fa-secondary')) {
obj.fill = secondaryColor;
obj.fillOpacity = secondaryOpacity;
} else {
obj.fill = primaryColor;
}
}
}

function hasPropertySetToValue(obj, property, value) {
return Object.prototype.hasOwnProperty.call(obj, property) && obj[property] === value;
}
Loading

0 comments on commit 2b938fb

Please sign in to comment.