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

Add support for useTheme hook #84

Merged
merged 16 commits into from
Feb 11, 2019
26 changes: 13 additions & 13 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
{
"dist/theming.js": {
"bundled": 49098,
"minified": 16242,
"gzipped": 5191
"bundled": 49491,
"minified": 16411,
"gzipped": 5229
},
"dist/theming.min.js": {
"bundled": 17490,
"minified": 6636,
"gzipped": 2485
"bundled": 17790,
"minified": 6729,
"gzipped": 2507
},
"dist/theming.cjs.js": {
"bundled": 5494,
"minified": 3494,
"gzipped": 1219
"bundled": 5914,
"minified": 3787,
"gzipped": 1265
},
"dist/theming.esm.js": {
"bundled": 5050,
"minified": 3122,
"gzipped": 1140,
"bundled": 5442,
"minified": 3389,
"gzipped": 1186,
"treeshaked": {
"rollup": {
"code": 1484,
"import_statements": 147
},
"webpack": {
"code": 2896
"code": 2976
}
}
}
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Next

- Improve bundle size ([#83](https://github.com/cssinjs/theming/pull/83))
- Add useTheme hook ([#84](https://github.com/cssinjs/theming/pull/84))

### 3.0.3 (2019-1-20)

Expand Down
34 changes: 28 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ See [Motivation](#motivation) for details.
* [API](#api)
* [ThemeProvider](#themeprovider)
* [withTheme](#withthemecomponent)
* [useTheme](#usetheme)
* [createTheming](#createthemingcustomchannel)
* [Credits](#credits)
* [License](#license)
Expand Down Expand Up @@ -218,6 +219,25 @@ export default App;

The `withTheme` HOC supports the new React forwardRef API so you can use the regular ref prop.

### useTheme

When you are on React 16.8 higher you will be able to use the `useTheme` hook which will return the theme object.

Usage with Component:

```jsx
import React from 'react';
import { useTheme } from 'theming';

const DemoBox = () => {
const theme = useTheme();
console.log(theme);
return (<div />);
}

export default Demobox;
```

### createTheming(context)

Function to create `ThemeProvider` and `withTheme` with custom context.
Expand All @@ -226,23 +246,25 @@ The context you pass in is used.
#### context

Type: `Object`
Result: `Object { withTheme, ThemeProvider }`
Result: `Object { withTheme, ThemeProvider, useTheme }`

`withTheme` and `ThemeProvider` use the context passed to `createTheming`.
`withTheme`, `ThemeProvider` and `useTheme` will use the context passed to `createTheming`.

Note: You will only be able to use `useTheme` when you are on React version 16.8 or higher.

```js
import { createTheming } from 'theming';
import createReactContext from 'create-react-context';

const context = createReactContext({});
import React from 'react';

const context = React.createContext({});
const theming = createTheming(context);

const { withTheme, ThemeProvider } = theming;
const { withTheme, ThemeProvider, useTheme } = theming;

export default {
withTheme,
ThemeProvider,
useTheme,
};
```

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@
"eslint-config-jss": "^5.0.1",
"flow-bin": "^0.88.0",
"nyc": "^13.1.0",
"react": "^16.6.0",
"react-test-renderer": "^16.6.0",
"react": "^16.8.0",
"react-test-renderer": "^16.8.0",
"rimraf": "^2.6.1",
"rollup": "^0.66.6",
"rollup-plugin-babel": "^4.0.3",
Expand Down
17 changes: 17 additions & 0 deletions src/create-use-theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @flow

import React, { type Context } from 'react';
import warning from 'tiny-warning';
import isObject from './is-object';

export default function createUseTheme<Theme>(context: Context<Theme>) {
HenriBeck marked this conversation as resolved.
Show resolved Hide resolved
const useTheme = () => {
const theme = React.useContext(context);

warning(isObject(theme), '[theming] Please use useTheme only with the ThemeProvider');

return theme;
};

return useTheme;
}
5 changes: 5 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,27 @@ interface ThemeProviderProps<Theme> {

type ThemeProviderFactory<Theme> = React.ComponentType<ThemeProviderProps<Theme>>;

type UseThemeFactory<Theme> = () => Theme;

interface Theming<Theme> {
context: React.Context<Theme>,
withTheme: WithThemeFactory<Theme>,
ThemeProvider: ThemeProviderFactory<Theme>,
useTheme: UseThemeFactory<Theme>,
}

declare function createTheming<Theme>(context: React.Context<Theme>): Theming<Theme>;

declare const withTheme: WithThemeFactory<DefaultTheme>;
declare const ThemeProvider: ThemeProviderFactory<DefaultTheme>;
declare const ThemeContext: React.Context<DefaultTheme>;
declare const useTheme: UseThemeFactory<DefaultTheme>;

export {
ThemeContext,
createTheming,
withTheme,
useTheme,
ThemeProvider,
ThemeProviderProps,
Theming,
Expand Down
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createContext, type Context } from 'react';

import createThemeProvider, { type ThemeProviderProps } from './create-theme-provider';
import createWithTheme from './create-with-theme';
import createUseTheme from './create-use-theme';

type ExtractReturnType<Theme> = <ReturnType>(
(context: Context<Theme>) => ReturnType
Expand All @@ -13,6 +14,7 @@ interface Theming<Theme> {
context: Context<Theme>,
withTheme: $Call<ExtractReturnType<Theme>, typeof createWithTheme>,
ThemeProvider: $Call<ExtractReturnType<Theme>, typeof createThemeProvider>,
useTheme: $Call<ExtractReturnType<Theme>, typeof createUseTheme>,
}

const ThemeContext = createContext<{} | void>();
Expand All @@ -21,13 +23,15 @@ function createTheming<Theme>(context: Context<Theme>): Theming<Theme> {
return {
context,
withTheme: createWithTheme(context),
useTheme: createUseTheme(context),
ThemeProvider: createThemeProvider(context),
};
}

const {
withTheme,
ThemeProvider,
useTheme,
} = createTheming(ThemeContext);

export type {
Expand All @@ -36,6 +40,7 @@ export type {
};

export {
useTheme,
ThemeContext,
withTheme,
createTheming,
Expand Down
2 changes: 1 addition & 1 deletion src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ test('createTheming()\'s key names', (t) => {
const context = createContext({});
const theming = createTheming(context);
const actual = Object.keys(theming);
const expected = ['context', 'withTheme', 'ThemeProvider'];
const expected = ['context', 'withTheme', 'useTheme', 'ThemeProvider'];

t.deepEqual(
actual,
Expand Down
37 changes: 21 additions & 16 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5400,30 +5400,35 @@ react-display-name@^0.2.4:
resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.4.tgz#e2a670b81d79a2204335510c01246f4c92ff12cf"
integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA==

react-is@^16.3.2, react-is@^16.6.0:
react-is@^16.3.2:
version "16.6.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.6.0.tgz#456645144581a6e99f6816ae2bd24ee94bdd0c01"
integrity sha512-q8U7k0Fi7oxF1HvQgyBjPwDXeMplEsArnKt2iYhuIF86+GBbgLHdAmokL3XUFjTd7Q363OSNG55FOGUdONVn1g==

react-test-renderer@^16.6.0:
version "16.6.0"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.6.0.tgz#fe490096bed55c3f4e92c023da3b89f9d03fceb3"
integrity sha512-w+Y3YT7OX1LP5KO7HCd0YR34Ol1qmISHaooPNMRYa6QzmwtcWhEGuZPr34wO8UCBIokswuhyLQUq7rjPDcEtJA==
react-is@^16.8.1:
version "16.8.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.1.tgz#a80141e246eb894824fb4f2901c0c50ef31d4cdb"
integrity sha512-ioMCzVDWvCvKD8eeT+iukyWrBGrA3DiFYkXfBsVYIRdaREZuBjENG+KjrikavCLasozqRWTwFUagU/O4vPpRMA==

react-test-renderer@^16.8.0:
version "16.8.1"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.1.tgz#72845ad9269be526126e97853311982f781767be"
integrity sha512-Bd21TN3+YVl6GZwav6O0T6m5UwGfOj+2+xZH5VH93ToD6M5uclN/c+R1DGX49ueG413KZPUx7Kw3sOYz2aJgfg==
dependencies:
object-assign "^4.1.1"
prop-types "^15.6.2"
react-is "^16.6.0"
scheduler "^0.10.0"
react-is "^16.8.1"
scheduler "^0.13.1"

react@^16.6.0:
version "16.6.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.6.0.tgz#b34761cfaf3e30f5508bc732fb4736730b7da246"
integrity sha512-zJPnx/jKtuOEXCbQ9BKaxDMxR0001/hzxXwYxG8septeyYGfsgAei6NgfbVgOhbY1WOP2o3VPs/E9HaN+9hV3Q==
react@^16.8.0:
version "16.8.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.8.1.tgz#ae11831f6cb2a05d58603a976afc8a558e852c4a"
integrity sha512-wLw5CFGPdo7p/AgteFz7GblI2JPOos0+biSoxf1FPsGxWQZdN/pj6oToJs1crn61DL3Ln7mN86uZ4j74p31ELQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.10.0"
scheduler "^0.13.1"

read-pkg-up@^2.0.0:
version "2.0.0"
Expand Down Expand Up @@ -5866,10 +5871,10 @@ sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==

scheduler@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1"
integrity sha512-+TSTVTCBAA3h8Anei3haDc1IRwMeDmtI/y/o3iBe3Mjl2vwYF9DtPDt929HyRmV/e7au7CLu8sc4C4W0VOs29w==
scheduler@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.1.tgz#1a217df1bfaabaf4f1b92a9127d5d732d85a9591"
integrity sha512-VJKOkiKIN2/6NOoexuypwSrybx13MY7NSy9RNt8wPvZDMRT1CW6qlpF5jXRToXNHz3uWzbm2elNpZfXfGPqP9A==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
Expand Down