@grafloria/element 0.4.27 → 0.4.28

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafloria/element",
3
- "version": "0.4.27",
3
+ "version": "0.4.28",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
package/src/index.d.ts CHANGED
@@ -79,7 +79,7 @@ export type { JoinColumn, JoinEnd, MatchTier, JoinGuidanceApi, JoinGuidanceOptio
79
79
  export type { ErColumn, ErEntitySpec, ErRelationshipSpec, ErCardinality, ErSide, ErDiagramOptions, UmlClassSpec, UmlRelationshipSpec, UmlRelationKind, UmlSide, UmlDiagramOptions, ErEntityDelta, UmlClassDelta, CardEditingHandle, } from './lib/diagram-kit/index.js';
80
80
  export { erTable, umlClass, erTables, umlClasses, CardHandle, ErTable, ErField, ErColumnList, UmlClass, UmlMemberList, } from './lib/diagram-kit/index.js';
81
81
  export type { HandleApi } from './lib/diagram-kit/index.js';
82
- export { bindDashboardGrid, normalizeCaption, captionReserve, captionBandHeight, paintCaptionBand, CAPTION_HEIGHT, CAPTION_HEIGHT_SUBTITLE, CAPTION_HEIGHT_TIGHT, CAPTION_PASS_THROUGH, rowHeightFor, boardHeightFor, columnUnitFor, cellToRect, pointToCell, sizeToSpan, gridItemFromCell, cellFromGridItem, buildCommitCommands, ensureDashboardKitStyles, DASHBOARD_KIT_STYLE_ID, dashboard, defaultWidgetRenderer, renderKpiWidget, renderLineWidget, renderBarWidget, renderDonutWidget, renderFunnelWidget, renderTableWidget, BUILT_IN_WIDGET_KINDS, } from './lib/dashboard-kit/index.js';
82
+ export { bindDashboardGrid, paintTabStrip, tabStripReserve, tabStripKey, TAB_STRIP_HEIGHT, normalizeCaption, captionReserve, captionBandHeight, paintCaptionBand, CAPTION_HEIGHT, CAPTION_HEIGHT_SUBTITLE, CAPTION_HEIGHT_TIGHT, CAPTION_PASS_THROUGH, rowHeightFor, boardHeightFor, columnUnitFor, cellToRect, pointToCell, sizeToSpan, gridItemFromCell, cellFromGridItem, buildCommitCommands, ensureDashboardKitStyles, DASHBOARD_KIT_STYLE_ID, dashboard, defaultWidgetRenderer, renderKpiWidget, renderLineWidget, renderBarWidget, renderDonutWidget, renderFunnelWidget, renderTableWidget, BUILT_IN_WIDGET_KINDS, } from './lib/dashboard-kit/index.js';
83
83
  export type { DashboardGridApi, DashboardGridOptions, DashboardGridHandle, CellRect, WorldRect, DashboardGridGeometry, TileDelta, DashboardOptions, DashboardSpec, DashboardSnapshot, DragHandleOption, DragGripOptions, DashboardHandle, DashboardViewSpec, DashboardWidgetSpec, SectionCaption, SectionCaptionOptions, TabsOptions, TabPage, SectionCaptionAction, SectionCaptionFont, WidgetHandle, WidgetRenderer, KpiWidgetData, LineWidgetData, LineSeries, BarWidgetData, DonutWidgetData, FunnelWidgetData, TableWidgetData, } from './lib/dashboard-kit/index.js';
84
84
  export { bindStencilPalette, bindShapeDataPanel, ensureStencilKitStyles } from './lib/stencil-kit/index.js';
85
85
  export type { StencilPaletteApi, StencilPaletteOptions, StencilPaletteHandle, ShapeDataPanelApi, ShapeDataPanelOptions, ShapeDataPanelHandle, } from './lib/stencil-kit/index.js';
package/src/index.js CHANGED
@@ -230,7 +230,7 @@ export { erTable, umlClass, erTables, umlClasses, CardHandle, ErTable, ErField,
230
230
  // GridItemConfig. Element-local code, so the Phase-0 wholesale re-export
231
231
  // below does NOT cover it — this curated block is its only door.
232
232
  // ===========================================================================
233
- export { bindDashboardGrid, normalizeCaption, captionReserve, captionBandHeight, paintCaptionBand, CAPTION_HEIGHT, CAPTION_HEIGHT_SUBTITLE, CAPTION_HEIGHT_TIGHT, CAPTION_PASS_THROUGH, rowHeightFor, boardHeightFor, columnUnitFor, cellToRect, pointToCell, sizeToSpan, gridItemFromCell, cellFromGridItem, buildCommitCommands, ensureDashboardKitStyles, DASHBOARD_KIT_STYLE_ID,
233
+ export { bindDashboardGrid, paintTabStrip, tabStripReserve, tabStripKey, TAB_STRIP_HEIGHT, normalizeCaption, captionReserve, captionBandHeight, paintCaptionBand, CAPTION_HEIGHT, CAPTION_HEIGHT_SUBTITLE, CAPTION_HEIGHT_TIGHT, CAPTION_PASS_THROUGH, rowHeightFor, boardHeightFor, columnUnitFor, cellToRect, pointToCell, sizeToSpan, gridItemFromCell, cellFromGridItem, buildCommitCommands, ensureDashboardKitStyles, DASHBOARD_KIT_STYLE_ID,
234
234
  // The DATA-FIRST authoring API — the erDiagram()/umlDiagram() equivalent.
235
235
  dashboard,
236
236
  // …and the built-in renderers behind `kind`, so a dashboard is useful with
@@ -230,6 +230,29 @@ function buildWidgetNode(w, rowHeight) {
230
230
  node.removePort(p.id);
231
231
  return node;
232
232
  }
233
+ /**
234
+ * EVERY CHILD OF A TAB CONTAINER IS A PAGE. A page is a container, so a plain
235
+ * widget written among them is wrapped in one carrying its title. Without this
236
+ * the tab system simply ignored it: it was never positioned and painted at the
237
+ * board's origin at its 100×60 placeholder size, silently losing part of the
238
+ * author's layout (measured on a container mixing a widget with two pages).
239
+ */
240
+ function wrapTabPages(ws) {
241
+ for (const w of ws) {
242
+ if (!w.widgets)
243
+ continue;
244
+ if (w.layout === 'tabs') {
245
+ w.widgets = w.widgets.map((c) => {
246
+ var _a;
247
+ return c.widgets
248
+ ? c
249
+ : Object.assign(Object.assign({ id: `${c.id}__page`, title: (_a = c.title) !== null && _a !== void 0 ? _a : c.id }, (w.columns !== undefined ? { columns: w.columns } : {})), { widgets: [Object.assign(Object.assign({}, c), { x: 0, y: 0 })] });
250
+ });
251
+ }
252
+ wrapTabPages(w.widgets);
253
+ }
254
+ return ws;
255
+ }
233
256
  function cloneWidgets(ws) {
234
257
  return ws.map((w) => (Object.assign(Object.assign({}, w), (w.widgets ? { widgets: cloneWidgets(w.widgets) } : {}))));
235
258
  }
@@ -1133,8 +1156,8 @@ export function dashboard(options) {
1133
1156
  const sizing = (_h = options.sizing) !== null && _h !== void 0 ? _h : (mode === 'fluid' ? 'grow' : 'fit');
1134
1157
  const layout = (_j = options.layout) !== null && _j !== void 0 ? _j : 'grid';
1135
1158
  const views = options.views
1136
- ? options.views.map((v) => (Object.assign(Object.assign({}, v), { widgets: cloneWidgets(v.widgets) })))
1137
- : [{ id: 'main', widgets: cloneWidgets((_k = options.widgets) !== null && _k !== void 0 ? _k : []) }];
1159
+ ? options.views.map((v) => (Object.assign(Object.assign({}, v), { widgets: wrapTabPages(cloneWidgets(v.widgets)) })))
1160
+ : [{ id: 'main', widgets: wrapTabPages(cloneWidgets((_k = options.widgets) !== null && _k !== void 0 ? _k : [])) }];
1138
1161
  for (const v of views)
1139
1162
  assignCellsDeep(v.widgets, (_l = v.columns) !== null && _l !== void 0 ? _l : columns);
1140
1163
  // -- the render spec: one custom-HTML node per widget ----------------------
@@ -2116,6 +2116,28 @@ export function bindDashboardGrid(api, group, options = {}) {
2116
2116
  return best;
2117
2117
  };
2118
2118
  /** This binder's side of an adoption: enter gateless, then live-push. */
2119
+ /**
2120
+ * Put an ARRIVING tile as close to the pointer as the board allows. The
2121
+ * exact cell is often refused because a SECTION is a locked tile and the
2122
+ * incoming tile overlaps it (E4b), and a refused placement left the tile
2123
+ * wherever it entered — the bottom row. That read as "it did not drop where
2124
+ * I put it". Slide along the row instead, nearest first, so a tile that
2125
+ * cannot take the cell under the pointer still lands beside it.
2126
+ */
2127
+ const placeNear = (id, x, y, w) => {
2128
+ if (engine.moveCheck(id, x, y, { gate: false }).changed)
2129
+ return true;
2130
+ const maxX = Math.max(0, columns - w);
2131
+ for (let d = 1; d <= columns; d++) {
2132
+ for (const cx of [x - d, x + d]) {
2133
+ if (cx < 0 || cx > maxX)
2134
+ continue;
2135
+ if (engine.moveCheck(id, cx, y, { gate: false }).changed)
2136
+ return true;
2137
+ }
2138
+ }
2139
+ return false;
2140
+ };
2119
2141
  const adopt = (node, world, pxSize) => {
2120
2142
  if (disposed)
2121
2143
  return null;
@@ -2153,7 +2175,7 @@ export function bindDashboardGrid(api, group, options = {}) {
2153
2175
  adoptedGhostId = node.id;
2154
2176
  const tl = centredTopLeft(world.x, world.y, span);
2155
2177
  const cell0 = pointToCell(tl.x, tl.y, f, gg, rows(), span.w);
2156
- engine.moveCheck(node.id, cell0.x, cell0.y, { gate: false });
2178
+ placeNear(node.id, cell0.x, cell0.y, span.w);
2157
2179
  armGlide();
2158
2180
  project();
2159
2181
  syncPlaceholder();
@@ -2165,7 +2187,7 @@ export function bindDashboardGrid(api, group, options = {}) {
2165
2187
  return;
2166
2188
  const tlm = centredTopLeft(w.x, w.y, { w: item.w, h: item.h });
2167
2189
  const cell = pointToCell(tlm.x, tlm.y, frame(), geom(), rows(), item.w);
2168
- if (engine.moveCheck(node.id, cell.x, cell.y).changed)
2190
+ if (placeNear(node.id, cell.x, cell.y, item.w))
2169
2191
  project();
2170
2192
  syncPlaceholder();
2171
2193
  },