@almadar/ui 2.41.0 → 2.43.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.
@@ -5881,27 +5881,27 @@ function useQuerySingleton(query) {
5881
5881
  store2.listeners.delete(listener);
5882
5882
  };
5883
5883
  }, [store2]);
5884
- const notifyListeners = React90.useCallback(() => {
5884
+ const notifyListeners2 = React90.useCallback(() => {
5885
5885
  store2.listeners.forEach((listener) => listener());
5886
5886
  }, [store2]);
5887
5887
  const setSearch = React90.useCallback((value) => {
5888
5888
  store2.search = value;
5889
- notifyListeners();
5890
- }, [store2, notifyListeners]);
5889
+ notifyListeners2();
5890
+ }, [store2, notifyListeners2]);
5891
5891
  const setFilter = React90.useCallback((key, value) => {
5892
5892
  store2.filters = { ...store2.filters, [key]: value };
5893
- notifyListeners();
5894
- }, [store2, notifyListeners]);
5893
+ notifyListeners2();
5894
+ }, [store2, notifyListeners2]);
5895
5895
  const clearFilters = React90.useCallback(() => {
5896
5896
  store2.filters = {};
5897
5897
  store2.search = "";
5898
- notifyListeners();
5899
- }, [store2, notifyListeners]);
5898
+ notifyListeners2();
5899
+ }, [store2, notifyListeners2]);
5900
5900
  const setSort = React90.useCallback((field, direction) => {
5901
5901
  store2.sortField = field;
5902
5902
  store2.sortDirection = direction;
5903
- notifyListeners();
5904
- }, [store2, notifyListeners]);
5903
+ notifyListeners2();
5904
+ }, [store2, notifyListeners2]);
5905
5905
  return {
5906
5906
  search: store2.search,
5907
5907
  setSearch,
@@ -8739,6 +8739,42 @@ var orbStyleOverrides = {
8739
8739
  "orb-op-async": { color: syntax.ORB_COLORS.dark.async }
8740
8740
  };
8741
8741
  var orbStyle = { ...dark__default.default, ...orbStyleOverrides };
8742
+ function computeFoldRegions(code) {
8743
+ const lines = code.split("\n");
8744
+ const regions = [];
8745
+ const stack = [];
8746
+ for (let i = 0; i < lines.length; i++) {
8747
+ const line = lines[i];
8748
+ let inString = false;
8749
+ for (let j = 0; j < line.length; j++) {
8750
+ const ch = line[j];
8751
+ if (ch === "\\" && inString) {
8752
+ j++;
8753
+ continue;
8754
+ }
8755
+ if (ch === '"') {
8756
+ inString = !inString;
8757
+ continue;
8758
+ }
8759
+ if (inString) continue;
8760
+ if (ch === "{" || ch === "[") {
8761
+ stack.push({ line: i, bracket: ch });
8762
+ } else if (ch === "}" || ch === "]") {
8763
+ const open = stack.pop();
8764
+ if (open && open.line < i) {
8765
+ regions.push({
8766
+ start: open.line,
8767
+ end: i,
8768
+ closeBracket: ch
8769
+ });
8770
+ }
8771
+ }
8772
+ }
8773
+ }
8774
+ return regions.sort((a, b) => a.start - b.start);
8775
+ }
8776
+ var LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
8777
+ var HIDDEN_LINE_NUMBERS = { display: "none" };
8742
8778
  var CodeBlock = React90__namespace.default.memo(
8743
8779
  ({
8744
8780
  code: rawCode,
@@ -8746,6 +8782,7 @@ var CodeBlock = React90__namespace.default.memo(
8746
8782
  showCopyButton = true,
8747
8783
  showLanguageBadge = true,
8748
8784
  maxHeight = "60vh",
8785
+ foldable: foldableProp,
8749
8786
  className
8750
8787
  }) => {
8751
8788
  const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
@@ -8754,8 +8791,114 @@ var CodeBlock = React90__namespace.default.memo(
8754
8791
  const eventBus = useEventBus();
8755
8792
  const { t: _t } = useTranslate();
8756
8793
  const scrollRef = React90.useRef(null);
8794
+ const codeRef = React90.useRef(null);
8757
8795
  const savedScrollLeftRef = React90.useRef(0);
8758
8796
  const [copied, setCopied] = React90.useState(false);
8797
+ const isFoldable = foldableProp ?? (language === "orb" || language === "json");
8798
+ const [collapsed, setCollapsed] = React90.useState(() => /* @__PURE__ */ new Set());
8799
+ const foldRegions = React90.useMemo(
8800
+ () => isFoldable ? computeFoldRegions(code) : [],
8801
+ [code, isFoldable]
8802
+ );
8803
+ const foldStartMap = React90.useMemo(() => {
8804
+ const m = /* @__PURE__ */ new Map();
8805
+ for (const r of foldRegions) m.set(r.start, r);
8806
+ return m;
8807
+ }, [foldRegions]);
8808
+ const hiddenLines = React90.useMemo(() => {
8809
+ const h = /* @__PURE__ */ new Set();
8810
+ for (const r of foldRegions) {
8811
+ if (!collapsed.has(r.start)) continue;
8812
+ for (let i = r.start + 1; i <= r.end; i++) h.add(i);
8813
+ }
8814
+ return h;
8815
+ }, [foldRegions, collapsed]);
8816
+ const collapsedRef = React90.useRef(collapsed);
8817
+ collapsedRef.current = collapsed;
8818
+ const foldStartMapRef = React90.useRef(foldStartMap);
8819
+ foldStartMapRef.current = foldStartMap;
8820
+ const toggleFold = React90.useCallback((lineNum) => {
8821
+ setCollapsed((prev) => {
8822
+ const next = new Set(prev);
8823
+ if (next.has(lineNum)) next.delete(lineNum);
8824
+ else next.add(lineNum);
8825
+ return next;
8826
+ });
8827
+ }, []);
8828
+ const toggleFoldRef = React90.useRef(toggleFold);
8829
+ toggleFoldRef.current = toggleFold;
8830
+ React90.useEffect(() => {
8831
+ setCollapsed(/* @__PURE__ */ new Set());
8832
+ }, [code]);
8833
+ const highlightedElement = React90.useMemo(
8834
+ () => /* @__PURE__ */ jsxRuntime.jsx(
8835
+ SyntaxHighlighter__default.default,
8836
+ {
8837
+ PreTag: "div",
8838
+ language,
8839
+ style: activeStyle,
8840
+ wrapLines: true,
8841
+ showLineNumbers: true,
8842
+ showInlineLineNumbers: false,
8843
+ lineNumberContainerStyle: HIDDEN_LINE_NUMBERS,
8844
+ lineProps: LINE_PROPS_FN,
8845
+ customStyle: {
8846
+ backgroundColor: "transparent",
8847
+ borderRadius: 0,
8848
+ padding: 0,
8849
+ margin: 0,
8850
+ whiteSpace: "pre",
8851
+ minWidth: "100%"
8852
+ },
8853
+ children: code
8854
+ }
8855
+ ),
8856
+ [code, language, activeStyle]
8857
+ );
8858
+ React90.useLayoutEffect(() => {
8859
+ const container = codeRef.current;
8860
+ if (!container) return;
8861
+ container.querySelectorAll(".fold-toggle, .fold-summary").forEach((el) => el.remove());
8862
+ const lineEls = container.querySelectorAll("[data-line]");
8863
+ if (!isFoldable || foldRegions.length === 0) {
8864
+ lineEls.forEach((el) => {
8865
+ el.style.display = "";
8866
+ el.style.position = "";
8867
+ el.style.paddingLeft = "";
8868
+ });
8869
+ return;
8870
+ }
8871
+ lineEls.forEach((el) => {
8872
+ const num = parseInt(el.getAttribute("data-line") ?? "-1", 10);
8873
+ if (hiddenLines.has(num)) {
8874
+ el.style.display = "none";
8875
+ return;
8876
+ }
8877
+ el.style.display = "";
8878
+ el.style.position = "relative";
8879
+ el.style.paddingLeft = "1.2em";
8880
+ const region = foldStartMap.get(num);
8881
+ if (!region) return;
8882
+ const isCollapsed = collapsed.has(num);
8883
+ const toggle = document.createElement("span");
8884
+ toggle.className = "fold-toggle";
8885
+ toggle.textContent = isCollapsed ? "\u25B6" : "\u25BC";
8886
+ toggle.style.cssText = "position:absolute;left:0;top:0;width:1.2em;text-align:center;cursor:pointer;color:#858585;font-size:10px;user-select:none;line-height:inherit;height:100%";
8887
+ toggle.addEventListener("click", (e) => {
8888
+ e.stopPropagation();
8889
+ toggleFoldRef.current(num);
8890
+ });
8891
+ el.insertBefore(toggle, el.firstChild);
8892
+ if (isCollapsed) {
8893
+ const summary = document.createElement("span");
8894
+ summary.className = "fold-summary";
8895
+ summary.style.cssText = "color:#858585;font-style:italic";
8896
+ const count = region.end - region.start - 1;
8897
+ summary.textContent = ` ... ${count} line${count !== 1 ? "s" : ""} ${region.closeBracket}`;
8898
+ el.appendChild(summary);
8899
+ }
8900
+ });
8901
+ }, [collapsed, hiddenLines, foldStartMap, foldRegions, isFoldable]);
8759
8902
  React90.useLayoutEffect(() => {
8760
8903
  const el = scrollRef.current;
8761
8904
  return () => {
@@ -8786,8 +8929,9 @@ var CodeBlock = React90__namespace.default.memo(
8786
8929
  eventBus.emit("UI:COPY_CODE", { language, success: false });
8787
8930
  }
8788
8931
  };
8932
+ const hasHeader = showLanguageBadge || showCopyButton;
8789
8933
  return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: `relative group ${className || ""}`, children: [
8790
- (showLanguageBadge || showCopyButton) && /* @__PURE__ */ jsxRuntime.jsxs(
8934
+ hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(
8791
8935
  HStack,
8792
8936
  {
8793
8937
  justify: "between",
@@ -8822,31 +8966,14 @@ var CodeBlock = React90__namespace.default.memo(
8822
8966
  touchAction: "pan-x pan-y",
8823
8967
  contain: "paint",
8824
8968
  backgroundColor: "#1e1e1e",
8825
- borderRadius: showLanguageBadge || showCopyButton ? "0 0 0.5rem 0.5rem" : "0.5rem",
8826
- padding: "1rem"
8969
+ borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem"
8827
8970
  },
8828
- children: /* @__PURE__ */ jsxRuntime.jsx(
8829
- SyntaxHighlighter__default.default,
8830
- {
8831
- PreTag: "div",
8832
- language,
8833
- style: activeStyle,
8834
- customStyle: {
8835
- backgroundColor: "transparent",
8836
- borderRadius: 0,
8837
- padding: 0,
8838
- margin: 0,
8839
- whiteSpace: "pre",
8840
- minWidth: "100%"
8841
- },
8842
- children: code
8843
- }
8844
- )
8971
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: codeRef, style: { padding: "1rem" }, children: highlightedElement })
8845
8972
  }
8846
8973
  )
8847
8974
  ] });
8848
8975
  },
8849
- (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight
8976
+ (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable
8850
8977
  );
8851
8978
  CodeBlock.displayName = "CodeBlock";
8852
8979
  var QuizBlock = ({
@@ -26880,7 +27007,7 @@ function SequencerBoard({
26880
27007
  setPlayState("playing");
26881
27008
  setCurrentStep(0);
26882
27009
  let step = 0;
26883
- const advance2 = () => {
27010
+ const advance = () => {
26884
27011
  step++;
26885
27012
  if (step >= entity.maxSlots) {
26886
27013
  const playerSeq = slots.map((s) => s?.id);
@@ -26911,10 +27038,10 @@ function SequencerBoard({
26911
27038
  }
26912
27039
  } else {
26913
27040
  setCurrentStep(step);
26914
- timerRef.current = setTimeout(advance2, stepDurationMs);
27041
+ timerRef.current = setTimeout(advance, stepDurationMs);
26915
27042
  }
26916
27043
  };
26917
- timerRef.current = setTimeout(advance2, stepDurationMs);
27044
+ timerRef.current = setTimeout(advance, stepDurationMs);
26918
27045
  }, [canPlay, slots, entity.maxSlots, entity.solutions, stepDurationMs, playEvent, completeEvent, emit]);
26919
27046
  const machine = {
26920
27047
  name: entity.title,
@@ -29026,25 +29153,92 @@ function generateCombatMessage(event) {
29026
29153
  var store = /* @__PURE__ */ new Map();
29027
29154
  var storeListeners = /* @__PURE__ */ new Set();
29028
29155
  var watchCallbacks = /* @__PURE__ */ new Map();
29029
- function advance(entityType, data) {
29030
- const prev = store.get(entityType);
29031
- const oldData = prev?.data ?? [];
29032
- store.set(entityType, { data, version: (prev?.version ?? 0) + 1 });
29156
+ function extractId(record) {
29157
+ const r = record;
29158
+ return String(r.id ?? r._id ?? r.key ?? "");
29159
+ }
29160
+ function materialize(snap) {
29161
+ return snap.ids.map((id) => snap.entities.get(id));
29162
+ }
29163
+ function notifyListeners(entityType, prev) {
29033
29164
  for (const listener of storeListeners) {
29034
29165
  listener();
29035
29166
  }
29036
29167
  const cbs = watchCallbacks.get(entityType);
29037
29168
  if (cbs) {
29169
+ const oldData = prev ? materialize(prev) : [];
29170
+ const cur = store.get(entityType);
29171
+ const newData = cur ? materialize(cur) : [];
29038
29172
  for (const cb of cbs) {
29039
29173
  try {
29040
- cb(oldData, data);
29174
+ cb(oldData, newData);
29041
29175
  } catch {
29042
29176
  }
29043
29177
  }
29044
29178
  }
29045
29179
  }
29180
+ function setAll(entityType, records) {
29181
+ const entities2 = /* @__PURE__ */ new Map();
29182
+ const ids = [];
29183
+ for (const r of records) {
29184
+ const rec = r;
29185
+ const id = extractId(rec);
29186
+ if (id) {
29187
+ entities2.set(id, rec);
29188
+ ids.push(id);
29189
+ }
29190
+ }
29191
+ const prev = store.get(entityType);
29192
+ store.set(entityType, { entities: entities2, ids, version: (prev?.version ?? 0) + 1 });
29193
+ notifyListeners(entityType, prev);
29194
+ }
29195
+ function upsertOne(entityType, record) {
29196
+ const id = extractId(record);
29197
+ if (!id) return;
29198
+ const prev = store.get(entityType);
29199
+ const snapshot = prev ? { entities: new Map(prev.entities), ids: [...prev.ids], version: prev.version } : { entities: /* @__PURE__ */ new Map(), ids: [], version: 0 };
29200
+ snapshot.entities.set(id, record);
29201
+ if (!snapshot.ids.includes(id)) snapshot.ids.push(id);
29202
+ snapshot.version++;
29203
+ store.set(entityType, snapshot);
29204
+ notifyListeners(entityType, prev);
29205
+ }
29206
+ function addOne(entityType, record) {
29207
+ upsertOne(entityType, record);
29208
+ }
29209
+ function updateOne(entityType, id, changes) {
29210
+ const prev = store.get(entityType);
29211
+ if (!prev?.entities.has(id)) return;
29212
+ const snapshot = {
29213
+ entities: new Map(prev.entities),
29214
+ ids: [...prev.ids],
29215
+ version: prev.version
29216
+ };
29217
+ snapshot.entities.set(id, { ...snapshot.entities.get(id), ...changes });
29218
+ snapshot.version++;
29219
+ store.set(entityType, snapshot);
29220
+ notifyListeners(entityType, prev);
29221
+ }
29222
+ function removeOne(entityType, id) {
29223
+ const prev = store.get(entityType);
29224
+ if (!prev) return;
29225
+ const snapshot = {
29226
+ entities: new Map(prev.entities),
29227
+ ids: prev.ids.filter((i) => i !== id),
29228
+ version: prev.version
29229
+ };
29230
+ snapshot.entities.delete(id);
29231
+ snapshot.version++;
29232
+ store.set(entityType, snapshot);
29233
+ notifyListeners(entityType, prev);
29234
+ }
29046
29235
  function getSnapshot2(entityType) {
29047
- return store.get(entityType)?.data ?? [];
29236
+ const snap = store.get(entityType);
29237
+ if (!snap) return [];
29238
+ return materialize(snap);
29239
+ }
29240
+ function getById(entityType, id) {
29241
+ return store.get(entityType)?.entities.get(id) ?? null;
29048
29242
  }
29049
29243
  function getVersion(entityType) {
29050
29244
  return store.get(entityType)?.version ?? 0;
@@ -29068,10 +29262,16 @@ function useEntityRef(entityType) {
29068
29262
  }, [entityType]);
29069
29263
  return React90.useSyncExternalStore(subscribeToStore, getSnapshotStable, () => []);
29070
29264
  }
29071
- React90.createContext({
29072
- advance,
29073
- getSnapshot: getSnapshot2
29074
- });
29265
+ var contextValue = {
29266
+ setAll,
29267
+ upsertOne,
29268
+ addOne,
29269
+ updateOne,
29270
+ removeOne,
29271
+ getSnapshot: getSnapshot2,
29272
+ getById
29273
+ };
29274
+ React90.createContext(contextValue);
29075
29275
  var ClientEffectConfigContext = React90.createContext(null);
29076
29276
  ClientEffectConfigContext.Provider;
29077
29277
 
@@ -34463,13 +34663,14 @@ function getToastPosition(position) {
34463
34663
  return "top-4 right-4";
34464
34664
  }
34465
34665
  }
34466
- function renderPatternChildren(children, onDismiss, parentId = "root") {
34666
+ function renderPatternChildren(children, onDismiss, parentId = "root", parentPath = "root") {
34467
34667
  if (!children || !Array.isArray(children) || children.length === 0) {
34468
34668
  return null;
34469
34669
  }
34470
34670
  return children.map((child, index) => {
34471
34671
  if (!child || typeof child !== "object") return null;
34472
34672
  const childId = `${parentId}-${index}`;
34673
+ const childPath = parentPath === "root" ? `root.children.${index}` : `${parentPath}.children.${index}`;
34473
34674
  const childContent = {
34474
34675
  id: childId,
34475
34676
  pattern: child.type,
@@ -34481,7 +34682,8 @@ function renderPatternChildren(children, onDismiss, parentId = "root") {
34481
34682
  SlotContentRenderer,
34482
34683
  {
34483
34684
  content: childContent,
34484
- onDismiss
34685
+ onDismiss,
34686
+ patternPath: childPath
34485
34687
  },
34486
34688
  childId
34487
34689
  );
@@ -34513,7 +34715,8 @@ function renderPatternProps(props, onDismiss) {
34513
34715
  }
34514
34716
  function SlotContentRenderer({
34515
34717
  content,
34516
- onDismiss
34718
+ onDismiss,
34719
+ patternPath
34517
34720
  }) {
34518
34721
  const entityProp = content.props.entity;
34519
34722
  const entityType = typeof entityProp === "string" ? entityProp : "";
@@ -34522,7 +34725,8 @@ function SlotContentRenderer({
34522
34725
  if (PatternComponent) {
34523
34726
  const childrenConfig = content.props.children;
34524
34727
  const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0;
34525
- const renderedChildren = hasChildren ? renderPatternChildren(childrenConfig, onDismiss, content.id) : void 0;
34728
+ const myPath = patternPath ?? "root";
34729
+ const renderedChildren = hasChildren ? renderPatternChildren(childrenConfig, onDismiss, content.id, myPath) : void 0;
34526
34730
  const { children: _childrenConfig, ...restProps } = content.props;
34527
34731
  const renderedProps = renderPatternProps(restProps, onDismiss);
34528
34732
  let finalProps;
@@ -34538,6 +34742,7 @@ function SlotContentRenderer({
34538
34742
  } else {
34539
34743
  finalProps = renderedProps;
34540
34744
  }
34745
+ const acceptsChildren = PATTERNS_WITH_CHILDREN.has(content.pattern);
34541
34746
  return /* @__PURE__ */ jsxRuntime.jsx(
34542
34747
  Box,
34543
34748
  {
@@ -34546,6 +34751,9 @@ function SlotContentRenderer({
34546
34751
  "data-id": content.id,
34547
34752
  "data-node-id": content.nodeId,
34548
34753
  "data-source-trait": content.sourceTrait,
34754
+ "data-pattern-path": myPath,
34755
+ "data-pattern-type": content.pattern,
34756
+ "data-accepts-children": acceptsChildren ? "true" : void 0,
34549
34757
  children: /* @__PURE__ */ jsxRuntime.jsx(PatternComponent, { ...finalProps, children: renderedChildren })
34550
34758
  }
34551
34759
  );
@@ -37220,6 +37428,98 @@ function usePinchZoom(options = {}) {
37220
37428
  resetZoom
37221
37429
  };
37222
37430
  }
37431
+ var ALMADAR_DND_MIME = "application/x-almadar-dnd";
37432
+ function useDraggable({ payload, disabled = false }) {
37433
+ const [isDragging, setIsDragging] = React90.useState(false);
37434
+ const eventBus = useEventBus();
37435
+ const handleDragStart = React90.useCallback(
37436
+ (e) => {
37437
+ if (disabled) {
37438
+ e.preventDefault();
37439
+ return;
37440
+ }
37441
+ e.dataTransfer.setData(ALMADAR_DND_MIME, JSON.stringify(payload));
37442
+ e.dataTransfer.effectAllowed = "copy";
37443
+ setIsDragging(true);
37444
+ eventBus.emit("UI:DRAG_START", { kind: payload.kind, data: payload.data });
37445
+ },
37446
+ [disabled, payload, eventBus]
37447
+ );
37448
+ const handleDragEnd = React90.useCallback(
37449
+ (e) => {
37450
+ setIsDragging(false);
37451
+ eventBus.emit("UI:DRAG_END", { kind: payload.kind, data: payload.data });
37452
+ },
37453
+ [payload, eventBus]
37454
+ );
37455
+ const dragProps = React90.useMemo(
37456
+ () => ({
37457
+ draggable: !disabled,
37458
+ onDragStart: handleDragStart,
37459
+ onDragEnd: handleDragEnd,
37460
+ "aria-grabbed": isDragging
37461
+ }),
37462
+ [disabled, handleDragStart, handleDragEnd, isDragging]
37463
+ );
37464
+ return { dragProps, isDragging };
37465
+ }
37466
+ function parsePayload(e) {
37467
+ try {
37468
+ const raw = e.dataTransfer.getData(ALMADAR_DND_MIME);
37469
+ if (!raw) return null;
37470
+ const parsed = JSON.parse(raw);
37471
+ if (typeof parsed.kind !== "string" || !parsed.data) return null;
37472
+ return parsed;
37473
+ } catch {
37474
+ return null;
37475
+ }
37476
+ }
37477
+ function hasAlmadarPayload(e) {
37478
+ return e.dataTransfer.types.includes(ALMADAR_DND_MIME);
37479
+ }
37480
+ function useDropZone({ accepts, onDrop, disabled = false }) {
37481
+ const [isOver, setIsOver] = React90.useState(false);
37482
+ const eventBus = useEventBus();
37483
+ const handleDragOver = React90.useCallback(
37484
+ (e) => {
37485
+ if (disabled) return;
37486
+ if (!hasAlmadarPayload(e)) return;
37487
+ e.preventDefault();
37488
+ e.dataTransfer.dropEffect = "copy";
37489
+ setIsOver(true);
37490
+ },
37491
+ [disabled]
37492
+ );
37493
+ const handleDragLeave = React90.useCallback(
37494
+ (e) => {
37495
+ setIsOver(false);
37496
+ },
37497
+ []
37498
+ );
37499
+ const handleDrop = React90.useCallback(
37500
+ (e) => {
37501
+ e.preventDefault();
37502
+ setIsOver(false);
37503
+ if (disabled) return;
37504
+ const payload = parsePayload(e);
37505
+ if (!payload) return;
37506
+ if (!accepts.includes(payload.kind)) return;
37507
+ const position = { x: e.clientX, y: e.clientY };
37508
+ onDrop(payload, position);
37509
+ eventBus.emit("UI:DROP", { kind: payload.kind, data: payload.data, ...position });
37510
+ },
37511
+ [disabled, accepts, onDrop, eventBus]
37512
+ );
37513
+ const dropProps = React90.useMemo(
37514
+ () => ({
37515
+ onDragOver: handleDragOver,
37516
+ onDragLeave: handleDragLeave,
37517
+ onDrop: handleDrop
37518
+ }),
37519
+ [handleDragOver, handleDragLeave, handleDrop]
37520
+ );
37521
+ return { dropProps, isOver };
37522
+ }
37223
37523
  var API_BASE = typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
37224
37524
  function getUserId() {
37225
37525
  return localStorage.getItem("userId") || "anonymous";
@@ -37297,6 +37597,7 @@ function useGitHubBranches(owner, repo, enabled = true) {
37297
37597
  }
37298
37598
 
37299
37599
  exports.ALL_PRESETS = ALL_PRESETS;
37600
+ exports.ALMADAR_DND_MIME = ALMADAR_DND_MIME;
37300
37601
  exports.AR_BOOK_FIELDS = AR_BOOK_FIELDS;
37301
37602
  exports.AboutPageTemplate = AboutPageTemplate;
37302
37603
  exports.Accordion = Accordion;
@@ -37641,6 +37942,8 @@ exports.useDeepAgentGeneration = useDeepAgentGeneration;
37641
37942
  exports.useDeleteEntity = useDeleteEntity;
37642
37943
  exports.useDisconnectGitHub = useDisconnectGitHub;
37643
37944
  exports.useDragReorder = useDragReorder;
37945
+ exports.useDraggable = useDraggable;
37946
+ exports.useDropZone = useDropZone;
37644
37947
  exports.useEmitEvent = useEmitEvent;
37645
37948
  exports.useEntities = useEntities;
37646
37949
  exports.useEntitiesByType = useEntitiesByType;