Skip to content

Commit

Permalink
feat: Add theme method (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
diegohaz authored Aug 18, 2018
1 parent ff88b16 commit 1514664
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 422 deletions.
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,21 @@ const Button = styled.button`
- [prop](#prop)
- [Parameters](#parameters)
- [Examples](#examples)
- [ifProp](#ifprop)
- [theme](#theme)
- [Parameters](#parameters-1)
- [Examples](#examples-1)
- [ifNotProp](#ifnotprop)
- [ifProp](#ifprop)
- [Parameters](#parameters-2)
- [Examples](#examples-2)
- [withProp](#withprop)
- [ifNotProp](#ifnotprop)
- [Parameters](#parameters-3)
- [Examples](#examples-3)
- [switchProp](#switchprop)
- [withProp](#withprop)
- [Parameters](#parameters-4)
- [Examples](#examples-4)
- [switchProp](#switchprop)
- [Parameters](#parameters-5)
- [Examples](#examples-5)
- [Types](#types)
- [Needle](#needle)

Expand All @@ -115,6 +118,26 @@ const Button = styled.button`

Returns **PropsFn**

### theme

Same as `prop`, except that it returns `props.theme[path]` instead of
`props[path]`.

#### Parameters

- `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `defaultValue` **any**

#### Examples

```javascript
const Button = styled.button`
color: ${theme("button.color", "red")};
`;
```

Returns **PropsWithThemeFn**

### ifProp

Returns `pass` if prop is truthy. Otherwise returns `fail`
Expand Down
1 change: 1 addition & 0 deletions documentation.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
toc:
- prop
- theme
- ifProp
- ifNotProp
- withProp
Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,31 +49,31 @@
"babel-cli": "^6.18.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.6",
"babel-jest": "^23.4.0",
"babel-jest": "^23.4.2",
"babel-plugin-transform-flow-strip-types": "^6.21.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-1": "^6.24.1",
"benchmark": "^2.1.4",
"cross-env": "^5.2.0",
"documentation": "^8.0.0",
"eslint": "^5.1.0",
"eslint-config-airbnb-base": "^13.0.0",
"eslint-config-prettier": "^2.9.0",
"documentation": "^8.1.1",
"eslint": "^5.4.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-config-prettier": "^3.0.1",
"eslint-plugin-flowtype": "^2.50.0",
"eslint-plugin-flowtype-errors": "^3.6.0",
"eslint-plugin-import": "^2.13.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-prettier": "^2.6.2",
"flow-bin": "^0.76.0",
"flow-bin": "^0.79.1",
"flow-typed": "^2.5.1",
"jest-cli": "^23.4.1",
"jest-cli": "^23.5.0",
"opn-cli": "^3.1.0",
"prettier": "^1.13.7",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"prettier": "^1.14.2",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"rimraf": "^2.6.2",
"standard-version": "^4.4.0",
"styled-components": "^3.3.3",
"styled-tools": "^1.0.0",
"styled-components": "^3.4.2",
"styled-tools": "^1.2.0",
"typescript": "^3.0.1"
}
}
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export ifNotProp from "./ifNotProp";
export ifProp from "./ifProp";
export prop from "./prop";
export switchProp from "./switchProp";
export theme from "./theme";
export withProp from "./withProp";
21 changes: 21 additions & 0 deletions src/theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import prop from "./prop";

type PropsWithThemeFn = (props: { theme: any }) => any;

/**
* Same as `prop`, except that it returns `props.theme[path]` instead of
* `props[path]`.
* @example
* const Button = styled.button`
* color: ${theme("button.color", "red")};
* `;
*/
const theme = (path: string, defaultValue?: any): PropsWithThemeFn => props => {
if (typeof props.theme[path] !== "undefined") {
return props.theme[path];
}
return prop(path, defaultValue)(props.theme);
};

export default theme;
18 changes: 18 additions & 0 deletions test/theme.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import theme from "../src/theme";

test("string argument", () => {
expect(theme("color")({ theme: {} })).toBeUndefined();
expect(theme("color")({ theme: { color: "red" } })).toBe("red");
});

test("deep string argument", () => {
expect(theme("color.primary")({ theme: { color: {} } })).toBeUndefined();
expect(theme("color.primary")({ theme: { color: { primary: "red" } } })).toBe(
"red"
);
});

test("defaultValue", () => {
expect(theme("color", "red")({ theme: { color: "blue" } })).toBe("blue");
expect(theme("color.primary", "red")({ theme: { color: {} } })).toBe("red");
});
6 changes: 6 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ type Dictionary<T = any> = { [key: string]: T };
type PropsFn<ReturnType = any> = (props?: Dictionary) => ReturnType;
type Needle = string | PropsFn;

type PropsWithThemeFn<ReturnType = any> = (
props: Dictionary & { theme: Dictionary }
) => ReturnType;

export function ifProp<Pass = string, Fail = string>(
test: Needle | Needle[] | Dictionary,
pass?: Pass,
Expand All @@ -22,6 +26,8 @@ export function switchProp<T = any, DefaultCase = undefined>(
defaultCase?: DefaultCase
): PropsFn<T | DefaultCase>;

export function theme(path: string, defaultValue?: any): PropsWithThemeFn;

export function withProp<T = any>(
needle: Needle | Needle[],
fn: (...props: any[]) => T
Expand Down
5 changes: 4 additions & 1 deletion types/tests.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ifProp, ifNotProp, prop, switchProp, withProp } from "..";
import { ifProp, ifNotProp, prop, switchProp, withProp, theme } from "..";

ifProp("a", true)({ a: true });
ifProp("a", true, false)({ a: true });
Expand All @@ -16,5 +16,8 @@ switchProp("a", { a: true, b: "c" })({ a: true });
switchProp("a", { a: true, b: "c" }, 1)({ a: true });
switchProp("a", { a: true, b: "c" }, 1)({ a: "a" });

theme("a")({ theme: { a: true } })
theme("a", "b")({ theme: { a: true } })

withProp("a", (a: boolean) => a)({ a: false });
withProp(["a", "b"], (a: number, b: string) => b)({ a: false });
Loading

0 comments on commit 1514664

Please sign in to comment.