@particle-academy/fancy-slides 0.5.0 → 0.6.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/dist/chart-host-ZJE7WAHE.js +30 -0
- package/dist/chart-host-ZJE7WAHE.js.map +1 -0
- package/dist/chunk-4HHEWTDW.js +45 -0
- package/dist/chunk-4HHEWTDW.js.map +1 -0
- package/dist/chunk-YEJZYKVB.js +44 -0
- package/dist/chunk-YEJZYKVB.js.map +1 -0
- package/dist/code-host-ZLDVJP2X.js +33 -0
- package/dist/code-host-ZLDVJP2X.js.map +1 -0
- package/dist/index.cjs +286 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +35 -3
- package/dist/index.js.map +1 -1
- package/dist/registry.cjs +82 -12
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +1 -42
- package/dist/registry.js.map +1 -1
- package/package.json +1 -1
- package/dist/chart-host-X55F6S44.js +0 -15
- package/dist/chart-host-X55F6S44.js.map +0 -1
- package/dist/code-host-IYT6QDLA.js +0 -21
- package/dist/code-host-IYT6QDLA.js.map +0 -1
package/dist/registry.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
|
-
var fancyEcharts = require('@particle-academy/fancy-echarts');
|
|
5
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
var fancyCode = require('@particle-academy/fancy-code');
|
|
7
5
|
var reactFancy = require('@particle-academy/react-fancy');
|
|
8
6
|
|
|
9
7
|
var __defProp = Object.defineProperty;
|
|
@@ -24,6 +22,48 @@ var init_slide_context = __esm({
|
|
|
24
22
|
SlideContext = react.createContext(null);
|
|
25
23
|
}
|
|
26
24
|
});
|
|
25
|
+
function PeerMissing({ label, install }) {
|
|
26
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
27
|
+
"div",
|
|
28
|
+
{
|
|
29
|
+
style: {
|
|
30
|
+
width: "100%",
|
|
31
|
+
height: "100%",
|
|
32
|
+
display: "flex",
|
|
33
|
+
flexDirection: "column",
|
|
34
|
+
alignItems: "center",
|
|
35
|
+
justifyContent: "center",
|
|
36
|
+
gap: "0.4em",
|
|
37
|
+
textAlign: "center",
|
|
38
|
+
padding: "0.6em",
|
|
39
|
+
boxSizing: "border-box",
|
|
40
|
+
border: "1px dashed currentColor",
|
|
41
|
+
borderRadius: 8,
|
|
42
|
+
opacity: 0.6,
|
|
43
|
+
overflow: "hidden",
|
|
44
|
+
fontFamily: "ui-sans-serif, system-ui, sans-serif"
|
|
45
|
+
},
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600 }, children: label }),
|
|
48
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
49
|
+
"code",
|
|
50
|
+
{
|
|
51
|
+
style: {
|
|
52
|
+
fontSize: "0.72em",
|
|
53
|
+
opacity: 0.85,
|
|
54
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
55
|
+
},
|
|
56
|
+
children: install
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
var init_peer_missing = __esm({
|
|
64
|
+
"src/registry/element-renderers/peer-missing.tsx"() {
|
|
65
|
+
}
|
|
66
|
+
});
|
|
27
67
|
|
|
28
68
|
// src/registry/element-renderers/chart-host.tsx
|
|
29
69
|
var chart_host_exports = {};
|
|
@@ -33,13 +73,29 @@ __export(chart_host_exports, {
|
|
|
33
73
|
function ChartHost({ element }) {
|
|
34
74
|
const isDarkSlide = useIsDarkSlide();
|
|
35
75
|
const theme = element.chartTheme ?? (isDarkSlide ? "dark" : void 0);
|
|
36
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
76
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ChartInner, { option: element.option, theme }) });
|
|
37
77
|
}
|
|
78
|
+
var ChartInner;
|
|
38
79
|
var init_chart_host = __esm({
|
|
39
80
|
"src/registry/element-renderers/chart-host.tsx"() {
|
|
40
81
|
init_slide_context();
|
|
41
|
-
|
|
42
|
-
|
|
82
|
+
init_peer_missing();
|
|
83
|
+
ChartInner = react.lazy(async () => {
|
|
84
|
+
try {
|
|
85
|
+
const mod = await import('@particle-academy/fancy-echarts');
|
|
86
|
+
const EChart = mod.EChart;
|
|
87
|
+
if (!EChart) {
|
|
88
|
+
return { default: () => /* @__PURE__ */ jsxRuntime.jsx(PeerMissing, { label: "Chart", install: "npm i @particle-academy/fancy-echarts" }) };
|
|
89
|
+
}
|
|
90
|
+
mod.registerAll?.();
|
|
91
|
+
mod.registerBuiltinThemes?.();
|
|
92
|
+
return {
|
|
93
|
+
default: ({ option, theme }) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(EChart, { option, theme }) })
|
|
94
|
+
};
|
|
95
|
+
} catch {
|
|
96
|
+
return { default: () => /* @__PURE__ */ jsxRuntime.jsx(PeerMissing, { label: "Chart", install: "npm i @particle-academy/fancy-echarts" }) };
|
|
97
|
+
}
|
|
98
|
+
});
|
|
43
99
|
}
|
|
44
100
|
});
|
|
45
101
|
|
|
@@ -49,20 +105,34 @@ __export(code_host_exports, {
|
|
|
49
105
|
default: () => CodeHost
|
|
50
106
|
});
|
|
51
107
|
function CodeHost({ element }) {
|
|
52
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
53
|
-
|
|
108
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
109
|
+
CodeInner,
|
|
54
110
|
{
|
|
55
|
-
|
|
111
|
+
code: element.code,
|
|
56
112
|
language: element.language ?? "javascript",
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
lineNumbers: element.lineNumbers ?? true,
|
|
60
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(fancyCode.CodeEditor.Panel, {})
|
|
113
|
+
codeTheme: element.codeTheme ?? "dark",
|
|
114
|
+
lineNumbers: element.lineNumbers ?? true
|
|
61
115
|
}
|
|
62
116
|
) });
|
|
63
117
|
}
|
|
118
|
+
var CodeInner;
|
|
64
119
|
var init_code_host = __esm({
|
|
65
120
|
"src/registry/element-renderers/code-host.tsx"() {
|
|
121
|
+
init_peer_missing();
|
|
122
|
+
CodeInner = react.lazy(async () => {
|
|
123
|
+
try {
|
|
124
|
+
const mod = await import('@particle-academy/fancy-code');
|
|
125
|
+
const CodeEditor = mod.CodeEditor;
|
|
126
|
+
if (!CodeEditor) {
|
|
127
|
+
return { default: () => /* @__PURE__ */ jsxRuntime.jsx(PeerMissing, { label: "Code", install: "npm i @particle-academy/fancy-code" }) };
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
default: ({ code, language, codeTheme, lineNumbers }) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "100%", height: "100%", overflow: "hidden", borderRadius: 8 }, children: /* @__PURE__ */ jsxRuntime.jsx(CodeEditor, { value: code, language, theme: codeTheme, readOnly: true, lineNumbers, children: /* @__PURE__ */ jsxRuntime.jsx(CodeEditor.Panel, {}) }) })
|
|
131
|
+
};
|
|
132
|
+
} catch {
|
|
133
|
+
return { default: () => /* @__PURE__ */ jsxRuntime.jsx(PeerMissing, { label: "Code", install: "npm i @particle-academy/fancy-code" }) };
|
|
134
|
+
}
|
|
135
|
+
});
|
|
66
136
|
}
|
|
67
137
|
});
|
|
68
138
|
|
package/dist/registry.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Slide/slide-context.ts","../src/registry/element-renderers/chart-host.tsx","../src/registry/element-renderers/code-host.tsx","../src/registry/element-renderers/table-host.tsx","../src/registry/element-renderers/embed-host.tsx","../src/registry/index.tsx"],"names":["useContext","createContext","jsx","EChart","registerAll","registerBuiltinThemes","CodeEditor","jsxs","Table","ChartHost","lazy","CodeHost","TableHost","EmbedHost","Suspense"],"mappings":"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","file":"registry.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { Theme } from \"../../types\";\n\n/**\n * What the surrounding <Slide> knows about itself. Exposed to children\n * (including `renderElement` callbacks and registry hosts like chart-host)\n * via React context so they can react to the deck's theme without the\n * renderElement signature having to carry it around.\n */\nexport interface SlideContextValue {\n /** Fully-resolved theme (merged with defaults). */\n theme: Theme;\n /**\n * Heuristic: true when the resolved background is dark enough that\n * native-rendered widgets (charts, code blocks) should use a dark variant.\n * Computed once from `theme.colors.background` luminance.\n */\n isDark: boolean;\n /** Slide width in CSS pixels at the current render size. */\n slideWidthPx: number;\n}\n\nexport const SlideContext = createContext<SlideContextValue | null>(null);\n\n/**\n * Read the surrounding <Slide>'s context. Returns null when called outside\n * a Slide — chart-host / code-host can use that signal to fall back to\n * a sensible default (light theme, no resize anchor).\n */\nexport function useSlideContext(): SlideContextValue | null {\n return useContext(SlideContext);\n}\n\n/**\n * Convenience: returns the resolved theme, or undefined when the caller\n * isn't inside a Slide.\n */\nexport function useSlideTheme(): Theme | undefined {\n return useContext(SlideContext)?.theme;\n}\n\n/**\n * Convenience: returns true when the surrounding slide's background reads\n * as \"dark enough\" — useful for charts/code blocks that ship a dark variant.\n */\nexport function useIsDarkSlide(): boolean {\n return useContext(SlideContext)?.isDark ?? false;\n}\n\n/** Compute `isDark` from a hex/rgb colour. Used by Slide when building the context. */\nexport function isDarkColor(color: string): boolean {\n // Normalise #rgb / #rrggbb / rgb()/rgba() to a triple.\n const m = color.match(/^#([0-9a-f]{3,8})$/i);\n if (m) {\n let hex = m[1];\n if (hex.length === 3) {\n hex = hex.split(\"\").map((c) => c + c).join(\"\");\n }\n if (hex.length >= 6) {\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n return relativeLuminance(r, g, b) < 0.5;\n }\n }\n const rgb = color.match(/rgba?\\(([^)]+)\\)/i);\n if (rgb) {\n const [r, g, b] = rgb[1].split(\",\").map((s) => parseInt(s.trim(), 10));\n if (!Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b)) {\n return relativeLuminance(r, g, b) < 0.5;\n }\n }\n return false;\n}\n\nfunction relativeLuminance(r: number, g: number, b: number): number {\n // Standard sRGB → relative luminance.\n const toLinear = (c: number) => {\n const v = c / 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n };\n return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n","import { EChart, registerAll, registerBuiltinThemes } from \"@particle-academy/fancy-echarts\";\nimport type { ChartElement } from \"../../types\";\nimport { useIsDarkSlide } from \"../../components/Slide/slide-context\";\n\n// fancy-echarts ships its chart types as opt-in tree-shake-friendly modules,\n// so the consumer normally calls `registerAll()` somewhere global. The\n// registry subpath here is the natural spot to wire it: this module only\n// loads when a deck actually contains a chart element (defaultElementRegistry\n// is React.lazy), so the registration cost is paid by chart-using hosts\n// only — non-chart consumers never even import this file.\n//\n// `registerAll()` is idempotent on echarts' side, so re-imports across\n// chunks are safe.\nregisterAll();\nregisterBuiltinThemes();\n\nexport default function ChartHost({ element }: { element: ChartElement; slideWidthPx: number }) {\n // If the slide background reads as dark and the chart doesn't already\n // pin a theme explicitly, fall back to echarts' built-in \"dark\" theme\n // so the chart legend/axis/tooltip text stay legible.\n const isDarkSlide = useIsDarkSlide();\n const theme = element.chartTheme ?? (isDarkSlide ? \"dark\" : undefined);\n return (\n <div style={{ width: \"100%\", height: \"100%\" }}>\n <EChart option={element.option as Parameters<typeof EChart>[0][\"option\"]} theme={theme} />\n </div>\n );\n}\n","import { CodeEditor } from \"@particle-academy/fancy-code\";\nimport type { CodeElement } from \"../../types\";\n\nexport default function CodeHost({ element }: { element: CodeElement }) {\n return (\n <div style={{ width: \"100%\", height: \"100%\", overflow: \"hidden\", borderRadius: 8 }}>\n <CodeEditor\n value={element.code}\n language={element.language ?? \"javascript\"}\n theme={element.codeTheme ?? \"dark\"}\n readOnly\n lineNumbers={element.lineNumbers ?? true}\n >\n <CodeEditor.Panel />\n </CodeEditor>\n </div>\n );\n}\n","import { Table } from \"@particle-academy/react-fancy\";\nimport type { TableElement } from \"../../types\";\n\nexport default function TableHost({ element }: { element: TableElement }) {\n return (\n <div style={{ width: \"100%\", height: \"100%\", overflow: \"auto\" }}>\n <Table className=\"w-full\">\n <Table.Head>\n <Table.Row>\n {element.columns.map((c) => (\n <Table.Cell key={c.key} header>\n {c.label}\n </Table.Cell>\n ))}\n </Table.Row>\n </Table.Head>\n <Table.Body>\n {element.rows.map((row, i) => (\n <Table.Row key={i}>\n {element.columns.map((c) => (\n <Table.Cell key={c.key}>{formatCell(row[c.key])}</Table.Cell>\n ))}\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n </div>\n );\n}\n\nfunction formatCell(v: unknown): string {\n if (v == null) return \"\";\n if (typeof v === \"object\") return JSON.stringify(v);\n return String(v);\n}\n","import type { EmbedElement } from \"../../types\";\n\nexport default function EmbedHost({ element }: { element: EmbedElement }) {\n return (\n <iframe\n src={element.src}\n title={element.title ?? \"Embedded content\"}\n sandbox={element.sandbox ?? \"allow-scripts\"}\n style={{ width: \"100%\", height: \"100%\", border: 0, display: \"block\" }}\n />\n );\n}\n","/**\n * Default element registry. Wires up the element types fancy-slides doesn't\n * render natively (chart / code / table / embed) by composing the other\n * fancy packages as optional peer deps.\n *\n * Hosts opt into this by importing from the `/registry` subpath:\n *\n * import { defaultElementRegistry } from \"@particle-academy/fancy-slides/registry\";\n * <DeckEditor renderElement={defaultElementRegistry} … />\n *\n * Keeping it behind a subpath means consumers who only render decks with\n * built-in element types (text / image / shape) never pull fancy-echarts,\n * fancy-code, or react-fancy Table into their bundle.\n */\n\nimport { lazy, Suspense } from \"react\";\nimport type { ChartElement, CodeElement, SlideElement, EmbedElement, TableElement } from \"../types\";\n\nconst ChartHost = lazy(() => import(\"./element-renderers/chart-host\"));\nconst CodeHost = lazy(() => import(\"./element-renderers/code-host\"));\nconst TableHost = lazy(() => import(\"./element-renderers/table-host\"));\nconst EmbedHost = lazy(() => import(\"./element-renderers/embed-host\"));\n\nconst Loading = ({ label }: { label: string }) => (\n <div\n style={{\n display: \"grid\",\n placeItems: \"center\",\n width: \"100%\",\n height: \"100%\",\n color: \"rgba(0,0,0,0.4)\",\n fontSize: 12,\n fontFamily: \"ui-sans-serif, system-ui, sans-serif\",\n }}\n >\n {label}…\n </div>\n);\n\n/**\n * Renderer signature compatible with `Slide`'s `renderElement` prop. Returns\n * `undefined` for element types fancy-slides handles itself, so the call\n * site falls back to the built-in renderer.\n */\nexport function defaultElementRegistry(element: SlideElement, slideWidthPx: number) {\n switch (element.type) {\n case \"chart\":\n return (\n <Suspense fallback={<Loading label=\"Loading chart\" />}>\n <ChartHost element={element as ChartElement} slideWidthPx={slideWidthPx} />\n </Suspense>\n );\n case \"code\":\n return (\n <Suspense fallback={<Loading label=\"Loading code\" />}>\n <CodeHost element={element as CodeElement} />\n </Suspense>\n );\n case \"table\":\n return (\n <Suspense fallback={<Loading label=\"Loading table\" />}>\n <TableHost element={element as TableElement} />\n </Suspense>\n );\n case \"embed\":\n return (\n <Suspense fallback={<Loading label=\"Loading embed\" />}>\n <EmbedHost element={element as EmbedElement} />\n </Suspense>\n );\n default:\n return undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/Slide/slide-context.ts","../src/registry/element-renderers/peer-missing.tsx","../src/registry/element-renderers/chart-host.tsx","../src/registry/element-renderers/code-host.tsx","../src/registry/element-renderers/table-host.tsx","../src/registry/element-renderers/embed-host.tsx","../src/registry/index.tsx"],"names":["useContext","createContext","jsxs","jsx","Suspense","lazy","Table","ChartHost","CodeHost","TableHost","EmbedHost"],"mappings":"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","file":"registry.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { Theme } from \"../../types\";\n\n/**\n * What the surrounding <Slide> knows about itself. Exposed to children\n * (including `renderElement` callbacks and registry hosts like chart-host)\n * via React context so they can react to the deck's theme without the\n * renderElement signature having to carry it around.\n */\nexport interface SlideContextValue {\n /** Fully-resolved theme (merged with defaults). */\n theme: Theme;\n /**\n * Heuristic: true when the resolved background is dark enough that\n * native-rendered widgets (charts, code blocks) should use a dark variant.\n * Computed once from `theme.colors.background` luminance.\n */\n isDark: boolean;\n /** Slide width in CSS pixels at the current render size. */\n slideWidthPx: number;\n}\n\nexport const SlideContext = createContext<SlideContextValue | null>(null);\n\n/**\n * Read the surrounding <Slide>'s context. Returns null when called outside\n * a Slide — chart-host / code-host can use that signal to fall back to\n * a sensible default (light theme, no resize anchor).\n */\nexport function useSlideContext(): SlideContextValue | null {\n return useContext(SlideContext);\n}\n\n/**\n * Convenience: returns the resolved theme, or undefined when the caller\n * isn't inside a Slide.\n */\nexport function useSlideTheme(): Theme | undefined {\n return useContext(SlideContext)?.theme;\n}\n\n/**\n * Convenience: returns true when the surrounding slide's background reads\n * as \"dark enough\" — useful for charts/code blocks that ship a dark variant.\n */\nexport function useIsDarkSlide(): boolean {\n return useContext(SlideContext)?.isDark ?? false;\n}\n\n/** Compute `isDark` from a hex/rgb colour. Used by Slide when building the context. */\nexport function isDarkColor(color: string): boolean {\n // Normalise #rgb / #rrggbb / rgb()/rgba() to a triple.\n const m = color.match(/^#([0-9a-f]{3,8})$/i);\n if (m) {\n let hex = m[1];\n if (hex.length === 3) {\n hex = hex.split(\"\").map((c) => c + c).join(\"\");\n }\n if (hex.length >= 6) {\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n return relativeLuminance(r, g, b) < 0.5;\n }\n }\n const rgb = color.match(/rgba?\\(([^)]+)\\)/i);\n if (rgb) {\n const [r, g, b] = rgb[1].split(\",\").map((s) => parseInt(s.trim(), 10));\n if (!Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b)) {\n return relativeLuminance(r, g, b) < 0.5;\n }\n }\n return false;\n}\n\nfunction relativeLuminance(r: number, g: number, b: number): number {\n // Standard sRGB → relative luminance.\n const toLinear = (c: number) => {\n const v = c / 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n };\n return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n","/**\n * Placeholder shown when an OPTIONAL peer package isn't installed. The\n * chart / code hosts load their peer (`fancy-echarts` / `fancy-code`) via a\n * guarded dynamic import; if that import resolves to a stub (because the\n * consumer never installed the peer), the host renders this instead of\n * crashing — and, crucially, the consumer's build never fails on a missing\n * static import.\n *\n * Inline styles only (no Tailwind), fills 100%×100% so it drops into the\n * element box exactly like the real widget would.\n */\nexport function PeerMissing({ label, install }: { label: string; install: string }) {\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"0.4em\",\n textAlign: \"center\",\n padding: \"0.6em\",\n boxSizing: \"border-box\",\n border: \"1px dashed currentColor\",\n borderRadius: 8,\n opacity: 0.6,\n overflow: \"hidden\",\n fontFamily: \"ui-sans-serif, system-ui, sans-serif\",\n }}\n >\n <span style={{ fontWeight: 600 }}>{label}</span>\n <code\n style={{\n fontSize: \"0.72em\",\n opacity: 0.85,\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n }}\n >\n {install}\n </code>\n </div>\n );\n}\n","import { lazy, Suspense, type ComponentType } from \"react\";\nimport type { ChartElement } from \"../../types\";\nimport { useIsDarkSlide } from \"../../components/Slide/slide-context\";\nimport { PeerMissing } from \"./peer-missing\";\n\n/**\n * fancy-echarts is an OPTIONAL peer. A static `import { EChart } from\n * \"@particle-academy/fancy-echarts\"` would make Rollup statically resolve the\n * peer when a CONSUMER builds — and blow up with MISSING_EXPORT if they never\n * installed it. So instead we load the peer via a DYNAMIC import and read its\n * members off the resolved module at RUNTIME, guarding for the stub case.\n *\n * The dynamic `import().then(m => …)` resolves to the optional-peer stub when\n * the peer is absent (`m.EChart` is `undefined`), which we detect and swap for\n * a placeholder — no build-time named binding to break.\n */\ninterface InnerProps {\n option: unknown;\n theme: string | undefined;\n}\n\nconst ChartInner: ComponentType<InnerProps> = lazy(async () => {\n try {\n const mod: Record<string, unknown> = await import(\"@particle-academy/fancy-echarts\");\n const EChart = mod.EChart as\n | ComponentType<{ option: unknown; theme?: string }>\n | undefined;\n if (!EChart) {\n return { default: () => <PeerMissing label=\"Chart\" install=\"npm i @particle-academy/fancy-echarts\" /> };\n }\n // fancy-echarts ships its chart types as opt-in tree-shake-friendly\n // modules, so the consumer normally calls `registerAll()` somewhere\n // global. We wire it here, but only once the peer has actually loaded —\n // both calls are idempotent on echarts' side, so re-imports are safe.\n (mod.registerAll as (() => void) | undefined)?.();\n (mod.registerBuiltinThemes as (() => void) | undefined)?.();\n return {\n default: ({ option, theme }: InnerProps) => (\n <div style={{ width: \"100%\", height: \"100%\" }}>\n <EChart option={option} theme={theme} />\n </div>\n ),\n };\n } catch {\n return { default: () => <PeerMissing label=\"Chart\" install=\"npm i @particle-academy/fancy-echarts\" /> };\n }\n});\n\nexport default function ChartHost({ element }: { element: ChartElement; slideWidthPx: number }) {\n // Hooks stay in the OUTER component (Rules of Hooks); resolved values are\n // passed into the lazily-loaded inner. If the slide background reads as dark\n // and the chart doesn't pin a theme, fall back to echarts' built-in \"dark\".\n const isDarkSlide = useIsDarkSlide();\n const theme = element.chartTheme ?? (isDarkSlide ? \"dark\" : undefined);\n return (\n <Suspense fallback={null}>\n <ChartInner option={element.option} theme={theme} />\n </Suspense>\n );\n}\n","import { lazy, Suspense, type ComponentType } from \"react\";\nimport type { CodeElement } from \"../../types\";\nimport { PeerMissing } from \"./peer-missing\";\n\n/**\n * fancy-code is an OPTIONAL peer. As with chart-host, a static\n * `import { CodeEditor } from \"@particle-academy/fancy-code\"` would make\n * Rollup statically resolve the peer at CONSUMER build time and fail with\n * MISSING_EXPORT when it isn't installed. We load it via a DYNAMIC import and\n * read `CodeEditor` off the resolved module at RUNTIME, guarding the stub case.\n */\ninterface InnerProps {\n code: string;\n language: string;\n codeTheme: string;\n lineNumbers: boolean;\n}\n\nconst CodeInner: ComponentType<InnerProps> = lazy(async () => {\n try {\n const mod: Record<string, unknown> = await import(\"@particle-academy/fancy-code\");\n // CodeEditor is a component with a static `.Panel` sub-component.\n const CodeEditor = mod.CodeEditor as\n | (ComponentType<{\n value: string;\n language: string;\n theme: string;\n readOnly?: boolean;\n lineNumbers?: boolean;\n children?: React.ReactNode;\n }> & { Panel: ComponentType })\n | undefined;\n if (!CodeEditor) {\n return { default: () => <PeerMissing label=\"Code\" install=\"npm i @particle-academy/fancy-code\" /> };\n }\n return {\n default: ({ code, language, codeTheme, lineNumbers }: InnerProps) => (\n <div style={{ width: \"100%\", height: \"100%\", overflow: \"hidden\", borderRadius: 8 }}>\n <CodeEditor value={code} language={language} theme={codeTheme} readOnly lineNumbers={lineNumbers}>\n <CodeEditor.Panel />\n </CodeEditor>\n </div>\n ),\n };\n } catch {\n return { default: () => <PeerMissing label=\"Code\" install=\"npm i @particle-academy/fancy-code\" /> };\n }\n});\n\nexport default function CodeHost({ element }: { element: CodeElement }) {\n return (\n <Suspense fallback={null}>\n <CodeInner\n code={element.code}\n language={element.language ?? \"javascript\"}\n codeTheme={element.codeTheme ?? \"dark\"}\n lineNumbers={element.lineNumbers ?? true}\n />\n </Suspense>\n );\n}\n","import { Table } from \"@particle-academy/react-fancy\";\nimport type { TableElement } from \"../../types\";\n\nexport default function TableHost({ element }: { element: TableElement }) {\n return (\n <div style={{ width: \"100%\", height: \"100%\", overflow: \"auto\" }}>\n <Table className=\"w-full\">\n <Table.Head>\n <Table.Row>\n {element.columns.map((c) => (\n <Table.Cell key={c.key} header>\n {c.label}\n </Table.Cell>\n ))}\n </Table.Row>\n </Table.Head>\n <Table.Body>\n {element.rows.map((row, i) => (\n <Table.Row key={i}>\n {element.columns.map((c) => (\n <Table.Cell key={c.key}>{formatCell(row[c.key])}</Table.Cell>\n ))}\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n </div>\n );\n}\n\nfunction formatCell(v: unknown): string {\n if (v == null) return \"\";\n if (typeof v === \"object\") return JSON.stringify(v);\n return String(v);\n}\n","import type { EmbedElement } from \"../../types\";\n\nexport default function EmbedHost({ element }: { element: EmbedElement }) {\n return (\n <iframe\n src={element.src}\n title={element.title ?? \"Embedded content\"}\n sandbox={element.sandbox ?? \"allow-scripts\"}\n style={{ width: \"100%\", height: \"100%\", border: 0, display: \"block\" }}\n />\n );\n}\n","/**\n * Default element registry. Wires up the element types fancy-slides doesn't\n * render natively (chart / code / table / embed) by composing the other\n * fancy packages as optional peer deps.\n *\n * Hosts opt into this by importing from the `/registry` subpath:\n *\n * import { defaultElementRegistry } from \"@particle-academy/fancy-slides/registry\";\n * <DeckEditor renderElement={defaultElementRegistry} … />\n *\n * Keeping it behind a subpath means consumers who only render decks with\n * built-in element types (text / image / shape) never pull fancy-echarts,\n * fancy-code, or react-fancy Table into their bundle.\n */\n\nimport { lazy, Suspense } from \"react\";\nimport type { ChartElement, CodeElement, SlideElement, EmbedElement, TableElement } from \"../types\";\n\nconst ChartHost = lazy(() => import(\"./element-renderers/chart-host\"));\nconst CodeHost = lazy(() => import(\"./element-renderers/code-host\"));\nconst TableHost = lazy(() => import(\"./element-renderers/table-host\"));\nconst EmbedHost = lazy(() => import(\"./element-renderers/embed-host\"));\n\nconst Loading = ({ label }: { label: string }) => (\n <div\n style={{\n display: \"grid\",\n placeItems: \"center\",\n width: \"100%\",\n height: \"100%\",\n color: \"rgba(0,0,0,0.4)\",\n fontSize: 12,\n fontFamily: \"ui-sans-serif, system-ui, sans-serif\",\n }}\n >\n {label}…\n </div>\n);\n\n/**\n * Renderer signature compatible with `Slide`'s `renderElement` prop. Returns\n * `undefined` for element types fancy-slides handles itself, so the call\n * site falls back to the built-in renderer.\n */\nexport function defaultElementRegistry(element: SlideElement, slideWidthPx: number) {\n switch (element.type) {\n case \"chart\":\n return (\n <Suspense fallback={<Loading label=\"Loading chart\" />}>\n <ChartHost element={element as ChartElement} slideWidthPx={slideWidthPx} />\n </Suspense>\n );\n case \"code\":\n return (\n <Suspense fallback={<Loading label=\"Loading code\" />}>\n <CodeHost element={element as CodeElement} />\n </Suspense>\n );\n case \"table\":\n return (\n <Suspense fallback={<Loading label=\"Loading table\" />}>\n <TableHost element={element as TableElement} />\n </Suspense>\n );\n case \"embed\":\n return (\n <Suspense fallback={<Loading label=\"Loading embed\" />}>\n <EmbedHost element={element as EmbedElement} />\n </Suspense>\n );\n default:\n return undefined;\n }\n}\n"]}
|
package/dist/registry.js
CHANGED
|
@@ -1,44 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
|
|
4
|
-
// src/registry/index.tsx
|
|
5
|
-
var ChartHost = lazy(() => import('./chart-host-X55F6S44.js'));
|
|
6
|
-
var CodeHost = lazy(() => import('./code-host-IYT6QDLA.js'));
|
|
7
|
-
var TableHost = lazy(() => import('./table-host-LWPOQHTL.js'));
|
|
8
|
-
var EmbedHost = lazy(() => import('./embed-host-ZECUEAOU.js'));
|
|
9
|
-
var Loading = ({ label }) => /* @__PURE__ */ jsxs(
|
|
10
|
-
"div",
|
|
11
|
-
{
|
|
12
|
-
style: {
|
|
13
|
-
display: "grid",
|
|
14
|
-
placeItems: "center",
|
|
15
|
-
width: "100%",
|
|
16
|
-
height: "100%",
|
|
17
|
-
color: "rgba(0,0,0,0.4)",
|
|
18
|
-
fontSize: 12,
|
|
19
|
-
fontFamily: "ui-sans-serif, system-ui, sans-serif"
|
|
20
|
-
},
|
|
21
|
-
children: [
|
|
22
|
-
label,
|
|
23
|
-
"\u2026"
|
|
24
|
-
]
|
|
25
|
-
}
|
|
26
|
-
);
|
|
27
|
-
function defaultElementRegistry(element, slideWidthPx) {
|
|
28
|
-
switch (element.type) {
|
|
29
|
-
case "chart":
|
|
30
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loading, { label: "Loading chart" }), children: /* @__PURE__ */ jsx(ChartHost, { element, slideWidthPx }) });
|
|
31
|
-
case "code":
|
|
32
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loading, { label: "Loading code" }), children: /* @__PURE__ */ jsx(CodeHost, { element }) });
|
|
33
|
-
case "table":
|
|
34
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loading, { label: "Loading table" }), children: /* @__PURE__ */ jsx(TableHost, { element }) });
|
|
35
|
-
case "embed":
|
|
36
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loading, { label: "Loading embed" }), children: /* @__PURE__ */ jsx(EmbedHost, { element }) });
|
|
37
|
-
default:
|
|
38
|
-
return void 0;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export { defaultElementRegistry };
|
|
1
|
+
export { defaultElementRegistry } from './chunk-YEJZYKVB.js';
|
|
43
2
|
//# sourceMappingURL=registry.js.map
|
|
44
3
|
//# sourceMappingURL=registry.js.map
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"registry.js"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@particle-academy/fancy-slides",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Presentation editor + web viewer for the fancy UI set — Google-Slides-style deck authoring with a JSON-friendly schema, full keyboard-driven viewer, and an agent bridge so LLMs can compose decks directly.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { useIsDarkSlide } from './chunk-WIUXPQAK.js';
|
|
2
|
-
import { registerAll, registerBuiltinThemes, EChart } from '@particle-academy/fancy-echarts';
|
|
3
|
-
import { jsx } from 'react/jsx-runtime';
|
|
4
|
-
|
|
5
|
-
registerAll();
|
|
6
|
-
registerBuiltinThemes();
|
|
7
|
-
function ChartHost({ element }) {
|
|
8
|
-
const isDarkSlide = useIsDarkSlide();
|
|
9
|
-
const theme = element.chartTheme ?? (isDarkSlide ? "dark" : void 0);
|
|
10
|
-
return /* @__PURE__ */ jsx("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(EChart, { option: element.option, theme }) });
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export { ChartHost as default };
|
|
14
|
-
//# sourceMappingURL=chart-host-X55F6S44.js.map
|
|
15
|
-
//# sourceMappingURL=chart-host-X55F6S44.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/registry/element-renderers/chart-host.tsx"],"names":[],"mappings":";;;;AAaA,WAAA,EAAY;AACZ,qBAAA,EAAsB;AAEP,SAAR,SAAA,CAA2B,EAAE,OAAA,EAAQ,EAAoD;AAI5F,EAAA,MAAM,cAAc,cAAA,EAAe;AACnC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,UAAA,KAAe,WAAA,GAAc,MAAA,GAAS,MAAA,CAAA;AAC5D,EAAA,uBACI,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAO,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAO,EACxC,8BAAC,MAAA,EAAA,EAAO,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAkD,OAAc,CAAA,EAC5F,CAAA;AAER","file":"chart-host-X55F6S44.js","sourcesContent":["import { EChart, registerAll, registerBuiltinThemes } from \"@particle-academy/fancy-echarts\";\nimport type { ChartElement } from \"../../types\";\nimport { useIsDarkSlide } from \"../../components/Slide/slide-context\";\n\n// fancy-echarts ships its chart types as opt-in tree-shake-friendly modules,\n// so the consumer normally calls `registerAll()` somewhere global. The\n// registry subpath here is the natural spot to wire it: this module only\n// loads when a deck actually contains a chart element (defaultElementRegistry\n// is React.lazy), so the registration cost is paid by chart-using hosts\n// only — non-chart consumers never even import this file.\n//\n// `registerAll()` is idempotent on echarts' side, so re-imports across\n// chunks are safe.\nregisterAll();\nregisterBuiltinThemes();\n\nexport default function ChartHost({ element }: { element: ChartElement; slideWidthPx: number }) {\n // If the slide background reads as dark and the chart doesn't already\n // pin a theme explicitly, fall back to echarts' built-in \"dark\" theme\n // so the chart legend/axis/tooltip text stay legible.\n const isDarkSlide = useIsDarkSlide();\n const theme = element.chartTheme ?? (isDarkSlide ? \"dark\" : undefined);\n return (\n <div style={{ width: \"100%\", height: \"100%\" }}>\n <EChart option={element.option as Parameters<typeof EChart>[0][\"option\"]} theme={theme} />\n </div>\n );\n}\n"]}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { CodeEditor } from '@particle-academy/fancy-code';
|
|
2
|
-
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
|
|
4
|
-
// src/registry/element-renderers/code-host.tsx
|
|
5
|
-
function CodeHost({ element }) {
|
|
6
|
-
return /* @__PURE__ */ jsx("div", { style: { width: "100%", height: "100%", overflow: "hidden", borderRadius: 8 }, children: /* @__PURE__ */ jsx(
|
|
7
|
-
CodeEditor,
|
|
8
|
-
{
|
|
9
|
-
value: element.code,
|
|
10
|
-
language: element.language ?? "javascript",
|
|
11
|
-
theme: element.codeTheme ?? "dark",
|
|
12
|
-
readOnly: true,
|
|
13
|
-
lineNumbers: element.lineNumbers ?? true,
|
|
14
|
-
children: /* @__PURE__ */ jsx(CodeEditor.Panel, {})
|
|
15
|
-
}
|
|
16
|
-
) });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export { CodeHost as default };
|
|
20
|
-
//# sourceMappingURL=code-host-IYT6QDLA.js.map
|
|
21
|
-
//# sourceMappingURL=code-host-IYT6QDLA.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/registry/element-renderers/code-host.tsx"],"names":[],"mappings":";;;;AAGe,SAAR,QAAA,CAA0B,EAAE,OAAA,EAAQ,EAA6B;AACpE,EAAA,uBACI,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,YAAA,EAAc,CAAA,EAAE,EAC7E,QAAA,kBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACG,OAAO,OAAA,CAAQ,IAAA;AAAA,MACf,QAAA,EAAU,QAAQ,QAAA,IAAY,YAAA;AAAA,MAC9B,KAAA,EAAO,QAAQ,SAAA,IAAa,MAAA;AAAA,MAC5B,QAAA,EAAQ,IAAA;AAAA,MACR,WAAA,EAAa,QAAQ,WAAA,IAAe,IAAA;AAAA,MAEpC,QAAA,kBAAA,GAAA,CAAC,UAAA,CAAW,KAAA,EAAX,EAAiB;AAAA;AAAA,GACtB,EACJ,CAAA;AAER","file":"code-host-IYT6QDLA.js","sourcesContent":["import { CodeEditor } from \"@particle-academy/fancy-code\";\nimport type { CodeElement } from \"../../types\";\n\nexport default function CodeHost({ element }: { element: CodeElement }) {\n return (\n <div style={{ width: \"100%\", height: \"100%\", overflow: \"hidden\", borderRadius: 8 }}>\n <CodeEditor\n value={element.code}\n language={element.language ?? \"javascript\"}\n theme={element.codeTheme ?? \"dark\"}\n readOnly\n lineNumbers={element.lineNumbers ?? true}\n >\n <CodeEditor.Panel />\n </CodeEditor>\n </div>\n );\n}\n"]}
|