@hirokisakabe/pom 1.1.3 → 1.3.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 +130 -15
- package/dist/calcYogaLayout/calcYogaLayout.js +8 -1
- package/dist/component.d.ts +90 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +123 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/inputSchema.d.ts +300 -4
- package/dist/inputSchema.d.ts.map +1 -1
- package/dist/inputSchema.js +31 -1
- package/dist/renderPptx/nodes/image.d.ts.map +1 -1
- package/dist/renderPptx/nodes/image.js +19 -0
- package/dist/renderPptx/nodes/processArrow.d.ts.map +1 -1
- package/dist/renderPptx/nodes/processArrow.js +9 -0
- package/dist/renderPptx/nodes/shape.d.ts.map +1 -1
- package/dist/renderPptx/nodes/shape.js +6 -0
- package/dist/renderPptx/nodes/table.d.ts.map +1 -1
- package/dist/renderPptx/nodes/table.js +5 -0
- package/dist/renderPptx/renderPptx.d.ts +1 -1
- package/dist/renderPptx/renderPptx.d.ts.map +1 -1
- package/dist/renderPptx/renderPptx.js +31 -5
- package/dist/renderPptx/textOptions.d.ts +26 -1
- package/dist/renderPptx/textOptions.d.ts.map +1 -1
- package/dist/renderPptx/textOptions.js +27 -0
- package/dist/renderPptx/utils/backgroundBorder.d.ts +3 -1
- package/dist/renderPptx/utils/backgroundBorder.d.ts.map +1 -1
- package/dist/renderPptx/utils/backgroundBorder.js +103 -23
- package/dist/renderPptx/utils/textDrawing.d.ts +5 -0
- package/dist/renderPptx/utils/textDrawing.d.ts.map +1 -1
- package/dist/renderPptx/utils/textDrawing.js +6 -1
- package/dist/types.d.ts +401 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +63 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,24 +60,138 @@ await pptx.writeFile({ fileName: "presentation.pptx" });
|
|
|
60
60
|
|
|
61
61
|
## Available Nodes
|
|
62
62
|
|
|
63
|
-
| Node | Description
|
|
64
|
-
| ------------ |
|
|
65
|
-
| text | Text with font styling and bullet points
|
|
66
|
-
| image | Images from file path, URL, or base64
|
|
67
|
-
| table | Tables with customizable columns and rows
|
|
68
|
-
| shape | PowerPoint shapes (roundRect, ellipse, etc.)
|
|
69
|
-
| chart | Charts (bar, line, pie, area, doughnut, radar)
|
|
70
|
-
| timeline | Timeline/roadmap visualizations
|
|
71
|
-
| matrix | 2x2 positioning maps
|
|
72
|
-
| tree | Organization charts and decision trees
|
|
73
|
-
| flow | Flowcharts with nodes and edges
|
|
74
|
-
| processArrow | Chevron-style process diagrams
|
|
75
|
-
| box | Container for single child with padding
|
|
76
|
-
| vstack | Vertical stack layout
|
|
77
|
-
| hstack | Horizontal stack layout
|
|
63
|
+
| Node | Description |
|
|
64
|
+
| ------------ | ----------------------------------------------------- |
|
|
65
|
+
| text | Text with font styling, decoration, and bullet points |
|
|
66
|
+
| image | Images from file path, URL, or base64 |
|
|
67
|
+
| table | Tables with customizable columns and rows |
|
|
68
|
+
| shape | PowerPoint shapes (roundRect, ellipse, etc.) |
|
|
69
|
+
| chart | Charts (bar, line, pie, area, doughnut, radar) |
|
|
70
|
+
| timeline | Timeline/roadmap visualizations |
|
|
71
|
+
| matrix | 2x2 positioning maps |
|
|
72
|
+
| tree | Organization charts and decision trees |
|
|
73
|
+
| flow | Flowcharts with nodes and edges |
|
|
74
|
+
| processArrow | Chevron-style process diagrams |
|
|
75
|
+
| box | Container for single child with padding |
|
|
76
|
+
| vstack | Vertical stack layout |
|
|
77
|
+
| hstack | Horizontal stack layout |
|
|
78
78
|
|
|
79
79
|
For detailed node documentation, see [Nodes Reference](./docs/nodes.md).
|
|
80
80
|
|
|
81
|
+
## Components
|
|
82
|
+
|
|
83
|
+
pom provides a `defineComponent` helper for creating reusable component templates. Components are simple functions that take props and return a `POMNode` — no runtime magic, no new node types.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { defineComponent, mergeTheme, POMNode, Theme } from "@hirokisakabe/pom";
|
|
87
|
+
|
|
88
|
+
// Define a reusable card component
|
|
89
|
+
const SectionCard = defineComponent<{
|
|
90
|
+
title: string;
|
|
91
|
+
content: POMNode; // Slot: any POMNode
|
|
92
|
+
theme?: Partial<Theme>; // Theme override
|
|
93
|
+
}>((props) => {
|
|
94
|
+
const t = mergeTheme(props.theme);
|
|
95
|
+
return {
|
|
96
|
+
type: "box",
|
|
97
|
+
padding: t.spacing.md,
|
|
98
|
+
backgroundColor: "FFFFFF",
|
|
99
|
+
border: { color: t.colors.border, width: 1 },
|
|
100
|
+
borderRadius: 8,
|
|
101
|
+
children: {
|
|
102
|
+
type: "vstack",
|
|
103
|
+
gap: t.spacing.sm,
|
|
104
|
+
children: [
|
|
105
|
+
{
|
|
106
|
+
type: "text",
|
|
107
|
+
text: props.title,
|
|
108
|
+
fontPx: t.fontPx.heading,
|
|
109
|
+
bold: true,
|
|
110
|
+
},
|
|
111
|
+
props.content,
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Use the component
|
|
118
|
+
const slide: POMNode = {
|
|
119
|
+
type: "vstack",
|
|
120
|
+
w: 1280,
|
|
121
|
+
h: 720,
|
|
122
|
+
padding: 48,
|
|
123
|
+
gap: 24,
|
|
124
|
+
children: [
|
|
125
|
+
SectionCard({
|
|
126
|
+
title: "Revenue",
|
|
127
|
+
content: { type: "text", text: "$1,000,000" },
|
|
128
|
+
}),
|
|
129
|
+
SectionCard({
|
|
130
|
+
title: "Custom Theme",
|
|
131
|
+
content: { type: "text", text: "Styled card" },
|
|
132
|
+
theme: { colors: { border: "CBD5E1" } },
|
|
133
|
+
}),
|
|
134
|
+
],
|
|
135
|
+
};
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Components support:
|
|
139
|
+
|
|
140
|
+
- **Slots**: Pass `POMNode` or `POMNode[]` as props for content injection
|
|
141
|
+
- **Theme**: Use `mergeTheme()` for colors, spacing, and font size overrides
|
|
142
|
+
- **Nesting**: Components can call other components
|
|
143
|
+
- **JSON / LLM**: Use `expandComponents()` to resolve component references in JSON
|
|
144
|
+
|
|
145
|
+
### Using Components with LLM-generated JSON
|
|
146
|
+
|
|
147
|
+
When an LLM outputs JSON containing `{ type: "component", name: "...", props: {...} }`, use `expandComponentSlides()` to resolve them before building:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import {
|
|
151
|
+
buildPptx,
|
|
152
|
+
defineComponent,
|
|
153
|
+
expandComponentSlides,
|
|
154
|
+
} from "@hirokisakabe/pom";
|
|
155
|
+
|
|
156
|
+
// Register components
|
|
157
|
+
const SectionCard = defineComponent<{ title: string; content: unknown }>(
|
|
158
|
+
(props) => ({
|
|
159
|
+
type: "box",
|
|
160
|
+
padding: 16,
|
|
161
|
+
children: {
|
|
162
|
+
type: "vstack",
|
|
163
|
+
gap: 8,
|
|
164
|
+
children: [
|
|
165
|
+
{ type: "text", text: props.title, bold: true },
|
|
166
|
+
props.content,
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
}),
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const registry = { SectionCard };
|
|
173
|
+
|
|
174
|
+
// LLM output (JSON with component references)
|
|
175
|
+
const llmOutput = [
|
|
176
|
+
{
|
|
177
|
+
type: "vstack",
|
|
178
|
+
w: 1280,
|
|
179
|
+
h: 720,
|
|
180
|
+
children: [
|
|
181
|
+
{
|
|
182
|
+
type: "component",
|
|
183
|
+
name: "SectionCard",
|
|
184
|
+
props: { title: "KPI", content: { type: "text", text: "$1M" } },
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
// Expand → Build
|
|
191
|
+
const slides = expandComponentSlides(llmOutput, registry);
|
|
192
|
+
const pptx = await buildPptx(slides, { w: 1280, h: 720 });
|
|
193
|
+
```
|
|
194
|
+
|
|
81
195
|
## Documentation
|
|
82
196
|
|
|
83
197
|
| Document | Description |
|
|
@@ -86,6 +200,7 @@ For detailed node documentation, see [Nodes Reference](./docs/nodes.md).
|
|
|
86
200
|
| [Master Slide](./docs/master-slide.md) | Headers, footers, and page numbers |
|
|
87
201
|
| [Serverless Environments](./docs/serverless.md) | Text measurement options for serverless |
|
|
88
202
|
| [LLM Integration](./docs/llm-integration.md) | Guide for generating slides with AI/LLM |
|
|
203
|
+
| [Components](./docs/nodes.md#components) | Reusable component templates |
|
|
89
204
|
|
|
90
205
|
## License
|
|
91
206
|
|
|
@@ -35,6 +35,10 @@ async function prefetchAllImageSizes(node) {
|
|
|
35
35
|
function collectImageSources(node) {
|
|
36
36
|
const sources = [];
|
|
37
37
|
function traverse(n) {
|
|
38
|
+
// backgroundImage の src を収集(全ノード共通)
|
|
39
|
+
if (n.backgroundImage) {
|
|
40
|
+
sources.push(n.backgroundImage.src);
|
|
41
|
+
}
|
|
38
42
|
if (n.type === "image") {
|
|
39
43
|
sources.push(n.src);
|
|
40
44
|
}
|
|
@@ -73,7 +77,10 @@ async function buildPomWithYogaTree(node, parentYoga, parentNode) {
|
|
|
73
77
|
node.yogaNode = yn; // 対応する YogaNode をセット
|
|
74
78
|
await applyStyleToYogaNode(node, yn);
|
|
75
79
|
// HStack の子要素で幅が指定されていない場合、デフォルトで均等分割
|
|
76
|
-
|
|
80
|
+
// テーブルは setMeasureFunc でカラム幅合計を返すため除外
|
|
81
|
+
if (parentNode?.type === "hstack" &&
|
|
82
|
+
node.w === undefined &&
|
|
83
|
+
node.type !== "table") {
|
|
77
84
|
yn.setFlexGrow(1);
|
|
78
85
|
yn.setFlexBasis(0);
|
|
79
86
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { POMNode } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* 再利用可能なコンポーネントを定義する。
|
|
4
|
+
* Props を受け取り POMNode を返す関数を作成する。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const SectionCard = defineComponent<{
|
|
9
|
+
* title: string;
|
|
10
|
+
* content: POMNode;
|
|
11
|
+
* color?: string;
|
|
12
|
+
* }>((props) => ({
|
|
13
|
+
* type: "box",
|
|
14
|
+
* padding: 20,
|
|
15
|
+
* backgroundColor: "FFFFFF",
|
|
16
|
+
* border: { color: "E2E8F0", width: 1 },
|
|
17
|
+
* borderRadius: 8,
|
|
18
|
+
* children: {
|
|
19
|
+
* type: "vstack",
|
|
20
|
+
* gap: 12,
|
|
21
|
+
* children: [
|
|
22
|
+
* {
|
|
23
|
+
* type: "text",
|
|
24
|
+
* text: props.title,
|
|
25
|
+
* fontPx: 18,
|
|
26
|
+
* bold: true,
|
|
27
|
+
* color: props.color ?? "334155",
|
|
28
|
+
* },
|
|
29
|
+
* props.content,
|
|
30
|
+
* ],
|
|
31
|
+
* },
|
|
32
|
+
* }));
|
|
33
|
+
*
|
|
34
|
+
* // Usage:
|
|
35
|
+
* const node = SectionCard({
|
|
36
|
+
* title: "KPI Summary",
|
|
37
|
+
* content: { type: "text", text: "Revenue: $1M" },
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function defineComponent<Props>(render: (props: Props) => POMNode): (props: Props) => POMNode;
|
|
42
|
+
/**
|
|
43
|
+
* テーマ設定の型。コンポーネントにスタイルの一括オーバーライドを提供する。
|
|
44
|
+
*/
|
|
45
|
+
export type Theme = {
|
|
46
|
+
colors?: {
|
|
47
|
+
primary?: string;
|
|
48
|
+
secondary?: string;
|
|
49
|
+
background?: string;
|
|
50
|
+
text?: string;
|
|
51
|
+
border?: string;
|
|
52
|
+
accent?: string;
|
|
53
|
+
};
|
|
54
|
+
spacing?: {
|
|
55
|
+
xs?: number;
|
|
56
|
+
sm?: number;
|
|
57
|
+
md?: number;
|
|
58
|
+
lg?: number;
|
|
59
|
+
xl?: number;
|
|
60
|
+
};
|
|
61
|
+
fontPx?: {
|
|
62
|
+
title?: number;
|
|
63
|
+
heading?: number;
|
|
64
|
+
body?: number;
|
|
65
|
+
caption?: number;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
type RequiredTheme = {
|
|
69
|
+
colors: Required<NonNullable<Theme["colors"]>>;
|
|
70
|
+
spacing: Required<NonNullable<Theme["spacing"]>>;
|
|
71
|
+
fontPx: Required<NonNullable<Theme["fontPx"]>>;
|
|
72
|
+
};
|
|
73
|
+
export declare const defaultTheme: RequiredTheme;
|
|
74
|
+
/**
|
|
75
|
+
* デフォルトテーマとユーザー指定テーマをマージする。
|
|
76
|
+
*/
|
|
77
|
+
export declare function mergeTheme(theme?: Partial<Theme>): RequiredTheme;
|
|
78
|
+
export type ComponentRegistry = Record<string, (props: any) => POMNode>;
|
|
79
|
+
/**
|
|
80
|
+
* JSON 入力内のコンポーネントノードを展開して POMNode を返す。
|
|
81
|
+
* LLM が出力した JSON に `{ type: "component", name: "...", props: {...} }` が
|
|
82
|
+
* 含まれている場合、レジストリからコンポーネント関数を取得して展開する。
|
|
83
|
+
*/
|
|
84
|
+
export declare function expandComponents(input: unknown, registry: ComponentRegistry): POMNode;
|
|
85
|
+
/**
|
|
86
|
+
* 複数スライドの JSON 入力内のコンポーネントノードを展開する。
|
|
87
|
+
*/
|
|
88
|
+
export declare function expandComponentSlides(inputs: unknown[], registry: ComponentRegistry): POMNode[];
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,eAAe,CAAC,KAAK,EACnC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,GAChC,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAE3B;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,CAAC;IACF,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC/C,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,aAsB1B,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,aAAa,CAMhE;AAGD,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;AA0CxE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EAAE,EACjB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,EAAE,CAEX"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 再利用可能なコンポーネントを定義する。
|
|
3
|
+
* Props を受け取り POMNode を返す関数を作成する。
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* const SectionCard = defineComponent<{
|
|
8
|
+
* title: string;
|
|
9
|
+
* content: POMNode;
|
|
10
|
+
* color?: string;
|
|
11
|
+
* }>((props) => ({
|
|
12
|
+
* type: "box",
|
|
13
|
+
* padding: 20,
|
|
14
|
+
* backgroundColor: "FFFFFF",
|
|
15
|
+
* border: { color: "E2E8F0", width: 1 },
|
|
16
|
+
* borderRadius: 8,
|
|
17
|
+
* children: {
|
|
18
|
+
* type: "vstack",
|
|
19
|
+
* gap: 12,
|
|
20
|
+
* children: [
|
|
21
|
+
* {
|
|
22
|
+
* type: "text",
|
|
23
|
+
* text: props.title,
|
|
24
|
+
* fontPx: 18,
|
|
25
|
+
* bold: true,
|
|
26
|
+
* color: props.color ?? "334155",
|
|
27
|
+
* },
|
|
28
|
+
* props.content,
|
|
29
|
+
* ],
|
|
30
|
+
* },
|
|
31
|
+
* }));
|
|
32
|
+
*
|
|
33
|
+
* // Usage:
|
|
34
|
+
* const node = SectionCard({
|
|
35
|
+
* title: "KPI Summary",
|
|
36
|
+
* content: { type: "text", text: "Revenue: $1M" },
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function defineComponent(render) {
|
|
41
|
+
return render;
|
|
42
|
+
}
|
|
43
|
+
export const defaultTheme = {
|
|
44
|
+
colors: {
|
|
45
|
+
primary: "1D4ED8",
|
|
46
|
+
secondary: "64748B",
|
|
47
|
+
background: "F8FAFC",
|
|
48
|
+
text: "1E293B",
|
|
49
|
+
border: "E2E8F0",
|
|
50
|
+
accent: "0EA5E9",
|
|
51
|
+
},
|
|
52
|
+
spacing: {
|
|
53
|
+
xs: 4,
|
|
54
|
+
sm: 8,
|
|
55
|
+
md: 16,
|
|
56
|
+
lg: 24,
|
|
57
|
+
xl: 48,
|
|
58
|
+
},
|
|
59
|
+
fontPx: {
|
|
60
|
+
title: 32,
|
|
61
|
+
heading: 20,
|
|
62
|
+
body: 14,
|
|
63
|
+
caption: 11,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* デフォルトテーマとユーザー指定テーマをマージする。
|
|
68
|
+
*/
|
|
69
|
+
export function mergeTheme(theme) {
|
|
70
|
+
return {
|
|
71
|
+
colors: { ...defaultTheme.colors, ...theme?.colors },
|
|
72
|
+
spacing: { ...defaultTheme.spacing, ...theme?.spacing },
|
|
73
|
+
fontPx: { ...defaultTheme.fontPx, ...theme?.fontPx },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function isRecord(value) {
|
|
77
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
78
|
+
}
|
|
79
|
+
function expandNode(input, registry) {
|
|
80
|
+
if (Array.isArray(input)) {
|
|
81
|
+
return input.map((item) => expandNode(item, registry));
|
|
82
|
+
}
|
|
83
|
+
if (!isRecord(input)) {
|
|
84
|
+
return input;
|
|
85
|
+
}
|
|
86
|
+
if (input.type === "component") {
|
|
87
|
+
const name = input.name;
|
|
88
|
+
const fn = registry[name];
|
|
89
|
+
if (!fn) {
|
|
90
|
+
throw new Error(`Unknown component: "${name}"`);
|
|
91
|
+
}
|
|
92
|
+
const rawProps = isRecord(input.props) ? input.props : {};
|
|
93
|
+
const expandedProps = Object.fromEntries(Object.entries(rawProps).map(([key, value]) => [
|
|
94
|
+
key,
|
|
95
|
+
expandNode(value, registry),
|
|
96
|
+
]));
|
|
97
|
+
return expandNode(fn(expandedProps), registry);
|
|
98
|
+
}
|
|
99
|
+
const result = {};
|
|
100
|
+
for (const [key, value] of Object.entries(input)) {
|
|
101
|
+
if (key === "children") {
|
|
102
|
+
result[key] = expandNode(value, registry);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
result[key] = value;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* JSON 入力内のコンポーネントノードを展開して POMNode を返す。
|
|
112
|
+
* LLM が出力した JSON に `{ type: "component", name: "...", props: {...} }` が
|
|
113
|
+
* 含まれている場合、レジストリからコンポーネント関数を取得して展開する。
|
|
114
|
+
*/
|
|
115
|
+
export function expandComponents(input, registry) {
|
|
116
|
+
return expandNode(input, registry);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 複数スライドの JSON 入力内のコンポーネントノードを展開する。
|
|
120
|
+
*/
|
|
121
|
+
export function expandComponentSlides(inputs, registry) {
|
|
122
|
+
return inputs.map((input) => expandComponents(input, registry));
|
|
123
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ export * from "./types.ts";
|
|
|
2
2
|
export * from "./inputSchema.ts";
|
|
3
3
|
export { buildPptx } from "./buildPptx.ts";
|
|
4
4
|
export type { TextMeasurementMode } from "./buildPptx.ts";
|
|
5
|
+
export { defineComponent, defaultTheme, mergeTheme, expandComponents, expandComponentSlides, } from "./component.ts";
|
|
6
|
+
export type { Theme, ComponentRegistry } from "./component.ts";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EACL,eAAe,EACf,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED