Skip to content

Commit

Permalink
Document useAuthenticator hook (#1075)
Browse files Browse the repository at this point in the history
* Initial draft for React

* Remove full-headless related content

* Restore custom slot example

* First attempt at useAuthenticator example

* Initial draft

* First attempt at useAuthenticator example

* Allow children to be null

* Remove initial state

* Provider now only stores static ref to service

* match new exports

* add useAuthenticator test

* remove unused variable

* Create weak-stingrays-raise.md

* Create aero-stingrays-raise.md

* Fix typo

* add more comments

* Add comment on selector choice

* useAuthenticator only returns selected values

* Update changesets

* update exports

* Fix types

* update exports list

* Update .changeset/aero-stingrays-raise.md

* Update .changeset/weak-stingrays-raise.md

* Update react documentation to match #1168

* revert non pr related chagnes

* Add angular example

* Trigger tests

* run angular tests

* Added Vue examples and documentation

* Vue tests will run

* selector returns an array of dependencies

* Update test name

* Update react documentation to match latest #1168

* Add angular docs

* Correct full-api link

* Remove unused variable

* Add instructions for injecting AuthenticatorService

* Remove unused export

* Remove lingering comment

* Change 'conditional-rendering' to `current-route'

* Send INIT event from I18n demo

* Fix typos

* wordiness

Co-authored-by: Erik Hanchett <ehhanche@amazon.com>
  • Loading branch information
wlee221 and Erik Hanchett committed Jan 27, 2022
1 parent 2e77982 commit 33b887c
Show file tree
Hide file tree
Showing 29 changed files with 452 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
You can use `AuthenticatorService` to access `route` string that represents the current `authState`. They can be one of:

- `idle`
- `setup`
- `signIn`
- `signUp`
- `confirmSignIn`
- `confirmSignUp`
- `setupTOTP`
- `forceNewPassword`
- `resetPassword`
- `confirmResetPassword`
- `verifyUser`
- `confirmVerifyUser`
- `signOut`
- `authenticated`

```html
<!-- Only render this if there's an authenticated user -->
<ng-container *ngIf="authenticator.route === 'authenticated'">
Welcome back!
</ng-container>

<!-- Render sign-in screen otherwise with authenticator -->
<ng-container *ngIf="authenticator.route !== 'authenticated'">
<amplify-authenticator></amplify-authenticator>
</ng-container>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
You can use `useAuthenticator` hook to access `route` string that represents the current `authState`. They can be one of:

- `idle`
- `setup`
- `signIn`
- `signUp`
- `confirmSignIn`
- `confirmSignUp`
- `setupTOTP`
- `forceNewPassword`
- `resetPassword`
- `confirmResetPassword`
- `verifyUser`
- `confirmVerifyUser`
- `signOut`
- `authenticated`

```tsx{1,4-7}
import { useAuthenticator } from '@aws-amplify/ui-react';
const App = () => {
const { route } = useAuthenticator(context => [context.route]);
// Use the value of route to decide which page to render
return route === 'authenticated' ? <Home /> : <Authenticator />;
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
You can use `useAuthenticator` composable to access `route` string that represents the current `authState`. They can be one of:

- `idle`
- `setup`
- `signIn`
- `signUp`
- `confirmSignIn`
- `confirmSignUp`
- `setupTOTP`
- `forceNewPassword`
- `resetPassword`
- `confirmResetPassword`
- `verifyUser`
- `confirmVerifyUser`
- `signOut`
- `authenticated`

```html{1,5-7}
<script setup>
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-vue';
const auth = useAuthenticator();
</script>
<template>
<authenticator></authenticator>
<template v-if="auth.route === 'authenticated'">
<button @click="auth.signOut">Sign out</button>
</template>
</template>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
You can use `AuthenticatorService` to access current signed in `user`. If no user is authenticated, it'll return `undefined`.

```html
<ng-container *ngIf="!!authenticator.user">
<h2>Welcome, {{ authenticator.user.username }}!</h2>
</ng-container>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
You can use `useAuthenticator` hook to access current signed in `user`. If no user is authenticated, it'll return `undefined`.

```tsx{1,4,8-9}
import { useAuthenticator } from '@aws-amplify/ui-react';
const Home = () => {
const { user, signOut } = useAuthenticator((context) => [context.user]);
return (
<>
<h2>Welcome, {user.username}!</h2>
<button onClick={signOut}>Sign Out</button>
</>
);
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
You can use `useAuthenticator` composable to access current signed in `user`. If no user is authenticated, it'll return `undefined`.

```html{1,5-8}
<script setup>
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-vue';
const auth = useAuthenticator();
</script>
<template>
<authenticator></authenticator>
<template v-if="auth.route === 'authenticated'">
<h1>Hello {{ auth.user?.username }}!</h1>
<button @click="auth.signOut">Sign out</button>
</template>
</template>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
_app.component.ts_

```ts
import { Component } from '@angular/core';
import { Amplify } from 'aws-amplify';
import { AuthenticatorService } from '@aws-amplify/ui-angular';

import awsExports from './aws-exports';

@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class UseAuthenticatorComponent {
constructor(public authenticator: AuthenticatorService) {
Amplify.configure(awsExports);
}
}
```

_app.component.html_

```js file=../../../../../../examples/angular/src/pages/ui/components/authenticator/useAuthenticator/useAuthenticator.component.html#L1-L8

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```js{3,10-34} file=../../../../../../examples/next/pages/ui/components/authenticator/useAuthenticator/index.page.tsx#L1-L34
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```js{4,10-33} file=../../../../../../examples/vue/src/pages/ui/components/authenticator/useAuthenticator/index.vue
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Below is the full list of context that `AuthenticatorService` provides.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Below is the full list of context that `useAuthenticator` hook returns.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Below is the full list of context that `useAuthenticator` composable returns.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
You can use `AuthenticatorService` to access functions that lets you trigger transitions to the authenticator. Please see [Full API](#full-api) to see all supported transition functions. Any invalid transitions (e.g. `signUp` directly to `authenticated`) will be ignored.

```html{3}
<ng-container *ngIf="!!authenticator.user">
<h2>Welcome, {{ authenticator.user.username }}!</h2>
<button (click)="authenticator.signOut()">Sign Out</button>
</ng-container>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
You can use `useAuthenticator` hook to access functions that lets you trigger transitions to the authenticator. Please see [Full API](#full-api) to see all supported transition functions. Any invalid transitions (e.g. `signUp` directly to `authenticated`) will be ignored.

```tsx{1,4-6}
import { useAuthenticator } from '@aws-amplify/ui-react';
const Home = () => {
const { user, signOut } = useAuthenticator((context) => [context.user]);
return <button onClick={signOut}>Welcome, {user.username}!</button>;
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
You can use `useAuthenticator` composable to access functions that lets you trigger transitions to the authenticator. Please see [Full API](#full-api) to see all supported transition functions. Any invalid transitions (e.g. `signUp` directly to `authenticated`) will be ignored.

```html{1,5-8}
<script setup>
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-vue';
const auth = useAuthenticator();
</script>
<template>
<authenticator></authenticator>
<template v-if="auth.route === 'authenticated'">
<h1>Hello {{ auth.user?.username }}!</h1>
<button @click="auth.signOut">Sign out</button>
</template>
</template>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
### Authenticator Service

`@aws-amplify/ui-angular` ships with `AuthenticatorService` Angular service that can be used to access, modify, and update Authenticator's auth state. To use them, first inject the service into your component:

_app.component.ts_

```ts{3,12}
import { Component } from '@angular/core';
import { Amplify } from 'aws-amplify';
import { AuthenticatorService } from '@aws-amplify/ui-angular';
import awsExports from './aws-exports';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class UseAuthenticatorComponent {
constructor(public authenticator: AuthenticatorService) {
Amplify.configure(awsExports);
}
}
```

Then you can use the `authenticator` value in your component or template:

_app.component.html_

```html
<button (click)="authenticator.signOut()">Sign Out</button>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
### useAuthenticator Hook

`@aws-amplify/ui-react` ships with `useAuthenticator` React hook that can be used to access, modify, and update Authenticator's auth state. To use them, first wrap your application with `<Authenticator.Provider>`:

```tsx
import { Authenticator } from '@aws-amplify/ui-react';

export default () => (
<Authenticator.Provider>
<App />
</Authenticator.Provider>
);
```

Then, you can use `useAuthenticator` on your App:

```tsx
import { useAuthenticator } from '@aws-amplify/ui-react';

const App = () => {
const { user, signOut } = useAuthenticator((context) => [context.user]);
// ...
};
```

### Prevent Re-renders

Using `useAuthenticator` hook at your `App` level is risky, because it'll trigger a re-render down its true whenever any of its context changes value.

To prevent undesired re-renders, you can pass a function to `useAuthenticator` that takes in Authenticator context and returns an array of desired context values. The hook will only trigger re-render if any of the array values change.

For example, you can ensure `useAuthenticator` to only reevaluate when its `user` context changes:

```tsx
import { useAuthenticator } from '@aws-amplify/ui-react';

// hook below is only reevaluated when `user` changes
const { user, signOut } = useAuthenticator((context) => [context.user]);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
### useAuthenticator

`@aws-amplify/ui-vue` ships with `useAuthenticator` Vue composable that can be used to access, modify, and update Authenticator's auth state. To use them, make sure the `<authenticator>` is present in the component or parent component:

```html
<script setup>
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-vue';
const auth = useAuthenticator();
</script>

<template>
<authenticator></authenticator>
<button @click="auth.signOut">Sign Out</button>
</template>
```

Note that the `auth` is an object wrapped with `reactive`, meaning there is no need to write `.value` after getters but, like `props` in `setup`, _we cannot destructure it:_

```html
<script setup>
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-vue';
const { signOut } = useAuthenticator();
// ❌ This won't work because it breaks reactivity
// it's the same as destructuring from `props`
</script>
```

In order to extract properties from the authenticator while keeping its reactivity, you need to use `toRefs`. It will create refs for any reactive property:

```html
<script setup>
import { toRefs } from 'vue';
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-vue';
// `route` `user` and `signOut` all are reactive.
const { route, user, signOut } = toRefs(useAuthenticator());
</script>
```
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
_app.component.ts_

```ts{3,12}
import { Component } from '@angular/core';
import { Amplify } from 'aws-amplify';
import { AuthenticatorService } from '@aws-amplify/ui-angular';
import awsExports from './aws-exports';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class UseAuthenticatorComponent {
constructor(public authenticator: AuthenticatorService) {
Amplify.configure(awsExports);
}
}
```

_app.component.html_

```tsx{2,8,14,30,36,52,60,66,70} file=../../../../../examples/angular/src/pages/ui/components/authenticator/custom-slots/custom-slots.component.html
```

0 comments on commit 33b887c

Please sign in to comment.