accounts-ui/README.md

365 lines
13 KiB
Markdown
Raw Normal View History

2016-03-31 00:10:45 +02:00
# React Accounts UI
2016-03-28 22:34:50 +02:00
2016-04-02 12:59:50 +02:00
Current version 1.1.1
2016-03-28 22:34:50 +02:00
## Features
2016-03-31 00:10:45 +02:00
1. **[Easy to use](#using-react-accounts-ui)**, mixing the ideas of useraccounts configuration and accounts-ui that everyone already knows and loves.
3. **[Components](#components-available)** are everywhere, and extensible by replacing them on Accounts.ui.
4. **[Basic routing](#configuration)** included, redirections when the user clicks a link in an email or when signing in or out.
5. **[Unstyled](#styling)** is the default, no CSS included.
6. **[No password](#no-password-required)** sign up and sign in are included.
2016-03-30 17:30:26 +02:00
7. **[Extra fields](#extra-fields)** is now supported.
2016-03-31 05:13:06 +02:00
8. **[Server Side Rendering](#example-setup-using-flowrouter-meteor-13)** are supported, trough FlowRouter (SSR).
2016-03-31 00:42:18 +02:00
9. **[Extending](#create-your-own-styled-version)** to make your own custom form, for your app, or as a package, all components can be extended and customized.
2016-03-28 22:34:50 +02:00
2016-03-31 00:10:45 +02:00
## Styling
2016-03-31 00:17:54 +02:00
This package does not by standard come with any styling, you can easily [extend and make your own](#create-your-own-styled-version), here are a couple versions we've made for the typical use case:
2016-03-29 06:34:37 +02:00
2016-04-02 10:32:36 +02:00
* [**Basic**](https://atmospherejs.com/studiointeract/accounts-basic) `std:accounts-basic`
* [**Semantic UI**](https://atmospherejs.com/studiointeract/accounts-semantic) `std:accounts-semantic`
* [Bootstrap 3] (help out on this: http://github.com/studiointeract/accounts-bootstrap)
* [Material UI] (help out on this: http://github.com/studiointeract/accounts-material)
2016-03-29 06:35:41 +02:00
2016-03-31 00:17:54 +02:00
* Add your styled version here [Learn how](#create-your-own-styled-version)
2016-03-29 06:34:37 +02:00
2016-03-31 00:17:04 +02:00
## Installation
2016-04-02 10:32:36 +02:00
`meteor add std:accounts-ui`
2016-03-31 00:17:04 +02:00
2016-03-31 00:10:45 +02:00
## Configuration
We support the standard [configuration in the account-ui package](http://docs.meteor.com/#/full/accounts_ui_config). But have extended with some new options.
2016-03-31 00:14:52 +02:00
### Accounts.ui.config(options)
2016-03-31 00:10:45 +02:00
2016-04-02 10:32:36 +02:00
`import { Accounts } from 'meteor/std:accounts-ui`
2016-03-31 00:10:45 +02:00
Configure the behavior of `<Accounts.ui.LoginForm />`
**_Options:_**
* **requestPermissions**&nbsp;&nbsp;&nbsp; Object
Which [permissions](http://docs.meteor.com/#requestpermissions) to request from the user for each external service.
* **requestOfflineToken**&nbsp;&nbsp;&nbsp; Object
To ask the user for permission to act on their behalf when offline, map the relevant external service to true. Currently only supported with Google. See [Meteor.loginWithExternalService](http://docs.meteor.com/#meteor_loginwithexternalservice) for more details.
* **forceApprovalPrompt**&nbsp;&nbsp;&nbsp; Object
If true, forces the user to approve the app's permissions, even if previously approved. Currently only supported with Google.
* **passwordSignupFields**&nbsp;&nbsp;&nbsp; String
Which fields to display in the user creation form. One of `'USERNAME_AND_EMAIL'`, `'USERNAME_AND_OPTIONAL_EMAIL'`, `'USERNAME_ONLY'`, `'EMAIL_ONLY'`, `'USERNAME_AND_EMAIL_NO_PASSWORD'`, **`'EMAIL_ONLY_NO_PASSWORD'`** (**default**).
2016-03-31 00:10:45 +02:00
* **loginPath**&nbsp;&nbsp;&nbsp; String
Change the default path a user should be redirected to after a clicking a link in a mail provided to them from the accounts system, it could be a mail set to them when they have reset their password, verifying their email if the setting for `sendVerificationEmail` is turned on ([read more on accounts configuration ](http://docs.meteor.com/#/full/accounts_config)).
* **homeRoutePath**&nbsp;&nbsp;&nbsp; String
Set the path to where you would like the user to be redirected after a successful login or sign out.
2016-04-02 12:59:50 +02:00
* **onSubmitHook**&nbsp;&nbsp;&nbsp; function(error, state)&nbsp;&nbsp;&nbsp; **client**
2016-03-31 00:10:45 +02:00
Called when the LoginForm is being submitted: allows for custom actions to be taken on form submission. error contains possible errors occurred during the submission process, state specifies the LoginForm internal state from which the submission was triggered. A nice use case might be closing the modal or side-menu or dropdown showing LoginForm.
2016-04-02 12:59:50 +02:00
* **onPreSignUpHook**&nbsp;&nbsp;&nbsp; function(options)&nbsp;&nbsp;&nbsp; **client**
2016-03-31 00:10:45 +02:00
Called just before submitting the LoginForm for sign-up: allows for custom actions on the data being submitted. A nice use could be extending the user profile object accessing options.profile. to be taken on form submission. The plain text password is also provided for any reasonable use. If you return a promise, the submission will wait until you resolve it.
2016-04-02 12:59:50 +02:00
* **onPostSignUpHook**&nbsp;&nbsp;&nbsp; func(userId, info)&nbsp;&nbsp;&nbsp; **server**
2016-03-31 00:10:45 +02:00
Called server side, just after a successful user account creation, post submitting the pwdForm for sign-up: allows for custom actions on the data being submitted after we are sure a new user was successfully created. A common use might be applying roles to the user, as this is only possible after fully completing user creation in `alanning:roles`. The userId is available as the first parameter, so that user user object may be retrieved.
2016-04-02 12:59:50 +02:00
* **onPostSignUpHook**&nbsp;&nbsp;&nbsp; func(userId, info)&nbsp;&nbsp;&nbsp; **client**
2016-03-31 00:10:45 +02:00
Called client side, just after a successful user account creation, post submitting the pwdForm for sign-up: allows for custom actions on the data being submitted after we are sure a new user was successfully created. Default is **loginPath**.
2016-04-02 12:59:50 +02:00
* **onResetPasswordHook**&nbsp;&nbsp;&nbsp; function()
2016-03-31 00:10:45 +02:00
Change the default redirect behavior when the user clicks the link to reset their email sent from the system, i.e. you want a custom path for the reset password form. Default is **loginPath**.
* **onEnrollAccountHook**&nbsp;&nbsp;&nbsp; function()
Change the default redirect behavior when the user clicks the link to enroll for an account sent from the system, i.e. you want a custom path for the enrollment form. Learn more about [how to send enrollment emails](http://docs.meteor.com/#/full/accounts_sendenrollmentemail). Default is **loginPath**.
* **onVerifyEmailHook**&nbsp;&nbsp;&nbsp; function()
Change the default redirect behavior when the user clicks the link to verify their email sent from the system, i.e. you want a custom path after the user verifies their email or login with `NO_PASSWORD`. Default is **homeRoutePath**.
* **onSignedInHook**&nbsp;&nbsp;&nbsp; function()
Change the default redirect behavior when the user successfully login to your application, i.e. you want a custom path for the reset password form. Default is **homeRoutePath**.
* **onSignedOutHook**&nbsp;&nbsp;&nbsp; function()
Change the default redirect behavior when the user signs out using the LoginForm, i.e. you want a custom path after the user signs out. Default is **homeRoutePath**.
## No password required
2016-03-28 22:34:50 +02:00
2016-03-31 00:10:45 +02:00
This package provides a state that makes it possible to create and manage accounts without a password. The idea is simple, you always verify your email, so to login you enter your mail and the system emails you a link to login. The mail that is sent can be changed if needed, just [how you alter the email templates in accounts-base](http://docs.meteor.com/#/full/accounts_emailtemplates).
This is the default setting for **passwordSignupFields** in the [configuration](#configuration).
## Using React Accounts UI
### Example setup (Meteor 1.3)
`meteor add accounts-password`
2016-04-02 10:32:36 +02:00
`meteor add std:accounts-ui`
2016-03-31 00:10:45 +02:00
```javascript
import React from 'react';
2016-04-01 08:18:26 +02:00
import { Accounts } from 'meteor/std:react-accounts-ui';
2016-03-31 00:10:45 +02:00
Accounts.ui.config({
passwordSignupFields: 'NO_PASSWORD',
loginPath: '/',
});
if (Meteor.isClient) {
ReactDOM.render(<Accounts.ui.LoginForm />, document.body)
}
2016-03-28 22:34:50 +02:00
2016-03-31 00:10:45 +02:00
```
2016-03-28 22:34:50 +02:00
2016-03-31 00:10:45 +02:00
### Example setup using FlowRouter (Meteor 1.3)
2016-03-28 22:34:50 +02:00
2016-03-28 22:40:55 +02:00
`meteor add accounts-password`
2016-04-02 10:32:36 +02:00
`meteor add std:accounts-ui`
2016-03-29 02:38:29 +02:00
`meteor add kadira:flow-router-ssr`
2016-03-28 22:38:18 +02:00
2016-03-28 22:34:50 +02:00
```javascript
import React from 'react';
2016-04-02 10:32:36 +02:00
import { Accounts } from 'meteor/std:accounts-ui';
2016-03-31 00:10:45 +02:00
import { FlowRouter } from 'meteor/kadira:flow-router-ssr';
2016-03-28 22:34:50 +02:00
Accounts.ui.config({
2016-03-29 00:39:15 +02:00
passwordSignupFields: 'NO_PASSWORD',
2016-03-29 04:03:32 +02:00
loginPath: '/login',
onSignedInHook: () => FlowRouter.go('/general'),
onSignedOutHook: () => FlowRouter.go('/')
2016-03-28 22:34:50 +02:00
});
FlowRouter.route("/login", {
action(params) {
mount(MainLayout, {
content: <Accounts.ui.LoginForm />
});
}
});
```
2016-03-28 22:53:14 +02:00
2016-04-01 08:18:26 +02:00
### Example setup using the STATES api.
You can define the inital state you want in your route for the component,
as set the path where the links in the component link to, for example below we
have one route for /login and one for /signup.
`meteor add accounts-password`
2016-04-02 10:32:36 +02:00
`meteor add std:accounts-ui`
2016-04-01 08:18:26 +02:00
`meteor add kadira:flow-router-ssr`
```javascript
T9n.setLanguage('en');
Accounts.config({
sendVerificationEmail: true,
forbidClientAccountCreation: false
});
Accounts.ui.config({
passwordSignupFields: 'USERNAME_AND_OPTIONAL_EMAIL',
loginPath: '/login'
});
FlowRouter.route("/login", {
action(params) {
mount(MainLayout, {
content: <Accounts.ui.LoginForm {...{
formState: STATES.SIGN_IN,
signUpPath: '/signup'
}} />
});
}
});
FlowRouter.route("/signup", {
action(params) {
mount(MainLayout, {
content: <Accounts.ui.LoginForm {...{
formState: STATES.SIGN_UP,
loginPath: '/login'
}} />
});
}
});
```
2016-03-31 00:10:45 +02:00
## Create your own styled version
2016-03-28 22:53:14 +02:00
2016-04-02 10:32:36 +02:00
**To you who are a package author**, its easy to write extensions for `std:accounts-ui` by importing and export like the following example:
2016-03-28 22:53:14 +02:00
```javascript
// package.js
Package.describe({
2016-04-02 10:32:36 +02:00
name: 'author:accounts-bootstrap',
2016-03-28 22:53:14 +02:00
version: '1.0.0',
summary: 'Bootstrap Accounts UI for React in Meteor 1.3',
2016-04-02 10:32:36 +02:00
git: 'https://github.com/author/accounts-bootstrap',
2016-03-28 22:53:14 +02:00
documentation: 'README.md'
});
Package.onUse(function(api) {
2016-03-29 00:41:02 +02:00
api.versionsFrom('1.3');
2016-03-28 22:53:14 +02:00
api.use('ecmascript');
2016-04-02 10:32:36 +02:00
api.use('std:accounts-ui');
2016-03-28 22:53:14 +02:00
api.imply('session');
2016-03-28 22:53:14 +02:00
api.mainModule('main.jsx');
});
```
2016-03-29 00:39:15 +02:00
2016-03-29 03:16:01 +02:00
```javascript
2016-03-29 04:47:40 +02:00
// package.json
2016-03-29 03:16:01 +02:00
{
2016-04-02 10:32:36 +02:00
"name": "accounts-bootstrap",
2016-03-29 03:16:01 +02:00
"description": "Bootstrap Accounts UI for React in Meteor 1.3",
"repository": {
"type": "git",
2016-04-02 10:32:36 +02:00
"url": "https://github.com/author/accounts-bootstrap.git"
2016-03-29 03:16:01 +02:00
},
"keywords": [
"react",
"meteor",
"accounts",
"tracker"
],
"author": "author",
"license": "MIT",
"bugs": {
2016-04-02 10:32:36 +02:00
"url": "https://github.com/author/accounts-bootstrap/issues"
2016-03-29 03:16:01 +02:00
},
2016-04-02 10:32:36 +02:00
"homepage": "https://github.com/author/accounts-bootstrap",
2016-03-29 03:16:01 +02:00
"dependencies": {
"react": "^15.x",
"react-dom": "^15.x",
2016-03-31 00:21:17 +02:00
"tracker-component": "^1.3.13"
2016-03-29 03:16:01 +02:00
}
}
```
2016-03-31 00:10:45 +02:00
To install the dependencies added in your package.json run:
2016-03-29 04:47:40 +02:00
`npm i`
2016-03-28 22:53:14 +02:00
```javascript
// main.jsx
import React from 'react';
2016-04-02 10:32:36 +02:00
import { Accounts } from 'meteor/std:accounts-ui';
2016-03-28 22:53:14 +02:00
/**
* Form.propTypes = {
* fields: React.PropTypes.object.isRequired,
* buttons: React.PropTypes.object.isRequired,
* error: React.PropTypes.string,
* ready: React.PropTypes.bool
* };
*/
class Form extends Accounts.ui.Form {
render() {
const { fields, buttons, error, message, ready = true} = this.props;
return (
<form className={ready ? "ready" : null} onSubmit={ evt => evt.preventDefault() } className="accounts-ui">
<Accounts.ui.Fields fields={ fields } />
<Accounts.ui.Buttons buttons={ buttons } />
<Accounts.ui.FormMessage message={ message } />
</form>
);
}
}
class Buttons extends Accounts.ui.Buttons {}
class Button extends Accounts.ui.Button {}
class Fields extends Accounts.ui.Fields {}
class Field extends Accounts.ui.Field {}
class FormMessage extends Accounts.ui.FormMessage {}
2016-03-31 00:10:45 +02:00
// Notice! Accounts.ui.LoginForm manages all state logic
// at the moment, so avoid overwriting this one, but have
// a look at it and learn how it works. And pull
2016-03-28 22:53:14 +02:00
// requests altering how that works are welcome.
// Alter provided default unstyled UI.
Accounts.ui.Form = Form;
Accounts.ui.Buttons = Buttons;
Accounts.ui.Button = Button;
Accounts.ui.Fields = Fields;
Accounts.ui.Field = Field;
Accounts.ui.FormMessage = FormMessage;
2016-03-29 04:47:40 +02:00
// Export the themed version.
export { Accounts as default };
2016-03-28 22:53:14 +02:00
```
### Available components
* Accounts.ui.LoginForm
* Accounts.ui.Form
* Accounts.ui.Fields
* Accounts.ui.Field
* Accounts.ui.Buttons
* Accounts.ui.Button
* Accounts.ui.FormMessage
2016-03-31 16:59:52 +02:00
* Accounts.ui.PasswordOrService
* Accounts.ui.SocialButtons
2016-03-29 05:12:33 +02:00
2016-03-30 17:30:26 +02:00
## Extra fields
> Example provided by [@radzom](https://github.com/radzom).
```javascript
2016-04-02 10:32:36 +02:00
import { Accounts, STATES } from 'meteor/accounts-ui';
2016-03-30 17:35:40 +02:00
2016-03-30 17:30:26 +02:00
class NewLogin extends Accounts.ui.LoginForm {
fields() {
const { formState } = this.state;
if (formState == STATES.SIGN_UP) {
return {
firstname: {
id: 'firstname',
hint: 'Enter firstname',
label: 'firstname',
onChange: this.handleChange.bind(this, 'firstname')
},
...super.fields()
};
}
return super.fields();
}
signUp(options = {}) {
const { firstname = null } = this.state;
if (firstname !== null) {
options.profile = Object.assign(options.profile || {}, {
firstname: firstname
});
}
super.signUp(options);
}
}
```
And on the server you can store the extra fields like this:
```javascript
import { Accounts } from 'meteor/accounts-base';
Accounts.onCreateUser(function (options, user) {
user.profile = options.profile || {};
user.roles = {};
return user;
});
```
2016-03-30 17:30:26 +02:00
2016-03-29 05:12:33 +02:00
## Credits
2016-03-30 17:12:22 +02:00
Made by the [creative folks at Studio Interact](http://studiointeract.com)