Skip to content

Commit 1e695aa

Browse files
authored
feat: add a useIsSignedIn custom hook for react (#3093)
Add signed in state core functionality Add a hook to check the signed in state Add documentation of custom hooks on read me Add tests for isSignedIn Update the react-contoso sample to use the mgt-react hook Add sample stories for HTML and React usages
1 parent 056b15e commit 1e695aa

File tree

12 files changed

+149
-36
lines changed

12 files changed

+149
-36
lines changed

packages/mgt-element/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export * from './utils/LocalizationHelper';
3939
export * from './utils/mgtHtml';
4040
export * from './utils/CustomElement';
4141
export * from './utils/registerComponent';
42+
export * from './utils/isSignedIn';
4243

4344
export { PACKAGE_VERSION } from './utils/version';
4445

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
import { expect } from '@open-wc/testing';
9+
import { MockProvider } from '../mock/MockProvider';
10+
import { ProviderState } from '../providers/IProvider';
11+
import { Providers } from '../providers/Providers';
12+
import { isSignedIn } from './isSignedIn';
13+
14+
describe('signedInState', () => {
15+
it('should change', () => {
16+
/* eslint-disable @typescript-eslint/no-unused-expressions */
17+
Providers.globalProvider = new MockProvider(false);
18+
expect(isSignedIn()).to.be.false;
19+
Providers.globalProvider.setState(ProviderState.SignedIn);
20+
expect(isSignedIn()).to.be.true;
21+
});
22+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
import { ProviderState } from '../providers/IProvider';
9+
import { Providers } from '../providers/Providers';
10+
11+
/**
12+
* Checks the provider state if it's in signed in.
13+
*
14+
* @returns true if signed in, otherwise false.
15+
*/
16+
export const isSignedIn = (): boolean => {
17+
const provider = Providers.globalProvider;
18+
return provider && provider.state === ProviderState.SignedIn;
19+
};

packages/mgt-react/readme.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,24 @@ const App = (props) => {
9393

9494
The `template` prop allows you to specify which template to overwrite. In this case, the `MyEvent` component will be repeated for every event, and the `event` object will be passed as part of the `dataContext` prop.
9595

96+
## Custom hooks
97+
98+
`mgt-react` exposes some custom hooks that you can use in your app:
99+
100+
### `useIsSignedIn`
101+
102+
You can use this hook to check the signed in state:
103+
104+
```tsx
105+
import { Agenda, useIsSignedIn } from '@microsoft/mgt-react';
106+
107+
const App = (props) => {
108+
const [isSignedIn] = useIsSignedIn();
109+
110+
return {isSignedIn && <Agenda></Agenda>}
111+
}
112+
```
113+
96114
## Why
97115

98116
If you've used web components in React, you know that proper interop between web components and React components requires a bit of extra work.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
export * from './useIsSignedIn';
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
import { isSignedIn, Providers } from '@microsoft/mgt-element';
9+
import { useState, useEffect } from 'react';
10+
11+
/**
12+
* Hook to check if a user is signed in.
13+
*
14+
* @returns true if a user is signed on, otherwise false.
15+
*/
16+
export const useIsSignedIn = (): [boolean] => {
17+
const [signedIn, setIsSignedIn] = useState(false);
18+
useEffect(() => {
19+
const updateState = () => {
20+
setIsSignedIn(isSignedIn());
21+
};
22+
23+
Providers.onProviderUpdated(updateState);
24+
updateState();
25+
26+
return () => {
27+
Providers.removeProviderUpdatedListener(updateState);
28+
};
29+
}, [setIsSignedIn]);
30+
return [signedIn];
31+
};

packages/mgt-react/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
export * from './Mgt';
99
export * from './MgtTemplateProps';
1010
export * from './generated/react';
11+
export * from './hooks';
1112
export * from '@microsoft/mgt-components/dist/es6/exports';
1213
export * from '@microsoft/mgt-element';

samples/react-contoso/src/Layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { Suspense, lazy } from 'react';
22
import { BrowserRouter, Route, Routes } from 'react-router-dom';
33
import { Header } from './components/Header';
44
import { SideNavigation } from './components/SideNavigation';
5-
import { useIsSignedIn } from './hooks/useIsSignedIn';
5+
import { useIsSignedIn } from '@microsoft/mgt-react';
66
import { NavigationItem } from './models/NavigationItem';
77
import { getNavigation } from './services/Navigation';
88
import { FluentProvider, makeStyles, mergeClasses, shorthands } from '@fluentui/react-components';

samples/react-contoso/src/components/Header.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import * as React from 'react';
2-
import { Login, SearchBox } from '@microsoft/mgt-react';
2+
import { Login, SearchBox, useIsSignedIn } from '@microsoft/mgt-react';
33
import { PACKAGE_VERSION } from '@microsoft/mgt-element';
4-
import { InfoButton } from '@fluentui/react-components/unstable';
54
import { SimpleLogin } from './SimpleLogin';
6-
import { useIsSignedIn } from '../hooks/useIsSignedIn';
75
import { useNavigate } from 'react-router-dom';
86
import { ThemeSwitcher } from './ThemeSwitcher';
97
import { useAppContext } from '../AppContext';
10-
import { Label, makeStyles, mergeClasses, shorthands, tokens } from '@fluentui/react-components';
8+
import { Label, makeStyles, mergeClasses, shorthands, tokens, InfoLabel } from '@fluentui/react-components';
119
import { GridDotsRegular } from '@fluentui/react-icons';
1210
import { useLocation } from 'react-router-dom';
1311

@@ -149,11 +147,7 @@ const HeaderComponent: React.FunctionComponent = () => {
149147

150148
<div className={styles.waffleTitle}>
151149
<Label className={styles.name}>{import.meta.env.VITE_SITE_NAME} </Label>
152-
<InfoButton
153-
className={styles.infoIcon}
154-
size="medium"
155-
info={<>Using the Graph Toolkit v{PACKAGE_VERSION}</>}
156-
/>
150+
<InfoLabel className={styles.infoIcon} size="medium" info={<>Using the Graph Toolkit v{PACKAGE_VERSION}</>} />
157151
</div>
158152
</div>
159153
<div className={styles.search}>

samples/react-contoso/src/hooks/useIsSignedIn.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)