Skip to content

Commit ca2d7df

Browse files
authored
[Storybook] Introduce Concept Theme page (#4916)
1 parent 3242f66 commit ca2d7df

File tree

7 files changed

+255
-0
lines changed

7 files changed

+255
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
import {
4+
CameraButton,
5+
ControlBar,
6+
EndCallButton,
7+
FluentThemeProvider,
8+
MicrophoneButton,
9+
DevicesButton,
10+
ScreenShareButton,
11+
darkTheme,
12+
DEFAULT_COMPONENT_ICONS
13+
} from '@azure/communication-react';
14+
import { registerIcons } from '@fluentui/react';
15+
16+
import React from 'react';
17+
18+
registerIcons({
19+
icons: DEFAULT_COMPONENT_ICONS
20+
});
21+
22+
export const DarkControlBar = (): JSX.Element => {
23+
return (
24+
<FluentThemeProvider fluentTheme={darkTheme} rootStyle={{ height: '56px', width: '280px' }}>
25+
<ControlBar>
26+
<CameraButton />
27+
<MicrophoneButton />
28+
<ScreenShareButton />
29+
<DevicesButton />
30+
<EndCallButton />
31+
</ControlBar>
32+
</FluentThemeProvider>
33+
);
34+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
import {
4+
CameraButton,
5+
ControlBar,
6+
EndCallButton,
7+
MicrophoneButton,
8+
ScreenShareButton,
9+
DEFAULT_COMPONENT_ICONS
10+
} from '@azure/communication-react';
11+
import { registerIcons } from '@fluentui/react';
12+
13+
import React from 'react';
14+
15+
registerIcons({
16+
icons: DEFAULT_COMPONENT_ICONS
17+
});
18+
19+
export const DefaultTheme = (): JSX.Element => {
20+
return (
21+
<div style={{ height: '56px', width: '280px' }}>
22+
<ControlBar>
23+
<CameraButton />
24+
<MicrophoneButton />
25+
<ScreenShareButton />
26+
<EndCallButton />
27+
</ControlBar>
28+
</div>
29+
);
30+
};
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { Meta, Controls, Primary, Source } from '@storybook/addon-docs';
2+
import { DarkControlBar } from './DarkControlBar.story';
3+
import { DefaultTheme } from './DefaultTheme.story';
4+
import { ThemedButton } from './ThemedButton.story';
5+
6+
import DarkControlBarText from '!!raw-loader!./snippets/DarkControlBar.snippet.tsx';
7+
import DefaultThemeSnippetText from '!!raw-loader!./snippets/DefaultTheme.snippet.tsx';
8+
import ThemedButtonText from '!!raw-loader!./snippets/ThemedButton.snippet.tsx';
9+
10+
<Meta title="Concepts/Theming" />
11+
12+
# Theming
13+
14+
ACS UI Library uses components and icons from both Fluent UI React [v8](https://aka.ms/fluentui#/controls/web)
15+
and [v9](https://react.fluentui.dev/). The `FluentThemeProvider`
16+
is a wrapping component that allows you to theme all ACS UI Library components consistently.
17+
18+
## Usage
19+
20+
ACS UI Library components are themed with a light theme by default as shown by the `ControlBar` and buttons below.
21+
22+
<Source code={DefaultThemeSnippetText} />
23+
<DefaultTheme />
24+
25+
To theme this ControlBar, import `FluentThemeProvider` from `@azure/communication-react` and wrap it around the `ControlBar`.
26+
Then import `darkTheme` from `@azure/communication-react` and assign it to the `fluentTheme` property of `FluentThemeProvider`.
27+
`darkTheme` is a [Theme](https://aka.ms/fluentui#/controls/web/references/theme) object from Fluent UI.
28+
29+
<Source code={DarkControlBarText} />
30+
<DarkControlBar />
31+
32+
## FluentThemeProvider Props
33+
34+
## Creating your own theme
35+
36+
`lightTheme` and `darkTheme` are available from `@azure/communication-react`. But if you wish to use your own theme,
37+
we recommend using Microsoft's [Fluent UI Theme Designer](https://aka.ms/themedesigner) to create your theme. Please ensure
38+
that the Accessibility checker on the same page passes when creating your own theme.
39+
40+
<img src="images/accessibility_checker_pass.png" alt="Accessibility checker pass" />
41+
42+
The default light theme we export looks like this:
43+
44+
```typescript
45+
export const lightTheme = {
46+
palette: {
47+
themePrimary: '#0078d4',
48+
themeLighterAlt: '#f3f9fd',
49+
themeLighter: '#d0e7f8',
50+
themeLight: '#a9d3f2',
51+
themeTertiary: '#5ca9e5',
52+
themeSecondary: '#1a86d9',
53+
themeDarkAlt: '#006cbe',
54+
themeDark: '#005ba1',
55+
themeDarker: '#004377',
56+
neutralLighterAlt: '#faf9f8',
57+
neutralLighter: '#f3f2f1',
58+
neutralLight: '#edebe9',
59+
neutralQuaternaryAlt: '#e1dfdd',
60+
neutralQuaternary: '#d0d0d0',
61+
neutralTertiaryAlt: '#c8c6c4',
62+
neutralTertiary: '#a19f9d',
63+
neutralSecondary: '#605e5c',
64+
neutralPrimaryAlt: '#3b3a39',
65+
neutralPrimary: '#323130',
66+
neutralDark: '#201f1e',
67+
black: '#000000',
68+
white: '#ffffff'
69+
}
70+
};
71+
```
72+
73+
## Custom Theme Mapping
74+
75+
The ACS UI Library and Fluent UI components are themed with palette values from the
76+
[Theme](https://aka.ms/fluentui#/controls/web/references/theme) object with a mapping that is designed to work for any valid theme.
77+
But if you wish to override the mapping, we recommend that you use the `useTheme` hook from `@azure/communication-react` and
78+
use the component's `styles` prop like in the example below.
79+
80+
<Source code={ThemedButtonText} />
81+
<ThemedButton />
82+
83+
Should you override the palette mapping, please note that ACS UI Library components abide by the general Fluent UI
84+
mappings. Foreground colors are used for text, icons, and outlines while background colors for component
85+
backgrounds. Primary colors are also used for component backgrounds or icons.
86+
87+
## Custom Fonts
88+
89+
Custom Fonts can be applied to UI Components or Composites using the existing theming mechansim.
90+
Along with the ability to change colors, a JSON object containing the theme palette also allows users to specify custom fonts.
91+
As long as the fonts have been loaded in the application, a custom font name can be specified as shown in the example below.
92+
93+
```tsx
94+
export const lightTheme = {
95+
defaultFontStyle: { fontFamily: 'Monaco, Menlo, Consolas', fontWeight: 'regular' },
96+
palette: {
97+
themePrimary: '#0078d4',
98+
themeLighterAlt: '#f3f9fd'
99+
}
100+
};
101+
```
102+
103+
If you wish to apply the same font to all the font weights, simply remove the `fontWeight` property from the `defaultFontStyle` object.
104+
105+
## Applying Custom Branding to the Composites
106+
107+
With the CallComposite and CallWithChatComposite you can also inject your own custom branding.
108+
You can inject a background and logo into the Composite configuration page to present to your users. This is done by
109+
passing background and logo properties to the `options` of the Composite.
110+
111+
For usage details and image recommendations please refer to the [Composites](./?path=/docs/composites-call-with-chat-basicexample--basic-example#custom-branding) section.
112+
113+
<img src="images/composite-logo-background.png" alt="CallWithChatComposite with a logo and background applied" />
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
import { useTheme, CameraButton } from '@azure/communication-react';
4+
import React from 'react';
5+
6+
export const ThemedButton = (): JSX.Element => {
7+
const theme = useTheme();
8+
9+
const defaultButtonStyle = {
10+
root: {
11+
background: theme.palette.neutralLighter
12+
},
13+
rootHovered: {
14+
background: theme.palette.neutralLight
15+
}
16+
};
17+
return <CameraButton styles={defaultButtonStyle} />;
18+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {
2+
CameraButton,
3+
ControlBar,
4+
EndCallButton,
5+
FluentThemeProvider,
6+
MicrophoneButton,
7+
DevicesButton,
8+
ScreenShareButton,
9+
darkTheme
10+
} from '@azure/communication-react';
11+
import React from 'react';
12+
13+
export const DarkControlBar = (): JSX.Element => {
14+
return (
15+
<FluentThemeProvider fluentTheme={darkTheme}>
16+
<ControlBar>
17+
<CameraButton />
18+
<MicrophoneButton />
19+
<ScreenShareButton />
20+
<DevicesButton />
21+
<EndCallButton />
22+
</ControlBar>
23+
</FluentThemeProvider>
24+
);
25+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {
2+
CameraButton,
3+
ControlBar,
4+
EndCallButton,
5+
MicrophoneButton,
6+
ScreenShareButton
7+
} from '@azure/communication-react';
8+
import React from 'react';
9+
10+
export const DefaultThemeSnippet = (): JSX.Element => {
11+
return (
12+
<ControlBar>
13+
<CameraButton />
14+
<MicrophoneButton />
15+
<ScreenShareButton />
16+
<EndCallButton />
17+
</ControlBar>
18+
);
19+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { useTheme, CameraButton } from '@azure/communication-react';
2+
import React from 'react';
3+
4+
export const ThemedButton = (): JSX.Element => {
5+
const theme = useTheme();
6+
7+
const defaultButtonStyle = {
8+
root: {
9+
background: theme.palette.neutralLighter
10+
},
11+
rootHovered: {
12+
background: theme.palette.neutralLight
13+
}
14+
};
15+
return <CameraButton styles={defaultButtonStyle} />;
16+
};

0 commit comments

Comments
 (0)