function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
/*
 * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Button } from "@base-ui/react/button";
import { DragHandleVertical, SmallCross, Trash } from "@blueprintjs/icons";
import { closestCenter, DndContext as BaseDndContext, KeyboardSensor, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import classNames from "classnames";
import React, { useCallback, useEffect, useMemo, useRef } from "react";
import styles from "./DraggableList.module.css.js";
function DraggableListItem({
  item,
  onRemove,
  removeIconVariant = "trash",
  renderContent
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging
  } = useSortable({
    id: item.id
  });
  const style = {
    transform: CSS.Transform.toString(transform),
    transition
  };
  const handleRemove = useCallback(() => {
    onRemove?.(item.id);
  }, [item.id, onRemove]);
  const RemoveIcon = removeIconVariant === "trash" ? Trash : SmallCross;
  return /*#__PURE__*/React.createElement("div", {
    ref: setNodeRef,
    style: style,
    className: styles.draggableItem,
    "data-dragging": isDragging
  }, /*#__PURE__*/React.createElement("div", _extends({
    className: styles.dragHandle,
    "aria-label": `Reorder ${item.label}`
  }, attributes, listeners), /*#__PURE__*/React.createElement(DragHandleVertical, {
    className: styles.icon
  })), /*#__PURE__*/React.createElement("div", {
    className: styles.itemContent
  }, renderContent ? renderContent(item) : item.label), onRemove && /*#__PURE__*/React.createElement(Button, {
    className: styles.removeButton,
    onClick: handleRemove,
    "aria-label": `Remove ${item.label}`
  }, /*#__PURE__*/React.createElement(RemoveIcon, {
    className: styles.icon
  })));
}
export function DraggableList({
  items,
  onReorder,
  onRemove,
  removeIconVariant = "cross",
  renderContent,
  emptyMessage,
  className
}) {
  const itemIds = useMemo(() => items.map(item => item.id), [items]);
  const sensors = useSensors(useSensor(PointerSensor, {
    activationConstraint: {
      distance: 5
    }
  }), useSensor(KeyboardSensor, {
    coordinateGetter: sortableKeyboardCoordinates
  }));
  const handleDragEnd = useCallback(event => {
    const {
      active,
      over
    } = event;
    if (over && active.id !== over.id) {
      const oldIndex = items.findIndex(item => item.id === active.id);
      const newIndex = items.findIndex(item => item.id === over.id);
      onReorder(oldIndex, newIndex);
    }
  }, [items, onReorder]);
  const containerRef = useRef(null);
  useKeyboardEvents(containerRef);

  // TODO: Revert when @types/react is fixed

  return /*#__PURE__*/React.createElement("div", {
    ref: containerRef,
    className: classNames(styles.draggableListContainer, className)
  }, /*#__PURE__*/React.createElement(BaseDndContext, {
    sensors: sensors,
    collisionDetection: closestCenter,
    onDragEnd: handleDragEnd
  }, /*#__PURE__*/React.createElement(SortableContext, {
    items: itemIds,
    strategy: verticalListSortingStrategy
  }, items.map(item => /*#__PURE__*/React.createElement(DraggableListItem, {
    key: item.id,
    item: item,
    onRemove: onRemove,
    removeIconVariant: removeIconVariant,
    renderContent: renderContent
  })))), items.length === 0 && emptyMessage && /*#__PURE__*/React.createElement("div", {
    className: styles.emptyState
  }, emptyMessage));
}
const useKeyboardEvents = containerRef => {
  // Base UI's DialogPopup calls stopPropagation on arrow key events, which
  // prevents them from reaching @dnd-kit's document-level KeyboardSensor
  // listener. We use a native capture-phase listener to intercept arrow keys
  // before the dialog can swallow them, and re-dispatch them on the document
  // so @dnd-kit can process keyboard-driven reordering.
  useEffect(() => {
    const el = containerRef.current;
    if (el == null) {
      return;
    }
    const ARROW_KEYS = new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]);
    function handleCapture(event) {
      if (!ARROW_KEYS.has(event.key)) {
        return;
      }

      // Only intercept when a drag is active (an item has [data-dragging="true"])
      if (el.querySelector('[data-dragging="true"]') == null) {
        return;
      }
      event.stopPropagation();
      document.dispatchEvent(new KeyboardEvent("keydown", {
        key: event.key,
        code: event.code,
        bubbles: true
      }));
    }
    el.addEventListener("keydown", handleCapture, true);
    return () => el.removeEventListener("keydown", handleCapture, true);
  }, [containerRef]);
};
//# sourceMappingURL=DraggableList.js.map