├── .babelrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── package.json
├── src
├── Consumer.js
├── Provider.js
├── __tests__
│ ├── Consumer.spec.js
│ └── Provider.spec.js
├── createContext.js
└── index.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "current"
8 | }
9 | }
10 | ]
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | lib
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 | .gitignore
3 | node_modules
4 | .npmignore
5 | .travis.yml
6 | yarn.lock
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | cache: yarn
3 | notifications:
4 | email: false
5 | node_js:
6 | - '10'
7 | - '9'
8 | - '8'
9 | script:
10 | - yarn build
11 | - yarn test
12 | after_success:
13 | - npm run travis-deploy-once "npm run semantic-release"
14 | branches:
15 | except:
16 | - /^v\d+\.\d+\.\d+$/
17 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ## [1.0.1](https://github.com/zephraph/vue-context-api/compare/v1.0.0...v1.0.1) (2018-05-22)
3 |
4 |
5 | ### Bug Fixes
6 |
7 | * Add vue as a peer dependency ([97da310](https://github.com/zephraph/vue-context-api/commit/97da310))
8 |
9 |
10 | # 1.0.0 (2018-05-22)
11 |
12 |
13 | ### Bug Fixes
14 |
15 | * Remove console statement ([9c1167f](https://github.com/zephraph/vue-context-api/commit/9c1167f))
16 | * **Consumer:** Render child content when slot-scope isn't defined. Provide a warning. ([c89a8d1](https://github.com/zephraph/vue-context-api/commit/c89a8d1))
17 | * **Provider:** Unwrap from provider object, don't overwrite context value with undefined prop ([04f3b3a](https://github.com/zephraph/vue-context-api/commit/04f3b3a))
18 |
19 |
20 | ### Features
21 |
22 | * **Update release process:** Adds semantic-release and commitizen to enable automatic, easy release ([100fa49](https://github.com/zephraph/vue-context-api/commit/100fa49))
23 | * Implement createContext, Provider, and Consumer apis ([b499b0b](https://github.com/zephraph/vue-context-api/commit/b499b0b))
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Zephraph
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-context-api
2 |
3 | A react-like context component api for Vue.js
4 |
5 | ## Installation
6 |
7 | ```
8 | npm install --save vue-context-api
9 | ```
10 |
11 | or
12 |
13 | ```
14 | yarn add vue-context-api
15 | ```
16 |
17 | ## Example Usage
18 |
19 | See a [live example](https://codesandbox.io/s/nrjz7ky4mp).
20 |
21 | **ThemeContext.js**
22 |
23 | ```javascript
24 | import { createContext } from "vue-context-api";
25 |
26 | // The argument passed to createContext is the default context value
27 | export const { Provider, Consumer } = createContext("light");
28 | ```
29 |
30 | **App.vue**
31 |
32 | ```html
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
51 | ```
52 |
53 | **ThemedButton.vue**
54 |
55 | ```html
56 |
57 |
58 |
59 |
60 |
61 |
62 |
78 | ```
79 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-context-api",
3 | "version": "1.0.1",
4 | "description": "A react-like context api for Vue",
5 | "keywords": [
6 | "vue",
7 | "react",
8 | "context",
9 | "api",
10 | "provider",
11 | "consumer",
12 | "inject",
13 | "provide"
14 | ],
15 | "source": "src/index.js",
16 | "main": "lib/vue-context-api.js",
17 | "umd:main": "lib/vue-context-api.umd.js",
18 | "module": "lib/vue-context-api.esm.js",
19 | "repository": "https://github.com/zephraph/vue-context-api",
20 | "author": "zephraph ",
21 | "license": "MIT",
22 | "scripts": {
23 | "build": "microbundle",
24 | "dev": "microbundle watch",
25 | "test": "jest",
26 | "semantic-release": "semantic-release",
27 | "travis-deploy-once": "travis-deploy-once"
28 | },
29 | "release": {
30 | "verifyConditions": [
31 | "@semantic-release/changelog",
32 | "@semantic-release/npm",
33 | "@semantic-release/git"
34 | ],
35 | "prepare": [
36 | "@semantic-release/changelog",
37 | "@semantic-release/npm",
38 | "@semantic-release/git"
39 | ],
40 | "publish": [
41 | "@semantic-release/github",
42 | "@semantic-release/npm"
43 | ]
44 | },
45 | "devDependencies": {
46 | "@babel/core": "^7.0.0-beta.47",
47 | "@babel/preset-env": "^7.0.0-beta.47",
48 | "@semantic-release/changelog": "^2.0.2",
49 | "@semantic-release/git": "^5.0.0",
50 | "@vue/test-utils": "^1.0.0-beta.16",
51 | "babel-core": "^7.0.0-0",
52 | "babel-jest": "^22.4.4",
53 | "cz-conventional-changelog": "^2.1.0",
54 | "jest": "^22.4.4",
55 | "microbundle": "^0.4.4",
56 | "semantic-release": "^15.5.0",
57 | "travis-deploy-once": "^5.0.0",
58 | "vue": "^2.5.16",
59 | "vue-template-compiler": "^2.5.16"
60 | },
61 | "peerDependencies": {
62 | "vue": "^2.5.0"
63 | },
64 | "config": {
65 | "commitizen": {
66 | "path": "./node_modules/cz-conventional-changelog"
67 | }
68 | },
69 | "jest": {
70 | "transform": {
71 | "^.+\\.js$": "babel-jest"
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Consumer.js:
--------------------------------------------------------------------------------
1 | export default function Consumer(context) {
2 | return {
3 | data: () => ({
4 | context
5 | }),
6 | render(h) {
7 | if (!this.$scopedSlots.default) {
8 | console.warn("Context consumer expected to define slot-scope");
9 | return this.$slots.default[0];
10 | }
11 | return this.$scopedSlots.default(this.context.value);
12 | }
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/src/Provider.js:
--------------------------------------------------------------------------------
1 | export default function Provider(context, defaultValue) {
2 | return {
3 | props: {
4 | value: {
5 | default: () => defaultValue
6 | }
7 | },
8 | created() {
9 | if (this.value !== undefined) {
10 | context.value = this.value;
11 | }
12 | },
13 | watch: {
14 | value(v) {
15 | context.value = v;
16 | }
17 | },
18 | render(h) {
19 | return this.$slots.default[0];
20 | }
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/src/__tests__/Consumer.spec.js:
--------------------------------------------------------------------------------
1 | import consumer from "../Consumer";
2 | import { mount } from "@vue/test-utils";
3 |
4 | const registerComponent = context => ({
5 | components: {
6 | Consumer: consumer(context)
7 | }
8 | });
9 |
10 | const ConsumerComponent = context => ({
11 | template: `
12 |
13 |
14 | {{ contextValue }}
15 |
16 |
17 | `,
18 | ...registerComponent(context)
19 | });
20 |
21 | const MalformedConsumerComponent = context => ({
22 | template: `
23 |
24 |
25 | test
26 |
27 |
28 | `,
29 | ...registerComponent(context)
30 | });
31 |
32 | describe("Consumer", () => {
33 | it("should return the given context as data", () => {
34 | const s = Symbol();
35 | expect(consumer(s).data().context).toBe(s);
36 | });
37 |
38 | it("should render the context's value", () => {
39 | const Consumer = ConsumerComponent({ value: "test-context" });
40 | const wrapper = mount(Consumer);
41 | expect(wrapper.html()).toContain("test-context");
42 | });
43 |
44 | it("should not fail to render if consumer is missing slot-scope", () => {
45 | const Consumer = MalformedConsumerComponent({ value: "test-context" });
46 | const wrapper = mount(Consumer);
47 | expect(wrapper.html()).toContain("test");
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/src/__tests__/Provider.spec.js:
--------------------------------------------------------------------------------
1 | import provider from "../Provider";
2 | import { mount } from "@vue/test-utils";
3 |
4 | describe("Provider", () => {
5 | it("should have a prop with the given default value", () => {
6 | const defaultValue = "TEST";
7 | const Provider = provider({}, defaultValue);
8 | const wrapper = mount(Provider, {
9 | slots: {
10 | default: "Test"
11 | }
12 | });
13 | expect(wrapper.props().value).toBe(defaultValue);
14 | });
15 |
16 | it("should not overwrite context if no prop provided", () => {
17 | let context = { value: "test" };
18 | const Provider = provider(context);
19 | const wrapper = mount(Provider, {
20 | slots: {
21 | default: "Test"
22 | }
23 | });
24 | expect(context.value).toBeDefined();
25 | });
26 |
27 | it("should update context when props change", () => {
28 | let context = { value: "test" };
29 | const Provider = provider(context);
30 | const wrapper = mount(Provider, {
31 | slots: {
32 | default: "Test"
33 | }
34 | });
35 | wrapper.setProps({ value: "123" });
36 | expect(context.value).toBe("123");
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/src/createContext.js:
--------------------------------------------------------------------------------
1 | import Provider from "./Provider";
2 | import Consumer from "./Consumer";
3 |
4 | export const createContext = defaultValue => {
5 | let context = {};
6 | return {
7 | Provider: Provider(context, defaultValue),
8 | Consumer: Consumer(context)
9 | };
10 | };
11 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { createContext } from "./createContext";
2 |
--------------------------------------------------------------------------------