@luckydraw/blex 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 +298 -0
- package/dist/blex-chart.min.global.js +23 -0
- package/dist/blex-chart.min.global.js.map +1 -0
- package/dist/blex.min.global.js +105 -0
- package/dist/blex.min.global.js.map +1 -0
- package/dist/esm/base-renderer.d.ts +28 -0
- package/dist/esm/base-renderer.d.ts.map +1 -0
- package/dist/esm/calendar-HUZDQQN2.js +314 -0
- package/dist/esm/calendar-HUZDQQN2.js.map +1 -0
- package/dist/esm/chart/index.d.ts +14 -0
- package/dist/esm/chart/index.d.ts.map +1 -0
- package/dist/esm/chart/index.js +3 -0
- package/dist/esm/chart/index.js.map +1 -0
- package/dist/esm/chart-2QT47W6E.js +38 -0
- package/dist/esm/chart-2QT47W6E.js.map +1 -0
- package/dist/esm/chunk-ODHF7VXV.js +74 -0
- package/dist/esm/chunk-ODHF7VXV.js.map +1 -0
- package/dist/esm/chunk-PBRPD4A5.js +91 -0
- package/dist/esm/chunk-PBRPD4A5.js.map +1 -0
- package/dist/esm/chunk-ZKSJGHJI.js +1573 -0
- package/dist/esm/chunk-ZKSJGHJI.js.map +1 -0
- package/dist/esm/defaults.d.ts +6 -0
- package/dist/esm/defaults.d.ts.map +1 -0
- package/dist/esm/fallback.d.ts +11 -0
- package/dist/esm/fallback.d.ts.map +1 -0
- package/dist/esm/gallery-ISM7FZA3.js +130 -0
- package/dist/esm/gallery-ISM7FZA3.js.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +91 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/kanban-XUXVTRX2.js +126 -0
- package/dist/esm/kanban-XUXVTRX2.js.map +1 -0
- package/dist/esm/mermaid-W3HX2CK2.js +130 -0
- package/dist/esm/mermaid-W3HX2CK2.js.map +1 -0
- package/dist/esm/placeholder.d.ts +8 -0
- package/dist/esm/placeholder.d.ts.map +1 -0
- package/dist/esm/plugin.d.ts +34 -0
- package/dist/esm/plugin.d.ts.map +1 -0
- package/dist/esm/react/chart.d.ts +12 -0
- package/dist/esm/react/chart.d.ts.map +1 -0
- package/dist/esm/react/chart.js +50 -0
- package/dist/esm/react/chart.js.map +1 -0
- package/dist/esm/react/index.d.ts +13 -0
- package/dist/esm/react/index.d.ts.map +1 -0
- package/dist/esm/react/index.js +66 -0
- package/dist/esm/react/index.js.map +1 -0
- package/dist/esm/registry.d.ts +46 -0
- package/dist/esm/registry.d.ts.map +1 -0
- package/dist/esm/render.d.ts +13 -0
- package/dist/esm/render.d.ts.map +1 -0
- package/dist/esm/renderers/calendar.d.ts +34 -0
- package/dist/esm/renderers/calendar.d.ts.map +1 -0
- package/dist/esm/renderers/chart.d.ts +12 -0
- package/dist/esm/renderers/chart.d.ts.map +1 -0
- package/dist/esm/renderers/code.d.ts +19 -0
- package/dist/esm/renderers/code.d.ts.map +1 -0
- package/dist/esm/renderers/confirm.d.ts +13 -0
- package/dist/esm/renderers/confirm.d.ts.map +1 -0
- package/dist/esm/renderers/diff.d.ts +24 -0
- package/dist/esm/renderers/diff.d.ts.map +1 -0
- package/dist/esm/renderers/file-tree.d.ts +24 -0
- package/dist/esm/renderers/file-tree.d.ts.map +1 -0
- package/dist/esm/renderers/form.d.ts +27 -0
- package/dist/esm/renderers/form.d.ts.map +1 -0
- package/dist/esm/renderers/gallery.d.ts +24 -0
- package/dist/esm/renderers/gallery.d.ts.map +1 -0
- package/dist/esm/renderers/image.d.ts +17 -0
- package/dist/esm/renderers/image.d.ts.map +1 -0
- package/dist/esm/renderers/kanban.d.ts +29 -0
- package/dist/esm/renderers/kanban.d.ts.map +1 -0
- package/dist/esm/renderers/layout.d.ts +17 -0
- package/dist/esm/renderers/layout.d.ts.map +1 -0
- package/dist/esm/renderers/mermaid.d.ts +19 -0
- package/dist/esm/renderers/mermaid.d.ts.map +1 -0
- package/dist/esm/renderers/metric.d.ts +16 -0
- package/dist/esm/renderers/metric.d.ts.map +1 -0
- package/dist/esm/renderers/poll.d.ts +17 -0
- package/dist/esm/renderers/poll.d.ts.map +1 -0
- package/dist/esm/renderers/progress.d.ts +18 -0
- package/dist/esm/renderers/progress.d.ts.map +1 -0
- package/dist/esm/renderers/status.d.ts +17 -0
- package/dist/esm/renderers/status.d.ts.map +1 -0
- package/dist/esm/renderers/svg.d.ts +13 -0
- package/dist/esm/renderers/svg.d.ts.map +1 -0
- package/dist/esm/renderers/table.d.ts +20 -0
- package/dist/esm/renderers/table.d.ts.map +1 -0
- package/dist/esm/renderers/terminal.d.ts +16 -0
- package/dist/esm/renderers/terminal.d.ts.map +1 -0
- package/dist/esm/renderers/timeline.d.ts +20 -0
- package/dist/esm/renderers/timeline.d.ts.map +1 -0
- package/dist/esm/theme.d.ts +10 -0
- package/dist/esm/theme.d.ts.map +1 -0
- package/dist/esm/types-C42V92x6.d.ts +75 -0
- package/dist/esm/types.d.ts +81 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/placeholder.ts","../../src/plugin.ts","../../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Render a typed skeleton placeholder for a block that hasn't finished\n * streaming yet. Used by cumulus while buffering fence content.\n *\n * Returns the placeholder element for later replacement.\n */\nexport function renderPlaceholder(type: string, container: HTMLElement): HTMLElement {\n const placeholder = document.createElement('div');\n placeholder.className = 'blex-placeholder';\n placeholder.setAttribute('data-testid', `blex-placeholder-${type}`);\n placeholder.setAttribute('data-loading', 'true');\n placeholder.setAttribute('aria-busy', 'true');\n\n const label = document.createElement('span');\n label.className = 'blex-placeholder__label';\n label.textContent = type;\n\n const pulse = document.createElement('div');\n pulse.className = 'blex-placeholder__pulse';\n\n placeholder.appendChild(label);\n placeholder.appendChild(pulse);\n container.appendChild(placeholder);\n\n return placeholder;\n}\n","import type { BlockRendererFactory } from './types.js';\nimport { registerBlockType, hasBlockType, isBuiltIn, unregisterBlockType as registryUnregister } from './registry.js';\n\n// --- Types ---\n\nexport interface PluginDefinition {\n namespace: string;\n name?: string;\n version?: string;\n description?: string;\n blocks: Record<string, BlockRendererFactory>;\n}\n\nexport interface PluginInfo {\n namespace: string;\n name?: string;\n version?: string;\n description?: string;\n blockTypes: string[];\n}\n\nexport interface PluginRegisterOptions {\n force?: boolean;\n}\n\n// --- Validation ---\n\nconst NAMESPACE_RE = /^[a-z][a-z0-9-]{0,63}$/;\nconst BLOCK_NAME_RE = /^[a-z][a-z0-9-]{0,63}$/;\nconst RESERVED_NAMESPACES = new Set(['blex', 'built-in', 'core', 'internal']);\n\nfunction validateNamespace(ns: string): void {\n if (!NAMESPACE_RE.test(ns)) {\n throw new Error(`Invalid plugin namespace \"${ns}\": must be lowercase alphanumeric + hyphens, 1-64 chars, starting with a letter`);\n }\n if (RESERVED_NAMESPACES.has(ns)) {\n throw new Error(`Reserved namespace \"${ns}\": cannot use blex, built-in, core, or internal`);\n }\n}\n\nfunction validateBlockName(name: string): void {\n if (!BLOCK_NAME_RE.test(name)) {\n throw new Error(`Invalid block name \"${name}\": must be lowercase alphanumeric + hyphens, 1-64 chars, starting with a letter`);\n }\n}\n\n// --- Plugin registry ---\n\nconst plugins = new Map<string, PluginInfo>();\n\n/**\n * Register a plugin with one or more block types.\n * Block types are namespaced as `namespace/block-name`.\n */\nexport function registerPlugin(plugin: PluginDefinition, options?: PluginRegisterOptions): void {\n validateNamespace(plugin.namespace);\n\n const blockNames = Object.keys(plugin.blocks);\n if (blockNames.length === 0) {\n throw new Error('Plugin must define at least one block');\n }\n\n // Validate all block names and check for conflicts before registering any\n const qualifiedTypes: string[] = [];\n for (const blockName of blockNames) {\n validateBlockName(blockName);\n const qualifiedType = `${plugin.namespace}/${blockName}`;\n qualifiedTypes.push(qualifiedType);\n\n if (hasBlockType(qualifiedType) && !options?.force) {\n if (isBuiltIn(qualifiedType)) {\n throw new Error(`Cannot override built-in block type \"${qualifiedType}\" without force: true`);\n }\n throw new Error(`Block type \"${qualifiedType}\" is already registered. Use force: true to override`);\n }\n }\n\n // All validation passed — register the blocks\n for (let i = 0; i < blockNames.length; i++) {\n registerBlockType(qualifiedTypes[i], plugin.blocks[blockNames[i]]);\n }\n\n // Store plugin metadata\n plugins.set(plugin.namespace, {\n namespace: plugin.namespace,\n name: plugin.name,\n version: plugin.version,\n description: plugin.description,\n blockTypes: qualifiedTypes,\n });\n}\n\n/**\n * Unregister all block types from a plugin.\n * No-op if the namespace isn't registered.\n */\nexport function unregisterPlugin(namespace: string): void {\n const info = plugins.get(namespace);\n if (!info) return;\n\n for (const type of info.blockTypes) {\n registryUnregister(type);\n }\n plugins.delete(namespace);\n}\n\n/**\n * Get plugin metadata. If namespace is provided, returns info for that plugin only.\n * Otherwise returns all registered plugins.\n */\nexport function getPluginInfo(namespace?: string): PluginInfo[] {\n if (namespace) {\n const info = plugins.get(namespace);\n return info ? [info] : [];\n }\n return Array.from(plugins.values());\n}\n","export type {\n ContentBlock,\n BlockRenderer,\n BlockHandle,\n BlockInteraction,\n RenderOptions,\n ChartConfig,\n ChartOptions,\n DataSet,\n ChartInstance,\n} from './types.js';\n\nexport { BaseRenderer } from './base-renderer.js';\nexport { registerBlockType, registerLazyBlockType, hasBlockType, getRegisteredTypes, unregisterBlockType } from './registry.js';\nexport { renderPlaceholder } from './placeholder.js';\nexport { renderBlock } from './render.js';\nexport type { PluginDefinition, PluginInfo, PluginRegisterOptions } from './plugin.js';\nexport { registerPlugin, unregisterPlugin, getPluginInfo } from './plugin.js';\n\n// Register built-in block types on import\nimport { registerDefaults } from './defaults.js';\nregisterDefaults();\n"]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { BaseRenderer } from './chunk-ODHF7VXV.js';
|
|
2
|
+
|
|
3
|
+
// src/renderers/kanban.ts
|
|
4
|
+
var KanbanRenderer = class extends BaseRenderer {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
// Class fields for drag state — dataTransfer is unreliable in jsdom
|
|
8
|
+
this.draggedItemId = null;
|
|
9
|
+
this.draggedFromColumn = null;
|
|
10
|
+
this.draggedItemTitle = null;
|
|
11
|
+
}
|
|
12
|
+
render(block, container) {
|
|
13
|
+
this.container = container;
|
|
14
|
+
this._build(block);
|
|
15
|
+
container.setAttribute("data-blex-ready", "true");
|
|
16
|
+
}
|
|
17
|
+
update(block) {
|
|
18
|
+
if (!this.container) return;
|
|
19
|
+
this.container.innerHTML = "";
|
|
20
|
+
this._build(block);
|
|
21
|
+
}
|
|
22
|
+
_build(block) {
|
|
23
|
+
const container = this.container;
|
|
24
|
+
const { columns, draggable = true } = block.data;
|
|
25
|
+
const board = document.createElement("div");
|
|
26
|
+
board.className = "blex-kanban";
|
|
27
|
+
board.setAttribute("data-testid", `blex-kanban-${block.id}`);
|
|
28
|
+
for (const col of columns) {
|
|
29
|
+
const colEl = this._buildColumn(col, draggable, block);
|
|
30
|
+
board.appendChild(colEl);
|
|
31
|
+
}
|
|
32
|
+
container.appendChild(board);
|
|
33
|
+
}
|
|
34
|
+
_buildColumn(col, draggable, block) {
|
|
35
|
+
const colEl = document.createElement("div");
|
|
36
|
+
colEl.className = "blex-kanban__column";
|
|
37
|
+
colEl.setAttribute("data-testid", `blex-kanban-col-${col.id}`);
|
|
38
|
+
const titleEl = document.createElement("div");
|
|
39
|
+
titleEl.className = "blex-kanban__column-title";
|
|
40
|
+
titleEl.textContent = col.title;
|
|
41
|
+
colEl.appendChild(titleEl);
|
|
42
|
+
for (const item of col.items) {
|
|
43
|
+
const itemEl = this._buildItem(item, col.id, draggable);
|
|
44
|
+
colEl.appendChild(itemEl);
|
|
45
|
+
}
|
|
46
|
+
if (draggable) {
|
|
47
|
+
this.addListener(colEl, "dragover", (e) => {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
});
|
|
50
|
+
this.addListener(colEl, "drop", (e) => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
if (this.draggedItemId === null || this.draggedFromColumn === null || this.draggedItemTitle === null) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const existingItems = Array.from(
|
|
56
|
+
colEl.querySelectorAll(".blex-kanban__item")
|
|
57
|
+
).filter((el) => !el.classList.contains("blex-kanban__item--dragging"));
|
|
58
|
+
const position = existingItems.length;
|
|
59
|
+
const itemId = this.draggedItemId;
|
|
60
|
+
const fromColumn = this.draggedFromColumn;
|
|
61
|
+
const itemTitle = this.draggedItemTitle;
|
|
62
|
+
const toColumn = col.id;
|
|
63
|
+
this.draggedItemId = null;
|
|
64
|
+
this.draggedFromColumn = null;
|
|
65
|
+
this.draggedItemTitle = null;
|
|
66
|
+
this.emit({
|
|
67
|
+
blockId: block.id,
|
|
68
|
+
type: "move",
|
|
69
|
+
payload: {
|
|
70
|
+
itemId,
|
|
71
|
+
fromColumn,
|
|
72
|
+
toColumn,
|
|
73
|
+
position
|
|
74
|
+
},
|
|
75
|
+
serialized: `Moved "${itemTitle}" from ${fromColumn} to ${toColumn}`
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return colEl;
|
|
80
|
+
}
|
|
81
|
+
_buildItem(item, colId, draggable) {
|
|
82
|
+
const itemEl = document.createElement("div");
|
|
83
|
+
itemEl.className = "blex-kanban__item";
|
|
84
|
+
itemEl.setAttribute("data-testid", `blex-kanban-item-${item.id}`);
|
|
85
|
+
if (draggable) {
|
|
86
|
+
itemEl.setAttribute("draggable", "true");
|
|
87
|
+
this.addListener(itemEl, "dragstart", () => {
|
|
88
|
+
this.draggedItemId = item.id;
|
|
89
|
+
this.draggedFromColumn = colId;
|
|
90
|
+
this.draggedItemTitle = item.title;
|
|
91
|
+
itemEl.classList.add("blex-kanban__item--dragging");
|
|
92
|
+
});
|
|
93
|
+
this.addListener(itemEl, "dragend", () => {
|
|
94
|
+
itemEl.classList.remove("blex-kanban__item--dragging");
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const titleEl = document.createElement("div");
|
|
98
|
+
titleEl.className = "blex-kanban__item-title";
|
|
99
|
+
titleEl.textContent = item.title;
|
|
100
|
+
itemEl.appendChild(titleEl);
|
|
101
|
+
if (item.subtitle) {
|
|
102
|
+
const subtitleEl = document.createElement("div");
|
|
103
|
+
subtitleEl.className = "blex-kanban__item-subtitle";
|
|
104
|
+
subtitleEl.textContent = item.subtitle;
|
|
105
|
+
itemEl.appendChild(subtitleEl);
|
|
106
|
+
}
|
|
107
|
+
if (item.tags && item.tags.length > 0) {
|
|
108
|
+
const tagsEl = document.createElement("div");
|
|
109
|
+
tagsEl.className = "blex-kanban__item-tags";
|
|
110
|
+
for (const tag of item.tags) {
|
|
111
|
+
const tagEl = document.createElement("span");
|
|
112
|
+
tagEl.textContent = tag;
|
|
113
|
+
tagsEl.appendChild(tagEl);
|
|
114
|
+
}
|
|
115
|
+
itemEl.appendChild(tagsEl);
|
|
116
|
+
}
|
|
117
|
+
return itemEl;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
function createKanbanRenderer() {
|
|
121
|
+
return new KanbanRenderer();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export { KanbanRenderer, createKanbanRenderer };
|
|
125
|
+
//# sourceMappingURL=kanban-XUXVTRX2.js.map
|
|
126
|
+
//# sourceMappingURL=kanban-XUXVTRX2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/renderers/kanban.ts"],"names":[],"mappings":"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","file":"kanban-XUXVTRX2.js","sourcesContent":["import { BaseRenderer } from '../base-renderer.js';\nimport type { ContentBlock } from '../types.js';\n\nexport interface KanbanItem {\n id: string;\n title: string;\n subtitle?: string;\n tags?: string[];\n}\n\nexport interface KanbanColumn {\n id: string;\n title: string;\n items: KanbanItem[];\n}\n\nexport interface KanbanData {\n columns: KanbanColumn[];\n draggable?: boolean;\n}\n\nexport class KanbanRenderer extends BaseRenderer<KanbanData> {\n // Class fields for drag state — dataTransfer is unreliable in jsdom\n draggedItemId: string | null = null;\n draggedFromColumn: string | null = null;\n draggedItemTitle: string | null = null;\n\n render(block: ContentBlock<KanbanData>, container: HTMLElement): void {\n this.container = container;\n this._build(block);\n container.setAttribute('data-blex-ready', 'true');\n }\n\n update(block: ContentBlock<KanbanData>): void {\n if (!this.container) return;\n this.container.innerHTML = '';\n this._build(block);\n }\n\n private _build(block: ContentBlock<KanbanData>): void {\n const container = this.container!;\n const { columns, draggable = true } = block.data;\n\n const board = document.createElement('div');\n board.className = 'blex-kanban';\n board.setAttribute('data-testid', `blex-kanban-${block.id}`);\n\n for (const col of columns) {\n const colEl = this._buildColumn(col, draggable, block);\n board.appendChild(colEl);\n }\n\n container.appendChild(board);\n }\n\n private _buildColumn(\n col: KanbanColumn,\n draggable: boolean,\n block: ContentBlock<KanbanData>,\n ): HTMLElement {\n const colEl = document.createElement('div');\n colEl.className = 'blex-kanban__column';\n colEl.setAttribute('data-testid', `blex-kanban-col-${col.id}`);\n\n const titleEl = document.createElement('div');\n titleEl.className = 'blex-kanban__column-title';\n titleEl.textContent = col.title;\n colEl.appendChild(titleEl);\n\n for (const item of col.items) {\n const itemEl = this._buildItem(item, col.id, draggable);\n colEl.appendChild(itemEl);\n }\n\n if (draggable) {\n this.addListener(colEl, 'dragover', (e) => {\n e.preventDefault();\n });\n\n this.addListener(colEl, 'drop', (e) => {\n e.preventDefault();\n\n if (\n this.draggedItemId === null ||\n this.draggedFromColumn === null ||\n this.draggedItemTitle === null\n ) {\n return;\n }\n\n // Count non-dragging items currently in this column to get drop position\n const existingItems = Array.from(\n colEl.querySelectorAll('.blex-kanban__item'),\n ).filter((el) => !el.classList.contains('blex-kanban__item--dragging'));\n const position = existingItems.length;\n\n const itemId = this.draggedItemId;\n const fromColumn = this.draggedFromColumn;\n const itemTitle = this.draggedItemTitle;\n const toColumn = col.id;\n\n // Reset drag state before emitting so re-entrant handlers see clean state\n this.draggedItemId = null;\n this.draggedFromColumn = null;\n this.draggedItemTitle = null;\n\n this.emit({\n blockId: block.id,\n type: 'move',\n payload: {\n itemId,\n fromColumn,\n toColumn,\n position,\n },\n serialized: `Moved \"${itemTitle}\" from ${fromColumn} to ${toColumn}`,\n });\n });\n }\n\n return colEl;\n }\n\n private _buildItem(\n item: KanbanItem,\n colId: string,\n draggable: boolean,\n ): HTMLElement {\n const itemEl = document.createElement('div');\n itemEl.className = 'blex-kanban__item';\n itemEl.setAttribute('data-testid', `blex-kanban-item-${item.id}`);\n\n if (draggable) {\n itemEl.setAttribute('draggable', 'true');\n\n this.addListener(itemEl, 'dragstart', () => {\n this.draggedItemId = item.id;\n this.draggedFromColumn = colId;\n this.draggedItemTitle = item.title;\n itemEl.classList.add('blex-kanban__item--dragging');\n });\n\n this.addListener(itemEl, 'dragend', () => {\n itemEl.classList.remove('blex-kanban__item--dragging');\n });\n }\n\n const titleEl = document.createElement('div');\n titleEl.className = 'blex-kanban__item-title';\n titleEl.textContent = item.title;\n itemEl.appendChild(titleEl);\n\n if (item.subtitle) {\n const subtitleEl = document.createElement('div');\n subtitleEl.className = 'blex-kanban__item-subtitle';\n subtitleEl.textContent = item.subtitle;\n itemEl.appendChild(subtitleEl);\n }\n\n if (item.tags && item.tags.length > 0) {\n const tagsEl = document.createElement('div');\n tagsEl.className = 'blex-kanban__item-tags';\n for (const tag of item.tags) {\n const tagEl = document.createElement('span');\n tagEl.textContent = tag;\n tagsEl.appendChild(tagEl);\n }\n itemEl.appendChild(tagsEl);\n }\n\n return itemEl;\n }\n}\n\nexport function createKanbanRenderer(): KanbanRenderer {\n return new KanbanRenderer();\n}\n"]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { BaseRenderer } from './chunk-ODHF7VXV.js';
|
|
2
|
+
|
|
3
|
+
// src/renderers/mermaid.ts
|
|
4
|
+
var MermaidRenderer = class extends BaseRenderer {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.showSource = false;
|
|
8
|
+
/**
|
|
9
|
+
* Resolves when the most recent render/update call has fully completed
|
|
10
|
+
* (mermaid loaded and SVG injected). Useful for testing.
|
|
11
|
+
*/
|
|
12
|
+
this._renderPromise = Promise.resolve();
|
|
13
|
+
}
|
|
14
|
+
render(block, container) {
|
|
15
|
+
this.container = container;
|
|
16
|
+
this._renderPromise = this.renderDiagram(block);
|
|
17
|
+
}
|
|
18
|
+
update(block) {
|
|
19
|
+
if (!this.container) return;
|
|
20
|
+
this.container.innerHTML = "";
|
|
21
|
+
this.container.removeAttribute("data-blex-ready");
|
|
22
|
+
this._renderPromise = this.renderDiagram(block);
|
|
23
|
+
}
|
|
24
|
+
async renderDiagram(block) {
|
|
25
|
+
const container = this.container;
|
|
26
|
+
const { source, title } = block.data;
|
|
27
|
+
const wrapper = document.createElement("div");
|
|
28
|
+
wrapper.className = "blex-mermaid blex-mermaid--loading";
|
|
29
|
+
wrapper.setAttribute("data-testid", `blex-mermaid-${block.id}`);
|
|
30
|
+
wrapper.setAttribute("data-loading", "true");
|
|
31
|
+
if (title) {
|
|
32
|
+
const titleEl = document.createElement("div");
|
|
33
|
+
titleEl.className = "blex-mermaid__title";
|
|
34
|
+
titleEl.textContent = title;
|
|
35
|
+
wrapper.appendChild(titleEl);
|
|
36
|
+
}
|
|
37
|
+
const diagramEl = document.createElement("div");
|
|
38
|
+
diagramEl.className = "blex-mermaid__diagram";
|
|
39
|
+
diagramEl.setAttribute("data-testid", `blex-mermaid-diagram-${block.id}`);
|
|
40
|
+
wrapper.appendChild(diagramEl);
|
|
41
|
+
const sourceEl = document.createElement("pre");
|
|
42
|
+
sourceEl.className = "blex-mermaid__source";
|
|
43
|
+
sourceEl.style.display = this.showSource ? "block" : "none";
|
|
44
|
+
const codeEl = document.createElement("code");
|
|
45
|
+
codeEl.textContent = source;
|
|
46
|
+
sourceEl.appendChild(codeEl);
|
|
47
|
+
wrapper.appendChild(sourceEl);
|
|
48
|
+
const actions = document.createElement("div");
|
|
49
|
+
actions.className = "blex-mermaid__actions";
|
|
50
|
+
const toggleBtn = document.createElement("button");
|
|
51
|
+
toggleBtn.className = "blex-mermaid__btn";
|
|
52
|
+
toggleBtn.textContent = this.showSource ? "Hide source" : "Show source";
|
|
53
|
+
toggleBtn.setAttribute("data-testid", `blex-mermaid-toggle-${block.id}`);
|
|
54
|
+
this.addListener(toggleBtn, "click", () => {
|
|
55
|
+
this.showSource = !this.showSource;
|
|
56
|
+
sourceEl.style.display = this.showSource ? "block" : "none";
|
|
57
|
+
toggleBtn.textContent = this.showSource ? "Hide source" : "Show source";
|
|
58
|
+
});
|
|
59
|
+
actions.appendChild(toggleBtn);
|
|
60
|
+
const exportSvgBtn = document.createElement("button");
|
|
61
|
+
exportSvgBtn.className = "blex-mermaid__btn";
|
|
62
|
+
exportSvgBtn.textContent = "Export SVG";
|
|
63
|
+
exportSvgBtn.setAttribute("data-testid", `blex-mermaid-export-svg-${block.id}`);
|
|
64
|
+
this.addListener(exportSvgBtn, "click", () => {
|
|
65
|
+
const svgContent = diagramEl.innerHTML;
|
|
66
|
+
const blob = new Blob([svgContent], { type: "image/svg+xml" });
|
|
67
|
+
const url = URL.createObjectURL(blob);
|
|
68
|
+
const a = document.createElement("a");
|
|
69
|
+
a.href = url;
|
|
70
|
+
a.download = `${block.id}.svg`;
|
|
71
|
+
a.click();
|
|
72
|
+
URL.revokeObjectURL(url);
|
|
73
|
+
});
|
|
74
|
+
actions.appendChild(exportSvgBtn);
|
|
75
|
+
const exportPngBtn = document.createElement("button");
|
|
76
|
+
exportPngBtn.className = "blex-mermaid__btn";
|
|
77
|
+
exportPngBtn.textContent = "Export PNG";
|
|
78
|
+
exportPngBtn.setAttribute("data-testid", `blex-mermaid-export-png-${block.id}`);
|
|
79
|
+
this.addListener(exportPngBtn, "click", () => {
|
|
80
|
+
const svgContent = diagramEl.innerHTML;
|
|
81
|
+
const svgBlob = new Blob([svgContent], { type: "image/svg+xml" });
|
|
82
|
+
const url = URL.createObjectURL(svgBlob);
|
|
83
|
+
const img = new Image();
|
|
84
|
+
img.onload = () => {
|
|
85
|
+
const canvas = document.createElement("canvas");
|
|
86
|
+
canvas.width = img.naturalWidth || img.width || 800;
|
|
87
|
+
canvas.height = img.naturalHeight || img.height || 600;
|
|
88
|
+
const ctx = canvas.getContext("2d");
|
|
89
|
+
if (ctx) {
|
|
90
|
+
ctx.drawImage(img, 0, 0);
|
|
91
|
+
canvas.toBlob((pngBlob) => {
|
|
92
|
+
if (pngBlob) {
|
|
93
|
+
const pngUrl = URL.createObjectURL(pngBlob);
|
|
94
|
+
const a = document.createElement("a");
|
|
95
|
+
a.href = pngUrl;
|
|
96
|
+
a.download = `${block.id}.png`;
|
|
97
|
+
a.click();
|
|
98
|
+
URL.revokeObjectURL(pngUrl);
|
|
99
|
+
}
|
|
100
|
+
}, "image/png");
|
|
101
|
+
}
|
|
102
|
+
URL.revokeObjectURL(url);
|
|
103
|
+
};
|
|
104
|
+
img.src = url;
|
|
105
|
+
});
|
|
106
|
+
actions.appendChild(exportPngBtn);
|
|
107
|
+
wrapper.appendChild(actions);
|
|
108
|
+
container.appendChild(wrapper);
|
|
109
|
+
try {
|
|
110
|
+
const mermaidModule = await import('mermaid');
|
|
111
|
+
const mermaidApi = mermaidModule.default ?? mermaidModule;
|
|
112
|
+
mermaidApi.initialize({ startOnLoad: false, theme: "default" });
|
|
113
|
+
const { svg } = await mermaidApi.render(`blex-mermaid-${block.id}`, source);
|
|
114
|
+
diagramEl.innerHTML = svg;
|
|
115
|
+
} catch {
|
|
116
|
+
diagramEl.textContent = "Mermaid render error";
|
|
117
|
+
diagramEl.classList.add("blex-mermaid__diagram--error");
|
|
118
|
+
}
|
|
119
|
+
wrapper.classList.remove("blex-mermaid--loading");
|
|
120
|
+
wrapper.removeAttribute("data-loading");
|
|
121
|
+
container.setAttribute("data-blex-ready", "true");
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
function createMermaidRenderer() {
|
|
125
|
+
return new MermaidRenderer();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { MermaidRenderer, createMermaidRenderer };
|
|
129
|
+
//# sourceMappingURL=mermaid-W3HX2CK2.js.map
|
|
130
|
+
//# sourceMappingURL=mermaid-W3HX2CK2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/renderers/mermaid.ts"],"names":[],"mappings":"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","file":"mermaid-W3HX2CK2.js","sourcesContent":["import { BaseRenderer } from '../base-renderer.js';\nimport type { ContentBlock } from '../types.js';\n\nexport interface MermaidData {\n source: string;\n title?: string;\n}\n\nexport class MermaidRenderer extends BaseRenderer<MermaidData> {\n private showSource = false;\n\n /**\n * Resolves when the most recent render/update call has fully completed\n * (mermaid loaded and SVG injected). Useful for testing.\n */\n _renderPromise: Promise<void> = Promise.resolve();\n\n render(block: ContentBlock<MermaidData>, container: HTMLElement): void {\n this.container = container;\n this._renderPromise = this.renderDiagram(block);\n }\n\n update(block: ContentBlock<MermaidData>): void {\n if (!this.container) return;\n this.container.innerHTML = '';\n this.container.removeAttribute('data-blex-ready');\n this._renderPromise = this.renderDiagram(block);\n }\n\n private async renderDiagram(block: ContentBlock<MermaidData>): Promise<void> {\n const container = this.container!;\n const { source, title } = block.data;\n\n const wrapper = document.createElement('div');\n wrapper.className = 'blex-mermaid blex-mermaid--loading';\n wrapper.setAttribute('data-testid', `blex-mermaid-${block.id}`);\n wrapper.setAttribute('data-loading', 'true');\n\n if (title) {\n const titleEl = document.createElement('div');\n titleEl.className = 'blex-mermaid__title';\n titleEl.textContent = title;\n wrapper.appendChild(titleEl);\n }\n\n // Diagram container\n const diagramEl = document.createElement('div');\n diagramEl.className = 'blex-mermaid__diagram';\n diagramEl.setAttribute('data-testid', `blex-mermaid-diagram-${block.id}`);\n wrapper.appendChild(diagramEl);\n\n // Source view (raw mermaid code)\n const sourceEl = document.createElement('pre');\n sourceEl.className = 'blex-mermaid__source';\n sourceEl.style.display = this.showSource ? 'block' : 'none';\n\n const codeEl = document.createElement('code');\n codeEl.textContent = source;\n sourceEl.appendChild(codeEl);\n wrapper.appendChild(sourceEl);\n\n // Actions toolbar\n const actions = document.createElement('div');\n actions.className = 'blex-mermaid__actions';\n\n const toggleBtn = document.createElement('button');\n toggleBtn.className = 'blex-mermaid__btn';\n toggleBtn.textContent = this.showSource ? 'Hide source' : 'Show source';\n toggleBtn.setAttribute('data-testid', `blex-mermaid-toggle-${block.id}`);\n this.addListener(toggleBtn, 'click', () => {\n this.showSource = !this.showSource;\n sourceEl.style.display = this.showSource ? 'block' : 'none';\n toggleBtn.textContent = this.showSource ? 'Hide source' : 'Show source';\n });\n actions.appendChild(toggleBtn);\n\n // Export as SVG via blob download\n const exportSvgBtn = document.createElement('button');\n exportSvgBtn.className = 'blex-mermaid__btn';\n exportSvgBtn.textContent = 'Export SVG';\n exportSvgBtn.setAttribute('data-testid', `blex-mermaid-export-svg-${block.id}`);\n this.addListener(exportSvgBtn, 'click', () => {\n const svgContent = diagramEl.innerHTML;\n const blob = new Blob([svgContent], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `${block.id}.svg`;\n a.click();\n URL.revokeObjectURL(url);\n });\n actions.appendChild(exportSvgBtn);\n\n // Export as PNG via canvas\n const exportPngBtn = document.createElement('button');\n exportPngBtn.className = 'blex-mermaid__btn';\n exportPngBtn.textContent = 'Export PNG';\n exportPngBtn.setAttribute('data-testid', `blex-mermaid-export-png-${block.id}`);\n this.addListener(exportPngBtn, 'click', () => {\n const svgContent = diagramEl.innerHTML;\n const svgBlob = new Blob([svgContent], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(svgBlob);\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth || img.width || 800;\n canvas.height = img.naturalHeight || img.height || 600;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.drawImage(img, 0, 0);\n canvas.toBlob((pngBlob) => {\n if (pngBlob) {\n const pngUrl = URL.createObjectURL(pngBlob);\n const a = document.createElement('a');\n a.href = pngUrl;\n a.download = `${block.id}.png`;\n a.click();\n URL.revokeObjectURL(pngUrl);\n }\n }, 'image/png');\n }\n URL.revokeObjectURL(url);\n };\n img.src = url;\n });\n actions.appendChild(exportPngBtn);\n\n wrapper.appendChild(actions);\n container.appendChild(wrapper);\n\n // Lazy-load mermaid (~200 KB) then render the diagram as SVG\n try {\n const mermaidModule = await import('mermaid');\n // Handle both default export and named export patterns\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mermaidApi = (mermaidModule as any).default ?? mermaidModule;\n mermaidApi.initialize({ startOnLoad: false, theme: 'default' });\n const { svg } = await mermaidApi.render(`blex-mermaid-${block.id}`, source);\n diagramEl.innerHTML = svg;\n } catch {\n diagramEl.textContent = 'Mermaid render error';\n diagramEl.classList.add('blex-mermaid__diagram--error');\n }\n\n // Loading complete — remove loading indicators, mark ready\n wrapper.classList.remove('blex-mermaid--loading');\n wrapper.removeAttribute('data-loading');\n container.setAttribute('data-blex-ready', 'true');\n }\n}\n\nexport function createMermaidRenderer(): MermaidRenderer {\n return new MermaidRenderer();\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a typed skeleton placeholder for a block that hasn't finished
|
|
3
|
+
* streaming yet. Used by cumulus while buffering fence content.
|
|
4
|
+
*
|
|
5
|
+
* Returns the placeholder element for later replacement.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderPlaceholder(type: string, container: HTMLElement): HTMLElement;
|
|
8
|
+
//# sourceMappingURL=placeholder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder.d.ts","sourceRoot":"","sources":["../../src/placeholder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,WAAW,CAmBnF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { BlockRendererFactory } from './types.js';
|
|
2
|
+
export interface PluginDefinition {
|
|
3
|
+
namespace: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
version?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
blocks: Record<string, BlockRendererFactory>;
|
|
8
|
+
}
|
|
9
|
+
export interface PluginInfo {
|
|
10
|
+
namespace: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
version?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
blockTypes: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface PluginRegisterOptions {
|
|
17
|
+
force?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Register a plugin with one or more block types.
|
|
21
|
+
* Block types are namespaced as `namespace/block-name`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function registerPlugin(plugin: PluginDefinition, options?: PluginRegisterOptions): void;
|
|
24
|
+
/**
|
|
25
|
+
* Unregister all block types from a plugin.
|
|
26
|
+
* No-op if the namespace isn't registered.
|
|
27
|
+
*/
|
|
28
|
+
export declare function unregisterPlugin(namespace: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get plugin metadata. If namespace is provided, returns info for that plugin only.
|
|
31
|
+
* Otherwise returns all registered plugins.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getPluginInfo(namespace?: string): PluginInfo[];
|
|
34
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKvD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA2BD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAoC9F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAQxD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAM9D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ChartConfig } from '../types.js';
|
|
2
|
+
export interface BexChartProps {
|
|
3
|
+
config: ChartConfig;
|
|
4
|
+
className?: string;
|
|
5
|
+
style?: React.CSSProperties;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* React wrapper for the standalone blex chart renderer.
|
|
9
|
+
* Import from '@luckydraw/blex/react/chart'.
|
|
10
|
+
*/
|
|
11
|
+
export declare function BexChart({ config, className, style }: BexChartProps): React.JSX.Element;
|
|
12
|
+
//# sourceMappingURL=chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../../src/react/chart.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,aAAa,CAAC;AAG9D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAiDvF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { renderChart } from '../chunk-PBRPD4A5.js';
|
|
2
|
+
import { useRef, useEffect } from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function BexChart({ config, className, style }) {
|
|
6
|
+
const containerRef = useRef(null);
|
|
7
|
+
const instanceRef = useRef(null);
|
|
8
|
+
const configRef = useRef(config);
|
|
9
|
+
configRef.current = config;
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const container = containerRef.current;
|
|
12
|
+
if (!container) return;
|
|
13
|
+
let cancelled = false;
|
|
14
|
+
renderChart(container, configRef.current).then((instance) => {
|
|
15
|
+
if (cancelled) {
|
|
16
|
+
instance.destroy();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
instanceRef.current = instance;
|
|
20
|
+
container.setAttribute("data-blex-ready", "true");
|
|
21
|
+
});
|
|
22
|
+
return () => {
|
|
23
|
+
cancelled = true;
|
|
24
|
+
instanceRef.current?.destroy();
|
|
25
|
+
instanceRef.current = null;
|
|
26
|
+
if (container) {
|
|
27
|
+
container.innerHTML = "";
|
|
28
|
+
container.removeAttribute("data-blex-ready");
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (instanceRef.current) {
|
|
34
|
+
instanceRef.current.update(config);
|
|
35
|
+
}
|
|
36
|
+
}, [config]);
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
ref: containerRef,
|
|
41
|
+
className,
|
|
42
|
+
style,
|
|
43
|
+
"data-testid": "bex-chart"
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { BexChart };
|
|
49
|
+
//# sourceMappingURL=chart.js.map
|
|
50
|
+
//# sourceMappingURL=chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/react/chart.tsx"],"names":[],"mappings":";;;;AAcO,SAAS,QAAA,CAAS,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAM,EAAqC;AACvF,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,WAAA,GAAc,OAA6B,IAAI,CAAA;AACrD,EAAA,MAAM,SAAA,GAAY,OAAoB,MAAM,CAAA;AAE5C,EAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAGpB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAA,WAAA,CAAY,WAAW,SAAA,CAAU,OAAO,CAAA,CAAE,IAAA,CAAK,CAAC,QAAA,KAAa;AAC3D,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,QAAA,CAAS,OAAA,EAAQ;AACjB,QAAA;AAAA,MACF;AACA,MAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AACtB,MAAA,SAAA,CAAU,YAAA,CAAa,mBAAmB,MAAM,CAAA;AAAA,IAClD,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,WAAA,CAAY,SAAS,OAAA,EAAQ;AAC7B,MAAA,WAAA,CAAY,OAAA,GAAU,IAAA;AACtB,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,SAAA,CAAU,SAAA,GAAY,EAAA;AACtB,QAAA,SAAA,CAAU,gBAAgB,iBAAiB,CAAA;AAAA,MAC7C;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,YAAY,OAAA,EAAS;AACvB,MAAA,WAAA,CAAY,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,IACnC;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,YAAA;AAAA,MACL,SAAA;AAAA,MACA,KAAA;AAAA,MACA,aAAA,EAAY;AAAA;AAAA,GACd;AAEJ","file":"chart.js","sourcesContent":["import { useRef, useEffect } from 'react';\nimport type { ChartConfig, ChartInstance } from '../types.js';\nimport { renderChart } from '../chart/index.js';\n\nexport interface BexChartProps {\n config: ChartConfig;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * React wrapper for the standalone blex chart renderer.\n * Import from '@luckydraw/blex/react/chart'.\n */\nexport function BexChart({ config, className, style }: BexChartProps): React.JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null);\n const instanceRef = useRef<ChartInstance | null>(null);\n const configRef = useRef<ChartConfig>(config);\n\n configRef.current = config;\n\n // Mount: render chart, set ready attribute\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n let cancelled = false;\n\n renderChart(container, configRef.current).then((instance) => {\n if (cancelled) {\n instance.destroy();\n return;\n }\n instanceRef.current = instance;\n container.setAttribute('data-blex-ready', 'true');\n });\n\n return () => {\n cancelled = true;\n instanceRef.current?.destroy();\n instanceRef.current = null;\n if (container) {\n container.innerHTML = '';\n container.removeAttribute('data-blex-ready');\n }\n };\n }, []);\n\n // Update: push new config to existing chart\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.update(config);\n }\n }, [config]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={style}\n data-testid=\"bex-chart\"\n />\n );\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ContentBlock, BlockInteraction } from '../types.js';
|
|
2
|
+
export interface BexBlockProps {
|
|
3
|
+
block: ContentBlock;
|
|
4
|
+
onInteraction?: (interaction: BlockInteraction) => void;
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* React wrapper for any blex block type.
|
|
10
|
+
* Manages renderer lifecycle: mount → update → destroy on unmount.
|
|
11
|
+
*/
|
|
12
|
+
export declare function BexBlock({ block, onInteraction, className, style }: BexBlockProps): React.JSX.Element;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAe,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/E,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAWD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA8DrG"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { renderBlock, registerDefaults } from '../chunk-ZKSJGHJI.js';
|
|
2
|
+
import '../chunk-ODHF7VXV.js';
|
|
3
|
+
import { useRef, useCallback, useEffect } from 'react';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var defaultsRegistered = false;
|
|
7
|
+
function ensureDefaults() {
|
|
8
|
+
if (!defaultsRegistered) {
|
|
9
|
+
registerDefaults();
|
|
10
|
+
defaultsRegistered = true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function BexBlock({ block, onInteraction, className, style }) {
|
|
14
|
+
const containerRef = useRef(null);
|
|
15
|
+
const handleRef = useRef(null);
|
|
16
|
+
const blockRef = useRef(block);
|
|
17
|
+
const interactionRef = useRef(onInteraction);
|
|
18
|
+
interactionRef.current = onInteraction;
|
|
19
|
+
blockRef.current = block;
|
|
20
|
+
const interactionCallback = useCallback((interaction) => {
|
|
21
|
+
interactionRef.current?.(interaction);
|
|
22
|
+
}, []);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const container = containerRef.current;
|
|
25
|
+
if (!container) return;
|
|
26
|
+
ensureDefaults();
|
|
27
|
+
let cancelled = false;
|
|
28
|
+
renderBlock(blockRef.current, container, {
|
|
29
|
+
onReady: () => {
|
|
30
|
+
if (!cancelled) {
|
|
31
|
+
container.setAttribute("data-blex-ready", "true");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}).then((handle) => {
|
|
35
|
+
if (cancelled) {
|
|
36
|
+
handle.destroy();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
handleRef.current = handle;
|
|
40
|
+
handle.onInteraction(interactionCallback);
|
|
41
|
+
});
|
|
42
|
+
return () => {
|
|
43
|
+
cancelled = true;
|
|
44
|
+
handleRef.current?.destroy();
|
|
45
|
+
handleRef.current = null;
|
|
46
|
+
};
|
|
47
|
+
}, [block.type, block.id]);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (handleRef.current) {
|
|
50
|
+
handleRef.current.update(block);
|
|
51
|
+
}
|
|
52
|
+
}, [block]);
|
|
53
|
+
return /* @__PURE__ */ jsx(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
ref: containerRef,
|
|
57
|
+
className,
|
|
58
|
+
style,
|
|
59
|
+
"data-testid": `bex-block-${block.type}`
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { BexBlock };
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
66
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/react/index.tsx"],"names":[],"mappings":";;;;;AAaA,IAAI,kBAAA,GAAqB,KAAA;AACzB,SAAS,cAAA,GAAuB;AAC9B,EAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,IAAA,gBAAA,EAAiB;AACjB,IAAA,kBAAA,GAAqB,IAAA;AAAA,EACvB;AACF;AAMO,SAAS,SAAS,EAAE,KAAA,EAAO,aAAA,EAAe,SAAA,EAAW,OAAM,EAAqC;AACrG,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,SAAA,GAAY,OAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,QAAA,GAAW,OAAqB,KAAK,CAAA;AAC3C,EAAA,MAAM,cAAA,GAAiB,OAAO,aAAa,CAAA;AAG3C,EAAA,cAAA,CAAe,OAAA,GAAU,aAAA;AACzB,EAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAEnB,EAAA,MAAM,mBAAA,GAAsB,WAAA,CAAY,CAAC,WAAA,KAAkC;AACzE,IAAA,cAAA,CAAe,UAAU,WAAW,CAAA;AAAA,EACtC,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,cAAA,EAAe;AAEf,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAA,WAAA,CAAY,QAAA,CAAS,SAAS,SAAA,EAAW;AAAA,MACvC,SAAS,MAAM;AACb,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA,SAAA,CAAU,YAAA,CAAa,mBAAmB,MAAM,CAAA;AAAA,QAClD;AAAA,MACF;AAAA,KACD,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AAClB,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAA,CAAO,OAAA,EAAQ;AACf,QAAA;AAAA,MACF;AACA,MAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,MAAA,MAAA,CAAO,cAAc,mBAAmB,CAAA;AAAA,IAC1C,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,SAAA,CAAU,SAAS,OAAA,EAAQ;AAC3B,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EAGF,GAAG,CAAC,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,EAAE,CAAC,CAAA;AAGzB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,SAAA,CAAU,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,IAChC;AAAA,EACF,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,YAAA;AAAA,MACL,SAAA;AAAA,MACA,KAAA;AAAA,MACA,aAAA,EAAa,CAAA,UAAA,EAAa,KAAA,CAAM,IAAI,CAAA;AAAA;AAAA,GACtC;AAEJ","file":"index.js","sourcesContent":["import { useRef, useEffect, useCallback } from 'react';\nimport type { ContentBlock, BlockHandle, BlockInteraction } from '../types.js';\nimport { renderBlock } from '../render.js';\nimport { registerDefaults } from '../defaults.js';\n\nexport interface BexBlockProps {\n block: ContentBlock;\n onInteraction?: (interaction: BlockInteraction) => void;\n className?: string;\n style?: React.CSSProperties;\n}\n\n// Ensure built-in types are registered\nlet defaultsRegistered = false;\nfunction ensureDefaults(): void {\n if (!defaultsRegistered) {\n registerDefaults();\n defaultsRegistered = true;\n }\n}\n\n/**\n * React wrapper for any blex block type.\n * Manages renderer lifecycle: mount → update → destroy on unmount.\n */\nexport function BexBlock({ block, onInteraction, className, style }: BexBlockProps): React.JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<BlockHandle | null>(null);\n const blockRef = useRef<ContentBlock>(block);\n const interactionRef = useRef(onInteraction);\n\n // Keep refs current\n interactionRef.current = onInteraction;\n blockRef.current = block;\n\n const interactionCallback = useCallback((interaction: BlockInteraction) => {\n interactionRef.current?.(interaction);\n }, []);\n\n // Mount: render block, wire interaction, set ready attribute\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n ensureDefaults();\n\n let cancelled = false;\n\n renderBlock(blockRef.current, container, {\n onReady: () => {\n if (!cancelled) {\n container.setAttribute('data-blex-ready', 'true');\n }\n },\n }).then((handle) => {\n if (cancelled) {\n handle.destroy();\n return;\n }\n handleRef.current = handle;\n handle.onInteraction(interactionCallback);\n });\n\n return () => {\n cancelled = true;\n handleRef.current?.destroy();\n handleRef.current = null;\n };\n // Only re-mount if block type or id changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [block.type, block.id]);\n\n // Update: push new data to existing renderer without re-mount\n useEffect(() => {\n if (handleRef.current) {\n handleRef.current.update(block);\n }\n }, [block]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={style}\n data-testid={`bex-block-${block.type}`}\n />\n );\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BlockRenderer, BlockRendererFactory } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Register a block type with a synchronous factory.
|
|
4
|
+
* Overrides any existing registration for the same type.
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerBlockType(type: string, factory: BlockRendererFactory): void;
|
|
7
|
+
/**
|
|
8
|
+
* Mark a type as built-in. Built-in types cannot be overridden by plugins
|
|
9
|
+
* unless force is used.
|
|
10
|
+
*/
|
|
11
|
+
export declare function markBuiltIn(type: string): void;
|
|
12
|
+
/**
|
|
13
|
+
* Check if a type is a built-in block type.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isBuiltIn(type: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Remove a block type from the registry.
|
|
18
|
+
* Returns true if the type was removed, false if it wasn't registered.
|
|
19
|
+
*/
|
|
20
|
+
export declare function unregisterBlockType(type: string, options?: {
|
|
21
|
+
force?: boolean;
|
|
22
|
+
}): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Register a block type with a lazy loader.
|
|
25
|
+
* The loader is called once on first use; subsequent calls use the cached factory.
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerLazyBlockType(type: string, loader: () => Promise<BlockRendererFactory>): void;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a block type to a renderer instance.
|
|
30
|
+
* For lazy-loaded types, loads the module on first use and caches the factory.
|
|
31
|
+
* Returns null if the type is not registered.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveRenderer(type: string): Promise<BlockRenderer | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if a block type is registered.
|
|
36
|
+
*/
|
|
37
|
+
export declare function hasBlockType(type: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Get all registered block type names.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getRegisteredTypes(): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Clear the registry. Used for testing.
|
|
44
|
+
*/
|
|
45
|
+
export declare function clearRegistry(): void;
|
|
46
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAiB,MAAM,YAAY,CAAC;AAKrF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAEnF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAQxF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAErG;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiBjF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ContentBlock, BlockHandle, RenderOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Render a content block into a container element.
|
|
4
|
+
*
|
|
5
|
+
* 1. Injects theme defaults (once)
|
|
6
|
+
* 2. Resolves block type from registry (falls back to FallbackRenderer)
|
|
7
|
+
* 3. Loads renderer (lazy if needed)
|
|
8
|
+
* 4. Calls renderer.render()
|
|
9
|
+
* 5. Wires up interaction callbacks
|
|
10
|
+
* 6. Returns a BlockHandle for updates, interactions, and cleanup
|
|
11
|
+
*/
|
|
12
|
+
export declare function renderBlock(block: ContentBlock, container: HTMLElement, options?: RenderOptions): Promise<BlockHandle>;
|
|
13
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAoB,aAAa,EAAE,MAAM,YAAY,CAAC;AAK7F;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,WAAW,CAAC,CA+CtB"}
|