@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/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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blorkfield/blork-tabs",
3
- "version": "0.2.6",
3
+ "version": "0.3.0",
4
4
  "description": "A framework-agnostic tab/panel management system with snapping and docking",
5
5
  "packageManager": "pnpm@10.28.2",
6
6
  "type": "module",