An open API service indexing awesome lists of open source software.

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

Awesome Lists containing this project

README

          



Icons made by Pixel perfect from www.flaticon.com


Feature Flags



NPM version


LICENSE


CI


Size

Tiny 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)