Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion packages/electrode-archetype-njs-module-dev
Submodule electrode-archetype-njs-module-dev deleted from 419782
3 changes: 3 additions & 0 deletions packages/electrode-react-context/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
extends:
- "./node_modules/electrode-archetype-njs-module-dev/config/eslint/.eslintrc-node"
229 changes: 229 additions & 0 deletions packages/electrode-react-context/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@

# Created by https://www.gitignore.io/api/osx,node

### OSX ###
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk


### Node ###
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

### Vim template
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
### GitBook template
# Node rules:
## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

## Dependency directory
## Commenting this out is preferred by some people, see
## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git
node_modules

# Book build output
_book

# eBook build output
*.epub
*.mobi
*.pdf
### TortoiseGit template
# Project-level settings
/.tgitconfig
### Xcode template
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
build/
DerivedData

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata

## Other
*.xccheckout
*.moved-aside
*.xcuserstate
### Emacs template
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*

# Org-mode
.org-id-locations
*_archive

# flymake-mode
*_flymake.*

# eshell files
/eshell/history
/eshell/lastdir

# elpa packages
/elpa/

# reftex files
*.rel

# AUCTeX auto folder
/auto/

# cask packages
.cask/
### OSX template
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio

*.iml

## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:

# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries

# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml

# Gradle:
# .idea/gradle.xml
# .idea/libraries

# Mongo Explorer plugin:
# .idea/mongoSettings.xml

## File-based project format:
*.ipr
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
/xclap.js
/.npmignore
.nyc_output
/test
/.eslintrc

99 changes: 99 additions & 0 deletions packages/electrode-react-context/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Electrode React Context

Higher order React component used to add an `app` object property to the global React context. Each Electrode application can pass arbitrary props to make available to components via `this.context.app` but at a minimum should include the hapi `request`.

## Installing

```
npm install electrode-react-context --save
```

## Usage

The typical way to use the context is when contructing the app router. The `electrodeContext` wrapper is used to construct the parent Route component.

~~~js
import electrodeContext from "electrode-react-context";
import uiConfig from "electrode-ui-config";

// This function is invoked both on client and server. The `request` will be undefined on the client.
export const createRoutes = (request) => {
return (
<Route path={uiConfig.fullPath()} component={electrodeContext(Page, {request})}>
<IndexRoute component={Home}/>
<Route path={uiConfig.fullPath("/status")} component={Status}/>
<Route path={uiConfig.fullPath("/store")} component={Store}/>
<Route path={uiConfig.fullPath("/analytics")} component={AnalyticsDemo}/>
<Route path={uiConfig.fullPath("/cookies")} component={CookiesDemo}/>
</Route>
);
};
~~~

Now all components in the app have access to an `app` property in the global context. This should be passed as the last argument to calls to functions exported by `electrode-ui-logger` and `electrode-cookies`. The `app.request` is needed for server-rendering since continuation local storage has been deprecated. By always passing in `app` component authors need not worry whether their component is rendering client or server-side.

~~~js
import log from "electrode-ui-logger";
import config from "electrode-ui-config";

export class Home extends React.Component {
constructor(props, context) {
super(props, context);
}

render() {
log.info("Rendering Home component", this.context.app);
return (
<Well padded filled={false}>
<Button onClick={() => log.info("Hi button clicked!", this.context.app)}>
Hi! {config.ui.name} {config.ui.env}
</Button>
</Well>
);
}
}

Home.contextTypes = {
app: PropTypes.object
};
~~~

### Functional Components

Context is also available to functional components as the second argument. The `Home` component above could be re-written as:

~~~js
export const Home = (props, {app}) => {
log.info("Rendering Home component", app);
return (
<Well padded filled={false}>
<Button onClick={() => log.info("Hi button clicked!", app)}>
Hi! {config.ui.name} {config.ui.env}
</Button>
</Well>
);
};
~~~

## Working with cookies

The `electrode-cookies` module requires the `request` option when being invoked on the server. Since the `app` has the `request`, it can act as the `options` argument:

~~~js
import Cookies from "electrode-cookies";

const CookieComponent = (props, {app}) => {
const cookieValue = Cookies.get("cookieName", app);
return <div>{cookieValue}</div>;
};

CookieComponent.contextTypes = {
app: PropTypes.object
};
~~~

If you need to pass additional cookie specific options, you could do something like this:

~~~js
Cookies.get("cookieName", Object.assign({}, app, { matchSubStr: true }));
~~~
26 changes: 26 additions & 0 deletions packages/electrode-react-context/lib/context-provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use strict";
/* eslint-disable no-var */

var React = require("react");
var PropTypes = require("prop-types");
var createReactClass = require("create-react-class");

// This function is called both during SSR (from server/app.js) and CSR (client/app.jsx). The
// request arg will be undefined when called during CSR.
var contextProvider = function(Component, appContext) {
var ContextProvider = createReactClass({
childContextTypes: {
app: PropTypes.object
},
getChildContext: function() {
return {app: appContext};
},
render: function() {
return React.createElement(Component, this.props);
}
});

return ContextProvider;
};

module.exports = contextProvider;
Loading