Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
abdc31a
chore: improve package.js description
WilliamKelley Dec 14, 2021
a222ece
chore: add dep on 'accounts-base'
WilliamKelley Dec 14, 2021
2579d4b
fix(types): wrong / incomplete function signatures
WilliamKelley Dec 14, 2021
4ceeffc
feat: add index file and check React version
WilliamKelley Dec 14, 2021
0bce7be
chore: add jsdoc descriptions to fns
WilliamKelley Dec 14, 2021
b1f5721
chore(docs): adjust return types and ts signatures
WilliamKelley Dec 14, 2021
5f05ccc
feat: let forwarded props be overridable
WilliamKelley Dec 14, 2021
5e86dd2
fix: hoc type signatures not injecting prop
WilliamKelley Dec 14, 2021
9d8a7c2
feat: add utils for loggingIn and loggingOut
WilliamKelley Dec 14, 2021
16f3562
test(useUserId): initial tests
WilliamKelley Dec 14, 2021
9de28c5
test(useLoggingIn): add initial tests
WilliamKelley Dec 14, 2021
d93cc5c
test(useLoggingOut): add initial tests
WilliamKelley Dec 14, 2021
9016b54
test(useUser): add initial tests
WilliamKelley Dec 14, 2021
8ae8594
fix(types): HOC's requiring their inserted prop on wrapper instantiation
WilliamKelley Dec 14, 2021
07daaf8
test: add initial tests for HOCs
WilliamKelley Dec 14, 2021
a235d5b
chore(docs): add sections for hooks/HOCs of loggingIn/Out
WilliamKelley Dec 15, 2021
da75326
chore(docs): split docs of hooks and HOCs
WilliamKelley Dec 15, 2021
585f1f7
fix: re-export all utils from index
WilliamKelley Dec 15, 2021
81ef37d
fix: correct package name in warning
WilliamKelley Dec 15, 2021
4ba4ae4
fix(internal): missing null union in return types
WilliamKelley Dec 22, 2021
667b94f
fix(types): remove unnecessary module aug. & add null union for `user`
WilliamKelley Dec 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 223 additions & 61 deletions packages/react-meteor-accounts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ Simple hooks and higher-order components (HOCs) for getting reactive, stateful v
- [Peer npm dependencies](#peer-npm-dependencies)
- [Changelog](#changelog)
- [Usage](#usage)
- [`useUser` / `withUser`](#useuser--withUser)
- [`useUserId` / `withUserId`](#useuserid--withUserId)
- [`useUser`](#useuser)
- [`useUserId`](#useuserid)
- [`useLoggingIn`](#useloggingin)
- [`useLoggingOut`](#useloggingout)
- [`withUser`](#withuser)
- [`withUserId`](#withuserid)
- [`withLoggingIn`](#withloggingin)
- [`withLoggingOut`](#withloggingout)

## Installation

Expand Down Expand Up @@ -39,32 +45,19 @@ Utilities for each data source are available for the two ways of writing React c

_Note:_ All HOCs forward refs.

### useUser() / withUser(...)
### useUser()

Get a stateful value of the current user record from [`Meteor.user`](https://docs.meteor.com/api/accounts.html#Meteor-user), a reactive data source.

The hook, `useUser()`, returns a stateful value of the current user record.
Get a stateful value of the current user record. A hook. Uses [`Meteor.user`](https://docs.meteor.com/api/accounts.html#Meteor-user), a reactive data source.

- Arguments: *none*.
- Returns: `object | null`.

The HOC, `withUser(Component)`, returns a wrapped version of `Component`, where `Component` receives a prop of the current user record, `user`.

- Arguments:

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| Component | `any` | yes | A React component. |

- Returns: `React.ForwardRefExoticComponent`.

Examples:
Example:

```tsx
import React from 'react';
import { useUser, withUser } from 'meteor/react-meteor-accounts';
import { useUser } from 'meteor/react-meteor-accounts';

// Hook
function Foo() {
const user = useUser();

Expand All @@ -74,74 +67,169 @@ function Foo() {

return <h1>Hello {user.username}</h1>;
}
```

// HOC
class Bar extends React.Component {
render() {
if (this.props.user === null) {
return <h1>Log in</h1>;
}
TypeScript signature:

return <h1>Hello {this.props.user.username}</h1>;
}
}
```ts
function useUser(): Meteor.User | null;
```

### useUserId()

Get a stateful value of the current user id. A hook. Uses [`Meteor.userId`](https://docs.meteor.com/api/accounts.html#Meteor-userId), a reactive data source.

const WrappedBar = withUser(Bar);
- Arguments: *none*.
- Returns: `string | null`.

Example:

```tsx
import React from 'react';
import { useUserId } from 'meteor/react-meteor-accounts';

function Foo() {
const userId = useUserId();

return (
<div>
<h1>Account Details</h1>
{userId ? (
<p>Your unique account id is {userId}.</p>
) : (
<p>Log-in to view your account details.</p>
)}
</div>
);
}
```

TypeScript signatures:
TypeScript signature:

```ts
// Hook
const useUser: () => Meteor.User;
function useUserId(): string | null;
```

### useLoggingIn()

Get a stateful value of whether a login method (e.g. `loginWith<Service>`) is currently in progress. A hook. Uses [`Meteor.loggingIn`](https://docs.meteor.com/api/accounts.html#Meteor-loggingIn), a reactive data source.

- Arguments: *none*.
- Returns: `boolean`.

Example:

```tsx
import React from 'react';
import { useLoggingIn } from 'meteor/react-meteor-accounts';

function Foo() {
const loggingIn = useLoggingIn();

// HOC
const withUser: (Component: any) => React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
if (!loggingIn) {
return null;
}

return (
<div>Logging in, please wait a moment.</div>
);
}
```

### useUserId() / withUserId(...)
TypeScript signature:

Get a stateful value of the current user id from [`Meteor.userId`](https://docs.meteor.com/api/accounts.html#Meteor-userId), a reactive data source.
```ts
function useLoggingIn(): boolean;
```

### useLoggingOut()

The hook, `useUserId()`, returns a stateful value of the current user id.
Get a stateful value of whether the logout method is currently in progress. A hook. Uses `Meteor.loggingOut` (no online documentation), a reactive data source.

- Arguments: *none*.
- Returns: `string`.
- Returns: `boolean`.

Example:

```tsx
import React from 'react';
import { useLoggingOut } from 'meteor/react-meteor-accounts';

function Foo() {
const loggingOut = useLoggingOut();

if (!loggingOut) {
return null;
}

return (
<div>Logging out, please wait a moment.</div>
);
}
```

The HOC, `withUserId(Component)`, returns a wrapped version of `Component`, where `Component` receives a prop of the current user id, `userId`.
TypeScript signature:

```ts
function useLoggingOut(): boolean;
```

### withUser(...)

Return a wrapped version of the given component, where the component receives a stateful prop of the current user record, `user`. A higher-order component. Uses [`Meteor.user`](https://docs.meteor.com/api/accounts.html#Meteor-user), a reactive data source.

- Arguments:

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| Component | `any` | yes | A React component. |
| Component | `React.ComponentType` | yes | A React component. |

- Returns: `React.ForwardRefExoticComponent`.

Examples:

```tsx
import React from 'react';
import { useUserId, withUserId } from 'meteor/react-meteor-accounts';
import { withUser } from 'meteor/react-meteor-accounts';

// Hook
function Foo() {
const userId = useUserId();
class Foo extends React.Component {
render() {
if (this.props.user === null) {
return <h1>Log in</h1>;
}

return (
<div>
<h1>Account Details</h1>
{userId ? (
<p>Your unique account id is {userId}.</p>
) : (
<p>Log-in to view your account details.</p>
)}
</div>
);
return <h1>Hello {this.props.user.username}</h1>;
}
}

// HOC
class Bar extends React.Component {
const FooWithUser = withUser(Foo);
```

TypeScript signature:

```ts
function withUser<P>(Component: React.ComponentType<P>): React.ForwardRefExoticComponent<React.PropsWithoutRef<Omit<P, "user"> & Partial<WithUserProps>> & React.RefAttributes<unknown>>;
```

### withUserId(...)

Return a wrapped version of the given component, where the component receives a stateful prop of the current user id. A higher-order component. Uses [`Meteor.userId`](https://docs.meteor.com/api/accounts.html#Meteor-userId), a reactive data source.

- Arguments:

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| Component | `React.ComponentType` | yes | A React component. |

- Returns: `React.ForwardRefExoticComponent`.

Example:

```tsx
import React from 'react';
import { withUserId } from 'meteor/react-meteor-accounts';

class Foo extends React.Component {
render() {
return (
<div>
Expand All @@ -156,15 +244,89 @@ class Bar extends React.Component {
}
}

const WrappedBar = withUserId(Bar);
const FooWithUserId = withUserId(Foo);
```

TypeScript signature:

```ts
function withUserId<P>(Component: React.ComponentType<P>): React.ForwardRefExoticComponent<React.PropsWithoutRef<Omit<P, "userId"> & Partial<WithUserIdProps>> & React.RefAttributes<unknown>>;
```

### withLoggingIn(...)

Return a wrapped version of the given component, where the component receives a stateful prop of whether a login method (e.g. `loginWith<Service>`) is currently in progress. A higher-order component. Uses [`Meteor.loggingIn`](https://docs.meteor.com/api/accounts.html#Meteor-loggingIn), a reactive data source.

- Arguments:

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| Component | `React.ComponentType` | yes | A React component. |

- Returns: `React.ForwardRefExoticComponent`.

Example:

```tsx
import React from 'react';
import { withLoggingIn } from 'meteor/react-meteor-accounts';

class Foo extends React.Component {
render() {
if (!this.props.loggingIn) {
return null;
}

return (
<div>Logging in, please wait a moment.</div>
);
}
}

const FooWithLoggingIn = withLoggingIn(Foo);
```

TypeScript signatures:

```ts
// Hook
const useUserId: () => string;
function withLoggingIn<P>(Component: React.ComponentType<P>): React.ForwardRefExoticComponent<React.PropsWithoutRef<Omit<P, "loggingIn"> & Partial<WithLoggingInProps>> & React.RefAttributes<unknown>>;
```

### withLoggingOut(...)

Return a wrapped version of the given component, where the component receives a stateful prop of whether the logout method is currently in progress. A higher-order component. Uses `Meteor.loggingOut` (no online documentation), a reactive data source.

- Arguments:

// HOC
const withUserId: (Component: any) => React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| Component | `React.ComponentType` | yes | A React component. |

- Returns: `React.ForwardRefExoticComponent`.

Example:

```tsx
import React from 'react';
import { withLoggingOut } from 'meteor/react-meteor-accounts';

class Foo extends React.Component {
render() {
if (!this.props.loggingOut) {
return null;
}

return (
<div>Logging out, please wait a moment.</div>
);
}
}

const FooWithLoggingOut = withLoggingOut(Foo);
```

TypeScript signature:

```ts
function withLoggingOut<P>(Component: React.ComponentType<P>): React.ForwardRefExoticComponent<React.PropsWithoutRef<Omit<P, "loggingOut"> & Partial<WithLoggingOutProps>> & React.RefAttributes<unknown>>;
```
1 change: 1 addition & 0 deletions packages/react-meteor-accounts/index.tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './react-accounts.tests.tsx';
21 changes: 21 additions & 0 deletions packages/react-meteor-accounts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Meteor } from 'meteor/meteor';
import React from 'react';

if (Meteor.isDevelopment) {
// Custom check instead of `checkNpmVersions` to reduce prod bundle size (~8kb).
const v = React.version.split('.').map(val => parseInt(val));
if (v[0] < 16 || (v[0] === 16 && v[1] < 8)) {
console.warn('react-accounts requires React version >= 16.8.');
}
}

export {
useUser,
useUserId,
useLoggingIn,
useLoggingOut,
withUser,
withUserId,
withLoggingIn,
withLoggingOut
} from './react-accounts';
Loading