Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions ACCORDION_FEATURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Accordion Feature for "In This Chapter" Section

## Overview

This document describes the accordion feature implementation for the "In This Chapter" table of contents section.

## Problem Statement

Previously, there was no option to hide the "In This Chapter" section, which could be problematic on pages with extensive content (e.g., Interview Questions page).

## Solution

Implemented an accordion feature that allows users to toggle the visibility of the "In This Chapter" section.

## Implementation Details

### Files Created

1. **`gitbook-plugin-toc-accordion/`** - Custom HonKit plugin
- `index.js` - Plugin entry point
- `package.json` - Plugin metadata
- `assets/accordion.css` - Accordion styles
- `assets/accordion.js` - Accordion functionality
- `README.md` - Plugin documentation

2. **`styles/website.css`** - Custom global styles (configured in book.json)

### Files Modified

1. **`book.json`** - Added `toc-accordion` plugin to the plugins list and configured custom styles
2. **`node_modules/gitbook-plugin-toc-accordion`** - Symlink to local plugin

Comment on lines +31 to +32
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation mentions node_modules/gitbook-plugin-toc-accordion as a modified file, but this directory is typically git-ignored and should not be part of the repository. The symlink setup (if needed) should be documented in the installation/setup instructions instead.

Recommendation: Remove this entry from the "Files Modified" section or clarify that this is a setup step, not a file modification tracked in git.

Suggested change
2. **`node_modules/gitbook-plugin-toc-accordion`** - Symlink to local plugin
## Setup
To use the local `gitbook-plugin-toc-accordion` plugin during development, create a symlink in `node_modules`:
```sh
ln -s ../gitbook-plugin-toc-accordion node_modules/gitbook-plugin-toc-accordion

This step ensures HonKit loads the local plugin code. Do not commit node_modules or the symlink to version control.

Copilot uses AI. Check for mistakes.
## Features

### ✅ User Features
- **Click to toggle**: Click on "In This Chapter" heading to show/hide content
- **Visual indicator**: Arrow icon that rotates based on state
- **Default open**: Accordion starts in open state for better UX
- **Persistent state**: User preference is saved in localStorage
- **Smooth animations**: CSS transitions for expand/collapse
- **Hover effects**: Visual feedback when hovering over the heading

### ✅ Accessibility Features
- **Keyboard navigation**: Works with Enter and Space keys
- **ARIA attributes**: Proper `role`, `aria-expanded`, and `aria-label` attributes
- **Focus indicator**: Tab navigation support
- **Screen reader friendly**: Announces state changes

### ✅ Technical Features
- **No conflicts**: Works alongside existing `intopic-toc` plugin
- **Responsive**: Works on all screen sizes
- **Browser compatible**: Supports all modern browsers
- **Lightweight**: Minimal CSS and JavaScript

## How to Use

1. Navigate to any page with a "In This Chapter" section
2. Click on the "In This Chapter" heading to collapse the section
3. Click again to expand it
4. Your preference is automatically saved

## Testing

To test the feature:

1. Start the development server: `npm start`
2. Open http://localhost:4000 in your browser
3. Navigate to any chapter page (e.g., `/en/basics/`)
4. Click on "In This Chapter" heading to test the accordion
5. Refresh the page to verify state persistence
6. Try keyboard navigation (Tab + Enter/Space)

## Browser Support

- Chrome/Edge: ✅
- Firefox: ✅
- Safari: ✅
- Opera: ✅

## Future Enhancements

Potential improvements:
- Add animation duration configuration
- Add option to change default state (open/closed)
- Add option to disable persistence
- Add custom icons support
55 changes: 55 additions & 0 deletions assets/accordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Accordion functionality for "In This Chapter" section
require(['gitbook', 'jQuery'], function(gitbook, $) {
gitbook.events.bind('page.change', function() {
// Wait for the intopic-toc to be rendered
setTimeout(function() {
var $tocNav = $('nav.intopic-toc');
var $tocHeader = $tocNav.find('h3');

if ($tocHeader.length === 0) return;

// Check if accordion is already initialized
if ($tocHeader.data('accordion-initialized')) return;

// Mark as initialized
$tocHeader.data('accordion-initialized', true);

// Load saved state from localStorage (default: open)
var isCollapsed = localStorage.getItem('intopic-toc-collapsed') === 'true';

if (isCollapsed) {
$tocNav.addClass('toc-collapsed');
}

// Add click handler to toggle accordion
$tocHeader.on('click', function(e) {
e.preventDefault();
e.stopPropagation();

$tocNav.toggleClass('toc-collapsed');

// Save state to localStorage
var collapsed = $tocNav.hasClass('toc-collapsed');
localStorage.setItem('intopic-toc-collapsed', collapsed);
});

// Make header keyboard accessible
$tocHeader.attr('tabindex', '0');
$tocHeader.attr('role', 'button');
$tocHeader.attr('aria-expanded', !isCollapsed);
$tocHeader.attr('aria-label', 'Toggle table of contents');

// Handle keyboard navigation
$tocHeader.on('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
$(this).click();

// Update aria-expanded
var expanded = !$tocNav.hasClass('toc-collapsed');
$(this).attr('aria-expanded', expanded);
}
});
}, 500); // Wait for plugin to render
});
});
Comment on lines +1 to +55
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This JavaScript file is an exact duplicate of gitbook-plugin-toc-accordion/assets/accordion.js. The plugin already provides this script through its index.js configuration, so this duplicate will cause the accordion initialization logic to run twice.

Recommendation: Remove this file entirely and rely on the plugin's JavaScript. The duplicate initialization could lead to unexpected behavior and double event handlers being attached.

Suggested change
// Accordion functionality for "In This Chapter" section
require(['gitbook', 'jQuery'], function(gitbook, $) {
gitbook.events.bind('page.change', function() {
// Wait for the intopic-toc to be rendered
setTimeout(function() {
var $tocNav = $('nav.intopic-toc');
var $tocHeader = $tocNav.find('h3');
if ($tocHeader.length === 0) return;
// Check if accordion is already initialized
if ($tocHeader.data('accordion-initialized')) return;
// Mark as initialized
$tocHeader.data('accordion-initialized', true);
// Load saved state from localStorage (default: open)
var isCollapsed = localStorage.getItem('intopic-toc-collapsed') === 'true';
if (isCollapsed) {
$tocNav.addClass('toc-collapsed');
}
// Add click handler to toggle accordion
$tocHeader.on('click', function(e) {
e.preventDefault();
e.stopPropagation();
$tocNav.toggleClass('toc-collapsed');
// Save state to localStorage
var collapsed = $tocNav.hasClass('toc-collapsed');
localStorage.setItem('intopic-toc-collapsed', collapsed);
});
// Make header keyboard accessible
$tocHeader.attr('tabindex', '0');
$tocHeader.attr('role', 'button');
$tocHeader.attr('aria-expanded', !isCollapsed);
$tocHeader.attr('aria-label', 'Toggle table of contents');
// Handle keyboard navigation
$tocHeader.on('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
$(this).click();
// Update aria-expanded
var expanded = !$tocNav.hasClass('toc-collapsed');
$(this).attr('aria-expanded', expanded);
}
});
}, 500); // Wait for plugin to render
});
});

Copilot uses AI. Check for mistakes.
4 changes: 4 additions & 0 deletions book.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"theme-creative",
"sidebar-ad",
"intopic-toc",
"toc-accordion",
"sharing",
"exercises",
"@honkit/honkit-plugin-ga",
Expand All @@ -27,6 +28,9 @@
"edit-link",
"ace-editor"
],
"styles": {
"website": "styles/website.css"
},
"pdf": {
"pageNumbers": true,
"margin": {
Expand Down
40 changes: 40 additions & 0 deletions gitbook-plugin-toc-accordion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# gitbook-plugin-toc-accordion

A HonKit/GitBook plugin that adds accordion functionality to the "In This Chapter" section generated by the `intopic-toc` plugin.

## Features

- ✅ **Toggle visibility**: Click on the "In This Chapter" heading to show/hide the table of contents
- ✅ **Visual indicator**: Arrow icon that rotates when collapsed/expanded
- ✅ **Persistent state**: Remembers your preference using localStorage
- ✅ **Default open**: The accordion is open by default for better UX
- ✅ **Keyboard accessible**: Supports Enter and Space keys for toggling
- ✅ **Smooth animations**: CSS transitions for a polished experience
- ✅ **Hover effects**: Visual feedback on hover

## Installation

This plugin is already installed locally in this project. It works in conjunction with the `intopic-toc` plugin.

## Usage

Simply click on the "In This Chapter" heading to collapse or expand the table of contents. The state will be saved and restored when you navigate between pages.

### Keyboard Navigation

- Press `Tab` to focus on the "In This Chapter" heading
- Press `Enter` or `Space` to toggle the accordion

## How It Works

1. The plugin loads CSS styles that add a clickable cursor and arrow indicator to the TOC heading
2. JavaScript adds click handlers to toggle the `toc-collapsed` class
3. The collapsed state is saved to localStorage for persistence across page loads
4. ARIA attributes ensure screen reader compatibility

## Browser Support

Works in all modern browsers that support:
- CSS3 transitions
- localStorage API
- ES5 JavaScript
41 changes: 41 additions & 0 deletions gitbook-plugin-toc-accordion/assets/accordion.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Accordion functionality for "In This Chapter" section */
nav.intopic-toc h3 {
cursor: pointer;
user-select: none;
position: relative;
transition: color 0.3s ease;
}

Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heading lacks a visible focus indicator for keyboard navigation, which is important for accessibility. Users navigating with keyboard won't have clear visual feedback when the heading is focused.

Recommendation: Add a focus style:

nav.intopic-toc h3:focus {
  outline: 2px solid #4A90E2;
  outline-offset: 2px;
}

Or use your project's standard focus styling.

Suggested change
nav.intopic-toc h3:focus {
outline: 2px solid #4A90E2;
outline-offset: 2px;
}

Copilot uses AI. Check for mistakes.
nav.intopic-toc h3:hover {
color: #6c767f;
}

/* Add arrow indicator */
nav.intopic-toc h3::after {
content: "";
display: inline-block;
width: 0;
height: 0;
margin-left: 8px;
vertical-align: middle;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #9DAAB6;
transition: transform 0.3s ease;
}

/* Rotate arrow when collapsed */
nav.intopic-toc.toc-collapsed h3::after {
transform: rotate(-90deg);
}

/* Hide content when collapsed */
nav.intopic-toc.toc-collapsed .navbar-nav {
display: none;
}

/* Smooth transition for content */
nav.intopic-toc .navbar-nav {
transition: all 0.3s ease;
Comment on lines +34 to +39
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using display: none prevents CSS transitions from working. The element immediately disappears without any smooth animation. Combined with the transition: all 0.3s ease on .navbar-nav, this creates an inconsistent user experience where the collapse has no visual transition.

Recommendation: Use max-height, opacity, or transform with overflow: hidden for smooth animations:

/* Hide content when collapsed */
nav.intopic-toc.toc-collapsed .navbar-nav {
  max-height: 0;
  opacity: 0;
  pointer-events: none;
}

/* Smooth transition for content */
nav.intopic-toc .navbar-nav {
  max-height: 1000px; /* Adjust based on your content */
  opacity: 1;
  transition: max-height 0.3s ease, opacity 0.3s ease;
  overflow: hidden;
}
Suggested change
display: none;
}
/* Smooth transition for content */
nav.intopic-toc .navbar-nav {
transition: all 0.3s ease;
max-height: 0;
opacity: 0;
pointer-events: none;
}
/* Smooth transition for content */
nav.intopic-toc .navbar-nav {
max-height: 1000px; /* Adjust based on your content */
opacity: 1;
transition: max-height 0.3s ease, opacity 0.3s ease;

Copilot uses AI. Check for mistakes.
overflow: hidden;
Comment on lines +39 to +40
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using transition: all can cause performance issues as it transitions every property, including properties that don't need animation. This can trigger unnecessary repaints and reflows.

Recommendation: Be specific about which properties to transition:

nav.intopic-toc .navbar-nav {
  transition: opacity 0.3s ease, max-height 0.3s ease;
  overflow: hidden;
}

Note: You may also need to add max-height with a reasonable value for the transition to work properly with display: none.

Suggested change
transition: all 0.3s ease;
overflow: hidden;
transition: opacity 0.3s ease, max-height 0.3s ease;
overflow: hidden;
max-height: 1000px; /* Adjust as needed for your content */

Copilot uses AI. Check for mistakes.
}
55 changes: 55 additions & 0 deletions gitbook-plugin-toc-accordion/assets/accordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Accordion functionality for "In This Chapter" section
require(['gitbook', 'jQuery'], function(gitbook, $) {
gitbook.events.bind('page.change', function() {
// Wait for the intopic-toc to be rendered
setTimeout(function() {
var $tocNav = $('nav.intopic-toc');
var $tocHeader = $tocNav.find('h3');

if ($tocHeader.length === 0) return;

// Check if accordion is already initialized
if ($tocHeader.data('accordion-initialized')) return;

// Mark as initialized
$tocHeader.data('accordion-initialized', true);

// Load saved state from localStorage (default: open)
var isCollapsed = localStorage.getItem('intopic-toc-collapsed') === 'true';
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code doesn't handle the case where localStorage is unavailable (e.g., in private browsing mode or when disabled). This will throw an error and break the accordion functionality.

Recommendation: Add a try-catch block or check for localStorage availability:

// Load saved state from localStorage (default: open)
var isCollapsed = false;
try {
  isCollapsed = localStorage.getItem('intopic-toc-collapsed') === 'true';
} catch (e) {
  // localStorage not available, use default
}

Similarly, wrap the localStorage.setItem call on line 33 in a try-catch.

Copilot uses AI. Check for mistakes.

if (isCollapsed) {
$tocNav.addClass('toc-collapsed');
}

// Add click handler to toggle accordion
$tocHeader.on('click', function(e) {
e.preventDefault();
e.stopPropagation();

$tocNav.toggleClass('toc-collapsed');

// Save state to localStorage
var collapsed = $tocNav.hasClass('toc-collapsed');
localStorage.setItem('intopic-toc-collapsed', collapsed);
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aria-expanded attribute is only set during initialization but not updated when the user clicks the heading (only updated on keyboard interaction). This creates an inconsistency for screen reader users.

Recommendation: Update the aria-expanded attribute in the click handler as well:

$tocHeader.on('click', function(e) {
  e.preventDefault();
  e.stopPropagation();
  
  $tocNav.toggleClass('toc-collapsed');
  
  // Save state to localStorage
  var collapsed = $tocNav.hasClass('toc-collapsed');
  localStorage.setItem('intopic-toc-collapsed', collapsed);
  
  // Update aria-expanded for accessibility
  $(this).attr('aria-expanded', !collapsed);
});
Suggested change
localStorage.setItem('intopic-toc-collapsed', collapsed);
localStorage.setItem('intopic-toc-collapsed', collapsed);
// Update aria-expanded for accessibility
$(this).attr('aria-expanded', !collapsed);

Copilot uses AI. Check for mistakes.
});

// Make header keyboard accessible
$tocHeader.attr('tabindex', '0');
$tocHeader.attr('role', 'button');
$tocHeader.attr('aria-expanded', !isCollapsed);
$tocHeader.attr('aria-label', 'Toggle table of contents');

// Handle keyboard navigation
$tocHeader.on('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keyboard event handler uses the .key property which is not supported in older browsers. For better compatibility, especially with Internet Explorer, you should also check for e.keyCode or use a more compatible approach.

Recommendation:

if (e.key === 'Enter' || e.key === ' ' || e.keyCode === 13 || e.keyCode === 32) {
Suggested change
if (e.key === 'Enter' || e.key === ' ') {
if (e.key === 'Enter' || e.key === ' ' || e.keyCode === 13 || e.keyCode === 32) {

Copilot uses AI. Check for mistakes.
e.preventDefault();
$(this).click();

// Update aria-expanded
var expanded = !$tocNav.hasClass('toc-collapsed');
$(this).attr('aria-expanded', expanded);
}
});
}, 500); // Wait for plugin to render
});
});
7 changes: 7 additions & 0 deletions gitbook-plugin-toc-accordion/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
book: {
assets: './assets',
js: ['accordion.js'],
css: ['accordion.css']
}
};
9 changes: 9 additions & 0 deletions gitbook-plugin-toc-accordion/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "gitbook-plugin-toc-accordion",
"version": "1.0.0",
"description": "Adds accordion functionality to In This Chapter section",
"main": "index.js",
"engines": {
"gitbook": ">=3.0.0"
}
}
Comment on lines +1 to +9
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package.json is missing several important fields for a proper npm package. Consider adding:

  • "author": Package author information
  • "license": License type (e.g., "MIT", "ISC")
  • "repository": Link to the source code repository
  • "keywords": For better discoverability if published

While this works for a local plugin, adding these fields follows npm best practices and makes the plugin more complete.

Copilot uses AI. Check for mistakes.
41 changes: 41 additions & 0 deletions styles/website.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Accordion functionality for "In This Chapter" section */
nav.intopic-toc h3 {
cursor: pointer;
user-select: none;
position: relative;
transition: color 0.3s ease;
}

nav.intopic-toc h3:hover {
color: #6c767f;
}

/* Add arrow indicator */
nav.intopic-toc h3::after {
content: "";
display: inline-block;
width: 0;
height: 0;
margin-left: 8px;
vertical-align: middle;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #9DAAB6;
transition: transform 0.3s ease;
}

/* Rotate arrow when collapsed */
nav.intopic-toc.toc-collapsed h3::after {
transform: rotate(-90deg);
}

/* Hide content when collapsed */
nav.intopic-toc.toc-collapsed .navbar-nav {
display: none;
}

/* Smooth transition for content */
nav.intopic-toc .navbar-nav {
transition: all 0.3s ease;
overflow: hidden;
}
Comment on lines +1 to +41
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This CSS file is an exact duplicate of gitbook-plugin-toc-accordion/assets/accordion.css. Since the plugin already provides the CSS through its index.js configuration, this file creates redundancy and could lead to maintainability issues.

Recommendation: Remove this file and rely solely on the plugin's CSS, or remove the CSS from the plugin if you prefer to manage all styles globally in styles/website.css.

Suggested change
/* Accordion functionality for "In This Chapter" section */
nav.intopic-toc h3 {
cursor: pointer;
user-select: none;
position: relative;
transition: color 0.3s ease;
}
nav.intopic-toc h3:hover {
color: #6c767f;
}
/* Add arrow indicator */
nav.intopic-toc h3::after {
content: "";
display: inline-block;
width: 0;
height: 0;
margin-left: 8px;
vertical-align: middle;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #9DAAB6;
transition: transform 0.3s ease;
}
/* Rotate arrow when collapsed */
nav.intopic-toc.toc-collapsed h3::after {
transform: rotate(-90deg);
}
/* Hide content when collapsed */
nav.intopic-toc.toc-collapsed .navbar-nav {
display: none;
}
/* Smooth transition for content */
nav.intopic-toc .navbar-nav {
transition: all 0.3s ease;
overflow: hidden;
}

Copilot uses AI. Check for mistakes.
Loading