deckjsx 0.7.0 → 0.8.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 +167 -64
- package/dist/adapter-BamaV2yi.mjs +8638 -0
- package/dist/adapter-C2AHiDGa.d.mts +38 -0
- package/dist/adapter.d.mts +2 -2
- package/dist/adapter.mjs +2 -2
- package/dist/{index-C-LDA3Lj.d.mts → index-dx2ZSBgF.d.mts} +137 -194
- package/dist/index.d.mts +69 -25
- package/dist/index.mjs +5326 -1178
- package/dist/inspect.d.mts +4 -3
- package/dist/inspect.mjs +2 -1
- package/dist/jsx-DGGM5erN.mjs +403 -0
- package/dist/jsx-dev-runtime.d.mts +26 -4
- package/dist/jsx-dev-runtime.mjs +6 -7
- package/dist/jsx-runtime-_eIs-wi1.d.mts +42 -0
- package/dist/jsx-runtime.d.mts +3 -3
- package/dist/jsx-runtime.mjs +1 -1
- package/dist/model-BVkO8qGK.d.mts +1257 -0
- package/dist/model-DIuh51qh.mjs +32 -0
- package/dist/node-output-ChRpOCV8.mjs +28 -0
- package/dist/resolve-BD1dHxZd.d.mts +36 -0
- package/package.json +6 -22
- package/dist/adapter-NxGlM8_c.d.mts +0 -22
- package/dist/adapter-rS3mWdi0.mjs +0 -11244
- package/dist/jsx-DetoUfLm.mjs +0 -279
- package/dist/jsx-runtime-Dz8WBHpq.d.mts +0 -56
- package/dist/pptx-DaSXvESd.d.mts +0 -448
package/README.md
CHANGED
|
@@ -14,8 +14,9 @@ JSX
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
This project is being designed as a compiler, not as a thin `PptxGenJS` wrapper.
|
|
17
|
-
The API uses a class-based compiler with callback-based `.slide()`, `.compile()`,
|
|
18
|
-
`.render()`. Authoring uses typed JSX elements with CSS-like style and class
|
|
17
|
+
The API uses a class-based compiler with callback-based `.slide()`, synchronous `.compile()`, async
|
|
18
|
+
`.project()`, and async `.render()`. Authoring uses typed JSX elements with CSS-like style and class
|
|
19
|
+
semantics.
|
|
19
20
|
|
|
20
21
|
The implementation preserves the compiler model with explicit module boundaries for authoring,
|
|
21
22
|
semantic graph construction, style resolution, output projection, writer adapters, and runtime
|
|
@@ -27,7 +28,7 @@ output.
|
|
|
27
28
|
npm install deckjsx
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
The package currently targets PPTX output
|
|
31
|
+
The package currently targets PPTX output through deckjsx's direct PPTX writer.
|
|
31
32
|
|
|
32
33
|
## Usage
|
|
33
34
|
|
|
@@ -42,66 +43,75 @@ const deck = new Deck({
|
|
|
42
43
|
deck.slide(
|
|
43
44
|
{ name: "Quarterly Review", style: { backgroundColor: "#F8FAFC" } },
|
|
44
45
|
({ composition }) => (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
>
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
{composition.slideIndex + 1} / {composition.totalSlides}
|
|
86
|
-
</p>
|
|
87
|
-
</footer>
|
|
88
|
-
</main>
|
|
89
|
-
</>
|
|
46
|
+
<main
|
|
47
|
+
style={{
|
|
48
|
+
x: 0.7,
|
|
49
|
+
y: 0.5,
|
|
50
|
+
width: 11.9,
|
|
51
|
+
height: 6.3,
|
|
52
|
+
display: "grid",
|
|
53
|
+
gridTemplateRows: ["0.9in", "1fr", "0.4in"],
|
|
54
|
+
rowGap: 0.25,
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
<header>
|
|
58
|
+
<h1 style={{ width: "100%", height: 0.6, fontSize: 28, fontWeight: 700, color: "#0F172A" }}>
|
|
59
|
+
Quarterly Review
|
|
60
|
+
</h1>
|
|
61
|
+
</header>
|
|
62
|
+
|
|
63
|
+
<section style={{ display: "grid", gridTemplateColumns: "1fr 1fr", columnGap: 0.35 }}>
|
|
64
|
+
<p style={{ fontSize: 18, color: "#334155", fit: "shrink" }}>
|
|
65
|
+
Author slides with typed JSX, inspect the projected document model, and render PPTX files.
|
|
66
|
+
</p>
|
|
67
|
+
<figure style={{ backgroundColor: "#E0F2FE", borderRadius: 0.15, padding: 0.25 }}>
|
|
68
|
+
<img src="chart.png" style={{ width: "100%", height: "100%", fit: "contain" }} />
|
|
69
|
+
</figure>
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
<footer>
|
|
73
|
+
<p
|
|
74
|
+
style={{
|
|
75
|
+
width: "100%",
|
|
76
|
+
height: 0.3,
|
|
77
|
+
fontSize: 11,
|
|
78
|
+
color: "#64748B",
|
|
79
|
+
textAlign: "right",
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
{composition.slideIndex + 1} / {composition.totalSlides}
|
|
83
|
+
</p>
|
|
84
|
+
</footer>
|
|
85
|
+
</main>
|
|
90
86
|
),
|
|
91
87
|
);
|
|
92
88
|
|
|
93
|
-
const project = deck.project();
|
|
89
|
+
const project = await deck.project();
|
|
94
90
|
await deck.render({ output: "quarterly-review.pptx" });
|
|
95
91
|
```
|
|
96
92
|
|
|
97
|
-
Use `deck.compile()` for authoring semantics, `deck.project()` for output-facing inspection,
|
|
98
|
-
`deck.render({ output })` when writing a PowerPoint file.
|
|
93
|
+
Use `deck.compile()` for authoring semantics, `await deck.project()` for output-facing inspection,
|
|
94
|
+
and `await deck.render({ output })` when writing a PowerPoint file.
|
|
95
|
+
|
|
96
|
+
When a hot path only needs the projected model or rendered artifact, inspection summaries can be
|
|
97
|
+
skipped with `await deck.project({ inspection: "none" })` or
|
|
98
|
+
`await deck.render({ inspection: "none" })`.
|
|
99
|
+
|
|
100
|
+
The default render path uses deckjsx's built-in direct PPTX writer. If an explicit writer adapter is
|
|
101
|
+
needed, import `pptx()` from `deckjsx/adapter`; writer internals such as XML emitters, ZIP settings,
|
|
102
|
+
and sinks are intentionally not part of the public API.
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { pptx } from "deckjsx/adapter";
|
|
106
|
+
|
|
107
|
+
await deck.render(pptx({ output: "quarterly-review.pptx" }));
|
|
108
|
+
```
|
|
99
109
|
|
|
100
110
|
## JSX elements
|
|
101
111
|
|
|
102
|
-
`deckjsx`
|
|
112
|
+
`deckjsx` exposes a typed HTML-like JSX authoring surface.
|
|
103
113
|
|
|
104
|
-
View-like elements compile to grouped layout containers:
|
|
114
|
+
View-like lowercase elements compile to grouped layout containers:
|
|
105
115
|
|
|
106
116
|
```tsx
|
|
107
117
|
<main>
|
|
@@ -115,7 +125,7 @@ View-like elements compile to grouped layout containers:
|
|
|
115
125
|
</main>
|
|
116
126
|
```
|
|
117
127
|
|
|
118
|
-
Text-like elements compile to text boxes:
|
|
128
|
+
Text-like lowercase elements compile to text boxes:
|
|
119
129
|
|
|
120
130
|
```tsx
|
|
121
131
|
<h1>Title</h1>
|
|
@@ -123,12 +133,85 @@ Text-like elements compile to text boxes:
|
|
|
123
133
|
<p>Body copy</p>
|
|
124
134
|
```
|
|
125
135
|
|
|
126
|
-
Image elements compile to images and require either `src` or `data`:
|
|
136
|
+
Image lowercase elements compile to images and require either `src` or `data`:
|
|
127
137
|
|
|
128
138
|
```tsx
|
|
129
139
|
<img src="diagram.png" style={{ width: 4, height: 2.5, fit: "contain" }} />
|
|
130
140
|
```
|
|
131
141
|
|
|
142
|
+
The lowercase `shape` element compiles to PPTX shapes:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
<shape shape="rect" style={{ width: 2, height: 1, fill: "#2563EB" }} />
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Slide Templates
|
|
149
|
+
|
|
150
|
+
Deck templates describe reusable slide structure without asking authors to write PowerPoint
|
|
151
|
+
placeholder ids. Define named Template Areas on the Deck, then place authored content through the
|
|
152
|
+
typed `template` handle passed to templated slide factories:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
const deck = new Deck({
|
|
156
|
+
layout: { width: 13.333, height: 7.5, unit: "in" },
|
|
157
|
+
templates: {
|
|
158
|
+
report: {
|
|
159
|
+
areas: {
|
|
160
|
+
title: { kind: "title", frame: { x: 0.7, y: 0.6, width: 8, height: 0.8 } },
|
|
161
|
+
body: { frame: { x: 0.7, y: 1.6, width: 8, height: 4.8 } },
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
deck.slide({ template: "report" }, ({ template }) => (
|
|
168
|
+
<main>
|
|
169
|
+
<h1 area={template.title}>Quarterly Review</h1>
|
|
170
|
+
<section area={template.body}>Performance highlights</section>
|
|
171
|
+
</main>
|
|
172
|
+
));
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`TemplateArea.kind` is an authoring-level hint such as `"title"`, `"body"`, `"picture"`, or
|
|
176
|
+
`"generic"`. Missing kinds default to `"generic"` and are not inferred from area names. Project keeps
|
|
177
|
+
Template Area anchors visible in the Pptx Package Model inspection surface, while the writer decides
|
|
178
|
+
how to serialize the corresponding PPTX slide layout structure.
|
|
179
|
+
|
|
180
|
+
## Assets
|
|
181
|
+
|
|
182
|
+
Image sources are resolved through the asset loading boundary. The core package includes
|
|
183
|
+
multi-runtime handling for data/bytes and absolute URL-like sources, while filesystem paths,
|
|
184
|
+
framework-public assets, authenticated URLs, and app media stores should be provided with
|
|
185
|
+
`deck.useAssets(loader)`.
|
|
186
|
+
For built-in data, bytes, and absolute URL-like image sources, Project probes PNG, GIF, JPEG, and
|
|
187
|
+
SVG dimensions into media metadata without putting media bytes into the Pptx Package Model.
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
import type { AssetLoader } from "deckjsx";
|
|
191
|
+
|
|
192
|
+
const publicAssets = {
|
|
193
|
+
name: "public-assets",
|
|
194
|
+
async probe({ source }) {
|
|
195
|
+
if (source.kind !== "path") return undefined;
|
|
196
|
+
return { mediaType: "image/png", extension: "png", width: 1200, height: 800 };
|
|
197
|
+
},
|
|
198
|
+
async load({ source }) {
|
|
199
|
+
if (source.kind !== "path") return undefined;
|
|
200
|
+
const bytes = await loadFromYourRuntime(source.path);
|
|
201
|
+
return { bytes, mediaType: "image/png", extension: "png", width: 1200, height: 800 };
|
|
202
|
+
},
|
|
203
|
+
} satisfies AssetLoader;
|
|
204
|
+
|
|
205
|
+
deck.useAssets(publicAssets);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Registered loaders run in registration order before the built-in fallback. Project uses `probe()` for
|
|
209
|
+
metadata needed by the Pptx Package Model, and Render uses the same winning resolver scope for
|
|
210
|
+
`load()` so media metadata and bytes come from the same runtime assumptions.
|
|
211
|
+
If a loader claims an image source but cannot provide dimensions, treat that as an asset data
|
|
212
|
+
retrieval failure and report it through Project diagnostics rather than waiting for the writer to
|
|
213
|
+
guess.
|
|
214
|
+
|
|
132
215
|
Primitive string and number children inside view-like elements are normalized to implicit text
|
|
133
216
|
nodes. Inline rich text uses `span` inside text-like elements:
|
|
134
217
|
|
|
@@ -138,18 +221,18 @@ nodes. Inline rich text uses `span` inside text-like elements:
|
|
|
138
221
|
</p>
|
|
139
222
|
```
|
|
140
223
|
|
|
141
|
-
## View Layout Semantics
|
|
224
|
+
## View-like Layout Semantics
|
|
142
225
|
|
|
143
|
-
|
|
144
|
-
`bottom`, `width`, and `height` values are resolved relative to the parent
|
|
226
|
+
View-like elements are containing blocks for their children. Child `x`, `y`, `left`, `top`, `right`,
|
|
227
|
+
`bottom`, `width`, and `height` values are resolved relative to the parent view-like element, not
|
|
145
228
|
the slide, so authors can build panels with local coordinates. Percentage lengths use
|
|
146
229
|
the parent frame as their reference.
|
|
147
230
|
|
|
148
231
|
```tsx
|
|
149
|
-
<
|
|
150
|
-
<
|
|
151
|
-
<
|
|
152
|
-
</
|
|
232
|
+
<div style={{ x: 1, y: 1, width: 6, height: 3 }}>
|
|
233
|
+
<p style={{ x: "10%", y: "20%", width: "50%", height: "25%" }}>local percent frame</p>
|
|
234
|
+
<p style={{ left: "55%", top: "10%", right: "10%", bottom: "60%" }}>inset frame</p>
|
|
235
|
+
</div>
|
|
153
236
|
```
|
|
154
237
|
|
|
155
238
|
For `display: "flex"` and `display: "grid"`, normal-flow children are laid out inside
|
|
@@ -159,13 +242,33 @@ rendering. Absolutely positioned children inside flex or grid containers also us
|
|
|
159
242
|
container content frame, including padding, as their containing block.
|
|
160
243
|
|
|
161
244
|
Use direct slide children when you want slide-global absolute placement. Use children
|
|
162
|
-
inside a
|
|
245
|
+
inside a view-like element when you want a local, web-like layout region.
|
|
246
|
+
|
|
247
|
+
`overflow: "hidden"` is projected as clipping metadata rather than treated as an authoring error.
|
|
248
|
+
When CSS-like clipping, transform, opacity, or compositing behavior cannot be represented exactly in
|
|
249
|
+
PPTX yet, Project reports nonblocking warnings and preserves the observable projected values for
|
|
250
|
+
inspection.
|
|
251
|
+
|
|
252
|
+
Unsupported CSS-like meanings that can still produce a structurally valid PPTX are reported through
|
|
253
|
+
Project diagnostics and the inspection surface rather than treated as authoring errors. These records
|
|
254
|
+
include the unsupported feature, the projected value, and a fallback strategy describing which values
|
|
255
|
+
were preserved and which behavior is still missing. Malformed projected unsupported-semantic payloads
|
|
256
|
+
from custom projections fail before Render emits bytes.
|
|
163
257
|
|
|
164
258
|
## Development
|
|
165
259
|
|
|
166
260
|
```bash
|
|
167
261
|
vp install
|
|
168
262
|
vp check
|
|
263
|
+
bun run build
|
|
264
|
+
npm ci --prefix sample
|
|
265
|
+
npm run --prefix sample smoke
|
|
169
266
|
vp test
|
|
170
|
-
|
|
267
|
+
bun run benchmark:pptx -- --iterations 1 --strict
|
|
268
|
+
bun run verify:render -- --skip-raster
|
|
269
|
+
npm run --prefix .github/compat/pptxgenjs compare
|
|
171
270
|
```
|
|
271
|
+
|
|
272
|
+
For output or public-surface changes, keep the direct PPTX writer as the documented built-in path.
|
|
273
|
+
`pptxgenjs` should appear only in isolated regression tooling, not in runtime dependencies or public
|
|
274
|
+
adapter examples.
|