Skip to content

Commit 64f41a7

Browse files
committed
✨ feat: adicionar botão de modo leitura sem distrações na navbar
- Criar componente ReadModeToggle com toggle visual - Adicionar botão na navbar antes do link "Original (EN)" - Implementar funcionalidade para esconder sidebar - Persistir estado do modo leitura no localStorage - Adicionar CSS para transições suaves ao esconder/mostrar sidebar - Expandir conteúdo quando sidebar está escondida - Centralizar conteúdo (max-width: 900px) no modo leitura - Suportar tema claro e escuro - Ícones diferentes para cada estado (livro/olho) - Responsivo: esconde texto do botão em telas pequenas - Mobile mantém funcionamento normal (menu hambúrguer)
1 parent 583bc13 commit 64f41a7

5 files changed

Lines changed: 188 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, { useState, useEffect } from 'react';
2+
import styles from './styles.module.css';
3+
4+
/**
5+
* Toggle para Modo de Leitura (Distraction-Free)
6+
*
7+
* Botão que esconde/mostra a sidebar para uma leitura sem distrações.
8+
* O estado é persistido no localStorage.
9+
*/
10+
export default function ReadModeToggle() {
11+
const [isReadMode, setIsReadMode] = useState(false);
12+
13+
// Carregar estado do localStorage ao montar
14+
useEffect(() => {
15+
const savedMode = localStorage.getItem('readMode') === 'true';
16+
setIsReadMode(savedMode);
17+
if (savedMode) {
18+
document.documentElement.setAttribute('data-read-mode', 'true');
19+
}
20+
}, []);
21+
22+
const toggleReadMode = () => {
23+
const newMode = !isReadMode;
24+
setIsReadMode(newMode);
25+
localStorage.setItem('readMode', newMode.toString());
26+
27+
if (newMode) {
28+
document.documentElement.setAttribute('data-read-mode', 'true');
29+
} else {
30+
document.documentElement.removeAttribute('data-read-mode');
31+
}
32+
};
33+
34+
return (
35+
<button
36+
className={styles.readModeButton}
37+
onClick={toggleReadMode}
38+
title={isReadMode ? 'Sair do modo leitura' : 'Modo leitura sem distrações'}
39+
aria-label={isReadMode ? 'Sair do modo leitura' : 'Ativar modo leitura'}
40+
type="button"
41+
>
42+
<svg
43+
width="20"
44+
height="20"
45+
viewBox="0 0 20 20"
46+
fill="currentColor"
47+
aria-hidden="true"
48+
>
49+
{isReadMode ? (
50+
// Ícone de olho (modo normal)
51+
<>
52+
<path d="M10 3C5 3 1.73 7.11 1 10c.73 2.89 4 7 9 7s8.27-4.11 9-7c-.73-2.89-4-7-9-7zm0 12c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z" />
53+
<circle cx="10" cy="10" r="3" />
54+
</>
55+
) : (
56+
// Ícone de livro/leitura (modo leitura)
57+
<>
58+
<path d="M10 2c-1.82 0-3.53.5-5 1.35C3.53 2.5 1.82 2 0 2v14c1.82 0 3.53.5 5 1.35 1.47-.85 3.18-1.35 5-1.35s3.53.5 5 1.35c1.47-.85 3.18-1.35 5-1.35V2c-1.82 0-3.53.5-5 1.35C13.53 2.5 11.82 2 10 2zm0 12.5c-1.2 0-2.27-.24-3.2-.64V4.14c.93-.4 2-.64 3.2-.64s2.27.24 3.2.64v9.72c-.93.4-2 .64-3.2.64z" />
59+
</>
60+
)}
61+
</svg>
62+
<span className={styles.buttonText}>
63+
{isReadMode ? 'Mostrar Barra' : 'Modo Leitura'}
64+
</span>
65+
</button>
66+
);
67+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
.readModeButton {
2+
display: inline-flex;
3+
align-items: center;
4+
gap: 6px;
5+
padding: 6px 12px;
6+
border: 1px solid var(--ifm-color-emphasis-300);
7+
border-radius: 6px;
8+
background: transparent;
9+
color: var(--ifm-navbar-link-color);
10+
font-size: 14px;
11+
font-weight: 500;
12+
cursor: pointer;
13+
transition: all 0.2s ease;
14+
white-space: nowrap;
15+
margin-right: 8px;
16+
}
17+
18+
.readModeButton:hover {
19+
background: var(--ifm-color-emphasis-100);
20+
border-color: var(--ifm-color-emphasis-400);
21+
color: var(--ifm-navbar-link-hover-color);
22+
}
23+
24+
.readModeButton:active {
25+
transform: scale(0.95);
26+
}
27+
28+
.buttonText {
29+
display: inline;
30+
}
31+
32+
/* Responsivo: esconder texto em telas pequenas */
33+
@media (max-width: 768px) {
34+
.buttonText {
35+
display: none;
36+
}
37+
38+
.readModeButton {
39+
padding: 8px;
40+
margin-right: 4px;
41+
}
42+
}
43+
44+
/* Estilos para modo escuro */
45+
html[data-theme='dark'] .readModeButton {
46+
border-color: var(--ifm-color-emphasis-300);
47+
}
48+
49+
html[data-theme='dark'] .readModeButton:hover {
50+
background: var(--ifm-color-emphasis-200);
51+
border-color: var(--ifm-color-emphasis-500);
52+
}

src/css/custom.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
* Este arquivo contém estilos customizados para o tema do Docusaurus.
55
*/
66

7+
/* Importar estilos do modo leitura */
8+
@import './read-mode.css';
9+
710
:root {
811
/* Cores primárias */
912
--ifm-color-primary: #f7df1e;

src/css/read-mode.css

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Estilos para Modo de Leitura (Distraction-Free)
3+
*
4+
* Quando data-read-mode="true" está presente no HTML,
5+
* a sidebar é escondida para proporcionar uma experiência
6+
* de leitura sem distrações.
7+
*/
8+
9+
/* Esconder sidebar no modo leitura */
10+
html[data-read-mode='true'] aside.theme-doc-sidebar-container {
11+
display: none !important;
12+
}
13+
14+
/* Expandir conteúdo principal quando sidebar está escondida */
15+
html[data-read-mode='true'] .main-wrapper {
16+
max-width: 100% !important;
17+
}
18+
19+
html[data-read-mode='true'] .container {
20+
max-width: 1200px !important;
21+
margin: 0 auto !important;
22+
}
23+
24+
html[data-read-mode='true'] .col--9 {
25+
--ifm-col-width: 100% !important;
26+
max-width: 100% !important;
27+
}
28+
29+
/* Transição suave */
30+
aside.theme-doc-sidebar-container,
31+
.main-wrapper,
32+
.container {
33+
transition: all 0.3s ease;
34+
}
35+
36+
/* Ajustar padding do conteúdo no modo leitura */
37+
html[data-read-mode='true'] article {
38+
max-width: 900px;
39+
margin: 0 auto;
40+
padding-left: 2rem;
41+
padding-right: 2rem;
42+
}
43+
44+
/* Mobile: já está sem sidebar, então não precisa de ajustes especiais */
45+
@media (max-width: 996px) {
46+
html[data-read-mode='true'] aside.theme-doc-sidebar-container {
47+
/* Em mobile a sidebar já é um menu hambúrguer, então mantemos funcionamento normal */
48+
display: block !important;
49+
}
50+
}

src/theme/Navbar/Content/index.jsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import Content from '@theme-original/Navbar/Content';
3+
import ReadModeToggle from '@site/src/components/ReadModeToggle';
4+
5+
/**
6+
* Navbar Content wrapper
7+
* Adiciona o botão de modo leitura antes dos itens da direita
8+
*/
9+
export default function ContentWrapper(props) {
10+
return (
11+
<>
12+
<Content {...props} />
13+
<ReadModeToggle />
14+
</>
15+
);
16+
}

0 commit comments

Comments
 (0)