@blorkfield/blork-tabs 0.2.6 → 0.3.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 +162 -0
- package/dist/index.cjs +314 -5
- package/dist/index.d.cts +179 -2
- package/dist/index.d.ts +179 -2
- package/dist/index.js +309 -5
- package/dist/styles.css +175 -0
- package/package.json +1 -1
- package/src/AutoHideManager.ts +139 -0
- package/src/DebugPanel.ts +98 -0
- package/src/Panel.ts +33 -1
- package/src/TabManager.ts +166 -1
- package/src/index.ts +12 -0
- package/src/types.ts +76 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,61 @@
|
|
|
1
|
+
// src/DebugPanel.ts
|
|
2
|
+
function createDebugPanelContent(_config, classes) {
|
|
3
|
+
const content = document.createElement("div");
|
|
4
|
+
const logContainer = document.createElement("div");
|
|
5
|
+
logContainer.className = classes.debugLog;
|
|
6
|
+
content.appendChild(logContainer);
|
|
7
|
+
return {
|
|
8
|
+
content,
|
|
9
|
+
elements: { logContainer, clearButton: null }
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function createDebugPanelInterface(panel, elements, config, classes) {
|
|
13
|
+
const maxEntries = config.maxEntries ?? 50;
|
|
14
|
+
const showTimestamps = config.showTimestamps ?? false;
|
|
15
|
+
function addEntry(level, eventName, data) {
|
|
16
|
+
const entry = document.createElement("div");
|
|
17
|
+
entry.className = classes.debugLogEntry;
|
|
18
|
+
if (level === "warn") entry.classList.add(classes.debugLogEntryWarn);
|
|
19
|
+
if (level === "error") entry.classList.add(classes.debugLogEntryError);
|
|
20
|
+
let html = "";
|
|
21
|
+
if (showTimestamps) {
|
|
22
|
+
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
|
|
23
|
+
hour12: false,
|
|
24
|
+
hour: "2-digit",
|
|
25
|
+
minute: "2-digit",
|
|
26
|
+
second: "2-digit"
|
|
27
|
+
});
|
|
28
|
+
html += `<span class="${classes.debugLogTimestamp}">${time}</span>`;
|
|
29
|
+
}
|
|
30
|
+
html += `<span class="${classes.debugLogName}">${escapeHtml(eventName)}</span>`;
|
|
31
|
+
if (data) {
|
|
32
|
+
const dataStr = JSON.stringify(data);
|
|
33
|
+
html += `<span class="${classes.debugLogData}">${escapeHtml(dataStr)}</span>`;
|
|
34
|
+
}
|
|
35
|
+
entry.innerHTML = html;
|
|
36
|
+
elements.logContainer.appendChild(entry);
|
|
37
|
+
elements.logContainer.scrollTop = elements.logContainer.scrollHeight;
|
|
38
|
+
while (elements.logContainer.children.length > maxEntries) {
|
|
39
|
+
elements.logContainer.removeChild(elements.logContainer.children[0]);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
panel,
|
|
44
|
+
log: (name, data) => addEntry("log", name, data),
|
|
45
|
+
info: (name, data) => addEntry("info", name, data),
|
|
46
|
+
warn: (name, data) => addEntry("warn", name, data),
|
|
47
|
+
error: (name, data) => addEntry("error", name, data),
|
|
48
|
+
clear: () => {
|
|
49
|
+
elements.logContainer.innerHTML = "";
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function escapeHtml(str) {
|
|
54
|
+
const div = document.createElement("div");
|
|
55
|
+
div.textContent = str;
|
|
56
|
+
return div.innerHTML;
|
|
57
|
+
}
|
|
58
|
+
|
|
1
59
|
// src/Panel.ts
|
|
2
60
|
function createPanelElement(config, classes) {
|
|
3
61
|
const element = document.createElement("div");
|
|
@@ -52,7 +110,7 @@ function createPanelElement(config, classes) {
|
|
|
52
110
|
detachGrip
|
|
53
111
|
};
|
|
54
112
|
}
|
|
55
|
-
function createPanelState(config, classes) {
|
|
113
|
+
function createPanelState(config, classes, globalConfig) {
|
|
56
114
|
let element;
|
|
57
115
|
let dragHandle;
|
|
58
116
|
let collapseButton;
|
|
@@ -72,6 +130,11 @@ function createPanelState(config, classes) {
|
|
|
72
130
|
contentWrapper = created.contentWrapper;
|
|
73
131
|
detachGrip = created.detachGrip;
|
|
74
132
|
}
|
|
133
|
+
const resolvedStartHidden = config.startHidden ?? globalConfig?.startHidden ?? false;
|
|
134
|
+
const resolvedAutoHideDelay = config.autoHideDelay !== void 0 ? config.autoHideDelay === 0 ? void 0 : config.autoHideDelay : globalConfig?.autoHideDelay;
|
|
135
|
+
if (resolvedStartHidden) {
|
|
136
|
+
element.classList.add(classes.panelHidden);
|
|
137
|
+
}
|
|
75
138
|
return {
|
|
76
139
|
id: config.id,
|
|
77
140
|
element,
|
|
@@ -82,7 +145,9 @@ function createPanelState(config, classes) {
|
|
|
82
145
|
isCollapsed: config.startCollapsed !== false,
|
|
83
146
|
snappedTo: null,
|
|
84
147
|
snappedFrom: null,
|
|
85
|
-
config
|
|
148
|
+
config,
|
|
149
|
+
isHidden: resolvedStartHidden,
|
|
150
|
+
resolvedAutoHideDelay
|
|
86
151
|
};
|
|
87
152
|
}
|
|
88
153
|
function toggleCollapse(state, classes, collapsed) {
|
|
@@ -98,6 +163,16 @@ function toggleCollapse(state, classes, collapsed) {
|
|
|
98
163
|
}
|
|
99
164
|
return newState;
|
|
100
165
|
}
|
|
166
|
+
function showPanel(state, classes) {
|
|
167
|
+
if (!state.isHidden) return;
|
|
168
|
+
state.isHidden = false;
|
|
169
|
+
state.element.classList.remove(classes.panelHidden);
|
|
170
|
+
}
|
|
171
|
+
function hidePanel(state, classes) {
|
|
172
|
+
if (state.isHidden) return;
|
|
173
|
+
state.isHidden = true;
|
|
174
|
+
state.element.classList.add(classes.panelHidden);
|
|
175
|
+
}
|
|
101
176
|
function setPanelPosition(state, x, y) {
|
|
102
177
|
state.element.style.left = `${x}px`;
|
|
103
178
|
state.element.style.top = `${y}px`;
|
|
@@ -767,6 +842,109 @@ var SnapPreview = class {
|
|
|
767
842
|
}
|
|
768
843
|
};
|
|
769
844
|
|
|
845
|
+
// src/AutoHideManager.ts
|
|
846
|
+
var AutoHideManager = class {
|
|
847
|
+
constructor(panels, classes, callbacks) {
|
|
848
|
+
this.hideTimers = /* @__PURE__ */ new Map();
|
|
849
|
+
this.listenersAttached = false;
|
|
850
|
+
this.panels = panels;
|
|
851
|
+
this.classes = classes;
|
|
852
|
+
this.callbacks = callbacks;
|
|
853
|
+
this.boundActivityHandler = this.handleActivity.bind(this);
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Attach activity listeners to document
|
|
857
|
+
*/
|
|
858
|
+
attachListeners() {
|
|
859
|
+
if (this.listenersAttached) return;
|
|
860
|
+
document.addEventListener("mousemove", this.boundActivityHandler);
|
|
861
|
+
document.addEventListener("mousedown", this.boundActivityHandler);
|
|
862
|
+
document.addEventListener("keydown", this.boundActivityHandler);
|
|
863
|
+
this.listenersAttached = true;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Handle user activity - show hidden panels and reset timers
|
|
867
|
+
*/
|
|
868
|
+
handleActivity() {
|
|
869
|
+
for (const panel of this.panels.values()) {
|
|
870
|
+
if (panel.resolvedAutoHideDelay !== void 0 || panel.isHidden) {
|
|
871
|
+
this.show(panel, "activity");
|
|
872
|
+
if (panel.resolvedAutoHideDelay !== void 0) {
|
|
873
|
+
this.scheduleHide(panel);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Schedule a panel to hide after its delay
|
|
880
|
+
*/
|
|
881
|
+
scheduleHide(panel) {
|
|
882
|
+
this.clearTimer(panel.id);
|
|
883
|
+
if (panel.resolvedAutoHideDelay === void 0) return;
|
|
884
|
+
const timer = setTimeout(() => {
|
|
885
|
+
this.hide(panel, "timeout");
|
|
886
|
+
}, panel.resolvedAutoHideDelay);
|
|
887
|
+
this.hideTimers.set(panel.id, timer);
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Clear hide timer for a panel
|
|
891
|
+
*/
|
|
892
|
+
clearTimer(panelId) {
|
|
893
|
+
const timer = this.hideTimers.get(panelId);
|
|
894
|
+
if (timer) {
|
|
895
|
+
clearTimeout(timer);
|
|
896
|
+
this.hideTimers.delete(panelId);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Show a panel
|
|
901
|
+
*/
|
|
902
|
+
show(panel, trigger) {
|
|
903
|
+
if (!panel.isHidden) return;
|
|
904
|
+
showPanel(panel, this.classes);
|
|
905
|
+
this.callbacks.onShow?.(panel, trigger);
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Hide a panel
|
|
909
|
+
*/
|
|
910
|
+
hide(panel, trigger) {
|
|
911
|
+
if (panel.isHidden) return;
|
|
912
|
+
hidePanel(panel, this.classes);
|
|
913
|
+
this.callbacks.onHide?.(panel, trigger);
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Initialize a newly added panel's auto-hide state
|
|
917
|
+
*/
|
|
918
|
+
initializePanel(panel) {
|
|
919
|
+
if (panel.resolvedAutoHideDelay !== void 0 || panel.isHidden) {
|
|
920
|
+
this.attachListeners();
|
|
921
|
+
}
|
|
922
|
+
if (!panel.isHidden && panel.resolvedAutoHideDelay !== void 0) {
|
|
923
|
+
this.scheduleHide(panel);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Clean up when a panel is removed
|
|
928
|
+
*/
|
|
929
|
+
cleanupPanel(panelId) {
|
|
930
|
+
this.clearTimer(panelId);
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Clean up all resources
|
|
934
|
+
*/
|
|
935
|
+
destroy() {
|
|
936
|
+
if (this.listenersAttached) {
|
|
937
|
+
document.removeEventListener("mousemove", this.boundActivityHandler);
|
|
938
|
+
document.removeEventListener("mousedown", this.boundActivityHandler);
|
|
939
|
+
document.removeEventListener("keydown", this.boundActivityHandler);
|
|
940
|
+
}
|
|
941
|
+
for (const timer of this.hideTimers.values()) {
|
|
942
|
+
clearTimeout(timer);
|
|
943
|
+
}
|
|
944
|
+
this.hideTimers.clear();
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
|
|
770
948
|
// src/TabManager.ts
|
|
771
949
|
var DEFAULT_CONFIG = {
|
|
772
950
|
snapThreshold: 50,
|
|
@@ -776,7 +954,9 @@ var DEFAULT_CONFIG = {
|
|
|
776
954
|
defaultPanelWidth: 300,
|
|
777
955
|
container: document.body,
|
|
778
956
|
initializeDefaultAnchors: true,
|
|
779
|
-
classPrefix: "blork-tabs"
|
|
957
|
+
classPrefix: "blork-tabs",
|
|
958
|
+
startHidden: false,
|
|
959
|
+
autoHideDelay: void 0
|
|
780
960
|
};
|
|
781
961
|
function generateClasses(prefix) {
|
|
782
962
|
return {
|
|
@@ -792,13 +972,27 @@ function generateClasses(prefix) {
|
|
|
792
972
|
anchorIndicator: `${prefix}-anchor-indicator`,
|
|
793
973
|
anchorIndicatorVisible: `${prefix}-anchor-indicator-visible`,
|
|
794
974
|
anchorIndicatorActive: `${prefix}-anchor-indicator-active`,
|
|
795
|
-
dragging: `${prefix}-dragging
|
|
975
|
+
dragging: `${prefix}-dragging`,
|
|
976
|
+
panelHidden: `${prefix}-panel-hidden`,
|
|
977
|
+
debugLog: `${prefix}-debug-log`,
|
|
978
|
+
debugLogEntry: `${prefix}-debug-log-entry`,
|
|
979
|
+
debugLogEntryInfo: `${prefix}-debug-log-entry-info`,
|
|
980
|
+
debugLogEntryWarn: `${prefix}-debug-log-entry-warn`,
|
|
981
|
+
debugLogEntryError: `${prefix}-debug-log-entry-error`,
|
|
982
|
+
debugLogName: `${prefix}-debug-log-name`,
|
|
983
|
+
debugLogData: `${prefix}-debug-log-data`,
|
|
984
|
+
debugLogTimestamp: `${prefix}-debug-log-timestamp`,
|
|
985
|
+
debugClearButton: `${prefix}-debug-clear-btn`,
|
|
986
|
+
debugPanel: `${prefix}-debug-panel`,
|
|
987
|
+
debugPanelEnlarged: `${prefix}-debug-panel-enlarged`,
|
|
988
|
+
debugBackdrop: `${prefix}-debug-backdrop`
|
|
796
989
|
};
|
|
797
990
|
}
|
|
798
991
|
var TabManager = class {
|
|
799
992
|
constructor(userConfig = {}) {
|
|
800
993
|
this.panels = /* @__PURE__ */ new Map();
|
|
801
994
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
995
|
+
this.debugPanelElements = /* @__PURE__ */ new Map();
|
|
802
996
|
this.config = {
|
|
803
997
|
...DEFAULT_CONFIG,
|
|
804
998
|
...userConfig,
|
|
@@ -821,6 +1015,14 @@ var TabManager = class {
|
|
|
821
1015
|
findAnchorTarget: (panels) => this.anchorManager.findNearestAnchor(panels)
|
|
822
1016
|
}
|
|
823
1017
|
);
|
|
1018
|
+
this.autoHideManager = new AutoHideManager(
|
|
1019
|
+
this.panels,
|
|
1020
|
+
this.classes,
|
|
1021
|
+
{
|
|
1022
|
+
onShow: (panel, trigger) => this.emit("panel:show", { panel, trigger }),
|
|
1023
|
+
onHide: (panel, trigger) => this.emit("panel:hide", { panel, trigger })
|
|
1024
|
+
}
|
|
1025
|
+
);
|
|
824
1026
|
if (this.config.initializeDefaultAnchors) {
|
|
825
1027
|
this.anchorManager.addDefaultAnchors();
|
|
826
1028
|
}
|
|
@@ -830,7 +1032,10 @@ var TabManager = class {
|
|
|
830
1032
|
* Add a new panel
|
|
831
1033
|
*/
|
|
832
1034
|
addPanel(panelConfig) {
|
|
833
|
-
const state = createPanelState(panelConfig, this.classes
|
|
1035
|
+
const state = createPanelState(panelConfig, this.classes, {
|
|
1036
|
+
startHidden: this.config.startHidden,
|
|
1037
|
+
autoHideDelay: this.config.autoHideDelay
|
|
1038
|
+
});
|
|
834
1039
|
if (!panelConfig.element && !this.config.container.contains(state.element)) {
|
|
835
1040
|
this.config.container.appendChild(state.element);
|
|
836
1041
|
}
|
|
@@ -839,6 +1044,7 @@ var TabManager = class {
|
|
|
839
1044
|
if (panelConfig.initialPosition) {
|
|
840
1045
|
setPanelPosition(state, panelConfig.initialPosition.x, panelConfig.initialPosition.y);
|
|
841
1046
|
}
|
|
1047
|
+
this.autoHideManager.initializePanel(state);
|
|
842
1048
|
this.emit("panel:added", { panel: state });
|
|
843
1049
|
return state;
|
|
844
1050
|
}
|
|
@@ -862,6 +1068,8 @@ var TabManager = class {
|
|
|
862
1068
|
removePanel(id) {
|
|
863
1069
|
const panel = this.panels.get(id);
|
|
864
1070
|
if (!panel) return false;
|
|
1071
|
+
this.autoHideManager.cleanupPanel(id);
|
|
1072
|
+
this.debugPanelElements.delete(id);
|
|
865
1073
|
detachFromGroup(panel, this.panels);
|
|
866
1074
|
if (!panel.config.element) {
|
|
867
1075
|
panel.element.remove();
|
|
@@ -882,6 +1090,70 @@ var TabManager = class {
|
|
|
882
1090
|
getAllPanels() {
|
|
883
1091
|
return Array.from(this.panels.values());
|
|
884
1092
|
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Add a debug panel with built-in logging functionality
|
|
1095
|
+
*/
|
|
1096
|
+
addDebugPanel(config) {
|
|
1097
|
+
const { content, elements } = createDebugPanelContent(config, this.classes);
|
|
1098
|
+
const panelConfig = {
|
|
1099
|
+
...config,
|
|
1100
|
+
title: config.title ?? "Debug",
|
|
1101
|
+
content,
|
|
1102
|
+
startCollapsed: config.startCollapsed ?? true
|
|
1103
|
+
};
|
|
1104
|
+
const state = this.addPanel(panelConfig);
|
|
1105
|
+
state.element.classList.add(this.classes.debugPanel);
|
|
1106
|
+
const closeBtn = document.createElement("button");
|
|
1107
|
+
closeBtn.className = this.classes.debugClearButton;
|
|
1108
|
+
closeBtn.textContent = "\xD7";
|
|
1109
|
+
closeBtn.title = "Close enlarged view";
|
|
1110
|
+
if (state.collapseButton) {
|
|
1111
|
+
state.collapseButton.parentElement?.insertBefore(closeBtn, state.collapseButton);
|
|
1112
|
+
}
|
|
1113
|
+
elements.clearButton = closeBtn;
|
|
1114
|
+
this.debugPanelElements.set(state.id, elements);
|
|
1115
|
+
const debugPanel = createDebugPanelInterface(state, elements, config, this.classes);
|
|
1116
|
+
let hoverTimeout = null;
|
|
1117
|
+
let isEnlarged = false;
|
|
1118
|
+
let backdrop = null;
|
|
1119
|
+
const enlargedClass = this.classes.debugPanelEnlarged;
|
|
1120
|
+
const backdropClass = this.classes.debugBackdrop;
|
|
1121
|
+
const closeEnlarged = () => {
|
|
1122
|
+
if (!isEnlarged) return;
|
|
1123
|
+
isEnlarged = false;
|
|
1124
|
+
state.element.classList.remove(enlargedClass);
|
|
1125
|
+
if (backdrop) {
|
|
1126
|
+
backdrop.remove();
|
|
1127
|
+
backdrop = null;
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
const openEnlarged = () => {
|
|
1131
|
+
if (isEnlarged) return;
|
|
1132
|
+
isEnlarged = true;
|
|
1133
|
+
backdrop = document.createElement("div");
|
|
1134
|
+
backdrop.className = backdropClass;
|
|
1135
|
+
this.config.container.appendChild(backdrop);
|
|
1136
|
+
backdrop.addEventListener("click", closeEnlarged);
|
|
1137
|
+
state.element.classList.add(enlargedClass);
|
|
1138
|
+
};
|
|
1139
|
+
state.element.addEventListener("mouseenter", () => {
|
|
1140
|
+
if (isEnlarged) return;
|
|
1141
|
+
hoverTimeout = setTimeout(() => {
|
|
1142
|
+
openEnlarged();
|
|
1143
|
+
}, 5e3);
|
|
1144
|
+
});
|
|
1145
|
+
state.element.addEventListener("mouseleave", () => {
|
|
1146
|
+
if (hoverTimeout) {
|
|
1147
|
+
clearTimeout(hoverTimeout);
|
|
1148
|
+
hoverTimeout = null;
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
closeBtn.addEventListener("click", (e) => {
|
|
1152
|
+
e.stopPropagation();
|
|
1153
|
+
closeEnlarged();
|
|
1154
|
+
});
|
|
1155
|
+
return debugPanel;
|
|
1156
|
+
}
|
|
885
1157
|
/**
|
|
886
1158
|
* Set up event handlers for a panel
|
|
887
1159
|
*/
|
|
@@ -967,6 +1239,31 @@ var TabManager = class {
|
|
|
967
1239
|
getAnchors() {
|
|
968
1240
|
return this.anchorManager.getAnchors();
|
|
969
1241
|
}
|
|
1242
|
+
// ==================== Auto-Hide ====================
|
|
1243
|
+
/**
|
|
1244
|
+
* Show a hidden panel
|
|
1245
|
+
*/
|
|
1246
|
+
show(panelId) {
|
|
1247
|
+
const panel = this.panels.get(panelId);
|
|
1248
|
+
if (!panel) return false;
|
|
1249
|
+
this.autoHideManager.show(panel, "api");
|
|
1250
|
+
return true;
|
|
1251
|
+
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Hide a panel
|
|
1254
|
+
*/
|
|
1255
|
+
hide(panelId) {
|
|
1256
|
+
const panel = this.panels.get(panelId);
|
|
1257
|
+
if (!panel) return false;
|
|
1258
|
+
this.autoHideManager.hide(panel, "api");
|
|
1259
|
+
return true;
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Check if a panel is hidden
|
|
1263
|
+
*/
|
|
1264
|
+
isHidden(panelId) {
|
|
1265
|
+
return this.panels.get(panelId)?.isHidden ?? false;
|
|
1266
|
+
}
|
|
970
1267
|
// ==================== Drag Callbacks ====================
|
|
971
1268
|
handleDragStart(state) {
|
|
972
1269
|
this.anchorManager.showIndicators(null);
|
|
@@ -1105,6 +1402,7 @@ var TabManager = class {
|
|
|
1105
1402
|
this.dragManager.destroy();
|
|
1106
1403
|
this.anchorManager.destroy();
|
|
1107
1404
|
this.snapPreview.destroy();
|
|
1405
|
+
this.autoHideManager.destroy();
|
|
1108
1406
|
for (const panel of this.panels.values()) {
|
|
1109
1407
|
if (!panel.config.element) {
|
|
1110
1408
|
panel.element.remove();
|
|
@@ -1112,14 +1410,18 @@ var TabManager = class {
|
|
|
1112
1410
|
}
|
|
1113
1411
|
this.panels.clear();
|
|
1114
1412
|
this.eventListeners.clear();
|
|
1413
|
+
this.debugPanelElements.clear();
|
|
1115
1414
|
}
|
|
1116
1415
|
};
|
|
1117
1416
|
export {
|
|
1118
1417
|
AnchorManager,
|
|
1418
|
+
AutoHideManager,
|
|
1119
1419
|
DragManager,
|
|
1120
1420
|
SnapPreview,
|
|
1121
1421
|
TabManager,
|
|
1122
1422
|
areInSameChain,
|
|
1423
|
+
createDebugPanelContent,
|
|
1424
|
+
createDebugPanelInterface,
|
|
1123
1425
|
createPanelElement,
|
|
1124
1426
|
createPanelState,
|
|
1125
1427
|
createPresetAnchor,
|
|
@@ -1133,8 +1435,10 @@ export {
|
|
|
1133
1435
|
getPanelDimensions,
|
|
1134
1436
|
getPanelPosition,
|
|
1135
1437
|
getRightmostPanel,
|
|
1438
|
+
hidePanel,
|
|
1136
1439
|
setPanelPosition,
|
|
1137
1440
|
setPanelZIndex,
|
|
1441
|
+
showPanel,
|
|
1138
1442
|
snapPanels,
|
|
1139
1443
|
snapPanelsToTarget,
|
|
1140
1444
|
toggleCollapse,
|
package/dist/styles.css
CHANGED
|
@@ -119,6 +119,16 @@
|
|
|
119
119
|
display: none;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
/* Auto-hide state */
|
|
123
|
+
.blork-tabs-panel-hidden {
|
|
124
|
+
opacity: 0;
|
|
125
|
+
pointer-events: none;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.blork-tabs-panel {
|
|
129
|
+
transition: opacity 0.3s ease;
|
|
130
|
+
}
|
|
131
|
+
|
|
122
132
|
/* Snap Preview */
|
|
123
133
|
.blork-tabs-snap-preview {
|
|
124
134
|
position: fixed;
|
|
@@ -189,3 +199,168 @@
|
|
|
189
199
|
.blork-tabs-dragging .blork-tabs-panel {
|
|
190
200
|
transition: none !important;
|
|
191
201
|
}
|
|
202
|
+
|
|
203
|
+
/* Debug Panel Log */
|
|
204
|
+
.blork-tabs-debug-log {
|
|
205
|
+
min-height: 100px;
|
|
206
|
+
max-height: 200px;
|
|
207
|
+
background: rgba(0, 0, 0, 0.4);
|
|
208
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
209
|
+
border-radius: 4px;
|
|
210
|
+
padding: 8px;
|
|
211
|
+
font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
|
|
212
|
+
font-size: 11px;
|
|
213
|
+
overflow-y: auto;
|
|
214
|
+
overflow-x: hidden;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.blork-tabs-debug-log-entry {
|
|
218
|
+
padding: 3px 0;
|
|
219
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
220
|
+
color: #a0a0a0;
|
|
221
|
+
word-break: break-all;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.blork-tabs-debug-log-entry:last-child {
|
|
225
|
+
border-bottom: none;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.blork-tabs-debug-log-name {
|
|
229
|
+
color: var(--blork-tabs-accent, #4a90d9);
|
|
230
|
+
margin-right: 6px;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* Log level colors */
|
|
234
|
+
.blork-tabs-debug-log-entry-warn .blork-tabs-debug-log-name {
|
|
235
|
+
color: #feca57;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.blork-tabs-debug-log-entry-error .blork-tabs-debug-log-name {
|
|
239
|
+
color: #ff6b6b;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.blork-tabs-debug-log-data {
|
|
243
|
+
color: #888;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.blork-tabs-debug-log-timestamp {
|
|
247
|
+
color: #666;
|
|
248
|
+
margin-right: 6px;
|
|
249
|
+
font-size: 10px;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.blork-tabs-debug-clear-btn {
|
|
253
|
+
width: 20px;
|
|
254
|
+
height: 20px;
|
|
255
|
+
border: none;
|
|
256
|
+
background: transparent;
|
|
257
|
+
color: var(--blork-tabs-header-color, #e0e0e0);
|
|
258
|
+
font-size: 12px;
|
|
259
|
+
cursor: pointer;
|
|
260
|
+
border-radius: 4px;
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: center;
|
|
263
|
+
justify-content: center;
|
|
264
|
+
margin-right: 4px;
|
|
265
|
+
opacity: 0.6;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.blork-tabs-debug-clear-btn:hover {
|
|
269
|
+
background: rgba(255, 255, 255, 0.1);
|
|
270
|
+
opacity: 1;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* Hide close button when NOT enlarged (only show when zoomed) */
|
|
274
|
+
.blork-tabs-debug-panel .blork-tabs-debug-clear-btn {
|
|
275
|
+
display: none;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-debug-clear-btn {
|
|
279
|
+
display: flex;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* Debug panel hover effects */
|
|
283
|
+
.blork-tabs-debug-panel {
|
|
284
|
+
transition: border-color 0.3s ease, opacity 0.3s ease;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.blork-tabs-debug-panel:hover {
|
|
288
|
+
border-color: var(--blork-tabs-accent, #4a90d9);
|
|
289
|
+
box-shadow: 0 0 12px rgba(74, 144, 217, 0.3);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* Enlarged state after hover timeout - 75% of screen, modal-level z-index */
|
|
293
|
+
.blork-tabs-debug-panel-enlarged {
|
|
294
|
+
position: fixed !important;
|
|
295
|
+
width: 75vw !important;
|
|
296
|
+
left: 12.5vw !important;
|
|
297
|
+
top: 12.5vh !important;
|
|
298
|
+
z-index: 100000 !important;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* Make content area fill the enlarged panel */
|
|
302
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-content {
|
|
303
|
+
max-height: 70vh !important;
|
|
304
|
+
padding: 16px;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-debug-log {
|
|
308
|
+
max-height: 65vh !important;
|
|
309
|
+
min-height: 65vh !important;
|
|
310
|
+
font-size: 22px !important;
|
|
311
|
+
line-height: 1.6;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-debug-log-entry {
|
|
315
|
+
padding: 10px 0;
|
|
316
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-debug-log-name {
|
|
320
|
+
font-size: 22px;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-debug-log-data {
|
|
324
|
+
font-size: 20px;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-debug-log-timestamp {
|
|
328
|
+
font-size: 20px !important;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-header {
|
|
332
|
+
padding: 14px 18px;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.blork-tabs-debug-panel-enlarged .blork-tabs-title {
|
|
336
|
+
font-size: 20px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* Backdrop when enlarged */
|
|
340
|
+
.blork-tabs-debug-backdrop {
|
|
341
|
+
position: fixed;
|
|
342
|
+
top: 0;
|
|
343
|
+
left: 0;
|
|
344
|
+
right: 0;
|
|
345
|
+
bottom: 0;
|
|
346
|
+
background: rgba(0, 0, 0, 0.5);
|
|
347
|
+
z-index: 9999;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/* Debug log scrollbar styling */
|
|
351
|
+
.blork-tabs-debug-log::-webkit-scrollbar {
|
|
352
|
+
width: 6px;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.blork-tabs-debug-log::-webkit-scrollbar-track {
|
|
356
|
+
background: transparent;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.blork-tabs-debug-log::-webkit-scrollbar-thumb {
|
|
360
|
+
background: rgba(255, 255, 255, 0.2);
|
|
361
|
+
border-radius: 3px;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.blork-tabs-debug-log::-webkit-scrollbar-thumb:hover {
|
|
365
|
+
background: rgba(255, 255, 255, 0.3);
|
|
366
|
+
}
|