https://github.com/rqbazan/toggled
🏳 Tiny library to use feature flags in React
https://github.com/rqbazan/toggled
Last synced: 2 months ago
JSON representation
🏳 Tiny library to use feature flags in React
- Host: GitHub
- URL: https://github.com/rqbazan/toggled
- Owner: rqbazan
- License: mit
- Created: 2021-06-14T04:57:28.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-12-07T00:33:26.000Z (almost 4 years ago)
- Last Synced: 2024-04-25T21:43:49.621Z (over 1 year ago)
- Language: TypeScript
- Homepage:
- Size: 587 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![]()
Icons made by Pixel perfect from www.flaticon.com
Feature FlagsTiny library to use [feature flags](https://martinfowler.com/articles/feature-toggles.html) in React. Get features by its slug identifier or get a binary output using flag queries.
## Installation
NPM:
```sh
npm i toggled
```Yarn:
```sh
yarn add toggled
```## API
### `DefaultFeature` _Interface_
Internal public interface used by default to type the `` and `useFeature`.
#### Specification
```ts
export interface DefaultFeature {
slug: string
}
```#### Example
```ts
// src/types/toggled.d.ts
import 'toggled'// extend the interface if needed
declare module 'toggled' {
export interface DefaultFeature {
slug: string
settings?: any
}
}
```### `FlagQuery` _Type_
It could be the feature slug or an flag queries array or more powerful, an object query.
#### Specification
```ts
type FlagQuery =
| string
| FlagQuery[]
| {
$or: FlagQuery[]
}
| {
$and: FlagQuery[]
}
| {
[slug: string]: boolean
}
```#### Example
```tsx
// src/constants/domain.ts
import { Op } from 'toggled'// Note that each entry is a `FlagQuery`
export const flagQueries: Record = {
// True if the slug is in the context
FF_1: 'ff-1',// True if all the slugs are in the context
FF_2_FULL: ['ff-2.1', 'ff-2.2'],// True if `'ff-2.1'` is in the context and `'ff-2.2'` is not
FF_2_1_ONLY: {
'ff-2.1': true,
'ff-2.2': false,
},// True if `'ff-3.1'` **or** `'ff-3.2'` is in the context
FF_3_X: {
[Op.OR]: ['ff-3.1', 'ff-3.2'],
},// True if `'ff-4.1'` **and** `'ff-4.2'` are in the context
FF_4_FULL: {
[Op.AND]: ['ff-4.1', 'ff-4.2'],
},// True if all the previous queries are true
COMPLEX: {
FF_1: 'ff-1',
FF_2_FULL: ['ff-2.1', 'ff-2.2'],
FF_2_1_ONLY: {
'ff-2.1': true,
'ff-2.2': false,
},
FF_3_X: {
[Op.OR]: ['ff-3.1', 'ff-3.2'],
},
FF_4_FULL: {
[Op.AND]: ['ff-4.1', 'ff-4.2'],
},
},
}
```### `FeatureContext`
Library context, exported for no specific reason, avoid using it and prefer the custom hooks, or open a PR to add a new one that obligates you to use the `FeatureContext`.
#### Specification
```ts
interface FeatureContextValue {
cache: Map
}
```### ``
Provider component that exposes the features in a more convenient way to get them by its own slugs.
#### Specification
```ts
interface FeatureProviderProps {
features: F[]
children: React.ReactNode
}
```#### Example
```tsx
import { FeatureProvider } from 'toggled'
import apiClient from './api-client'
import App from './app'apiClient.getAllFeatures().then(features => {
ReactDOM.render(
,
document.getElementById('root'),
)
})
```### `useFeature`
Hook that is used to get a feature object from the context by its slug. Notice that it could be `undefined` because the context **only should contain the features that are enabled.**
#### Specification
```ts
interface UseFeature {
(slug: string): F | undefined
}
```#### Example
```tsx
// src/app.tsx
import { useFeature } from 'toggled'function App() {
const themeFF = useFeature('theme')return (
)
}
```### `useFlagQueryFn`
Hook that is used to get the magic function that can process a _flag query_.
#### Specification
```ts
interface UseFlagQueryFn {
(): (query: FlagQuery) => boolean
}
```#### Example
```tsx
import { useFlagQueryFn } from 'toggled'export default function App() {
const flagQueryFn = useFlagQueryFn()return (
{flagQueryFn('chat') && }
)
}
```> For more use cases, [please go to the tests.](./test/index.spec.tsx)
### `useFlag`
Hook that is used to get a binary output based on the existence of a feature in the context. So, if the feature is in the context then the flag will be `true`, otherwise `false`.
> The `useFlagQueryFn` hook is used internally.
#### Specification
```ts
interface UseFlag {
(query: FlagQuery): boolean
}
```#### Example
```tsx
import { useFlag } from 'toggled'export default function App() {
const hasChat = useFlag('chat')const hasDesignV2Only = useFlag({ 'design-v2': true, 'design-v1': false })
return (
{hasChat && }
)
}
```### ``
Component to apply conditional rendering using a `flagQuery`
#### Specification
```ts
interface FlagProps {
flagQuery: FlagQuery
children: React.ReactNode
}
```#### Example
```tsx
import { Flag } from 'toggled'export default function App() {
return (
)
}
```### ``
Component to consume a feature object declaratively instead of `useFeature`
#### Specification
```ts
export interface FeatureProps {
slug: string
children(feature: DefaultFeature): React.ReactElement
}
```#### Example
```tsx
import { Feature } from 'toggled'export default function App() {
return (
{feature => {
return
}}
)
}
```## License
MIT © [Ricardo Q. Bazan](https://rcrd.space)