Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
43c6a4f
feat(defaultProfiles): Providing default profiles
rgommezz Jul 28, 2017
d81f1a8
feat(defaultProfiles): Merging defaults in PaletteProvider
rgommezz Jul 28, 2017
0f26995
Addressing flow issues
rgommezz Jul 28, 2017
0f49067
Passing palette with defaults to connected components and event emitter
rgommezz Aug 1, 2017
665bfeb
Attempting to solve flow errors
rgommezz Aug 1, 2017
2d564b4
Small fix
rgommezz Aug 1, 2017
d263d35
fix flow error
zamotany Aug 1, 2017
0d2a8d0
fix and remove flow ignore comment
zamotany Aug 1, 2017
d971eef
remove globalDefaults from withPalette
zamotany Aug 1, 2017
bb7cd13
replace default export with named one for create function
zamotany Aug 1, 2017
b857638
this.props.defaults validator function
rgommezz Aug 1, 2017
49f5495
Unit tests for validateDefaults
rgommezz Aug 1, 2017
7a92c47
Fixing unit tests
rgommezz Aug 1, 2017
b1434b4
Disabling require flow parameter type rule
rgommezz Aug 1, 2017
6f59268
Defaults should only be provied for the types specified by the user
rgommezz Aug 1, 2017
0f1c7c1
Separating createMaterialPalette into its own module
rgommezz Aug 1, 2017
c8de240
Unit test for PaletteProvider merge with defaults
rgommezz Aug 1, 2017
3b70ee7
Not duplicating logic
rgommezz Aug 1, 2017
41c95bd
Unit test for createMaterialPalette
rgommezz Aug 1, 2017
95d5ae4
Adding artifacts and fixing async test for palette
rgommezz Aug 3, 2017
f564ad1
Trying out different path for coverage
rgommezz Aug 3, 2017
8054f5b
Trying out different path for coverage
rgommezz Aug 3, 2017
6ba98c4
100% test coverage on utils
rgommezz Aug 3, 2017
1578bf5
100% test coverage for createMaterialPalette
rgommezz Aug 3, 2017
57e1576
100% coverage, fucking genious?
rgommezz Aug 3, 2017
993bfe1
removing console.log
rgommezz Aug 3, 2017
fef3d01
simplifying mock
rgommezz Aug 3, 2017
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
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ jobs:
- v1-dependencies

- run: yarn

- save_cache:
paths:
- node_modules
Expand All @@ -33,3 +32,5 @@ jobs:
# run flow and unit tests!
- run: yarn run flow
- run: yarn run jest:coverage
- store_artifacts:
path: coverage
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ create: (image: Image, options?: Options) => Promise<PaletteInstance>

##### Creating a palette from a network resource, with 'vibrant' color profile, maximumColorCount = 16 and the whole region of the image (default behaviour)
```js
import MaterialPalette from "react-native-material-palette";
import { createMaterialPalette } from "react-native-material-palette";

const palette = await MaterialPalette.create({ uri: 'http://dummySite/images/yummy.jpg' });
const palette = await createMaterialPalette({ uri: 'http://dummySite/images/yummy.jpg' });
```

##### Creating a palette from an internal image asset, with 'muted' and 'lightVibrant' color profiles, maximumColorCount = 32 and a specific region of the image
```js
import MaterialPalette from "react-native-material-palette";
import { createMaterialPalette } from "react-native-material-palette";

const palette = await MaterialPalette.create(require('./assets/image.jpg'), {
const palette = await createMaterialPalette(require('./assets/image.jpg'), {
region: { top: 0, left: 0, bottom: 50, right: 50},
maximumColorCount: 32,
type: ['muted', 'lightVibrant'],
Expand Down
29 changes: 2 additions & 27 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

## `MaterialPaletteProvider`

__Also available from the default import:__ `MaterialPalette.PaletteProvider`

### Example of usage:
```javascript
import React from 'react';
Expand All @@ -30,16 +28,6 @@ class App extends React.Component {
}
```

> You can import the component directly, as a named import:
> ```javascript
> import { MaterialPaletteProvider } from 'react-native-material-palette';
> ```
> or using the default import and accessing the component using `PaletteProvider` property:
> ```javascript
> import MaterialPalette from 'react-native-material-palette';
> // MaterialPalette.PaletteProvider
> ```

### Description
`MaterialPaletteProvider` is a component, which handles palette creation and provides the access to the palette instance for _connected_ components (via `withMaterialPalette`) using context. Ideally, `MaterialPaletteProvider` should be placed at the top of components tree, so that all nested components can _connect_ to it. By default it will render `null` when the palette is being created unless either `forceRender` or `LoaderComponent` is specified.

Expand All @@ -53,8 +41,7 @@ The concept is very similar to `Provider` component from `react-redux`.
type Options = {
region?: { top: number, left: number, bottom: number, right: number },
maximumColorCount?: number = 16,
type?: ColorProfile = 'vibrant',
types?: Array<ColorProfile> = []
type?: ColorProfile | Array<ColorProfile> = 'vibrant',
}
```

Expand Down Expand Up @@ -88,16 +75,14 @@ The concept is very similar to `Provider` component from `react-redux`.

* `onInit?: () => void` - (optional) - Init handler, called when the `MaterialPaletteProvider` is just about to start creating the palette.

* `onFinish?: (palette: PaletteInstance, globalDefaults: PaletteDefaults) => void` - (optional) - Finish handler, called when the palette is created, but before it gets propagated to _connected_ components - use it, if you want to mutate the palette instance.
* `onFinish?: (palette: PaletteInstance) => void` - (optional) - Finish handler, called when the palette is created, but before it gets propagated to _connected_ components - use it, if you want to mutate the palette instance. If some profiles are not available for the provided image, the defaults will apply, taking precedence the ones you passed to the component as `this.props.defaults`.

* `children: React$Element<*>`, - (__required__) - Children elements - the rest of your app's component tree.

--------------

## `withMaterialPalette`

__Also available from the default import:__ `MaterialPalette.withPalette`

### Example of usage:
```javascript
import React from 'react';
Expand All @@ -112,16 +97,6 @@ export default withMaterialPalette(
)(Text);
```

> You can import the function directly, as a named import:
> ```javascript
> import { withMaterialPalette } from 'react-native-material-palette';
> ```
> or using the default import and accessing the component using `withPalette` property:
> ```javascript
> import MaterialPalette from 'react-native-material-palette';
> // MaterialPalette.withPalette
> ```

### Description
`withMaterialPalette` is a function that returns a Higher Order Component (HOC), which allows to seemlessy _connect_ to the `MaterialPaletteProvider` and get the palette instance via context.

Expand Down
4 changes: 2 additions & 2 deletions example/index.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, Image } from 'react-native';

import MaterialPalette from 'react-native-material-palette';
import { createMaterialPalette } from 'react-native-material-palette';

export default class TestPalette extends Component {
state = {
Expand All @@ -16,7 +16,7 @@ export default class TestPalette extends Component {
};

async componentDidMount() {
const palette = await MaterialPalette.create(
const palette = await createMaterialPalette(
require('./assets/wroclaw.jpg'), // eslint-disable-line global-require
{
type: ['lightMuted', 'darkVibrant', 'vibrant'],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
"boolean"
],
"flowtype/no-weak-types": 1,
"flowtype/require-parameter-type": 2,
"flowtype/require-parameter-type": 0,
"flowtype/require-return-type": [
0,
"always",
Expand Down
72 changes: 61 additions & 11 deletions src/PaletteProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import createEventEmitter from './createEventEmitter';
import MaterialPalette from './index';
import { createMaterialPalette } from './index';
import { defaultSwatches } from './constants/defaults';
import { validateDefaults } from './utils/validateCreatePaletteArgs';

import type { PaletteInstance, Image, Options, PaletteDefaults } from './types';
import type {
PaletteInstance,
Image,
Options,
PaletteDefaults,
ColorProfile,
} from './types';

export const KEY = '__react-native-material-palette__';

Expand Down Expand Up @@ -37,10 +45,7 @@ type Props = {
/**
* Finish handler, called right after the palette is generated
*/
onFinish?: (
palette: PaletteInstance,
globalDefaults: PaletteDefaults,
) => void,
onFinish?: (palette: PaletteInstance) => void,
/**
* Render the children regardless whether palette is still being created, does not
* take effect if `LoaderComponent` is specified
Expand Down Expand Up @@ -93,17 +98,62 @@ export default class MaterialPaletteProvider
};
}

_mergeWithDefaults(palette: PaletteInstance) {
const globalDefaultsForTypesProvided = ((Object.keys(
palette,
): any): ColorProfile[]).reduce(
(acc, profile) => ({
...acc,
[profile]: defaultSwatches[profile],
}),
{},
);

const defaults = {
...globalDefaultsForTypesProvided,
...((Object.keys(
this.props.defaults || {},
): any): ColorProfile[]).reduce(
(acc: *, profile: ColorProfile) => ({
...acc,
[profile]: {
...(this.props.defaults && this.props.defaults[profile]
? this.props.defaults[profile]
: defaultSwatches[profile]),
population: 0,
},
}),
{},
),
};
return {
...defaults,
...((Object.keys(palette): any): ColorProfile[])
.filter((profile: ColorProfile) => !!palette[profile]) // Stripping out unavailable profiles
.reduce(
(acc: *, profile: ColorProfile) => ({
...acc,
[profile]: palette[profile],
}),
{},
),
};
}

componentWillMount() {
if (this.props.defaults) {
validateDefaults(this.props.defaults);
}
execIfFunction(this.props.onInit);
MaterialPalette.create(this.props.image, this.props.options)
createMaterialPalette(this.props.image, this.props.options)
.then((palette: PaletteInstance) => {
execIfFunction(this.props.onFinish, palette, this.props.defaults);
const paletteWithDefaults = this._mergeWithDefaults(palette);
execIfFunction(this.props.onFinish, paletteWithDefaults);
if (!this.props.forceRender) {
this.setState({ palette });
this.setState({ palette: paletteWithDefaults });
}
this.eventEmitter.publish({
palette,
globalDefaults: this.props.defaults,
palette: paletteWithDefaults,
});
})
.catch((error: Error) => {
Expand Down
Loading