@fusedashlabs/widgets 0.4.3 → 0.4.5
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/CHANGELOG.md +12 -0
- package/dist/components/bar-chart/element/styles.js +3 -3
- package/dist/components/bar-chart/element/styles.js.map +1 -1
- package/dist/components/box-plot-chart/element/styles.js +3 -3
- package/dist/components/box-plot-chart/element/styles.js.map +1 -1
- package/dist/components/chart-renderer/element/styles.d.ts.map +1 -1
- package/dist/components/chart-renderer/element/styles.js +4 -1
- package/dist/components/chart-renderer/element/styles.js.map +1 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.d.ts.map +1 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.js +12 -0
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.js.map +1 -1
- package/dist/components/chart-renderer/metadata.json.d.ts +6 -1
- package/dist/components/chart-renderer/metadata.json.js +1 -1
- package/dist/components/custom-widget/element/styles.d.ts +2 -0
- package/dist/components/custom-widget/element/styles.d.ts.map +1 -0
- package/dist/components/custom-widget/element/styles.js +286 -0
- package/dist/components/custom-widget/element/styles.js.map +1 -0
- package/dist/components/custom-widget/element/ui9000-custom-widget.d.ts +48 -0
- package/dist/components/custom-widget/element/ui9000-custom-widget.d.ts.map +1 -0
- package/dist/components/custom-widget/element/ui9000-custom-widget.js +265 -0
- package/dist/components/custom-widget/element/ui9000-custom-widget.js.map +1 -0
- package/dist/components/custom-widget/index.d.ts +4 -0
- package/dist/components/custom-widget/index.d.ts.map +1 -0
- package/dist/components/custom-widget/index.js +19 -0
- package/dist/components/custom-widget/index.js.map +1 -0
- package/dist/components/custom-widget/lib/content.d.ts +13 -0
- package/dist/components/custom-widget/lib/content.d.ts.map +1 -0
- package/dist/components/custom-widget/lib/content.js +22 -0
- package/dist/components/custom-widget/lib/content.js.map +1 -0
- package/dist/components/custom-widget/lib/index.d.ts +8 -0
- package/dist/components/custom-widget/lib/index.d.ts.map +1 -0
- package/dist/components/custom-widget/lib/layout.d.ts +35 -0
- package/dist/components/custom-widget/lib/layout.d.ts.map +1 -0
- package/dist/components/custom-widget/lib/layout.js +13 -0
- package/dist/components/custom-widget/lib/layout.js.map +1 -0
- package/dist/components/custom-widget/lib/markdown.d.ts +4 -0
- package/dist/components/custom-widget/lib/markdown.d.ts.map +1 -0
- package/dist/components/custom-widget/lib/markdown.js +125 -0
- package/dist/components/custom-widget/lib/markdown.js.map +1 -0
- package/dist/components/custom-widget/lib/normalize.d.ts +6 -0
- package/dist/components/custom-widget/lib/normalize.d.ts.map +1 -0
- package/dist/components/custom-widget/lib/normalize.js +144 -0
- package/dist/components/custom-widget/lib/normalize.js.map +1 -0
- package/dist/components/custom-widget/lib/table.d.ts +55 -0
- package/dist/components/custom-widget/lib/table.d.ts.map +1 -0
- package/dist/components/custom-widget/lib/table.js +181 -0
- package/dist/components/custom-widget/lib/table.js.map +1 -0
- package/dist/components/custom-widget/lib/types.d.ts +55 -0
- package/dist/components/custom-widget/lib/types.d.ts.map +1 -0
- package/dist/components/custom-widget/metadata.json.d.ts +96 -0
- package/dist/components/custom-widget/metadata.json.js +42 -0
- package/dist/components/custom-widget/metadata.json.js.map +1 -0
- package/dist/components/histogram-chart/element/styles.js +2 -2
- package/dist/components/histogram-chart/element/styles.js.map +1 -1
- package/dist/components/line-chart/element/styles.js +2 -2
- package/dist/components/line-chart/element/styles.js.map +1 -1
- package/dist/components/lollipop/element/styles.js +3 -3
- package/dist/components/lollipop/element/styles.js.map +1 -1
- package/dist/components/map-chart/lib/constants.d.ts +2 -0
- package/dist/components/map-chart/lib/constants.d.ts.map +1 -1
- package/dist/components/map-chart/lib/constants.js +6 -0
- package/dist/components/map-chart/lib/constants.js.map +1 -1
- package/dist/components/map-chart/lib/geo-index.d.ts.map +1 -1
- package/dist/components/map-chart/lib/geo-index.js +5 -1
- package/dist/components/map-chart/lib/geo-index.js.map +1 -1
- package/dist/components/step-line-chart/element/styles.js +2 -2
- package/dist/components/step-line-chart/element/styles.js.map +1 -1
- package/dist/element/chart-shell-styles.d.ts.map +1 -1
- package/dist/element/chart-shell-styles.js +11 -4
- package/dist/element/chart-shell-styles.js.map +1 -1
- package/dist/element/ui9000-chart-base.d.ts +5 -0
- package/dist/element/ui9000-chart-base.d.ts.map +1 -1
- package/dist/element/ui9000-chart-base.js +7 -1
- package/dist/element/ui9000-chart-base.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/lazy/custom-widget.d.ts +4 -0
- package/dist/lazy/custom-widget.d.ts.map +1 -0
- package/dist/lazy/index.d.ts +2 -1
- package/dist/lazy/index.d.ts.map +1 -1
- package/dist/lazy/index.js +8 -0
- package/dist/lazy/index.js.map +1 -1
- package/package.json +9 -1
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { html, nothing } from "lit";
|
|
2
|
+
import { property, state, customElement } from "lit/decorators.js";
|
|
3
|
+
import { styleMap } from "lit/directives/style-map.js";
|
|
4
|
+
import { Ui9000ChartElement } from "../../../element/ui9000-chart-base.js";
|
|
5
|
+
import { loadChart } from "../../../lazy/index.js";
|
|
6
|
+
import { parseJsonAttr } from "../../../utils/chart-helpers.js";
|
|
7
|
+
import { customWidgetStyles } from "./styles.js";
|
|
8
|
+
import { normalizeCustomWidget } from "../lib/normalize.js";
|
|
9
|
+
import { renderMarkdown } from "../lib/markdown.js";
|
|
10
|
+
import { paneFlexDirection } from "../lib/layout.js";
|
|
11
|
+
import { chartShellStyles } from "../../../element/chart-shell-styles.js";
|
|
12
|
+
var __defProp = Object.defineProperty;
|
|
13
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
14
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
15
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
16
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
17
|
+
if (decorator = decorators[i])
|
|
18
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
19
|
+
if (kind && result) __defProp(target, key, result);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
const flagConverter = {
|
|
23
|
+
fromAttribute: (value) => value !== null && value !== "false",
|
|
24
|
+
toAttribute: (value) => value ? "" : "false"
|
|
25
|
+
};
|
|
26
|
+
const EMPTY_MODEL = {
|
|
27
|
+
title: "",
|
|
28
|
+
direction: "vertical",
|
|
29
|
+
hasKpi: false,
|
|
30
|
+
panes: [],
|
|
31
|
+
widget: null,
|
|
32
|
+
isEmpty: true
|
|
33
|
+
};
|
|
34
|
+
const DEFAULT_STATE_TITLE = "Choose an Option";
|
|
35
|
+
const DEFAULT_STATE_SUBTITLE = "We recommend starting with a chart, then enhancing your widget with lists, tables, or descriptions.";
|
|
36
|
+
let Ui9000CustomWidget = class extends Ui9000ChartElement {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this.scale = "default";
|
|
40
|
+
this.direction = "";
|
|
41
|
+
this.showGrid = true;
|
|
42
|
+
this.showLegend = true;
|
|
43
|
+
this.showTooltip = true;
|
|
44
|
+
this._model = EMPTY_MODEL;
|
|
45
|
+
}
|
|
46
|
+
connectedCallback() {
|
|
47
|
+
super.connectedCallback();
|
|
48
|
+
this._model = normalizeCustomWidget(parseJsonAttr(this.dataJson, null));
|
|
49
|
+
void this.loadPaneElements();
|
|
50
|
+
}
|
|
51
|
+
willUpdate(changed) {
|
|
52
|
+
if (changed.has("dataJson")) {
|
|
53
|
+
this._model = normalizeCustomWidget(parseJsonAttr(this.dataJson, null));
|
|
54
|
+
void this.loadPaneElements();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Register the child elements this model actually uses. */
|
|
58
|
+
async loadPaneElements() {
|
|
59
|
+
const pending = [];
|
|
60
|
+
if (this._model.hasKpi) pending.push(loadChart("kpi-widget"));
|
|
61
|
+
if (this._model.panes.some((pane) => pane.kind === "chartWidget" && pane.renderable)) {
|
|
62
|
+
pending.push(loadChart("chart-renderer"));
|
|
63
|
+
}
|
|
64
|
+
await Promise.all(pending);
|
|
65
|
+
}
|
|
66
|
+
get resolvedDirection() {
|
|
67
|
+
return this.direction === "horizontal" || this.direction === "vertical" ? this.direction : this._model.direction;
|
|
68
|
+
}
|
|
69
|
+
/** chart-renderer reads absent as "unset", so forward an explicit value */
|
|
70
|
+
flag(value) {
|
|
71
|
+
return value ? "" : "false";
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Inner FuseDash chartType for the chart pane. Must be forwarded as
|
|
75
|
+
* `chart-type` so the renderer does not treat `isCustom` as customWidget.
|
|
76
|
+
*/
|
|
77
|
+
paneChartType() {
|
|
78
|
+
var _a;
|
|
79
|
+
const chartType = (_a = this._model.widget) == null ? void 0 : _a.chartType;
|
|
80
|
+
return typeof chartType === "string" ? chartType.trim() : "";
|
|
81
|
+
}
|
|
82
|
+
/** KPI cards only — omit widget `name` so the band does not repeat the shell title */
|
|
83
|
+
kpiDataJson() {
|
|
84
|
+
var _a;
|
|
85
|
+
const kpis = (_a = this._model.widget) == null ? void 0 : _a.kpis;
|
|
86
|
+
return JSON.stringify(Array.isArray(kpis) ? kpis : []);
|
|
87
|
+
}
|
|
88
|
+
renderEmpty(title, subtitle, className) {
|
|
89
|
+
return html`
|
|
90
|
+
<div class=${className}>
|
|
91
|
+
<div>
|
|
92
|
+
<strong>${title}</strong>
|
|
93
|
+
<span>${subtitle}</span>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
renderTable(pane) {
|
|
99
|
+
const table = pane.table;
|
|
100
|
+
if (!table) {
|
|
101
|
+
return this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, "pane-empty");
|
|
102
|
+
}
|
|
103
|
+
return html`
|
|
104
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
105
|
+
<div class="table-root">
|
|
106
|
+
<div class="table-scroll">
|
|
107
|
+
<table class="table">
|
|
108
|
+
<thead>
|
|
109
|
+
<tr>
|
|
110
|
+
${table.columns.map(
|
|
111
|
+
(col) => html`<th class="table-cell" data-header>${col.label}</th>`
|
|
112
|
+
)}
|
|
113
|
+
</tr>
|
|
114
|
+
</thead>
|
|
115
|
+
<tbody>
|
|
116
|
+
${table.cells.map(
|
|
117
|
+
(row) => html`
|
|
118
|
+
<tr class="table-row">
|
|
119
|
+
${row.map(
|
|
120
|
+
(cell) => cell.badge ? html`<td class="table-cell">
|
|
121
|
+
<span class="table-badge" data-type=${cell.badge}>${cell.text}</span>
|
|
122
|
+
</td>` : html`<td class="table-cell">${cell.text}</td>`
|
|
123
|
+
)}
|
|
124
|
+
</tr>
|
|
125
|
+
`
|
|
126
|
+
)}
|
|
127
|
+
</tbody>
|
|
128
|
+
</table>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
`;
|
|
133
|
+
}
|
|
134
|
+
renderText(pane) {
|
|
135
|
+
if (!pane.text) {
|
|
136
|
+
return html`
|
|
137
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
138
|
+
${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, "pane-empty")}
|
|
139
|
+
</div>
|
|
140
|
+
`;
|
|
141
|
+
}
|
|
142
|
+
return html`
|
|
143
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
144
|
+
<div class="text-pane">${renderMarkdown(pane.text)}</div>
|
|
145
|
+
</div>
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
renderImage(pane) {
|
|
149
|
+
if (!pane.image) {
|
|
150
|
+
return html`
|
|
151
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
152
|
+
${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, "pane-empty")}
|
|
153
|
+
</div>
|
|
154
|
+
`;
|
|
155
|
+
}
|
|
156
|
+
return html`
|
|
157
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
158
|
+
<div class="image-pane">
|
|
159
|
+
<img
|
|
160
|
+
src=${pane.image.src}
|
|
161
|
+
alt=${pane.image.alt}
|
|
162
|
+
referrerpolicy="no-referrer"
|
|
163
|
+
/>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
168
|
+
renderPane(pane) {
|
|
169
|
+
if (pane.kind === "tableWidget") {
|
|
170
|
+
return pane.renderable ? this.renderTable(pane) : html`
|
|
171
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
172
|
+
${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, "pane-empty")}
|
|
173
|
+
</div>
|
|
174
|
+
`;
|
|
175
|
+
}
|
|
176
|
+
if (pane.kind === "textWidget") return this.renderText(pane);
|
|
177
|
+
if (pane.kind === "imageWidget") return this.renderImage(pane);
|
|
178
|
+
if (!pane.renderable) {
|
|
179
|
+
return html`
|
|
180
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
181
|
+
${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, "pane-empty")}
|
|
182
|
+
</div>
|
|
183
|
+
`;
|
|
184
|
+
}
|
|
185
|
+
return html`
|
|
186
|
+
<div class="pane" data-kind=${pane.kind}>
|
|
187
|
+
<ui9000-chart-renderer
|
|
188
|
+
embedded
|
|
189
|
+
data=${this.dataJson}
|
|
190
|
+
chart-type=${this.paneChartType()}
|
|
191
|
+
scale=${this.scale}
|
|
192
|
+
show-header="false"
|
|
193
|
+
show-grid=${this.flag(this.showGrid)}
|
|
194
|
+
show-legend=${this.flag(this.showLegend)}
|
|
195
|
+
show-tooltip=${this.flag(this.showTooltip)}
|
|
196
|
+
></ui9000-chart-renderer>
|
|
197
|
+
</div>
|
|
198
|
+
`;
|
|
199
|
+
}
|
|
200
|
+
renderKpiBand() {
|
|
201
|
+
return html`
|
|
202
|
+
<div class="kpi-band">
|
|
203
|
+
<ui9000-kpi-widget
|
|
204
|
+
data=${this.kpiDataJson()}
|
|
205
|
+
scale=${this.scale}
|
|
206
|
+
show-header="false"
|
|
207
|
+
></ui9000-kpi-widget>
|
|
208
|
+
</div>
|
|
209
|
+
`;
|
|
210
|
+
}
|
|
211
|
+
render() {
|
|
212
|
+
const model = this._model;
|
|
213
|
+
const title = this.headerTitle();
|
|
214
|
+
return html`
|
|
215
|
+
<div class="widget-shell custom-root" part="shell">
|
|
216
|
+
${this.renderShellHeader(title)} ${model.hasKpi ? this.renderKpiBand() : nothing}
|
|
217
|
+
${model.isEmpty ? this.renderEmpty(DEFAULT_STATE_TITLE, DEFAULT_STATE_SUBTITLE, "default-state") : html`
|
|
218
|
+
<div
|
|
219
|
+
class="custom-content"
|
|
220
|
+
data-direction=${this.resolvedDirection}
|
|
221
|
+
data-panes=${model.panes.length}
|
|
222
|
+
style=${styleMap({
|
|
223
|
+
flexDirection: paneFlexDirection(this.resolvedDirection)
|
|
224
|
+
})}
|
|
225
|
+
>
|
|
226
|
+
${model.panes.map((pane) => this.renderPane(pane))}
|
|
227
|
+
</div>
|
|
228
|
+
`}
|
|
229
|
+
${this.renderShellLabelTooltip()}
|
|
230
|
+
</div>
|
|
231
|
+
`;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
Ui9000CustomWidget.styles = [customWidgetStyles, chartShellStyles];
|
|
235
|
+
__decorateClass([
|
|
236
|
+
property({ type: String, attribute: "scale" })
|
|
237
|
+
], Ui9000CustomWidget.prototype, "scale", 2);
|
|
238
|
+
__decorateClass([
|
|
239
|
+
property({ type: String, attribute: "direction" })
|
|
240
|
+
], Ui9000CustomWidget.prototype, "direction", 2);
|
|
241
|
+
__decorateClass([
|
|
242
|
+
property({ converter: flagConverter, attribute: "show-grid" })
|
|
243
|
+
], Ui9000CustomWidget.prototype, "showGrid", 2);
|
|
244
|
+
__decorateClass([
|
|
245
|
+
property({ converter: flagConverter, attribute: "show-legend" })
|
|
246
|
+
], Ui9000CustomWidget.prototype, "showLegend", 2);
|
|
247
|
+
__decorateClass([
|
|
248
|
+
property({ converter: flagConverter, attribute: "show-tooltip" })
|
|
249
|
+
], Ui9000CustomWidget.prototype, "showTooltip", 2);
|
|
250
|
+
__decorateClass([
|
|
251
|
+
state()
|
|
252
|
+
], Ui9000CustomWidget.prototype, "_model", 2);
|
|
253
|
+
Ui9000CustomWidget = __decorateClass([
|
|
254
|
+
customElement("ui9000-custom-widget")
|
|
255
|
+
], Ui9000CustomWidget);
|
|
256
|
+
function registerCustomWidget() {
|
|
257
|
+
if (!customElements.get("ui9000-custom-widget")) {
|
|
258
|
+
customElements.define("ui9000-custom-widget", Ui9000CustomWidget);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
export {
|
|
262
|
+
Ui9000CustomWidget,
|
|
263
|
+
registerCustomWidget
|
|
264
|
+
};
|
|
265
|
+
//# sourceMappingURL=ui9000-custom-widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui9000-custom-widget.js","sources":["../../../../src/components/custom-widget/element/ui9000-custom-widget.ts"],"sourcesContent":["import { html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport { chartShellStyles, Ui9000ChartElement } from '../../../element/ui9000-chart-base.js';\nimport { loadChart } from '../../../lazy/index.js';\nimport type { WidgetScale } from '../../../types/index.js';\nimport { parseJsonAttr } from '../../../utils/chart-helpers.js';\nimport {\n normalizeCustomWidget,\n paneFlexDirection,\n renderMarkdown,\n type ArrangingDirection,\n type CustomPane,\n type CustomWidgetModel,\n} from '../lib/index.js';\nimport { customWidgetStyles } from './styles.js';\n\n/**\n * `show-*` flags default to on; `show-x=\"false\"` turns them off. Matches how\n * `ui9000-chart-renderer` reads the same attributes.\n */\nconst flagConverter = {\n fromAttribute: (value: string | null): boolean => value !== null && value !== 'false',\n toAttribute: (value: boolean): string => (value ? '' : 'false'),\n};\n\nconst EMPTY_MODEL: CustomWidgetModel = {\n title: '',\n direction: 'vertical',\n hasKpi: false,\n panes: [],\n widget: null,\n isEmpty: true,\n};\n\n/** Client `WidgetDefaultState` copy, minus the editor-only toolbar */\nconst DEFAULT_STATE_TITLE = 'Choose an Option';\nconst DEFAULT_STATE_SUBTITLE =\n 'We recommend starting with a chart, then enhancing your widget with lists, tables, or descriptions.';\n\n/**\n * FuseDash CustomWidget shell: title, optional KPI band, and up to two arranged\n * panes. Chart panes mount `ui9000-chart-renderer`, the KPI band mounts\n * `ui9000-kpi-widget`; table / text / image panes render inline. Child charts\n * are lazy-loaded so this entry stays small.\n */\n@customElement('ui9000-custom-widget')\nexport class Ui9000CustomWidget extends Ui9000ChartElement {\n static override styles = [customWidgetStyles, chartShellStyles];\n\n @property({ type: String, attribute: 'scale' })\n scale: WidgetScale = 'default';\n\n /** Overrides `arranging.direction` from the payload */\n @property({ type: String, attribute: 'direction' })\n direction: ArrangingDirection | '' = '';\n\n @property({ converter: flagConverter, attribute: 'show-grid' })\n showGrid = true;\n\n @property({ converter: flagConverter, attribute: 'show-legend' })\n showLegend = true;\n\n @property({ converter: flagConverter, attribute: 'show-tooltip' })\n showTooltip = true;\n\n @state()\n private _model: CustomWidgetModel = EMPTY_MODEL;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._model = normalizeCustomWidget(parseJsonAttr<unknown>(this.dataJson, null));\n void this.loadPaneElements();\n }\n\n override willUpdate(changed: PropertyValues): void {\n if (changed.has('dataJson')) {\n this._model = normalizeCustomWidget(parseJsonAttr<unknown>(this.dataJson, null));\n void this.loadPaneElements();\n }\n }\n\n /** Register the child elements this model actually uses. */\n private async loadPaneElements(): Promise<void> {\n const pending: Promise<unknown>[] = [];\n if (this._model.hasKpi) pending.push(loadChart('kpi-widget'));\n if (this._model.panes.some((pane) => pane.kind === 'chartWidget' && pane.renderable)) {\n pending.push(loadChart('chart-renderer'));\n }\n await Promise.all(pending);\n }\n\n private get resolvedDirection(): ArrangingDirection {\n return this.direction === 'horizontal' || this.direction === 'vertical'\n ? this.direction\n : this._model.direction;\n }\n\n /** chart-renderer reads absent as \"unset\", so forward an explicit value */\n private flag(value: boolean): string {\n return value ? '' : 'false';\n }\n\n /**\n * Inner FuseDash chartType for the chart pane. Must be forwarded as\n * `chart-type` so the renderer does not treat `isCustom` as customWidget.\n */\n private paneChartType(): string {\n const chartType = this._model.widget?.chartType;\n return typeof chartType === 'string' ? chartType.trim() : '';\n }\n\n /** KPI cards only — omit widget `name` so the band does not repeat the shell title */\n private kpiDataJson(): string {\n const kpis = this._model.widget?.kpis;\n return JSON.stringify(Array.isArray(kpis) ? kpis : []);\n }\n\n private renderEmpty(title: string, subtitle: string, className: string): TemplateResult {\n return html`\n <div class=${className}>\n <div>\n <strong>${title}</strong>\n <span>${subtitle}</span>\n </div>\n </div>\n `;\n }\n\n private renderTable(pane: CustomPane): TemplateResult {\n const table = pane.table;\n if (!table) {\n return this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, 'pane-empty');\n }\n return html`\n <div class=\"pane\" data-kind=${pane.kind}>\n <div class=\"table-root\">\n <div class=\"table-scroll\">\n <table class=\"table\">\n <thead>\n <tr>\n ${table.columns.map(\n (col) => html`<th class=\"table-cell\" data-header>${col.label}</th>`,\n )}\n </tr>\n </thead>\n <tbody>\n ${table.cells.map(\n (row) => html`\n <tr class=\"table-row\">\n ${row.map((cell) =>\n cell.badge\n ? html`<td class=\"table-cell\">\n <span class=\"table-badge\" data-type=${cell.badge}>${cell.text}</span>\n </td>`\n : html`<td class=\"table-cell\">${cell.text}</td>`,\n )}\n </tr>\n `,\n )}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n `;\n }\n\n private renderText(pane: CustomPane): TemplateResult {\n if (!pane.text) {\n return html`\n <div class=\"pane\" data-kind=${pane.kind}>\n ${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, 'pane-empty')}\n </div>\n `;\n }\n return html`\n <div class=\"pane\" data-kind=${pane.kind}>\n <div class=\"text-pane\">${renderMarkdown(pane.text)}</div>\n </div>\n `;\n }\n\n private renderImage(pane: CustomPane): TemplateResult {\n if (!pane.image) {\n return html`\n <div class=\"pane\" data-kind=${pane.kind}>\n ${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, 'pane-empty')}\n </div>\n `;\n }\n return html`\n <div class=\"pane\" data-kind=${pane.kind}>\n <div class=\"image-pane\">\n <img\n src=${pane.image.src}\n alt=${pane.image.alt}\n referrerpolicy=\"no-referrer\"\n />\n </div>\n </div>\n `;\n }\n\n private renderPane(pane: CustomPane): TemplateResult {\n if (pane.kind === 'tableWidget') {\n return pane.renderable ? this.renderTable(pane) : html`\n <div class=\"pane\" data-kind=${pane.kind}>\n ${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, 'pane-empty')}\n </div>\n `;\n }\n if (pane.kind === 'textWidget') return this.renderText(pane);\n if (pane.kind === 'imageWidget') return this.renderImage(pane);\n if (!pane.renderable) {\n return html`\n <div class=\"pane\" data-kind=${pane.kind}>\n ${this.renderEmpty(pane.emptyTitle, pane.emptySubtitle, 'pane-empty')}\n </div>\n `;\n }\n return html`\n <div class=\"pane\" data-kind=${pane.kind}>\n <ui9000-chart-renderer\n embedded\n data=${this.dataJson}\n chart-type=${this.paneChartType()}\n scale=${this.scale}\n show-header=\"false\"\n show-grid=${this.flag(this.showGrid)}\n show-legend=${this.flag(this.showLegend)}\n show-tooltip=${this.flag(this.showTooltip)}\n ></ui9000-chart-renderer>\n </div>\n `;\n }\n\n private renderKpiBand(): TemplateResult {\n return html`\n <div class=\"kpi-band\">\n <ui9000-kpi-widget\n data=${this.kpiDataJson()}\n scale=${this.scale}\n show-header=\"false\"\n ></ui9000-kpi-widget>\n </div>\n `;\n }\n\n override render() {\n const model = this._model;\n const title = this.headerTitle();\n\n return html`\n <div class=\"widget-shell custom-root\" part=\"shell\">\n ${this.renderShellHeader(title)} ${model.hasKpi ? this.renderKpiBand() : nothing}\n ${model.isEmpty\n ? this.renderEmpty(DEFAULT_STATE_TITLE, DEFAULT_STATE_SUBTITLE, 'default-state')\n : html`\n <div\n class=\"custom-content\"\n data-direction=${this.resolvedDirection}\n data-panes=${model.panes.length}\n style=${styleMap({\n flexDirection: paneFlexDirection(this.resolvedDirection),\n })}\n >\n ${model.panes.map((pane) => this.renderPane(pane))}\n </div>\n `}\n ${this.renderShellLabelTooltip()}\n </div>\n `;\n }\n}\n\nexport function registerCustomWidget(): void {\n if (!customElements.get('ui9000-custom-widget')) {\n customElements.define('ui9000-custom-widget', Ui9000CustomWidget);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ui9000-custom-widget': Ui9000CustomWidget;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { Ui9000CustomWidget, registerCustomWidget } from './element/ui9000-custom-widget.js';
|
|
2
|
+
export { isContentChartType, normalizeCustomWidget, normalizeTableModel, paneFlexDirection, KPI_ROW_HEIGHT, MAX_PANES, PANE_GAP, type ArrangingDirection, type CustomPane, type CustomPaneKind, type CustomTableModel, type CustomWidgetArranging, type CustomWidgetModel, type CustomWidgetPayload, } from './lib/index.js';
|
|
3
|
+
export { default as customWidgetMetadata } from './metadata.json';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/custom-widget/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC7F,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,QAAQ,EACR,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { registerCustomWidget } from "./element/ui9000-custom-widget.js";
|
|
2
|
+
import { Ui9000CustomWidget } from "./element/ui9000-custom-widget.js";
|
|
3
|
+
import { default as default2 } from "./metadata.json.js";
|
|
4
|
+
import { KPI_ROW_HEIGHT, MAX_PANES, PANE_GAP, paneFlexDirection } from "./lib/layout.js";
|
|
5
|
+
import { isContentChartType, normalizeCustomWidget } from "./lib/normalize.js";
|
|
6
|
+
import { normalizeTableModel } from "./lib/table.js";
|
|
7
|
+
export {
|
|
8
|
+
KPI_ROW_HEIGHT,
|
|
9
|
+
MAX_PANES,
|
|
10
|
+
PANE_GAP,
|
|
11
|
+
Ui9000CustomWidget,
|
|
12
|
+
default2 as customWidgetMetadata,
|
|
13
|
+
isContentChartType,
|
|
14
|
+
normalizeCustomWidget,
|
|
15
|
+
normalizeTableModel,
|
|
16
|
+
paneFlexDirection,
|
|
17
|
+
registerCustomWidget
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Text + image panes — MCP is read-only (no editor, upload, or AI chat). */
|
|
2
|
+
export declare function normalizeTextContent(widget: {
|
|
3
|
+
text?: unknown;
|
|
4
|
+
}): string | null;
|
|
5
|
+
export declare function isExternalImageUrl(url: string): boolean;
|
|
6
|
+
export declare function normalizeImageContent(widget: {
|
|
7
|
+
imageUrl?: unknown;
|
|
8
|
+
alt?: unknown;
|
|
9
|
+
}): {
|
|
10
|
+
src: string;
|
|
11
|
+
alt: string;
|
|
12
|
+
} | null;
|
|
13
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/components/custom-widget/lib/content.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAI7E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAI9E;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMtC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const HTTP_URL = /^https?:\/\//i;
|
|
2
|
+
function normalizeTextContent(widget) {
|
|
3
|
+
if (typeof widget.text !== "string") return null;
|
|
4
|
+
const text = widget.text.trim();
|
|
5
|
+
return text ? text : null;
|
|
6
|
+
}
|
|
7
|
+
function isExternalImageUrl(url) {
|
|
8
|
+
return HTTP_URL.test(url.trim());
|
|
9
|
+
}
|
|
10
|
+
function normalizeImageContent(widget) {
|
|
11
|
+
if (typeof widget.imageUrl !== "string") return null;
|
|
12
|
+
const src = widget.imageUrl.trim();
|
|
13
|
+
if (!src || src === "-" || !isExternalImageUrl(src)) return null;
|
|
14
|
+
const alt = typeof widget.alt === "string" && widget.alt.trim() ? widget.alt.trim() : "Preview";
|
|
15
|
+
return { src, alt };
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
isExternalImageUrl,
|
|
19
|
+
normalizeImageContent,
|
|
20
|
+
normalizeTextContent
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sources":["../../../../src/components/custom-widget/lib/content.ts"],"sourcesContent":["/** Text + image panes — MCP is read-only (no editor, upload, or AI chat). */\n\nconst HTTP_URL = /^https?:\\/\\//i;\n\nexport function normalizeTextContent(widget: { text?: unknown }): string | null {\n if (typeof widget.text !== 'string') return null;\n const text = widget.text.trim();\n return text ? text : null;\n}\n\nexport function isExternalImageUrl(url: string): boolean {\n return HTTP_URL.test(url.trim());\n}\n\nexport function normalizeImageContent(widget: {\n imageUrl?: unknown;\n alt?: unknown;\n}): { src: string; alt: string } | null {\n if (typeof widget.imageUrl !== 'string') return null;\n const src = widget.imageUrl.trim();\n if (!src || src === '-' || !isExternalImageUrl(src)) return null;\n const alt = typeof widget.alt === 'string' && widget.alt.trim() ? widget.alt.trim() : 'Preview';\n return { src, alt };\n}\n"],"names":[],"mappings":"AAEA,MAAM,WAAW;AAEV,SAAS,qBAAqB,QAA2C;AAC9E,MAAI,OAAO,OAAO,SAAS,SAAU,QAAO;AAC5C,QAAM,OAAO,OAAO,KAAK,KAAA;AACzB,SAAO,OAAO,OAAO;AACvB;AAEO,SAAS,mBAAmB,KAAsB;AACvD,SAAO,SAAS,KAAK,IAAI,KAAA,CAAM;AACjC;AAEO,SAAS,sBAAsB,QAGE;AACtC,MAAI,OAAO,OAAO,aAAa,SAAU,QAAO;AAChD,QAAM,MAAM,OAAO,SAAS,KAAA;AAC5B,MAAI,CAAC,OAAO,QAAQ,OAAO,CAAC,mBAAmB,GAAG,EAAG,QAAO;AAC5D,QAAM,MAAM,OAAO,OAAO,QAAQ,YAAY,OAAO,IAAI,KAAA,IAAS,OAAO,IAAI,KAAA,IAAS;AACtF,SAAO,EAAE,KAAK,IAAA;AAChB;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { KPI_ROW_HEIGHT, MAX_PANES, PANE_GAP, paneFlexDirection, panesFromSlots, limitSelectedPanes, isPaneSlotDisabled, PANE_SLOT_KEYS, type CustomWidgetPaneSlot, type CustomWidgetSlots, } from './layout.js';
|
|
2
|
+
export { isContentChartType, normalizeCustomWidget } from './normalize.js';
|
|
3
|
+
export { renderMarkdown } from './markdown.js';
|
|
4
|
+
export { buildLiveTableRowsFromSources, formatTableCell, normalizeTableModel, parseTableHeaders, } from './table.js';
|
|
5
|
+
export { normalizeImageContent, normalizeTextContent } from './content.js';
|
|
6
|
+
export type { ArrangingDirection, CustomPane, CustomPaneKind, CustomWidgetArranging, CustomWidgetModel, CustomWidgetPayload, } from './types.js';
|
|
7
|
+
export type { CustomTableModel, TableCellModel, TableColumnSource, TableHeader } from './table.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/custom-widget/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,6BAA6B,EAC7B,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EACV,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ArrangingDirection, CustomPaneKind } from './types.js';
|
|
2
|
+
/** Client `WIDGET_DIMENSIONS.KPI_HEIGHT` — fixed band above the panes */
|
|
3
|
+
export declare const KPI_ROW_HEIGHT = 104;
|
|
4
|
+
/** Client renders a 10px spacer between two panes in MCP chat */
|
|
5
|
+
export declare const PANE_GAP = 10;
|
|
6
|
+
/** `useWidgetToolbar` disables adding past two panes */
|
|
7
|
+
export declare const MAX_PANES = 2;
|
|
8
|
+
/** Story / playground toggles — KPI is a band, not a pane */
|
|
9
|
+
export interface CustomWidgetSlots {
|
|
10
|
+
kpi?: boolean;
|
|
11
|
+
chart?: boolean;
|
|
12
|
+
table?: boolean;
|
|
13
|
+
text?: boolean;
|
|
14
|
+
image?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const PANE_SLOT_KEYS: readonly ["chart", "table", "text", "image"];
|
|
17
|
+
export type CustomWidgetPaneSlot = (typeof PANE_SLOT_KEYS)[number];
|
|
18
|
+
/**
|
|
19
|
+
* First two enabled pane slots, in chart → table → text → image order.
|
|
20
|
+
* KPI is ignored here — it is not a main widget.
|
|
21
|
+
*/
|
|
22
|
+
export declare function panesFromSlots(slots: CustomWidgetSlots): CustomPaneKind[];
|
|
23
|
+
/**
|
|
24
|
+
* At most two pane switches stay on. KPI is never capped.
|
|
25
|
+
* A third pane is rejected so the previous pair stays selected.
|
|
26
|
+
*/
|
|
27
|
+
export declare function limitSelectedPanes(slots: CustomWidgetSlots, previous?: CustomWidgetSlots): CustomWidgetSlots;
|
|
28
|
+
/**
|
|
29
|
+
* Client `WidgetContent` maps direction onto flex-direction inverted:
|
|
30
|
+
* `vertical` → row, `horizontal` → column.
|
|
31
|
+
*/
|
|
32
|
+
export declare function paneFlexDirection(direction: ArrangingDirection): 'row' | 'column';
|
|
33
|
+
/** Unselected pane switches disable once two panes are already on. KPI is not a pane. */
|
|
34
|
+
export declare function isPaneSlotDisabled(slots: CustomWidgetSlots, key: CustomWidgetPaneSlot): boolean;
|
|
35
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/components/custom-widget/lib/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAErE,yEAAyE;AACzE,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,iEAAiE;AACjE,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B,wDAAwD;AACxD,eAAO,MAAM,SAAS,IAAI,CAAC;AAE3B,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,cAAc,8CAA+C,CAAC;AAE3E,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AA2BnE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,cAAc,EAAE,CAIzE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,iBAAiB,EACxB,QAAQ,GAAE,iBAAsB,GAC/B,iBAAiB,CASnB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,KAAK,GAAG,QAAQ,CAEjF;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,iBAAiB,EACxB,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAGT"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const KPI_ROW_HEIGHT = 104;
|
|
2
|
+
const PANE_GAP = 10;
|
|
3
|
+
const MAX_PANES = 2;
|
|
4
|
+
function paneFlexDirection(direction) {
|
|
5
|
+
return direction === "vertical" ? "row" : "column";
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
KPI_ROW_HEIGHT,
|
|
9
|
+
MAX_PANES,
|
|
10
|
+
PANE_GAP,
|
|
11
|
+
paneFlexDirection
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sources":["../../../../src/components/custom-widget/lib/layout.ts"],"sourcesContent":["import type { ArrangingDirection, CustomPaneKind } from './types.js';\n\n/** Client `WIDGET_DIMENSIONS.KPI_HEIGHT` — fixed band above the panes */\nexport const KPI_ROW_HEIGHT = 104;\n\n/** Client renders a 10px spacer between two panes in MCP chat */\nexport const PANE_GAP = 10;\n\n/** `useWidgetToolbar` disables adding past two panes */\nexport const MAX_PANES = 2;\n\n/** Story / playground toggles — KPI is a band, not a pane */\nexport interface CustomWidgetSlots {\n kpi?: boolean;\n chart?: boolean;\n table?: boolean;\n text?: boolean;\n image?: boolean;\n}\n\nexport const PANE_SLOT_KEYS = ['chart', 'table', 'text', 'image'] as const;\n\nexport type CustomWidgetPaneSlot = (typeof PANE_SLOT_KEYS)[number];\n\nconst SLOT_PANES: readonly { key: CustomWidgetPaneSlot; kind: CustomPaneKind }[] = [\n { key: 'chart', kind: 'chartWidget' },\n { key: 'table', kind: 'tableWidget' },\n { key: 'text', kind: 'textWidget' },\n { key: 'image', kind: 'imageWidget' },\n];\n\nfunction selectedPaneSlots(slots: CustomWidgetSlots): CustomWidgetPaneSlot[] {\n return PANE_SLOT_KEYS.filter((key) => !!slots[key]);\n}\n\nfunction slotsFromPaneKeys(\n slots: CustomWidgetSlots,\n panes: readonly CustomWidgetPaneSlot[],\n): CustomWidgetSlots {\n const keep = new Set(panes);\n return {\n kpi: !!slots.kpi,\n chart: keep.has('chart'),\n table: keep.has('table'),\n text: keep.has('text'),\n image: keep.has('image'),\n };\n}\n\n/**\n * First two enabled pane slots, in chart → table → text → image order.\n * KPI is ignored here — it is not a main widget.\n */\nexport function panesFromSlots(slots: CustomWidgetSlots): CustomPaneKind[] {\n return SLOT_PANES.filter(({ key }) => !!slots[key])\n .slice(0, MAX_PANES)\n .map(({ kind }) => kind);\n}\n\n/**\n * At most two pane switches stay on. KPI is never capped.\n * A third pane is rejected so the previous pair stays selected.\n */\nexport function limitSelectedPanes(\n slots: CustomWidgetSlots,\n previous: CustomWidgetSlots = {},\n): CustomWidgetSlots {\n const selected = selectedPaneSlots(slots);\n if (selected.length <= MAX_PANES) return slotsFromPaneKeys(slots, selected);\n\n const previousSelected = selectedPaneSlots(previous);\n if (previousSelected.length === MAX_PANES) {\n return slotsFromPaneKeys(slots, previousSelected);\n }\n return slotsFromPaneKeys(slots, selected.slice(0, MAX_PANES));\n}\n\n/**\n * Client `WidgetContent` maps direction onto flex-direction inverted:\n * `vertical` → row, `horizontal` → column.\n */\nexport function paneFlexDirection(direction: ArrangingDirection): 'row' | 'column' {\n return direction === 'vertical' ? 'row' : 'column';\n}\n\n/** Unselected pane switches disable once two panes are already on. KPI is not a pane. */\nexport function isPaneSlotDisabled(\n slots: CustomWidgetSlots,\n key: CustomWidgetPaneSlot,\n): boolean {\n if (slots[key]) return false;\n return selectedPaneSlots(slots).length >= MAX_PANES;\n}\n"],"names":[],"mappings":"AAGO,MAAM,iBAAiB;AAGvB,MAAM,WAAW;AAGjB,MAAM,YAAY;AAwElB,SAAS,kBAAkB,WAAiD;AACjF,SAAO,cAAc,aAAa,QAAQ;AAC5C;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../src/components/custom-widget/lib/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAkDhD,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CA0F7D"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
const SAFE_HREF = /^https?:\/\//i;
|
|
3
|
+
function isSafeHref(href) {
|
|
4
|
+
return SAFE_HREF.test(href.trim());
|
|
5
|
+
}
|
|
6
|
+
function renderInline(text) {
|
|
7
|
+
const nodes = [];
|
|
8
|
+
const re = /(\*\*[^*]+\*\*|__[^_]+__|\*[^*]+\*|_[^_]+_|`[^`]+`|\[[^\]]+\]\([^)]+\))/g;
|
|
9
|
+
let last = 0;
|
|
10
|
+
let match;
|
|
11
|
+
while (match = re.exec(text)) {
|
|
12
|
+
if (match.index > last) {
|
|
13
|
+
nodes.push(html`${text.slice(last, match.index)}`);
|
|
14
|
+
}
|
|
15
|
+
const token = match[0];
|
|
16
|
+
if (token.startsWith("**") || token.startsWith("__")) {
|
|
17
|
+
nodes.push(html`<strong>${token.slice(2, -2)}</strong>`);
|
|
18
|
+
} else if (token.startsWith("*") || token.startsWith("_")) {
|
|
19
|
+
nodes.push(html`<em>${token.slice(1, -1)}</em>`);
|
|
20
|
+
} else if (token.startsWith("`")) {
|
|
21
|
+
nodes.push(html`<code>${token.slice(1, -1)}</code>`);
|
|
22
|
+
} else {
|
|
23
|
+
const link = token.match(/^\[([^\]]+)\]\(([^)]+)\)$/);
|
|
24
|
+
if (link && isSafeHref(link[2])) {
|
|
25
|
+
nodes.push(
|
|
26
|
+
html`<a href=${link[2]} target="_blank" rel="noopener noreferrer">${link[1]}</a>`
|
|
27
|
+
);
|
|
28
|
+
} else {
|
|
29
|
+
nodes.push(html`${token}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
last = match.index + token.length;
|
|
33
|
+
}
|
|
34
|
+
if (last < text.length) nodes.push(html`${text.slice(last)}`);
|
|
35
|
+
return nodes.length ? nodes : [html`${text}`];
|
|
36
|
+
}
|
|
37
|
+
function flushParagraph(lines, out) {
|
|
38
|
+
const text = lines.join("\n").trim();
|
|
39
|
+
if (!text) return;
|
|
40
|
+
out.push(html`<p>${renderInline(text)}</p>`);
|
|
41
|
+
lines.length = 0;
|
|
42
|
+
}
|
|
43
|
+
function renderMarkdown(source) {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
const lines = source.replace(/\r\n/g, "\n").split("\n");
|
|
46
|
+
const blocks = [];
|
|
47
|
+
const paragraph = [];
|
|
48
|
+
let listItems = null;
|
|
49
|
+
let fence = null;
|
|
50
|
+
const flushList = () => {
|
|
51
|
+
if (!(listItems == null ? void 0 : listItems.length)) {
|
|
52
|
+
listItems = null;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const items = listItems.map((item) => html`<li>${renderInline(item.text)}</li>`);
|
|
56
|
+
blocks.push(
|
|
57
|
+
listItems[0].ordered ? html`<ol>${items}</ol>` : html`<ul>${items}</ul>`
|
|
58
|
+
);
|
|
59
|
+
listItems = null;
|
|
60
|
+
};
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
if (fence) {
|
|
63
|
+
if (line.startsWith("```")) {
|
|
64
|
+
const code = fence.join("\n");
|
|
65
|
+
blocks.push(html`<pre><code>${code}</code></pre>`);
|
|
66
|
+
fence = null;
|
|
67
|
+
} else {
|
|
68
|
+
fence.push(line);
|
|
69
|
+
}
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (line.startsWith("```")) {
|
|
73
|
+
flushParagraph(paragraph, blocks);
|
|
74
|
+
flushList();
|
|
75
|
+
fence = [];
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const heading = line.match(/^(#{1,3})\s+(.+)$/);
|
|
79
|
+
if (heading) {
|
|
80
|
+
flushParagraph(paragraph, blocks);
|
|
81
|
+
flushList();
|
|
82
|
+
const title = heading[2];
|
|
83
|
+
const level = heading[1].length;
|
|
84
|
+
blocks.push(
|
|
85
|
+
level === 1 ? html`<h1>${renderInline(title)}</h1>` : level === 2 ? html`<h2>${renderInline(title)}</h2>` : html`<h3>${renderInline(title)}</h3>`
|
|
86
|
+
);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const ul = line.match(/^[-*]\s+(.+)$/);
|
|
90
|
+
if (ul) {
|
|
91
|
+
flushParagraph(paragraph, blocks);
|
|
92
|
+
if (!listItems || ((_a = listItems[0]) == null ? void 0 : _a.ordered)) {
|
|
93
|
+
flushList();
|
|
94
|
+
listItems = [];
|
|
95
|
+
}
|
|
96
|
+
listItems.push({ ordered: false, text: ul[1] });
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const ol = line.match(/^\d+[.)]\s+(.+)$/);
|
|
100
|
+
if (ol) {
|
|
101
|
+
flushParagraph(paragraph, blocks);
|
|
102
|
+
if (!listItems || !((_b = listItems[0]) == null ? void 0 : _b.ordered)) {
|
|
103
|
+
flushList();
|
|
104
|
+
listItems = [];
|
|
105
|
+
}
|
|
106
|
+
listItems.push({ ordered: true, text: ol[1] });
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (!line.trim()) {
|
|
110
|
+
flushParagraph(paragraph, blocks);
|
|
111
|
+
flushList();
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
flushList();
|
|
115
|
+
paragraph.push(line);
|
|
116
|
+
}
|
|
117
|
+
if (fence) blocks.push(html`<pre><code>${fence.join("\n")}</code></pre>`);
|
|
118
|
+
flushParagraph(paragraph, blocks);
|
|
119
|
+
flushList();
|
|
120
|
+
return html`<div class="md">${blocks}</div>`;
|
|
121
|
+
}
|
|
122
|
+
export {
|
|
123
|
+
renderMarkdown
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sources":["../../../../src/components/custom-widget/lib/markdown.ts"],"sourcesContent":["import { html, type TemplateResult } from 'lit';\n\n/** Safe markdown → Lit. No innerHTML; links/images restricted to http(s). */\n\nconst SAFE_HREF = /^https?:\\/\\//i;\n\nfunction isSafeHref(href: string): boolean {\n return SAFE_HREF.test(href.trim());\n}\n\nfunction renderInline(text: string): TemplateResult[] {\n const nodes: TemplateResult[] = [];\n const re =\n /(\\*\\*[^*]+\\*\\*|__[^_]+__|\\*[^*]+\\*|_[^_]+_|`[^`]+`|\\[[^\\]]+\\]\\([^)]+\\))/g;\n let last = 0;\n let match: RegExpExecArray | null;\n while ((match = re.exec(text))) {\n if (match.index > last) {\n nodes.push(html`${text.slice(last, match.index)}`);\n }\n const token = match[0];\n if (token.startsWith('**') || token.startsWith('__')) {\n nodes.push(html`<strong>${token.slice(2, -2)}</strong>`);\n } else if (token.startsWith('*') || token.startsWith('_')) {\n nodes.push(html`<em>${token.slice(1, -1)}</em>`);\n } else if (token.startsWith('`')) {\n nodes.push(html`<code>${token.slice(1, -1)}</code>`);\n } else {\n const link = token.match(/^\\[([^\\]]+)\\]\\(([^)]+)\\)$/);\n if (link && isSafeHref(link[2])) {\n nodes.push(\n html`<a href=${link[2]} target=\"_blank\" rel=\"noopener noreferrer\">${link[1]}</a>`,\n );\n } else {\n nodes.push(html`${token}`);\n }\n }\n last = match.index + token.length;\n }\n if (last < text.length) nodes.push(html`${text.slice(last)}`);\n return nodes.length ? nodes : [html`${text}`];\n}\n\nfunction flushParagraph(lines: string[], out: TemplateResult[]): void {\n const text = lines.join('\\n').trim();\n if (!text) return;\n out.push(html`<p>${renderInline(text)}</p>`);\n lines.length = 0;\n}\n\n/** Client TextWidget markdown view — headings, lists, emphasis, code, http(s) links. */\nexport function renderMarkdown(source: string): TemplateResult {\n const lines = source.replace(/\\r\\n/g, '\\n').split('\\n');\n const blocks: TemplateResult[] = [];\n const paragraph: string[] = [];\n let listItems: { ordered: boolean; text: string }[] | null = null;\n let fence: string[] | null = null;\n\n const flushList = () => {\n if (!listItems?.length) {\n listItems = null;\n return;\n }\n const items = listItems.map((item) => html`<li>${renderInline(item.text)}</li>`);\n blocks.push(\n listItems[0].ordered ? html`<ol>${items}</ol>` : html`<ul>${items}</ul>`,\n );\n listItems = null;\n };\n\n for (const line of lines) {\n if (fence) {\n if (line.startsWith('```')) {\n const code = fence.join('\\n');\n blocks.push(html`<pre><code>${code}</code></pre>`);\n fence = null;\n } else {\n fence.push(line);\n }\n continue;\n }\n if (line.startsWith('```')) {\n flushParagraph(paragraph, blocks);\n flushList();\n fence = [];\n continue;\n }\n\n const heading = line.match(/^(#{1,3})\\s+(.+)$/);\n if (heading) {\n flushParagraph(paragraph, blocks);\n flushList();\n const title = heading[2];\n const level = heading[1].length;\n blocks.push(\n level === 1\n ? html`<h1>${renderInline(title)}</h1>`\n : level === 2\n ? html`<h2>${renderInline(title)}</h2>`\n : html`<h3>${renderInline(title)}</h3>`,\n );\n continue;\n }\n\n const ul = line.match(/^[-*]\\s+(.+)$/);\n if (ul) {\n flushParagraph(paragraph, blocks);\n if (!listItems || listItems[0]?.ordered) {\n flushList();\n listItems = [];\n }\n listItems.push({ ordered: false, text: ul[1] });\n continue;\n }\n\n const ol = line.match(/^\\d+[.)]\\s+(.+)$/);\n if (ol) {\n flushParagraph(paragraph, blocks);\n if (!listItems || !listItems[0]?.ordered) {\n flushList();\n listItems = [];\n }\n listItems.push({ ordered: true, text: ol[1] });\n continue;\n }\n\n if (!line.trim()) {\n flushParagraph(paragraph, blocks);\n flushList();\n continue;\n }\n\n flushList();\n paragraph.push(line);\n }\n\n if (fence) blocks.push(html`<pre><code>${fence.join('\\n')}</code></pre>`);\n flushParagraph(paragraph, blocks);\n flushList();\n\n return html`<div class=\"md\">${blocks}</div>`;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CustomWidgetModel } from './types.js';
|
|
2
|
+
/** Chart panes whose widget `chartType` is a content type render empty, as in the client */
|
|
3
|
+
export declare function isContentChartType(chartType: string | undefined): boolean;
|
|
4
|
+
/** Build the shell model from a FuseDash CustomWidget payload. */
|
|
5
|
+
export declare function normalizeCustomWidget(input: unknown): CustomWidgetModel;
|
|
6
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/custom-widget/lib/normalize.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAIV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAqCpB,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEzE;AAyGD,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAsBvE"}
|