taleem-browser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -0
- package/package.json +39 -0
- package/src/index.js +110 -0
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
|
|
2
|
+
# taleem-browser
|
|
3
|
+
|
|
4
|
+
**taleem-browser** is a minimal, index-based slide document browser.
|
|
5
|
+
|
|
6
|
+
At its core, it is a **JSON → Slides engine**:
|
|
7
|
+
|
|
8
|
+
> **JSON in → slides out**
|
|
9
|
+
|
|
10
|
+
It takes a structured slide deck (JSON) and renders one slide at a time into the DOM, allowing simple, reliable navigation by index.
|
|
11
|
+
|
|
12
|
+
There is **no timeline**, **no autoplay**, and **no animation logic** by design.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Core idea
|
|
17
|
+
|
|
18
|
+
Slides are **documents**, not animations.
|
|
19
|
+
|
|
20
|
+
A deck is an **ordered list of slides**.
|
|
21
|
+
`taleem-browser` lets you **view and navigate** that list safely and deterministically.
|
|
22
|
+
|
|
23
|
+
- No matter how simple or complex the deck is
|
|
24
|
+
- Whether timing metadata exists or not
|
|
25
|
+
- Even if timing metadata is incomplete or wrong
|
|
26
|
+
|
|
27
|
+
Slides always render.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## What this library does
|
|
32
|
+
|
|
33
|
+
`taleem-browser`:
|
|
34
|
+
|
|
35
|
+
- Accepts a **deck JSON object**
|
|
36
|
+
- Renders slides using `taleem-slides`
|
|
37
|
+
- Owns a single DOM mount point
|
|
38
|
+
- Displays **exactly one slide at a time**
|
|
39
|
+
- Navigates slides by **index**
|
|
40
|
+
- Always succeeds at rendering content
|
|
41
|
+
|
|
42
|
+
Navigation is explicit and controlled via a small API:
|
|
43
|
+
|
|
44
|
+
- `next()`
|
|
45
|
+
- `prev()`
|
|
46
|
+
- `goTo(index)`
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## What this library intentionally does NOT do
|
|
51
|
+
|
|
52
|
+
`taleem-browser` does **not**:
|
|
53
|
+
|
|
54
|
+
- interpret `start`, `end`, or `showAt`
|
|
55
|
+
- manage time or intervals
|
|
56
|
+
- autoplay slides
|
|
57
|
+
- sync audio or narration
|
|
58
|
+
- perform animations
|
|
59
|
+
- depend on any framework (React, Svelte, etc.)
|
|
60
|
+
|
|
61
|
+
These concerns belong to a **separate playback layer**, not a document browser.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Relationship to other Taleem libraries
|
|
66
|
+
|
|
67
|
+
`taleem-browser` sits above lower-level libraries:
|
|
68
|
+
|
|
69
|
+
- **taleem-core**
|
|
70
|
+
Defines schemas and core data rules.
|
|
71
|
+
|
|
72
|
+
- **taleem-slides**
|
|
73
|
+
Converts slide JSON into HTML.
|
|
74
|
+
|
|
75
|
+
`taleem-browser` uses `taleem-slides` internally so users don’t have to wire renderers manually.
|
|
76
|
+
|
|
77
|
+
If you want full control over rendering, you can use `taleem-slides` directly.
|
|
78
|
+
If you want a **ready-to-use slide viewer**, use `taleem-browser`.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Usage (minimal)
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
import { createTaleemBrowser } from "taleem-browser";
|
|
86
|
+
import deck from "./deck.json";
|
|
87
|
+
|
|
88
|
+
const browser = createTaleemBrowser({
|
|
89
|
+
mount: "#app",
|
|
90
|
+
deck
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
browser.next();
|
|
94
|
+
browser.prev();
|
|
95
|
+
browser.goTo(3);
|
|
96
|
+
````
|
|
97
|
+
|
|
98
|
+
That’s it.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Design philosophy
|
|
103
|
+
|
|
104
|
+
* Slides are **content-first**
|
|
105
|
+
* Index is more fundamental than time
|
|
106
|
+
* Rendering should never fail because of timing
|
|
107
|
+
* Static viewing is the default
|
|
108
|
+
* Playback is an optional interpretation
|
|
109
|
+
|
|
110
|
+
> **Slides are documents.
|
|
111
|
+
> Timing is an optional playback layer.**
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Advanced playback
|
|
116
|
+
|
|
117
|
+
If you need timed playback (e.g. animations, narration, or video-like behavior), use a higher-level utility (such as a future `taleem-player`) that **drives** `taleem-browser`.
|
|
118
|
+
|
|
119
|
+
The browser itself remains simple, stable, and predictable.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "taleem-browser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Pure index-based slide document browser for Taleem decks",
|
|
5
|
+
"type": "module",
|
|
6
|
+
|
|
7
|
+
"main": "./src/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.js"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"files": [
|
|
13
|
+
"src"
|
|
14
|
+
],
|
|
15
|
+
|
|
16
|
+
"scripts": {
|
|
17
|
+
"test": "vitest run"
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"taleem-slides": "^0.3.0"
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"vitest": "^1.6.0",
|
|
26
|
+
"jsdom": "^24.0.0"
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
"keywords": [
|
|
30
|
+
"slides",
|
|
31
|
+
"presentation",
|
|
32
|
+
"education",
|
|
33
|
+
"browser",
|
|
34
|
+
"taleem"
|
|
35
|
+
],
|
|
36
|
+
|
|
37
|
+
"license": "MIT"
|
|
38
|
+
}
|
|
39
|
+
|
package/src/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
|
|
2
|
+
import { slideBuilder } from "taleem-slides";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* createTaleemBrowser
|
|
6
|
+
* A pure slide document browser (index-based, no time).
|
|
7
|
+
*/
|
|
8
|
+
export function createTaleemBrowser({ mount, deck }) {
|
|
9
|
+
if (!mount) {
|
|
10
|
+
throw new Error("taleem-browser: mount is required");
|
|
11
|
+
}
|
|
12
|
+
if (!deck || !Array.isArray(deck.deck)) {
|
|
13
|
+
throw new Error("taleem-browser: valid deck object required");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const root =
|
|
17
|
+
typeof mount === "string" ? document.querySelector(mount) : mount;
|
|
18
|
+
|
|
19
|
+
if (!root) {
|
|
20
|
+
throw new Error("taleem-browser: mount element not found");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let currentIndex = 0;
|
|
24
|
+
const total = deck.deck.length;
|
|
25
|
+
|
|
26
|
+
// build static DOM once
|
|
27
|
+
root.innerHTML = `
|
|
28
|
+
<div class="taleem-browser-bg"></div>
|
|
29
|
+
<div class="taleem-browser-slide"></div>
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
const bgEl = root.querySelector(".taleem-browser-bg");
|
|
33
|
+
const slideEl = root.querySelector(".taleem-browser-slide");
|
|
34
|
+
|
|
35
|
+
// apply background from deck (browser-level responsibility)
|
|
36
|
+
applyBackground(bgEl, deck.background);
|
|
37
|
+
|
|
38
|
+
// build slide renderer
|
|
39
|
+
const manager = slideBuilder(deck);
|
|
40
|
+
|
|
41
|
+
function render() {
|
|
42
|
+
slideEl.innerHTML = manager.renderSlide(currentIndex);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function next() {
|
|
46
|
+
if (currentIndex < total - 1) {
|
|
47
|
+
currentIndex++;
|
|
48
|
+
render();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function prev() {
|
|
53
|
+
if (currentIndex > 0) {
|
|
54
|
+
currentIndex--;
|
|
55
|
+
render();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function goTo(index) {
|
|
60
|
+
if (index < 0 || index >= total) return;
|
|
61
|
+
currentIndex = index;
|
|
62
|
+
render();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function getIndex() {
|
|
66
|
+
return currentIndex;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getTotal() {
|
|
70
|
+
return total;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function destroy() {
|
|
74
|
+
root.innerHTML = "";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// initial render
|
|
78
|
+
render();
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
next,
|
|
82
|
+
prev,
|
|
83
|
+
goTo,
|
|
84
|
+
getIndex,
|
|
85
|
+
getTotal,
|
|
86
|
+
render,
|
|
87
|
+
destroy
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* -----------------------------
|
|
92
|
+
helpers (internal only)
|
|
93
|
+
------------------------------ */
|
|
94
|
+
|
|
95
|
+
function applyBackground(el, bg = {}) {
|
|
96
|
+
el.style.position = "absolute";
|
|
97
|
+
el.style.inset = "0";
|
|
98
|
+
el.style.zIndex = "0";
|
|
99
|
+
|
|
100
|
+
el.style.backgroundColor = bg.backgroundColor || "#000";
|
|
101
|
+
el.style.backgroundImage = bg.backgroundImage
|
|
102
|
+
? `url(${bg.backgroundImage})`
|
|
103
|
+
: "none";
|
|
104
|
+
el.style.backgroundSize = "cover";
|
|
105
|
+
el.style.backgroundPosition = "center";
|
|
106
|
+
el.style.opacity =
|
|
107
|
+
bg.backgroundImageOpacity !== undefined
|
|
108
|
+
? bg.backgroundImageOpacity
|
|
109
|
+
: 1;
|
|
110
|
+
}
|