Skip to content

Commit

Permalink
Add StyleSheet.setStyleAttributePreprocessor
Browse files Browse the repository at this point in the history
Summary:
**Motivation**

On Exponent we load fonts dynamically and assign their native names by appending a session id, so that fonts from one Exponent "experience" do not clash with each other. So, before sending the `fontFamily` to native, we want to change it to the Exponent-scoped `fontFamily`.

Example:

```js
// Before rendering your app
StyleSheet.setStyleAttributePreprocessor('fontFamily', _processFontFamily);

function _processFontFamily(name) {
  // Pass system fonts through
  if (!name || Constants.systemFonts.indexOf(name) >= 0) {
    return name;
  }

  if (!Font.isLoaded(name)) {
    if (__DEV__) {
      console.error(`${name} is not a system font and has not been loaded through Exponent.Font.loadAsync. If you intended to use a system font, make sure you typed the name correctly and that it is supported by the current operating system. If this is a custom font, be sure to load it with Exponent.Font.loadAsync`);
    } else {
      return 'system';
    }
  }

  return `ExponentFont-
Closes facebook#11138

Differential Revision: D4245518

Pulled By: mkonicek

fbshipit-source-id: bd2452b1129d6675aa7b88e41351f8bb61fa20a3
  • Loading branch information
brentvatne authored and robclouth committed Dec 7, 2016
1 parent f727be8 commit 6ed4876
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
jest.disableAutomock();

const ReactNativeAttributePayload = require('ReactNativeAttributePayload');
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
const StyleSheet = require('StyleSheet');

describe('ReactNativeAttributePayload', () => {

describe('create', () => {
it('works with custom style processors', () => {
StyleSheet.setStyleAttributePreprocessor('fontFamily', (nextValue) => 'Wingdings');

const updatePayload = ReactNativeAttributePayload.create(
{style: {fontFamily: 'Comic Sans'}},
{style: ReactNativeStyleAttributes},
);

expect(updatePayload.fontFamily).toEqual('Wingdings');
});
});

});
31 changes: 30 additions & 1 deletion Libraries/StyleSheet/StyleSheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

var PixelRatio = require('PixelRatio');
var ReactNativePropRegistry = require('ReactNativePropRegistry');
var ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
var StyleSheetValidation = require('StyleSheetValidation');

var flatten = require('flattenStyle');
Expand Down Expand Up @@ -162,6 +163,34 @@ module.exports = {
*/
flatten,

/**
* WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will
* not be reliably announced. The whole thing might be deleted, who knows? Use
* at your own risk.
*
* Sets a function to use to pre-process a style property value. This is used
* internally to process color and transform values. You should not use this
* unless you really know what you are doing and have exhausted other options.
*/
setStyleAttributePreprocessor(property: string, process: (nextProp: mixed) => mixed) {
let value;

if (typeof ReactNativeStyleAttributes[property] === 'string') {
value = {};
} else if (typeof ReactNativeStyleAttributes[property] === 'object') {
value = ReactNativeStyleAttributes[property];
} else {
console.error(`${property} is not a valid style attribute`);
return;
}

if (__DEV__ && typeof value.process === 'function') {
console.warn(`Overwriting ${property} style attribute preprocessor`);
}

ReactNativeStyleAttributes[property] = { ...value, process };
},

/**
* Creates a StyleSheet style reference from the given object.
*/
Expand All @@ -172,5 +201,5 @@ module.exports = {
result[key] = ReactNativePropRegistry.register(obj[key]);
}
return result;
}
},
};

0 comments on commit 6ed4876

Please sign in to comment.