Package Exports
- @casl/react
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@casl/react) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
CASL React

This package allows to integrate @casl/ability into React application. So, you can show or hide UI elements based on user ability to see them.
Installation
npm install @casl/react @casl/abilityGetting Started
This package provides Can component which can be used to conditionally show UI elements based on user abilities.
This component accepts children and 3 properties:
do- name of the actionon- checked subjectability- an instance ofAbilitywhich will be used to check permissions
children property may be either a render function (a recommended way):
<Can do="create" on="Post" ability={ability}>
() => <button onClick={this.createPost.bind(this)}>Create Post</button>
</Can>or React elements:
<Can do="create" on="Post" ability={ability}>
<button onClick={this.createPost.bind(this)}>Create Post</button>
</Can>Note: it's better to pass children as a render function just because it will not create additional React elements if user doesn't have ability to do some action (in the case above read Post)
1. Scoping Can to use a particular ability
Yes, it's a bit unconvenient to pass ability in every Can component.
This was actually done for cases when you have several abilities in your app and/or want to restrict a particular Can component to check abilities using another instance.
There are 2 function which allow to scope Can to use a particular instance of Ability:
createCanBoundTocreateContextualCan
The first function just creates a new component which is bound to a particular ability and accepts only 2 properties: do and on:
// Can.js
import { createCanBoundTo } from '@casl/react'
import ability from './ability'
export default createCanBoundTo(ability)Then import bound Can into any component (now you don't need to pass ability property):
import Can from './Can'
export function button() {
return (
<Can do="create" on="Post">
() => <button onClick={this.createPost.bind(this)}>Create Post</button>
</Can>
)
}createContextualCan uses React Context API (available from React@16.3.0) and provides specified ability to all children components.
// ability-context.js
import { createContext } from 'react'
import { createContextualCan } from '@casl/react'
export const AbilityContext = createContext()
export const Can = createContextualCan(AbilityContext.Consumer)Later you need to provide your ability to AbilityContext.Provider
import { AbilityContext } from './ability-context'
import ability from './ability'
export default function App({ props }) {
return (
<AbilityContext.Provider value={ability}>
<TodoApp />
</AbilityContext.Provider>
)
}And inside TodoApp you can use previously created Can component:
import React, { Component } from 'react'
import { Can } from './ability-context'
export class TodoApp extends Component {
createTodo() {
// ....
}
render() {
return (
<Can do="create" on="Todo">
() => <button onClick={this.createTodo.bind(this)}>Create Todo</button>
</Can>
)
}
}See casl-react-example for more examples.
2. Defining Abilities
There are 2 options how you can define Ability instance:
- define an empty ability and update it when user login
- define ability using
AbilityBuilderand optionally update it when user login
To define empty ability:
// ability.js
import { Ability } from '@casl/ability'
export default new Ability([])To create ability using AbilityBuilder
// ability.js
import { AbilityBuilder } from '@casl/ability'
export default AbilityBuilder.define(can => {
can('read', 'all')
// ....
})Later in your login component:
import React, { Component } from 'react'
import ability from './ability'
export class LoginComponent extends Component {
login(event) {
event.preventDefault()
const { email, password } = this.state
return fetch('path/to/api/login', { method: 'POST', body: JSON.stringify({ email, password }) })
.then(response => response.json())
.then(session => ability.update(session.rules))
}
render() {
return (
<form onSubmit={this.login.bind(this)}>
// ...
</form>
)
}
}Obviously, in this case your server API should provide the list of user abilities in rules field of the response.
See @casl/ability package for more information on how to define abilities.
Want to help?
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on guidelines for contributing