@bitcobblers/wod-wiki-ui 0.44.2156 → 0.44.2159

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.
@@ -1021,15 +1021,22 @@ var embedPreviewDecorations = [
1021
1021
  var POPOVER_MIN_WIDTH = 192;
1022
1022
  var POPOVER_MAX_WIDTH = 320;
1023
1023
  var POPOVER_MAX_HEIGHT = 256;
1024
- function computeInlinePanelBox(field, host, viewportHeight) {
1025
- const offsetLeft = Math.max(0, Math.min(field.left - host.left, Math.max(0, host.width - POPOVER_MIN_WIDTH)));
1026
- const room = Math.max(host.width - offsetLeft, POPOVER_MIN_WIDTH);
1027
- const width = Math.min(Math.max(field.width, POPOVER_MIN_WIDTH), POPOVER_MAX_WIDTH, room);
1028
- const belowField = Math.max(0, viewportHeight - field.top - 64);
1024
+ var POPOVER_GAP = 8;
1025
+ function computeFloatingPlacement(field, viewport, panelHeight, avoid, gap = POPOVER_GAP) {
1026
+ const width = Math.min(Math.max(field.width, POPOVER_MIN_WIDTH), POPOVER_MAX_WIDTH);
1027
+ const height = Math.min(Math.max(panelHeight, 0), POPOVER_MAX_HEIGHT);
1028
+ const below = { top: field.bottom + gap, bottom: field.bottom + gap + height };
1029
+ const above = { top: field.top - gap - height};
1030
+ const fitsBelow = below.bottom <= viewport.height;
1031
+ const fitsAbove = above.top >= 0;
1032
+ const coversActions = avoid ? below.bottom > avoid.top && below.top < avoid.bottom : false;
1033
+ const placement = (coversActions || !fitsBelow) && fitsAbove ? "above" : "below";
1034
+ const chosen = placement === "below" ? below : above;
1029
1035
  return {
1036
+ left: Math.min(Math.max(gap, field.left), Math.max(gap, viewport.width - width - gap)),
1037
+ top: Math.min(Math.max(gap, chosen.top), Math.max(gap, viewport.height - height - gap)),
1030
1038
  width,
1031
- offsetLeft,
1032
- maxHeight: Math.max(96, Math.min(POPOVER_MAX_HEIGHT, belowField))
1039
+ placement
1033
1040
  };
1034
1041
  }
1035
1042
  var panelId = 0;
@@ -1037,8 +1044,7 @@ var SuggestionPanel = class {
1037
1044
  element;
1038
1045
  inputElement;
1039
1046
  onPick;
1040
- view;
1041
- host;
1047
+ avoid;
1042
1048
  listId;
1043
1049
  currentChoices = [];
1044
1050
  currentIndex = -1;
@@ -1046,18 +1052,17 @@ var SuggestionPanel = class {
1046
1052
  constructor(input, options) {
1047
1053
  this.inputElement = input;
1048
1054
  this.onPick = options.onPick;
1049
- this.view = options.view;
1050
- this.host = options.host;
1055
+ this.avoid = options.avoid;
1051
1056
  this.listId = `frontmatter-suggestions-${++panelId}`;
1052
1057
  const list = document.createElement("div");
1053
1058
  list.id = this.listId;
1054
1059
  list.setAttribute("role", "listbox");
1055
1060
  list.setAttribute("aria-label", options.label);
1056
1061
  list.tabIndex = -1;
1057
- list.className = "mt-1 overflow-auto rounded-md border border-border bg-popover text-popover-foreground shadow-md text-xs";
1062
+ list.className = "fixed z-[60] max-h-64 overflow-auto rounded-md border border-border bg-popover text-popover-foreground shadow-md text-xs";
1058
1063
  list.hidden = true;
1059
1064
  this.element = list;
1060
- this.attach();
1065
+ document.body.appendChild(list);
1061
1066
  input.setAttribute("role", "combobox");
1062
1067
  input.setAttribute("aria-haspopup", "listbox");
1063
1068
  input.setAttribute("aria-autocomplete", "list");
@@ -1091,10 +1096,10 @@ var SuggestionPanel = class {
1091
1096
  if (this.isOpen) return;
1092
1097
  this.isOpen = true;
1093
1098
  this.element.hidden = false;
1094
- this.attach();
1095
1099
  this.position();
1096
1100
  this.inputElement.setAttribute("aria-expanded", "true");
1097
- this.view.requestMeasure();
1101
+ window.addEventListener("scroll", this.handleViewportChange, true);
1102
+ window.addEventListener("resize", this.handleViewportChange);
1098
1103
  }
1099
1104
  close() {
1100
1105
  if (!this.isOpen) return;
@@ -1103,10 +1108,12 @@ var SuggestionPanel = class {
1103
1108
  this.currentIndex = -1;
1104
1109
  this.inputElement.setAttribute("aria-expanded", "false");
1105
1110
  this.inputElement.removeAttribute("aria-activedescendant");
1106
- this.view.requestMeasure();
1111
+ window.removeEventListener("scroll", this.handleViewportChange, true);
1112
+ window.removeEventListener("resize", this.handleViewportChange);
1107
1113
  }
1108
1114
  destroy() {
1109
1115
  this.close();
1116
+ this.element.remove();
1110
1117
  }
1111
1118
  activate(index) {
1112
1119
  this.currentIndex = index;
@@ -1134,21 +1141,31 @@ var SuggestionPanel = class {
1134
1141
  this.close();
1135
1142
  this.onPick(choice);
1136
1143
  }
1137
- /** Join the DOM under its host row (idempotent). */
1138
- attach() {
1139
- if (this.element.parentElement) return;
1140
- this.host.after(this.element);
1141
- }
1142
- /** Anchor the panel to the field inside its row. */
1144
+ handleViewportChange = () => {
1145
+ if (this.isOpen) this.position();
1146
+ };
1147
+ /** Anchor the panel to the field, flipped away from the metadata actions. */
1143
1148
  position() {
1144
- const box = computeInlinePanelBox(
1145
- this.inputElement.getBoundingClientRect(),
1146
- this.host.getBoundingClientRect(),
1147
- window.innerHeight
1149
+ const field = this.inputElement.getBoundingClientRect();
1150
+ const avoidElement = this.avoid?.() ?? null;
1151
+ const avoidRect = avoidElement?.getBoundingClientRect();
1152
+ const height = Math.min(this.element.scrollHeight, POPOVER_MAX_HEIGHT);
1153
+ const placement = computeFloatingPlacement(
1154
+ { top: field.top, bottom: field.bottom, left: field.left, width: field.width },
1155
+ { width: window.innerWidth, height: window.innerHeight },
1156
+ height,
1157
+ avoidRect ? {
1158
+ top: avoidRect.top,
1159
+ bottom: avoidRect.bottom,
1160
+ left: avoidRect.left,
1161
+ right: avoidRect.right
1162
+ } : void 0
1148
1163
  );
1149
- this.element.style.width = `${box.width}px`;
1150
- this.element.style.marginLeft = `${box.offsetLeft}px`;
1151
- this.element.style.maxHeight = `${box.maxHeight}px`;
1164
+ this.element.style.width = `${placement.width}px`;
1165
+ this.element.style.maxHeight = `${height}px`;
1166
+ this.element.style.left = `${placement.left}px`;
1167
+ this.element.style.top = `${placement.top}px`;
1168
+ this.element.dataset.placement = placement.placement;
1152
1169
  }
1153
1170
  };
1154
1171
 
@@ -1196,12 +1213,12 @@ function ensureColumnHeader(box, before) {
1196
1213
  function attachSuggestions(input, view, root, kind, key, excluded, commit, valueKind = "tags") {
1197
1214
  const provider = view.state.facet(frontmatterSuggestions);
1198
1215
  if (!provider || !input.parentElement) return;
1199
- const host = input.closest("[data-frontmatter-row]") ?? input.parentElement;
1200
1216
  const panel = new SuggestionPanel(input, {
1201
1217
  label: kind === "key" ? "Suggested properties" : suggestionListLabel(valueKind),
1202
1218
  onPick: () => commit(),
1203
- view,
1204
- host
1219
+ // The popup floats over the properties panel; it must never cover the
1220
+ // metadata actions below it.
1221
+ avoid: () => root.querySelector("[data-frontmatter-actions]")
1205
1222
  });
1206
1223
  let generation = 0;
1207
1224
  const close = () => {
@@ -1976,9 +1993,10 @@ var DefaultFrontmatterWidget = class extends WidgetType {
1976
1993
  box.appendChild(this.buildDefinitionRows(view, base));
1977
1994
  }
1978
1995
  if (!this.readOnly) {
1979
- const existingTagKey = entries.find(([key]) => isTagProperty(key))?.[0];
1996
+ const existingTagKey = entries.find(([key]) => key.trim().toLowerCase() === "tags")?.[0] ?? entries.find(([key]) => isTagProperty(key))?.[0];
1980
1997
  const actionsRow = document.createElement("div");
1981
1998
  actionsRow.className = "mt-2 flex items-center gap-3";
1999
+ actionsRow.dataset.frontmatterActions = "true";
1982
2000
  const addBtn = document.createElement("button");
1983
2001
  addBtn.type = "button";
1984
2002
  addBtn.setAttribute("aria-label", "Add property");
@@ -2051,9 +2069,9 @@ var DefaultFrontmatterWidget = class extends WidgetType {
2051
2069
  existingDraft.focus();
2052
2070
  return;
2053
2071
  }
2054
- const draftRow = createTagDraftRow(view, root, "tags", (val) => {
2055
- pendingFocus.set(view, { kind: "tag", key: "tags" });
2056
- patchPropertyInView(view, this.sectionId, ["tags"], [val]);
2072
+ const draftRow = createTagDraftRow(view, root, "category", (val) => {
2073
+ pendingFocus.set(view, { kind: "tag", key: "category" });
2074
+ patchPropertyInView(view, this.sectionId, ["category"], [val]);
2057
2075
  });
2058
2076
  box.appendChild(draftRow);
2059
2077
  draftRow.querySelector("input")?.focus();
@@ -2182,6 +2200,7 @@ var EmptyFrontmatterWidget = class extends WidgetType {
2182
2200
  root.appendChild(heading);
2183
2201
  const actionsRow = document.createElement("div");
2184
2202
  actionsRow.className = "flex items-center gap-3";
2203
+ actionsRow.dataset.frontmatterActions = "true";
2185
2204
  const addBtn = document.createElement("button");
2186
2205
  addBtn.type = "button";
2187
2206
  addBtn.setAttribute("aria-label", "Add property");
@@ -2213,9 +2232,9 @@ var EmptyFrontmatterWidget = class extends WidgetType {
2213
2232
  existingDraft.focus();
2214
2233
  return;
2215
2234
  }
2216
- const draftRow = createTagDraftRow(view, root, "tags", (val) => {
2217
- pendingFocus.set(view, { kind: "tag", key: "tags" });
2218
- patchPropertyInView(view, "new", ["tags"], [val]);
2235
+ const draftRow = createTagDraftRow(view, root, "category", (val) => {
2236
+ pendingFocus.set(view, { kind: "tag", key: "category" });
2237
+ patchPropertyInView(view, "new", ["category"], [val]);
2219
2238
  });
2220
2239
  root.appendChild(draftRow);
2221
2240
  ensureColumnHeader(root, draftRow);
@@ -12838,5 +12857,5 @@ function editorPreset(optionsOrDialect = "markdown") {
12838
12857
  }
12839
12858
 
12840
12859
  export { AGG_OPTIONS, CANONICAL_BLOCK_TYPES, CLAUSE_META, ComposerRegistry, DEFAULT_DIAGNOSTICS_DEBOUNCE_MS, DEFAULT_OUTPUT_FILTERS, DEFAULT_PRIMARY_FILTER, DefaultFrontmatterWidget, EditorDialog, GROUPBY_OPTIONS, GoalRings, KIND_OPTIONS, METRIC_OPTIONS, MULTI_VALUE_TYPES, MetricBadge, OUTPUT_TYPE_CLASS, OUTPUT_TYPE_DOT, OutputFilterPills, OutputStatementsTable, PLANE_OPTIONS, ProposedMetricBadge, QueryBlockView, QueryValue, ROLLUP_OPTIONS, RowsResultsChrome, RowsTable, SERIES_COLORS, SOURCE_OPTIONS, SUGGESTION_BINDINGS, StackedBar, TARGET_OPTIONS, TIME_OPTIONS, TONE_CLASS, TokenSlotPill, TopList, UNIT_OPTIONS, WHERE_AGGREGATORS, WHERE_METRICS, WidgetChart, WidgetProblemBadge, WqlBars, WqlComposer, WqlDiagnosticsStrip, WqlEmptyState, WqlQueryInspectorModal, WqlTable, WqlTimeseries, ZoneDistribution, activeCursorSection, addRuntimePanel, blockTypesFromBlocks, canonicalSuggestionItems, catalogIdsFromBlocks, cn, compactNumber, composerRegistry, configureOverlayActions, cursorFocusExtension, dateRangeSlot, dispatchAddRuntimePanel, dispatchExpandRuntimePanel, dispatchGutterHighlights, dispatchRemoveRuntimePanel, editQueryClause, editingWidgetsField, editorPreset, editorTheme, embedPreviewDecorations, expandRuntimePanel, extractBlockQueries, extractMetricsByCategory, fenceCompletion, findQueryBlockSection, findWorkoutErrors, forceSectionParse, formatClockTime, formatMMSS, formatTimestamp, frontmatterPreview, frontmatterPreviewField, frontmatterReferenceIndex, frontmatterSuggestions, frontmatterVisibility, getClauseMeta, getCursorFocusState, getOverlayActions, getSuggestionBinding, gutterHighlightsField, gutterUnified, handleFenceAutoWrap, hashCode, inlineButtonDecoration, invalidateSuggestions, lineIdsExtension, linkOpen, linkPreview, loadSuggestions, markdownSyntaxHiding, markdownTablePreview, matchFilterTypeahead, mergeSeries, mergeSuggestionItems, mergeTagSuggestions, navigationFacet, normalizeOutputFilter, patchBlockQuery, presentBadges, previewDecorations, queryBlockPreview, readSessionRpe, referenceIndexReload, registerCustomCompletionSource, registeredSectionWidgets, removeRuntimePanel, resolveQueryDraft, runtimePanelField, saveBlockQuerySource, sectionAtPos, sectionField, sectionGeometry, sectionIdentity, sectionIdentityHistory, sectionMove, sectionRestore, sectionSaved, sessionQueryInsert, sessionQueryWql, setGutterHighlights, setSuggestionBinding, smartIncrement, summarizeAggregate, summarizeFind, summarizePipeline, tagsFromStaticBlocks, toChartResult, toggleWidgetEdit, tooltipTimestamp, unregisterCustomCompletionSource, urlAtPos, useChartShape, useComposerSlots, useSuggestions, useVisualViewportRect, useWqlStageCounts, widgetBlockPreview, wodAutoWrap, wodAutocompletion, wodEditorKeymap, wodLinter, wodOverlayPanel, workoutLintSource, wqlToPills, wrapInTimeFence };
12841
- //# sourceMappingURL=chunk-NQMMGF3R.mjs.map
12842
- //# sourceMappingURL=chunk-NQMMGF3R.mjs.map
12860
+ //# sourceMappingURL=chunk-7OSBFQY7.mjs.map
12861
+ //# sourceMappingURL=chunk-7OSBFQY7.mjs.map