-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 983d6ba
Showing
34 changed files
with
7,277 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
lib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module.exports = { | ||
root: true, | ||
parser: '@typescript-eslint/parser', | ||
plugins: [ | ||
'@typescript-eslint', | ||
], | ||
extends: [ | ||
'eslint:recommended', | ||
'plugin:@typescript-eslint/recommended', | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
name: CI | ||
on: push | ||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Install modules | ||
run: yarn | ||
- name: Run tests | ||
run: yarn jest --json --outputFile=result.json --testLocationInResults | ||
- uses: tanmen/jest-reporter@v1 | ||
if: always() | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created | ||
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages | ||
|
||
name: Publish package | ||
|
||
on: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-node@v1 | ||
with: | ||
node-version: 12 | ||
registry-url: https://registry.npmjs.org | ||
- run: npm i | ||
- run: npm publish | ||
env: | ||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
lib | ||
coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__test__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# React permission gate | ||
inspired by https://isamatov.com/react-permissions-and-roles/ | ||
|
||
Easily render or hide pieces of UI relative to the user's access role. | ||
|
||
### Supports Typescript and Flow type | ||
|
||
|
||
### Example | ||
full example [here](example) | ||
```javascript | ||
import { FeatureGateProvider } from 'feature-gate'; | ||
|
||
// define or get from api features and freeze them | ||
const features = Object.freeze({ | ||
feature1: 'true', | ||
ABtest: 'A', | ||
}); | ||
|
||
function MyApp() { | ||
const featureFlags = {}; // get from user api | ||
|
||
return ( | ||
<FeatureGateProvider featureFlags={featureFlags} features={features}> | ||
<App /> | ||
</FeatureGateProvider> | ||
) | ||
} | ||
``` | ||
then anywhere in the app use names of features defined in the features map | ||
|
||
```javascript | ||
import { FeatureGate } from 'feature-gate'; | ||
|
||
<FeatureGate name="feature1"> | ||
<div>Component available for authorized user</div> | ||
</FeatureGate> | ||
|
||
``` | ||
```javascript | ||
import { FeatureSwitch } from 'feature-gate'; | ||
|
||
<FeatureSwitch name="ABtest" fallback={<div>B test</div>}> | ||
<div>A test</div> | ||
</FeatureSwitch> | ||
|
||
``` | ||
or use hook | ||
```javascript | ||
import { useFeature } from 'feature-gate'; | ||
... | ||
|
||
const { enabled: showFeature1 } = useFeature('feature1'); | ||
// feature status for the current user | ||
... | ||
{showFeature1 && <div>Component available for authorized user</div>} | ||
``` | ||
### Advanced usage | ||
A validator function can be provided | ||
```javascript | ||
import { FeatureGateProvider } from 'feature-gate'; | ||
... | ||
|
||
// define or get from api rules and freeze them | ||
const features = Object.freeze({ | ||
feature1: 'true', | ||
ABtest: 'A', | ||
}); | ||
|
||
function validator({ featureFlags, features, name }) { | ||
// default validator implementation | ||
const feature = featureFlags[name]; | ||
if (!feature) return false; | ||
|
||
return features[name] === feature; | ||
} | ||
|
||
function MyApp() { | ||
const featureFlags = {}; // get from user api | ||
|
||
return ( | ||
<FeatureGateProvider featureFlags={featureFlags} features={features} validator={validator}> | ||
<App /> | ||
</FeatureGateProvider> | ||
) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
# vercel | ||
.vercel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# TypeScript Next.js example | ||
|
||
This is an example of using react-feature-gate | ||
|
||
## Preview | ||
|
||
Preview the example live on [StackBlitz](http://stackblitz.com/): | ||
|
||
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/w01fgang/react-feature-gate/tree/main/example) | ||
|
||
## Deploy your own | ||
|
||
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): | ||
|
||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/w01fgang/react-feature-gate/tree/main/example&project-name=react-feature-gate&repository-name=react-feature-gate) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import React, { ReactElement, ReactNode } from 'react' | ||
import { PermissionGate } from 'feature-gate'; | ||
import Link from 'next/link' | ||
import Head from 'next/head' | ||
|
||
type Props = { | ||
children: ReactNode | ||
title?: string | ||
} | ||
|
||
const Layout = ({ children, title = 'This is the default title' }: Props): ReactElement => ( | ||
<div> | ||
<Head> | ||
<title>{title}</title> | ||
<meta charSet="utf-8" /> | ||
<meta name="viewport" content="initial-scale=1.0, width=device-width" /> | ||
</Head> | ||
<header> | ||
<nav> | ||
<Link href="/"> | ||
<a>Home</a> | ||
</Link> | ||
{' | '} | ||
<Link href="/about"> | ||
<a>About</a> | ||
</Link> | ||
|
||
<PermissionGate name="users"> | ||
<> | ||
{' | '} | ||
<Link href="/users"> | ||
<a>Users List</a> | ||
</Link> | ||
</> | ||
</PermissionGate> | ||
|
||
<PermissionGate name="users-api"> | ||
<span>{' | '}<a href="/api/users">Users API</a></span> | ||
</PermissionGate> | ||
</nav> | ||
</header> | ||
{children} | ||
<footer> | ||
<hr /> | ||
<span>I'm here to stay (Footer)</span> | ||
</footer> | ||
</div> | ||
) | ||
|
||
export default Layout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { ReactElement } from 'react' | ||
import ListItem from './ListItem' | ||
import { User } from '../interfaces' | ||
|
||
type Props = { | ||
items: User[] | ||
} | ||
|
||
const List = ({ items }: Props): ReactElement => ( | ||
<ul> | ||
{items.map((item) => ( | ||
<li key={item.id}> | ||
<ListItem data={item} /> | ||
</li> | ||
))} | ||
</ul> | ||
) | ||
|
||
export default List |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { ReactElement } from 'react' | ||
|
||
import { User } from '../interfaces' | ||
|
||
type ListDetailProps = { | ||
item: User | ||
} | ||
|
||
const ListDetail = ({ item: user }: ListDetailProps): ReactElement => ( | ||
<div> | ||
<h1>Detail for {user.name}</h1> | ||
<p>ID: {user.id}</p> | ||
</div> | ||
) | ||
|
||
export default ListDetail |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { ReactElement } from 'react' | ||
import Link from 'next/link' | ||
|
||
import { User } from '../interfaces' | ||
|
||
type Props = { | ||
data: User | ||
} | ||
|
||
const ListItem = ({ data }: Props): ReactElement => ( | ||
<Link href="/users/[id]" as={`/users/${data.id}`}> | ||
<a> | ||
{data.id}: {data.name} | ||
</a> | ||
</Link> | ||
) | ||
|
||
export default ListItem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { ChangeEvent, ReactElement } from 'react'; | ||
import { usePermission } from 'feature-gate'; | ||
|
||
type Props = { | ||
onChange: (role: string) => void, | ||
}; | ||
|
||
const RoleSelector = (props: Props): ReactElement => { | ||
const { role } = usePermission("users"); | ||
|
||
const handleChange = (e: ChangeEvent<HTMLSelectElement>) => { | ||
props.onChange(e.target.value) | ||
}; | ||
|
||
return ( | ||
<div id="role-selector"> | ||
<span>Select role: </span> | ||
<select name="role" value={role} onChange={handleChange}> | ||
<option value="user">user</option> | ||
<option value="admin">admin</option> | ||
</select> | ||
<style jsx>{` | ||
#role-selector { | ||
margin: 8px 0; | ||
} | ||
`}</style> | ||
</div> | ||
) | ||
} | ||
|
||
export default RoleSelector |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// You can include shared interfaces/types in a separate file | ||
// and then use them in any component by importing them. For | ||
// example, to import the interface below do: | ||
// | ||
// import { User } from 'path/to/interfaces'; | ||
|
||
export type User = { | ||
id: number | ||
name: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/// <reference types="next" /> | ||
/// <reference types="next/types/global" /> | ||
/// <reference types="next/image-types/global" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "with-typescript", | ||
"version": "1.0.0", | ||
"scripts": { | ||
"dev": "next", | ||
"build": "next build", | ||
"start": "next start", | ||
"type-check": "tsc" | ||
}, | ||
"dependencies": { | ||
"next": "latest", | ||
"feature-gate": "latest", | ||
"react": "^18.0.0", | ||
"react-dom": "^18.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^17.0.23", | ||
"@types/react": "^17.0.43", | ||
"@types/react-dom": "^17.0.14", | ||
"eslint-config-next": "^12.1.4", | ||
"typescript": "4.6" | ||
}, | ||
"license": "MIT" | ||
} |
Oops, something went wrong.