Skip to content

Commit d317ee8

Browse files
1010807: Added docs for theming and styling
1 parent 1774a56 commit d317ee8

1 file changed

Lines changed: 214 additions & 0 deletions

File tree

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
---
2+
layout: post
3+
title: Theming and styling in React PDF Viewer component | Syncfusion
4+
description: Learn how to apply built-in themes, configure dark mode, and customize the UI styles of the Syncfusion React PDF Viewer component.
5+
control: PDF Viewer
6+
platform: document-processing
7+
documentation: ug
8+
domainurl: ##DomainURL##
9+
---
10+
11+
# Theming and Styling
12+
13+
The React PDF Viewer supports a wide range of built-in themes and flexible UI customization to match your application's design.
14+
15+
## Supported Themes
16+
17+
The PDF Viewer applies styles to the toolbar, buttons, panels, annotations, and dialogs based on the selected theme. The available built-in Syncfusion themes are:
18+
19+
* Material 3
20+
* Fluent 2
21+
* Bootstrap 5
22+
* Tailwind
23+
24+
### How-to: Quick start
25+
26+
**Step-1:** Create a PDF Viewer sample by following the [React PDF Viewer getting started guide](./getting-started).
27+
28+
**Step-2:** To change the theme to tailwind, add the imports to tailwind theme in `app.css`.
29+
30+
```css
31+
@import '../node_modules/@syncfusion/ej2-base/styles/tailwind3.css';
32+
@import '../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css';
33+
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind3.css';
34+
@import '../node_modules/@syncfusion/ej2-inputs/styles/tailwind3.css';
35+
@import '../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css';
36+
@import '../node_modules/@syncfusion/ej2-popups/styles/tailwind3.css';
37+
@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind3.css';
38+
@import "../node_modules/@syncfusion/ej2-pdfviewer/styles/tailwind3.css";
39+
```
40+
41+
### Tutorial
42+
43+
This short, guided walkthrough shows a minimal end-to-end customization flow:
44+
45+
1. Create a new React app and install the viewer
46+
47+
2. Add the Tailwind theme imports to your global CSS (see Quick start).
48+
49+
3. Render `PdfViewerComponent` in `src/App.tsx` and verify the default look.
50+
51+
4. Add a theme switcher using the dark-mode logic in later shown in this file
52+
53+
5. Create `custom-overrides.css`, scope rules under `.e-custom-style`, load it after the theme CSS, and verify appearance and accessibility.
54+
55+
6. Pin or host theme files to avoid breaking changes when CDN versions update.
56+
57+
## Theming for Dark Mode
58+
59+
To provide a better viewing experience in low-light environments, you can apply dark themes or allow users to switch between light and dark modes.
60+
61+
### Apply Dark Theme
62+
63+
You can initialize the PDF Viewer with a dark theme by referencing the corresponding CSS:
64+
65+
* Material 3 Dark
66+
* Bootstrap 5 Dark
67+
* Fluent 2 Dark
68+
* Tailwind Dark
69+
* Fluent 2 High Contrast
70+
71+
### Switch between Light and Dark Mode
72+
73+
You can dynamically change the theme in your application to toggle between light and dark modes.
74+
75+
N> Ensure the background color of the PDF container is also updated to a dark shade when switching to a dark theme to maintain visual consistency.
76+
77+
#### How-to: Toggle Dark Mode
78+
79+
Below is an approach that can be copied into the app that switches themes by dynamically changing the link referenced in the style sheet in the head section of the document.
80+
81+
**Link-swap approach:**
82+
83+
```tsx
84+
// App.tsx
85+
type ThemeName = 'material3' | 'material3-dark';
86+
const THEME_LINK_ID = 'e-current-theme';
87+
function applyTheme(theme: ThemeName) {
88+
const path = `https://cdn.syncfusion.com/ej2/32.2.5/${theme}.css`;
89+
let primaryThemeLink = document.querySelector(`#${THEME_LINK_ID}`) as HTMLLinkElement;
90+
if (!primaryThemeLink) {
91+
primaryThemeLink = document.createElement('link');
92+
primaryThemeLink.id = THEME_LINK_ID;
93+
primaryThemeLink.rel = 'stylesheet';
94+
document.head.prepend(primaryThemeLink);
95+
}
96+
primaryThemeLink.href = path;
97+
}
98+
export function App() {
99+
const [theme, setTheme] = useState<ThemeName>('material3');
100+
useEffect(() => {
101+
applyTheme(theme);
102+
}, [theme]);
103+
// Simple memoized list for selector
104+
const options = useMemo(
105+
() => [
106+
{ value: 'material3', label: 'Material 3 (Light)' },
107+
{ value: 'material3-dark', label: 'Material 3 Dark' },
108+
],
109+
[]
110+
);
111+
return (<div>
112+
<label style={{ display: 'inline-flex', gap: 8, alignItems: 'center' }}>
113+
Theme:
114+
<select value={theme} onChange={(e) => setTheme(e.target.value as ThemeName)}>
115+
{options.map(o => (
116+
<option key={o.value} value={o.value}>{o.label}</option>
117+
))}
118+
</select>
119+
</label>
120+
<div className='control-section e-custom-style'>
121+
<PdfViewerComponent
122+
id="container"
123+
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
124+
resourceUrl="https://cdn.syncfusion.com/ej2/32.2.5/dist/ej2-pdfviewer-lib"
125+
style={{ 'height': '640px' }}>
126+
127+
<Inject services={[Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView, Print, TextSelection, TextSearch, Annotation, FormFields, FormDesigner, PageOrganizer]} />
128+
</PdfViewerComponent>
129+
</div>
130+
</div>);
131+
}
132+
```
133+
134+
## Custom Styles
135+
136+
While built-in themes provide a comprehensive look and feel, you might need to apply specific style overrides for your application.
137+
138+
### Implementation Guidelines
139+
140+
* **Load Order:** Always load the Syncfusion default theme CSS before applying any custom overrides.
141+
* **Custom Classes:** Prefer using `.e-custom-style` classes for overrides to ensure your styles are applied correctly without conflicting with internal logic.
142+
* **Avoid Deep Overrides:** Do not override internal classes deeply, as this may break the component's layout or responsiveness in future updates.
143+
144+
#### How-to: Apply Custom Styles
145+
146+
Apply overrides using a wrapper class so the rules are scoped and safe to maintain. The following example adds custom styles to signature form fields:
147+
148+
```css
149+
/* App.css */
150+
.e-custom-style .e-pv-page-container {
151+
background: #0b1220; /* custom viewer background */
152+
}
153+
/* Adds custom styles for signature fields */
154+
.e-custom-style .e-pdfviewer-signatureformfields,
155+
.e-custom-style .e-pdfviewer-signatureformfields-signature {
156+
border: 1px solid #b3d1ff !important;
157+
border-radius: 5px;
158+
}
159+
.e-custom-style span[id^='signIcon'] {
160+
background-color: #e6f2ff !important;
161+
border: 1px solid #b3d1ff !important;
162+
border-radius: 4px !important;
163+
font-weight: bold !important;
164+
color: #003366 !important;
165+
display: inline-block !important;
166+
height: 100% !important;
167+
text-align: center !important;
168+
}
169+
.e-custom-style span[id^='initialIcon'] {
170+
background-color: #e6f2ff !important;
171+
border: 1px solid #b3d1ff !important;
172+
border-radius: 4px !important;
173+
font-weight: bold !important;
174+
color: #003366 !important;
175+
display: inline-block !important;
176+
height: 100% !important;
177+
text-align: center !important;
178+
}
179+
```
180+
181+
```tsx
182+
// src/App.tsx
183+
import './App.css';
184+
import { PdfViewerComponent, Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView, Print, TextSelection, Annotation, TextSearch, FormFields, FormDesigner, PageOrganizer, Inject } from '@syncfusion/ej2-react-pdfviewer';
185+
186+
export function App() {
187+
return (
188+
<div className='control-section e-custom-style'>
189+
<PdfViewerComponent
190+
id="container"
191+
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
192+
resourceUrl="https://cdn.syncfusion.com/ej2/32.2.5/dist/ej2-pdfviewer-lib"
193+
style={{ 'height': '640px' }}>
194+
195+
<Inject services={[Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView, Print, TextSelection, TextSearch, Annotation, FormFields, FormDesigner, PageOrganizer]} />
196+
</PdfViewerComponent>
197+
</div>
198+
);
199+
}
200+
```
201+
202+
### Explanation
203+
204+
This section explains the rationale behind the recommendations and common pitfalls:
205+
206+
- Use a scoped wrapper class (for example `.e-custom-style`) to avoid fragile, global overrides that can break when internal selectors change.
207+
- Load order is important: theme CSS provides base variables and components' base rules; custom overrides must load after theme CSS to take effect reliably.
208+
- Prefer toggling theme files or a small root class rather than deep selector overrides when implementing dark mode — this makes switching simpler and reduces maintenance.
209+
- Avoid overusing `!important`; reserve it for third-party widgets or unavoidable form-field styling where the library applies strong specificity.
210+
- Always verify color-contrast and keyboard focus styles after applying themes or overrides to preserve accessibility.
211+
212+
### Reference
213+
214+
* [Theme Studio for Syncfusion<sup style="font-size:70%">&reg;</sup> React components](https://ej2.syncfusion.com/react/documentation/appearance/theme-studio)

0 commit comments

Comments
 (0)