Skip to content

Commit 4daf89c

Browse files
committed
Add comprehensive v4 documentation
19 markdown files under docs/ covering setup, architecture, theming, pages, components, charts, tables, forms, overlays, command palette, app modules, PWA, deployment, TypeScript, the data adapter, migration from v2, and a FAQ. Linked from the project README.
1 parent 5675256 commit 4daf89c

19 files changed

Lines changed: 4010 additions & 14 deletions

docs/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Gentelella v4 documentation
2+
3+
Practical guide to building with Gentelella v4. Pairs with the project [README](../README.md) (overview + marketing) and [CLAUDE.md](../CLAUDE.md) (rules-of-the-road for AI tools).
4+
5+
## Start here
6+
7+
1. **[Getting started](getting-started.md)** — install, run dev, build, deploy
8+
2. **[Project structure](project-structure.md)** — what every directory does
9+
3. **[Architecture](architecture.md)** — shell injection, NAV, lazy modules
10+
11+
## Customizing the UI
12+
13+
- **[Theming](theming.md)** — design tokens, dark mode, the live theme generator
14+
- **[Pages](pages.md)** — the `npm run new` scaffolder, body attributes, sidebar entries
15+
- **[Components](components.md)** — buttons, cards, badges, stat tiles, grids
16+
- **[Forms](forms.md)** — inputs, validation, date range, multi-select, rich text
17+
- **[Charts](charts.md)** — ECharts factories, dark-mode-aware tokens, the chart map
18+
- **[Tables](tables.md)** — DataTables, row selection, CSV export, page size
19+
- **[Overlays](overlays.md)**`showModal`, `showToast`, `openMenu`, `openPanel`
20+
- **[Command palette](command-palette.md)** — ⌘K, registering inline actions
21+
- **[App modules](app-modules.md)** — inbox, kanban, calendar, file manager, settings
22+
23+
## Platform
24+
25+
- **[PWA](pwa.md)** — service worker, manifest, offline shell
26+
- **[Deployment](deployment.md)** — hosts, subpath builds, Cloudflare R2, cache headers
27+
- **[TypeScript](typescript.md)** — IntelliSense via `types/gentelella.d.ts`
28+
- **[Data adapter](data-adapter.md)**`?api=1`, seed vs HTTP
29+
30+
## Migration
31+
32+
- **[Migration from v2](migration-v2.md)** — coming from the old Bootstrap-based Gentelella
33+
34+
## Help
35+
36+
- **[FAQ](faq.md)** — common questions
37+
- **[Open an issue](https://github.com/ColorlibHQ/gentelella/issues)** if you hit something not covered here
38+
39+
## At a glance
40+
41+
| You want to | Read |
42+
| --- | --- |
43+
| Run it locally | [Getting started](getting-started.md) |
44+
| Add a new page in the sidebar | [Pages](pages.md) |
45+
| Change the brand color | [Theming](theming.md) |
46+
| Add a sortable table | [Tables](tables.md) |
47+
| Add a chart | [Charts](charts.md) |
48+
| Show a modal or toast | [Overlays](overlays.md) |
49+
| Hook up a real backend | [Data adapter](data-adapter.md) |
50+
| Deploy under `/admin/` | [Deployment](deployment.md) |
51+
| Convert from old Gentelella | [Migration from v2](migration-v2.md) |

docs/app-modules.md

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# App modules
2+
3+
The five "app pages" — inbox, kanban, calendar, file manager, settings — are non-trivial interactive surfaces, each in its own module under [`src/v4/`](../src/v4/). They share the same loading pattern: lazy-imported when the relevant root element is present.
4+
5+
| Module | Page | Root selector |
6+
| --- | --- | --- |
7+
| `inbox.js` | [`inbox.html`](../production/inbox.html) | `#inbox-root` |
8+
| `kanban.js` | [`kanban.html`](../production/kanban.html) | `.kanban-board` (auto-detected) |
9+
| `calendar.js` | [`calendar.html`](../production/calendar.html) | `.calendar-grid` |
10+
| `file-manager.js` | [`file_manager.html`](../production/file_manager.html) | `.file-manager-root` (auto-detected) |
11+
| `settings.js` | [`settings.html`](../production/settings.html) | `.settings-content` |
12+
13+
Each exports an idempotent `init<Name>()` and is wired up in [`src/main-v4.js`](../src/main-v4.js):
14+
15+
```js
16+
if (document.getElementById('inbox-root')) {
17+
import('./v4/inbox.js').then((m) => m.initInbox());
18+
}
19+
if (document.querySelector('.calendar-grid')) {
20+
import('./v4/calendar.js').then((m) => m.initCalendar());
21+
}
22+
if (document.querySelector('.settings-content')) {
23+
import('./v4/settings.js').then((m) => m.initSettings());
24+
}
25+
```
26+
27+
## Inbox
28+
29+
A full email client UI: folders sidebar, message list, reader pane, compose modal.
30+
31+
### Features
32+
33+
- **Folders**: Inbox, Starred, Sent, Drafts, Spam, Trash — switching filters the message list
34+
- **Reader pane**: clicking a message shows the body to the right
35+
- **Compose**: button → modal with To / Subject / Body inputs
36+
- **Reply / Forward** buttons in the reader header
37+
- **Search** input filters messages in the current folder
38+
- **Keyboard shortcuts** (when not typing in an input):
39+
- `j` / `` — next message
40+
- `k` / `` — previous message
41+
- `r` — reply
42+
- `s` — toggle star on the selected message
43+
- `#` — delete the selected message
44+
- `c` — open compose
45+
46+
Forward is a button in the reader header (no keyboard shortcut).
47+
48+
### Data shape
49+
50+
The inbox seed is an array of message objects in [`src/v4/inbox.js`](../src/v4/inbox.js). To wire to a real backend, see [data-adapter.md](data-adapter.md) — append `?api=1` to the URL and the inbox switches from seed to HTTP.
51+
52+
```js
53+
{
54+
id: 1,
55+
folder: 'inbox', // inbox | sent | drafts | trash
56+
unread: true,
57+
starred: false,
58+
label: 'work', // work | personal | promotions | urgent | null
59+
from: 'Sarah K.', // inbox: sender name. sent/drafts: 'Me'
60+
fromEmail: 'sarah@design.co', // present on inbox items
61+
to: 'team@example.com', // present on sent/drafts items
62+
subject: 'Re: Q1 design review',
63+
preview: 'I\'ve added comments to the figma file…',
64+
body: 'Full message body as plain text with \\n line breaks',
65+
time: '9:42 AM', // display string, not an ISO date
66+
trashed: false // set on items in trash folder
67+
}
68+
```
69+
70+
Note: `time` is a display string (`'9:42 AM'`, `'Yesterday'`, `'Apr 19'`), not a `Date` or ISO timestamp. If you swap in an HTTP adapter, transform real timestamps to display strings before rendering.
71+
72+
### Extending
73+
74+
To add a new folder:
75+
76+
1. Add to the folders array at the top of `inbox.js`.
77+
2. Make sure seed messages have a matching `folder` value.
78+
79+
To add a label / tag system:
80+
81+
1. Add `labels: string[]` to the message shape.
82+
2. Render label chips in the message list item.
83+
3. Add a labels-filter UI to the folders sidebar.
84+
85+
## Kanban
86+
87+
Drag-and-drop board with columns and cards. [`src/v4/kanban.js`](../src/v4/kanban.js).
88+
89+
### Features
90+
91+
- **Columns** with title and card count
92+
- **Cards** with title, description, labels, assignees, due date, priority
93+
- **Drag-and-drop** between columns and reorder within a column (HTML5 native drag API)
94+
- **Click a card** to open an edit modal (title, description, labels, due, priority, delete)
95+
96+
### Data shape
97+
98+
```js
99+
{
100+
id: 1,
101+
col: 'todo', // column id
102+
title: 'Add user filter to contacts page',
103+
desc: 'Filter by role + active status',
104+
labels: ['eng', 'frontend'], // ids referencing LABELS list
105+
assignees: ['JS', 'MR'], // initials
106+
due: 'May 25',
107+
priority: 'high' // low | medium | high
108+
}
109+
```
110+
111+
Columns and labels are defined at the top of [`src/v4/kanban.js`](../src/v4/kanban.js) as `COLUMNS` and `LABELS` arrays.
112+
113+
### Extending
114+
115+
- **Add a card**: insert into the cards array, call `render()`; drag handlers are delegated on the board so no per-card wiring needed
116+
- **Persist drag**: hook the `drop` handler in `kanban.js` to PATCH the card's new `col` field
117+
- **Add columns**: append to `COLUMNS`; the rendered columns are derived from it
118+
- **WIP limits**: not built in. Add a `limit` field to columns and compare against `cards.filter(c => c.col === id).length` in `renderColumn()`
119+
120+
## Calendar
121+
122+
Month-grid view with event CRUD. [`src/v4/calendar.js`](../src/v4/calendar.js).
123+
124+
### Features
125+
126+
- **Month grid** with prev / today / next nav
127+
- **Click a day** → "Add event" modal
128+
- **Click an event** → edit / delete modal
129+
- **Color tags** for event categories (blue, yellow, purple, red, green)
130+
- **Procedural events** — recurring placeholders (e.g. weekly standup) generated on render so the grid always has content
131+
- **Drag-to-reschedule is not implemented** — events are edited via the modal instead
132+
133+
### Data shape
134+
135+
```js
136+
{
137+
id: 1,
138+
title: 'Sprint review',
139+
start: '2026-05-20T14:00:00Z',
140+
end: '2026-05-20T15:00:00Z',
141+
color: 'teal', // teal | blue | yellow | red | purple
142+
description: ''
143+
}
144+
```
145+
146+
### Extending
147+
148+
- **Week / day view**: add view-switcher buttons; the underlying date grid logic is already abstracted.
149+
- **All-day events**: add `allDay: true` to the shape; render in a separate row above the timed grid.
150+
- **Recurring events**: store an [iCalendar RRULE](https://datatracker.ietf.org/doc/html/rfc5545) and expand on render.
151+
152+
## File manager
153+
154+
Tree + grid file browser. [`src/v4/file-manager.js`](../src/v4/file-manager.js).
155+
156+
### Features
157+
158+
- **Folder tree** on the left with expand / collapse
159+
- **File area** on the right with grid / list view toggle
160+
- **Breadcrumb** above the file area
161+
- **Per-file menu button** (⋯) opens a popover via `openMenu()` with Rename and Delete
162+
- **Star / unstar** any file; a "Starred" virtual folder collects them
163+
- **Shared** virtual folder shows files from a designated parent folder (demo: `marketing`)
164+
165+
### Data shape
166+
167+
```js
168+
{
169+
folders: [
170+
{ id: 'root', name: 'My drive', parent: null },
171+
{ id: 'docs', name: 'Documents', parent: 'root' },
172+
{ id: 'photos', name: 'Photos', parent: 'root' }
173+
],
174+
files: [
175+
{
176+
id: 1,
177+
folder: 'docs',
178+
name: 'Q3 plan.pdf',
179+
type: 'pdf', // determines icon
180+
size: 1248000,
181+
modified: '2026-05-15T10:00:00Z'
182+
}
183+
]
184+
}
185+
```
186+
187+
### Extending
188+
189+
- **File preview**: add a click handler that opens a modal with the file content (image, PDF embed, video).
190+
- **Download**: add a `{ label: 'Download', action: () => downloadFile(id) }` entry to the per-file menu in `file-manager.js`.
191+
- **Right-click context menu**: not built in. Wire `contextmenu` events on file rows to call the same `openMenu()` with the file's item list.
192+
- **Multi-select**: add shift / cmd-click handling to mark multiple files; show a bulk-action bar at the top.
193+
- **Upload**: drop-zone over the file area → POST to your backend.
194+
- **Search**: add an `<input>` above the file area and filter `getCurrentFiles()` by name on input.
195+
196+
## Settings
197+
198+
`localStorage`-backed settings page. [`src/v4/settings.js`](../src/v4/settings.js).
199+
200+
### Features
201+
202+
- **Sections** (in [`production/settings.html`](../production/settings.html)): Account, Notifications, Privacy & security, Appearance, Integrations, Billing, Team, Danger zone
203+
- **Section nav** in a left rail with scroll-spy active state
204+
- **Persisted state** — toggles, radios, and form inputs save to `localStorage['gentelella:settings']` on change
205+
- **Theme controls** in Appearance read/write `localStorage.theme` (the same key used by the pre-paint script)
206+
207+
### Data shape
208+
209+
```js
210+
localStorage.getItem('gentelella:settings')
211+
// JSON-encoded object — keys vary by input type:
212+
{
213+
'toggle:notifications:Email digest': true, // toggles: toggle:<section-id>:<label>
214+
'toggle:notifications:Push': false,
215+
'radio:theme': 'dark', // radios: radio:<name>
216+
'radio:density': 'comfy'
217+
}
218+
```
219+
220+
The persister discovers inputs by class:
221+
222+
- Toggles in `.settings-toggle-list .toggle` get a key `toggle:<section-id>:<label>` derived from the closest `.settings-section` and the row's `.label` text
223+
- Radios in `.theme-options input[type="radio"]` get `radio:<name>`
224+
225+
To add a new persisted input, place it inside one of these container classes — no extra attribute needed.
226+
227+
### Extending
228+
229+
- **Add a section**: copy a `<section class="settings-section" id="…">` block in [`production/settings.html`](../production/settings.html) and append a `<a class="settings-nav-link" href="#…">` in the `.settings-nav` aside.
230+
- **Sync to backend**: wrap `load()` / `save()` in [`src/v4/settings.js`](../src/v4/settings.js) with a `httpAdapter` (see [data-adapter.md](data-adapter.md)) so settings persist server-side instead of (or in addition to) `localStorage`.
231+
- **Validation**: extend the toggle / radio change handlers in `settings.js` to validate the new value before calling `save()`.
232+
233+
## Common patterns
234+
235+
All five modules share these conventions:
236+
237+
- **Single root element**: each module checks for its root selector before doing anything else.
238+
- **Idempotent init**: safe to call twice; already-initialized roots are skipped via a marker class (`._gentelella-init`).
239+
- **Event delegation**: handlers attach to the root element and use `e.target.closest('.thing')` for matching. No per-element listeners on render.
240+
- **Seed-first**: starts with an in-memory data array; mutations re-render the affected DOM region. `?api=1` swaps the seed for an HTTP adapter.
241+
- **No SPA navigation**: each module is self-contained on its own page. There's no client-side router.
242+
243+
## Where to look
244+
245+
- [`src/v4/inbox.js`](../src/v4/inbox.js)
246+
- [`src/v4/kanban.js`](../src/v4/kanban.js)
247+
- [`src/v4/calendar.js`](../src/v4/calendar.js)
248+
- [`src/v4/file-manager.js`](../src/v4/file-manager.js)
249+
- [`src/v4/settings.js`](../src/v4/settings.js)
250+
- [data-adapter.md](data-adapter.md) for wiring up a real backend

0 commit comments

Comments
 (0)