@bpmnkit/plugins 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/storage/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CanvasPlugin } from "@bpmnkit/canvas";
|
|
2
|
-
import type { MainMenuApi } from "../main-menu/index.js";
|
|
2
|
+
import type { MainMenuApi, MenuItem } from "../main-menu/index.js";
|
|
3
3
|
import { StorageApi, type StorageApiOptions } from "./storage-api.js";
|
|
4
4
|
import type { FileType } from "./types.js";
|
|
5
5
|
export type { FileType, WorkspaceRecord, ProjectRecord, FileRecord, FileContentRecord, } from "./types.js";
|
|
@@ -30,6 +30,12 @@ export interface StoragePluginOptions extends StorageApiOptions {
|
|
|
30
30
|
* Update the corresponding tab's display name from this callback.
|
|
31
31
|
*/
|
|
32
32
|
onRenameCurrentFile?: (fileId: string, name: string) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Optional items prepended to the dynamic menu items on every open.
|
|
35
|
+
* Use this to inject context-sensitive items (e.g. mobile edit actions)
|
|
36
|
+
* without being overridden by storage change events.
|
|
37
|
+
*/
|
|
38
|
+
prependItems?: () => MenuItem[];
|
|
33
39
|
}
|
|
34
40
|
/**
|
|
35
41
|
* Creates an IndexedDB-backed storage plugin.
|
package/dist/storage/index.js
CHANGED
|
@@ -107,7 +107,7 @@ export function createStoragePlugin(options) {
|
|
|
107
107
|
}
|
|
108
108
|
function buildDynamicItems() {
|
|
109
109
|
const currentProjectId = storageApi.getCurrentProjectId();
|
|
110
|
-
const items = [];
|
|
110
|
+
const items = [...(options.prependItems?.() ?? [])];
|
|
111
111
|
if (currentProjectId) {
|
|
112
112
|
items.push({
|
|
113
113
|
type: "info",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import type { CanvasPlugin } from "@bpmnkit/canvas";
|
|
14
14
|
import type { CommandPalettePlugin } from "../command-palette/index.js";
|
|
15
|
-
import type { MainMenuApi } from "../main-menu/index.js";
|
|
15
|
+
import type { MainMenuApi, MenuItem } from "../main-menu/index.js";
|
|
16
16
|
import type { StorageApi } from "../storage/index.js";
|
|
17
17
|
import { InMemoryFileResolver } from "../tabs/index.js";
|
|
18
18
|
import type { TabConfig, TabsApi, WelcomeExample, WelcomeSection } from "../tabs/index.js";
|
|
@@ -81,6 +81,11 @@ export interface StorageTabsBridgeOptions {
|
|
|
81
81
|
* Use this to disable editing UI (toolbar buttons, sidebar) while raw mode is active.
|
|
82
82
|
*/
|
|
83
83
|
onRawModeChange?: (active: boolean) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Optional items prepended to the dynamic menu items on every menu open.
|
|
86
|
+
* Composed with storage items so they survive storage change events.
|
|
87
|
+
*/
|
|
88
|
+
prependItems?: () => MenuItem[];
|
|
84
89
|
}
|
|
85
90
|
export interface StorageTabsBridgeResult {
|
|
86
91
|
tabsPlugin: CanvasPlugin & {
|
|
@@ -131,6 +131,7 @@ export function createStorageTabsBridge(options) {
|
|
|
131
131
|
mainMenu: options.mainMenu,
|
|
132
132
|
getOpenTabs: () => tabsPlugin.api.getAllTabContent(),
|
|
133
133
|
initialTitle: options.initialTitle,
|
|
134
|
+
prependItems: options.prependItems,
|
|
134
135
|
onLeaveProject() {
|
|
135
136
|
tabsPlugin.api.closeAllTabs();
|
|
136
137
|
tabIdToStorageFileId.clear();
|
package/dist/tabs/tabs-plugin.js
CHANGED
|
@@ -84,7 +84,7 @@ export function createTabsPlugin(options = {}) {
|
|
|
84
84
|
const bpmnProcessNames = new Map();
|
|
85
85
|
/** Tracks the last-activated tab ID per type group. */
|
|
86
86
|
const groupActiveId = new Map();
|
|
87
|
-
/** Which type group's dropdown is currently open, if any. */
|
|
87
|
+
/** Which type group's dropdown is currently open, if any. "mobile" means the unified mobile dropdown. */
|
|
88
88
|
let openDropdownType = null;
|
|
89
89
|
let outsideClickHandler = null;
|
|
90
90
|
// --- Close-confirmation dialog ---
|
|
@@ -449,6 +449,59 @@ export function createTabsPlugin(options = {}) {
|
|
|
449
449
|
openDropdown(type, group, anchorEl);
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
|
+
function openMobileDropdown(anchorEl) {
|
|
453
|
+
if (!dropdownEl)
|
|
454
|
+
return;
|
|
455
|
+
dropdownEl.innerHTML = "";
|
|
456
|
+
dropdownEl.dataset.theme = theme;
|
|
457
|
+
for (const type of GROUP_TYPES) {
|
|
458
|
+
const group = tabs.filter((t) => t.config.type === type);
|
|
459
|
+
for (const tab of group) {
|
|
460
|
+
const item = document.createElement("div");
|
|
461
|
+
item.className = "bpmnkit-tab-drop-item";
|
|
462
|
+
if (tab.id === activeId)
|
|
463
|
+
item.classList.add("active");
|
|
464
|
+
const badge = document.createElement("span");
|
|
465
|
+
badge.className = `bpmnkit-tab-type ${type}`;
|
|
466
|
+
badge.textContent = type.toUpperCase();
|
|
467
|
+
item.appendChild(badge);
|
|
468
|
+
const nameSpan = document.createElement("span");
|
|
469
|
+
nameSpan.className = "bpmnkit-tab-drop-name";
|
|
470
|
+
nameSpan.textContent = tab.config.name ?? tab.id;
|
|
471
|
+
item.appendChild(nameSpan);
|
|
472
|
+
if (!isProjectMode) {
|
|
473
|
+
const closeBtn = document.createElement("span");
|
|
474
|
+
closeBtn.className = "bpmnkit-tab-close";
|
|
475
|
+
closeBtn.textContent = "×";
|
|
476
|
+
closeBtn.addEventListener("click", (e) => {
|
|
477
|
+
e.stopPropagation();
|
|
478
|
+
closeDropdownEl();
|
|
479
|
+
requestClose(tab);
|
|
480
|
+
});
|
|
481
|
+
item.appendChild(closeBtn);
|
|
482
|
+
}
|
|
483
|
+
item.addEventListener("click", () => {
|
|
484
|
+
groupActiveId.set(type, tab.id);
|
|
485
|
+
api.setActiveTab(tab.id);
|
|
486
|
+
closeDropdownEl();
|
|
487
|
+
});
|
|
488
|
+
dropdownEl.appendChild(item);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const rect = anchorEl.getBoundingClientRect();
|
|
492
|
+
dropdownEl.style.top = `${rect.bottom}px`;
|
|
493
|
+
dropdownEl.style.left = `${rect.left}px`;
|
|
494
|
+
dropdownEl.classList.add("open");
|
|
495
|
+
openDropdownType = "mobile";
|
|
496
|
+
}
|
|
497
|
+
function toggleMobileDropdown(anchorEl) {
|
|
498
|
+
if (openDropdownType === "mobile") {
|
|
499
|
+
closeDropdownEl();
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
openMobileDropdown(anchorEl);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
452
505
|
// --- Tab bar rendering ---
|
|
453
506
|
function requestClose(tab) {
|
|
454
507
|
if (isProjectMode)
|
|
@@ -465,29 +518,63 @@ export function createTabsPlugin(options = {}) {
|
|
|
465
518
|
/**
|
|
466
519
|
* Rebuilds the tab bar from scratch.
|
|
467
520
|
* At most three group tabs are rendered (one per type: BPMN, DMN, Form).
|
|
521
|
+
* On narrow viewports (≤600px) a single unified tab is shown instead.
|
|
468
522
|
*/
|
|
469
523
|
function renderTabBar() {
|
|
470
524
|
if (!tabBar)
|
|
471
525
|
return;
|
|
472
526
|
tabBar.innerHTML = "";
|
|
473
|
-
|
|
474
|
-
const
|
|
475
|
-
if (
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
527
|
+
if (window.innerWidth <= 600 && tabs.length > 0) {
|
|
528
|
+
const activeTab = tabs.find((t) => t.id === activeId);
|
|
529
|
+
if (activeTab) {
|
|
530
|
+
createMobileTabEl(activeTab);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
for (const type of GROUP_TYPES) {
|
|
535
|
+
const group = tabs.filter((t) => t.config.type === type);
|
|
536
|
+
if (group.length === 0)
|
|
537
|
+
continue;
|
|
538
|
+
// Ensure groupActiveId[type] points to a valid tab in this group
|
|
539
|
+
if (!group.some((t) => t.id === groupActiveId.get(type))) {
|
|
540
|
+
const first = group[0];
|
|
541
|
+
if (first)
|
|
542
|
+
groupActiveId.set(type, first.id);
|
|
543
|
+
}
|
|
544
|
+
const isGroupActive = group.some((t) => t.id === activeId);
|
|
545
|
+
createGroupTabEl(type, group, isGroupActive);
|
|
482
546
|
}
|
|
483
|
-
const isGroupActive = group.some((t) => t.id === activeId);
|
|
484
|
-
createGroupTabEl(type, group, isGroupActive);
|
|
485
547
|
}
|
|
486
548
|
// Center slot must be re-appended after innerHTML clear
|
|
487
549
|
if (centerSlotEl)
|
|
488
550
|
tabBar.appendChild(centerSlotEl);
|
|
489
551
|
updateRawModeBtn();
|
|
490
552
|
}
|
|
553
|
+
function createMobileTabEl(activeTab) {
|
|
554
|
+
const el = document.createElement("div");
|
|
555
|
+
el.className = "bpmnkit-tab active";
|
|
556
|
+
const typeBadge = document.createElement("span");
|
|
557
|
+
typeBadge.className = `bpmnkit-tab-type ${activeTab.config.type}`;
|
|
558
|
+
typeBadge.textContent = activeTab.config.type.toUpperCase();
|
|
559
|
+
el.appendChild(typeBadge);
|
|
560
|
+
const nameEl = document.createElement("span");
|
|
561
|
+
nameEl.className = "bpmnkit-tab-name";
|
|
562
|
+
nameEl.textContent = activeTab.config.name ?? activeTab.config.type;
|
|
563
|
+
el.appendChild(nameEl);
|
|
564
|
+
if (tabs.length > 1) {
|
|
565
|
+
const chevron = document.createElement("span");
|
|
566
|
+
chevron.className = "bpmnkit-tab-chevron";
|
|
567
|
+
chevron.innerHTML =
|
|
568
|
+
'<svg viewBox="0 0 10 6" fill="currentColor"><path d="M0 0l5 6 5-6z"/></svg>';
|
|
569
|
+
el.appendChild(chevron);
|
|
570
|
+
}
|
|
571
|
+
el.addEventListener("click", () => {
|
|
572
|
+
if (tabs.length > 1) {
|
|
573
|
+
toggleMobileDropdown(el);
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
tabBar?.appendChild(el);
|
|
577
|
+
}
|
|
491
578
|
function createGroupTabEl(type, group, isGroupActive) {
|
|
492
579
|
const el = document.createElement("div");
|
|
493
580
|
el.className = `bpmnkit-tab${isGroupActive ? " active" : ""}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpmnkit/plugins",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -104,10 +104,10 @@
|
|
|
104
104
|
"dist/**/*.d.ts"
|
|
105
105
|
],
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"@bpmnkit/ascii": "0.0.
|
|
108
|
-
"@bpmnkit/
|
|
109
|
-
"@bpmnkit/
|
|
110
|
-
"@bpmnkit/editor": "0.0.
|
|
107
|
+
"@bpmnkit/ascii": "0.0.13",
|
|
108
|
+
"@bpmnkit/canvas": "0.0.13",
|
|
109
|
+
"@bpmnkit/core": "0.0.13",
|
|
110
|
+
"@bpmnkit/editor": "0.0.13",
|
|
111
111
|
"@bpmnkit/feel": "0.0.12"
|
|
112
112
|
},
|
|
113
113
|
"description": "22 composable canvas plugins for BPMN editors and viewers — minimap, AI chat, process simulation, storage, and more",
|