import { jsxs, jsx } from 'react/jsx-runtime';
import { useRef, useState, useMemo, useEffect, forwardRef, useId, useCallback } from 'react';
import { w as warnDeprecatedErrorUsage } from './utils-CM48ODEJ.js';
import { a as useToggleSelection, M as MultiSelectOptions, u as useBulkActionRunner, r as resolveBulkActionCheckState, b as resolveBulkActionLabel } from './bulkActionTypes-CTKwMpO7.js';
import { c as cx } from './index-De1g9FRV.js';
import { B as Button } from './Button-BNzCI47m.js';
import { C as Chip } from './Chip-CxgryK86.js';
import { F as Flex } from './Flex-Bb3iHExM.js';
import { m as mergeRefs, u as useMergeRefs } from './useMergeRefs-Dfmtq9cI.js';
import { S as SvgChevronRight } from './chevron_right-BdpsxX7x.js';
import { S as SvgClose } from './close-DZj38AEh.js';
import { u as useChipLayout } from './useChipLayout-BWZfKDgd.js';
import { S as SelectFieldLabel } from './SelectFieldLabel-dKVBaki2.js';
import { s as styles$1 } from './SelectTriggerBase.module-Brmw1nYG.js';
import { u as useDownshiftEnvironment, a as useCombobox, b as useSelect } from './downshift.esm-xtSnQp44.js';
import { a as useProcessedOptions, b as buildSelectItems, s as shouldShowAddNewItem, A as AddNewItemButton, u as useSelectOrchestration, d as defaultSyncFilter, t as toSyncFilterFn } from './syncFilterUtils-BVclVovw.js';
import { O as OptionsDialog, a as OptionsPopover } from './useAdaptiveView-AvsDkChF.js';
import { F as FieldMessage } from './FieldMessage-mTGdycSA.js';
import { u as useDebouncedCallback } from './useDebouncedCallback-DLkapjcP.js';
import { u as useLayoutPropsUtil } from './useLayoutPropsUtil-DjqeAJZ9.js';
import { w as warnOnce } from './warnOnce-Y9PRHcU4.js';

import './MultiSelectFieldSync.css';const input = "_input_184hn_26";
const error = "_error_184hn_54";
const disabled = "_disabled_184hn_61";
const highlight = "_highlight_184hn_70";
const chip = "_chip_184hn_143";
const prefix = "_prefix_184hn_233";
const suffix = "_suffix_184hn_234";
const small = "_small_184hn_309";
const large = "_large_184hn_315";
const styles = {
	"input-wrapper": "_input-wrapper_184hn_26",
	input: input,
	error: error,
	disabled: disabled,
	highlight: highlight,
	"input-flex": "_input-flex_184hn_74",
	"rows-wrapper": "_rows-wrapper_184hn_132",
	"chip-wrapper": "_chip-wrapper_184hn_143",
	chip: chip,
	"buttons-wrapper": "_buttons-wrapper_184hn_155",
	"close-button-wrapper": "_close-button-wrapper_184hn_172",
	"close-button": "_close-button_184hn_172",
	"toggle-button-wrapper": "_toggle-button-wrapper_184hn_195",
	"toggle-button": "_toggle-button_184hn_195",
	prefix: prefix,
	suffix: suffix,
	"no-clear-button": "_no-clear-button_184hn_301",
	"no-toggle-button": "_no-toggle-button_184hn_305",
	small: small,
	large: large};

const MultiSelectFieldInput = ({
  placeholder,
  size,
  disableClearButton,
  disableToggleButton,
  disabled,
  readOnly,
  isHighlighted,
  error,
  onClear,
  id,
  inputWrapperRef,
  htmlInputWrapperProps,
  inputProps,
  toggleButtonProps,
  prefix,
  suffix,
  selectedOptions = [],
  onRemoveOption,
  singleRow,
  maxChips,
  getChipProps,
  onWrapperClick
}) => {
  const inputRef = useRef(null);
  const externalRef = inputProps?.ref;
  const mergedInputRef = mergeRefs([inputRef, externalRef]);
  const { rowsRef, displayCount, hiddenCount } = useChipLayout({
    selectedOptionsLength: selectedOptions.length,
    singleRow,
    maxChips
  });
  const inputWrapperClassNames = cx(styles["input-wrapper"], {
    [styles["small"]]: size === "small",
    [styles["large"]]: size === "large",
    [styles["no-clear-button"]]: disableClearButton,
    [styles["no-toggle-button"]]: disableToggleButton,
    [styles["disabled"]]: disabled || readOnly,
    [styles["highlight"]]: isHighlighted
  });
  const handleInputKeyDown = (e) => {
    if (e.key === "Backspace" && !inputProps?.value && selectedOptions.length > 0 && onRemoveOption && !disabled && !readOnly) {
      onRemoveOption(selectedOptions[selectedOptions.length - 1]);
    }
    if (inputProps?.onKeyDown) {
      inputProps.onKeyDown(e);
    }
  };
  const handleWrapperClick = (e) => {
    const target = e.target;
    if (target.closest("button") || target.tagName === "INPUT") {
      return;
    }
    onWrapperClick?.(e);
    inputRef.current?.focus();
  };
  return (
    // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events -- Click-to-focus container; Despite the disabled rules, this remains accessible. Keyboard interaction is provided by the input and nested buttons are filtered out in the handler.
    /* @__PURE__ */ jsxs(
      "div",
      {
        ref: inputWrapperRef,
        ...htmlInputWrapperProps,
        className: cx(inputWrapperClassNames, htmlInputWrapperProps?.className),
        onClick: handleWrapperClick,
        children: [
          prefix ? /* @__PURE__ */ jsx("div", { className: styles["prefix"], children: prefix }) : null,
          /* @__PURE__ */ jsxs("div", { className: styles["rows-wrapper"], ref: rowsRef, children: [
            selectedOptions.length > 0 && onRemoveOption ? selectedOptions.slice(0, displayCount).map((option, index) => /* @__PURE__ */ jsx(
              "div",
              {
                className: styles["chip-wrapper"],
                children: /* @__PURE__ */ jsx(
                  Chip,
                  {
                    ...getChipProps?.(option),
                    label: option.label,
                    onClose: disabled || readOnly ? void 0 : () => onRemoveOption(option),
                    className: styles["chip"],
                    title: option.label
                  }
                )
              },
              `selected-item-${option.id}-${index}`
            )) : null,
            hiddenCount > 0 ? /* @__PURE__ */ jsx("div", { className: styles["chip-wrapper"], children: /* @__PURE__ */ jsx(
              Chip,
              {
                label: `+${hiddenCount}`,
                className: styles["chip"],
                title: selectedOptions.slice(displayCount).map((option) => option.label).join(", ")
              }
            ) }) : null,
            /* @__PURE__ */ jsxs(Flex, { className: styles["input-flex"], alignItems: "center", children: [
              /* @__PURE__ */ jsx(
                "input",
                {
                  id,
                  type: "text",
                  placeholder,
                  disabled,
                  readOnly,
                  ...inputProps,
                  ref: mergedInputRef,
                  onKeyDown: handleInputKeyDown,
                  className: cx(styles["input"], inputProps?.className, {
                    [styles["error"]]: error
                  })
                }
              ),
              suffix ? /* @__PURE__ */ jsx("div", { className: styles["suffix"], children: suffix }) : null
            ] })
          ] }),
          /* @__PURE__ */ jsxs("div", { className: styles["buttons-wrapper"], children: [
            disableClearButton ? null : /* @__PURE__ */ jsx("div", { className: styles["close-button-wrapper"], children: /* @__PURE__ */ jsx(
              Button,
              {
                icon: SvgClose,
                "aria-label": "clear selection",
                appearance: "ghost",
                size: "small",
                className: styles["close-button"],
                onClick: () => {
                  onClear?.();
                }
              }
            ) }),
            disableToggleButton ? null : /* @__PURE__ */ jsx("div", { className: styles["toggle-button-wrapper"], children: /* @__PURE__ */ jsx(
              Button,
              {
                icon: SvgChevronRight,
                "aria-label": "toggle menu",
                appearance: "ghost",
                size: "small",
                disabled,
                ...toggleButtonProps,
                className: cx(
                  styles["toggle-button"],
                  toggleButtonProps?.className
                )
              }
            ) })
          ] })
        ]
      }
    )
  );
};
MultiSelectFieldInput.displayName = "MultiSelectFieldInput";

const useComboMultiple = ({
  options,
  pinned,
  groupToString,
  groupSorter,
  selectAll,
  selectFiltered,
  bulkPending,
  onBulkActivate,
  selectedOptions,
  onSelectedOptionsChange,
  onInputValueChange,
  onIsOpenChange,
  displayAs = "popover",
  disabled,
  loading = false,
  virtualize = false,
  onScrollToHighlight
}) => {
  const [inputValue, setInputValue] = useState("");
  const { pinnedSections, ungroupedItems, groupSections } = useProcessedOptions(
    {
      options,
      pinned,
      searchValue: inputValue,
      groupToString,
      groupSorter
    }
  );
  const bulkActionItems = useMemo(() => {
    const items2 = [];
    const hasSearchTerm = inputValue.trim().length > 0;
    const hasResults = ungroupedItems.length > 0 || groupSections.some((s) => s.options.length > 0) || pinnedSections.some((s) => s.options.length > 0);
    if (hasSearchTerm && selectFiltered && hasResults && !loading) {
      const config = selectFiltered(inputValue);
      items2.push({
        id: "select-filtered",
        type: "select-filtered",
        original: {
          id: "select-filtered",
          label: config.label ?? `Select items matching "${inputValue}"`
        },
        checkState: config.checkState
      });
    } else if (!hasSearchTerm && selectAll) {
      items2.push({
        id: "select-all",
        type: "select-all",
        original: {
          id: "select-all",
          label: selectAll.label ?? "Select All"
        },
        checkState: selectAll.checkState
      });
    }
    return items2;
  }, [
    inputValue,
    ungroupedItems,
    groupSections,
    pinnedSections,
    selectFiltered,
    selectAll,
    loading
  ]);
  const { items, sectionsMeta } = useMemo(
    () => buildSelectItems({
      prefixItems: bulkActionItems,
      pinnedSections,
      groupSections,
      ungroupedItems
    }),
    [bulkActionItems, pinnedSections, groupSections, ungroupedItems]
  );
  const { ref: wrapperDivRef, environment } = useDownshiftEnvironment();
  const { handleItemClick } = useToggleSelection({
    options,
    pinnedSections,
    selectedOptions,
    onSelectedOptionsChange
  });
  const {
    isOpen,
    highlightedIndex,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getInputProps,
    getItemProps,
    inputValue: downshiftInputValue,
    closeMenu,
    openMenu,
    toggleMenu
  } = useCombobox({
    isItemDisabled: (item, _index) => {
      if (!item) {
        return false;
      }
      if (bulkPending) return true;
      return (disabled || item.disabled) ?? false;
    },
    environment,
    // For multi-select, we don't track a single selected item
    selectedItem: null,
    onSelectedItemChange: ({
      selectedItem: si
    }) => {
      if (si) {
        if (si.type === "select-all") {
          onBulkActivate("selectAll", inputValue);
        } else if (si.type === "select-filtered") {
          onBulkActivate("selectFiltered", inputValue);
        } else if (si.type === "option" || si.type === "pinned-option" || si.type === "grouped-option") {
          handleItemClick(si.original);
        }
      }
    },
    onHighlightedIndexChange: ({ type, highlightedIndex: idx }) => {
      if (type !== useCombobox.stateChangeTypes.ItemMouseMove && idx >= 0) {
        onScrollToHighlight?.(idx);
      }
    },
    onInputValueChange: (changes) => {
      setInputValue(changes.inputValue ?? "");
      onInputValueChange?.(changes);
    },
    scrollIntoView: virtualize ? () => {
    } : (node, menuNode) => {
      if (!node || !menuNode) return;
      const firstItem = items[0];
      const hasBulkAction = firstItem?.type === "select-all" || firstItem?.type === "select-filtered";
      if (!hasBulkAction) {
        const nodeRect2 = node.getBoundingClientRect();
        const menuRect2 = menuNode.getBoundingClientRect();
        if (nodeRect2.bottom > menuRect2.bottom || nodeRect2.top < menuRect2.top) {
          node.scrollIntoView({ block: "nearest" });
        }
        return;
      }
      const bulkActionEl = menuNode.querySelector(
        '[data-type="select-all"], [data-type="select-filtered"]'
      );
      if (node === bulkActionEl) {
        menuNode.scrollTop = 0;
        return;
      }
      const stickyHeight = bulkActionEl?.getBoundingClientRect().height ?? 0;
      const nodeRect = node.getBoundingClientRect();
      const menuRect = menuNode.getBoundingClientRect();
      const visibleTop = menuRect.top + stickyHeight;
      if (nodeRect.top < visibleTop) {
        menuNode.scrollTop -= visibleTop - nodeRect.top;
      } else if (nodeRect.bottom > menuRect.bottom) {
        menuNode.scrollTop += nodeRect.bottom - menuRect.bottom;
      }
    },
    onIsOpenChange,
    items,
    itemToString(item) {
      return item?.original.label ?? "";
    },
    stateReducer: (state, actionAndChanges) => stateReducer$1(state, actionAndChanges, displayAs)
  });
  return {
    inputValue: downshiftInputValue,
    wrapperDivRef,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getInputProps,
    getItemProps,
    highlightedIndex,
    isOpen,
    items,
    sectionsMeta,
    closeMenu,
    openMenu,
    toggleMenu,
    selectedOptions
  };
};
function stateReducer$1(state, actionAndChanges, displayAs) {
  const { type, changes } = actionAndChanges;
  switch (type) {
    case useCombobox.stateChangeTypes.InputBlur:
      if (displayAs === "dialog" && state.isOpen) {
        return {
          ...changes,
          isOpen: state.isOpen,
          // Preserve input value for multi-select
          inputValue: state.inputValue
        };
      }
      return {
        ...changes,
        // For multi-select, preserve the input value on blur
        inputValue: state.inputValue
      };
    case useCombobox.stateChangeTypes.InputKeyDownEscape:
    case useCombobox.stateChangeTypes.FunctionCloseMenu:
      return {
        ...changes,
        // Clear input value when menu is closed
        inputValue: ""
      };
    case useCombobox.stateChangeTypes.InputClick:
      if (displayAs === "dialog" && state.isOpen) {
        return {
          ...changes,
          isOpen: state.isOpen
        };
      }
      return changes;
    case useCombobox.stateChangeTypes.InputKeyDownEnter:
    case useCombobox.stateChangeTypes.ItemClick:
      return {
        ...changes,
        isOpen: state.isOpen,
        // Keep menu open
        highlightedIndex: state.highlightedIndex,
        // Preserve highlight position
        inputValue: state.inputValue
        // Preserve input value for continued filtering
      };
    case useCombobox.stateChangeTypes.ControlledPropUpdatedSelectedItem:
      return {
        ...changes,
        inputValue: state.inputValue
      };
    default:
      return changes;
  }
}

const MultiSelectFieldComboboxMode = ({
  labelAiMark,
  id,
  helperUid,
  selectedOptions,
  onSelectedOptionsChange,
  displayAs,
  isDisabledOrReadOnly,
  disabled,
  readOnly,
  isHighlighted,
  required,
  placeholder,
  size,
  error,
  hasHelperText,
  disableClearButton,
  prefix,
  suffix,
  label,
  hideLabel,
  hint,
  moreInfo,
  moreInfoId,
  errorMessages,
  warning,
  description,
  className,
  style,
  layoutStyles,
  pinned,
  groupToString,
  groupSorter,
  virtualize,
  options,
  loading,
  loadingMore,
  hasMore,
  loadOptions,
  loadMore,
  initialLoad,
  initialLoadPerformed,
  setInitialLoadPerformed,
  inputWrapperRef,
  debounceMs,
  selectAll,
  selectFiltered,
  bulkPending,
  onBulkActivate,
  singleRow,
  maxChips,
  getChipProps,
  onSearchChange,
  addItemLabel,
  onAddNewItem,
  handleRemoveOption,
  handleClear
}) => {
  const listRef = useRef(null);
  const debouncedOptionLoader = useDebouncedCallback((inputValue2) => {
    loadOptions(inputValue2, { initial: true });
  }, debounceMs);
  const {
    isOpen,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getInputProps,
    wrapperDivRef,
    highlightedIndex,
    getItemProps,
    inputValue,
    items,
    sectionsMeta,
    closeMenu,
    toggleMenu
  } = useComboMultiple({
    displayAs,
    onSelectedOptionsChange,
    disabled: isDisabledOrReadOnly,
    options,
    loading,
    pinned,
    virtualize,
    groupToString,
    groupSorter,
    selectedOptions,
    selectAll,
    selectFiltered,
    bulkPending,
    onBulkActivate,
    async onIsOpenChange(changes) {
      if (initialLoad === "open" && !initialLoadPerformed && changes.isOpen) {
        await loadOptions("", { initial: true });
        setInitialLoadPerformed(true);
      }
    },
    onInputValueChange: ({ inputValue: iv }) => {
      debouncedOptionLoader(iv ?? "");
      onSearchChange?.(iv ?? "");
    },
    onScrollToHighlight: (i) => listRef.current?.scrollToIndex(i)
  });
  useEffect(() => {
    const performInitialLoad = async () => {
      if (initialLoad === "immediate" && !initialLoadPerformed) {
        await loadOptions("", { initial: true });
        setInitialLoadPerformed(true);
      }
    };
    performInitialLoad();
  }, [loadOptions, initialLoadPerformed, initialLoad, setInitialLoadPerformed]);
  const handleLoadMore = async () => {
    await loadMore(inputValue);
  };
  const addNewItemButton = shouldShowAddNewItem(
    onAddNewItem,
    addItemLabel,
    inputValue
  ) ? /* @__PURE__ */ jsx(
    AddNewItemButton,
    {
      searchText: inputValue,
      addItemLabel,
      onAddNewItem,
      onCloseMenu: closeMenu
    }
  ) : null;
  if (displayAs === "dialog") {
    return /* @__PURE__ */ jsxs(
      "div",
      {
        className: className ? `${styles$1["search-field"]} ${className}` : styles$1["search-field"],
        style: { ...layoutStyles, ...style },
        ref: wrapperDivRef,
        children: [
          /* @__PURE__ */ jsx(
            SelectFieldLabel,
            {
              aiMark: labelAiMark,
              label,
              hideLabel,
              getLabelProps,
              required,
              moreInfo,
              moreInfoId
            }
          ),
          /* @__PURE__ */ jsx(
            MultiSelectFieldInput,
            {
              disabled,
              readOnly,
              isHighlighted,
              disableToggleButton: false,
              placeholder,
              disableClearButton,
              toggleButtonProps: getToggleButtonProps(),
              onClear: handleClear,
              id: `${id}-input`,
              inputProps: getInputProps({
                "aria-describedby": [hasHelperText && helperUid, moreInfo && moreInfoId].filter(Boolean).join(" ") || void 0,
                "aria-invalid": error ? true : void 0
              }),
              size,
              error: !!error,
              prefix,
              suffix,
              selectedOptions,
              onRemoveOption: handleRemoveOption,
              singleRow,
              maxChips,
              getChipProps,
              onWrapperClick: toggleMenu
            }
          ),
          hasHelperText ? /* @__PURE__ */ jsx(
            FieldMessage,
            {
              id: helperUid,
              hint,
              error: errorMessages,
              warning,
              description
            }
          ) : null,
          /* @__PURE__ */ jsx(
            OptionsDialog,
            {
              id: `${id}-dialog`,
              isOpen,
              onClose: closeMenu,
              title: label,
              initialFocusResolver: (elements) => {
                return elements.find((element) => element.tagName === "INPUT") || elements[0];
              },
              field: /* @__PURE__ */ jsx(
                MultiSelectFieldInput,
                {
                  disabled,
                  readOnly,
                  isHighlighted,
                  inputProps: getInputProps(),
                  disableToggleButton: true,
                  placeholder,
                  disableClearButton,
                  onClear: handleClear,
                  id: `${id}-dialog-input`,
                  inputWrapperRef,
                  size: "medium",
                  error: !!error,
                  prefix,
                  suffix,
                  selectedOptions,
                  onRemoveOption: handleRemoveOption,
                  singleRow: true,
                  maxChips: 20,
                  getChipProps
                }
              ),
              footer: addNewItemButton ?? void 0,
              children: /* @__PURE__ */ jsx(
                MultiSelectOptions,
                {
                  isOpen: true,
                  items,
                  getMenuProps,
                  ref: listRef,
                  getItemProps,
                  highlightedIndex,
                  selectedOptions,
                  hasMore,
                  onLoadMore: handleLoadMore,
                  loading,
                  loadingMore,
                  disabled: isDisabledOrReadOnly,
                  sectionsMeta,
                  virtualize
                }
              )
            }
          )
        ]
      }
    );
  }
  return /* @__PURE__ */ jsxs(
    "div",
    {
      className: className ? `${styles$1["search-field"]} ${className}` : styles$1["search-field"],
      style: { ...layoutStyles, ...style },
      children: [
        /* @__PURE__ */ jsx(
          SelectFieldLabel,
          {
            aiMark: labelAiMark,
            label,
            hideLabel,
            getLabelProps,
            required,
            moreInfo,
            moreInfoId
          }
        ),
        /* @__PURE__ */ jsx(
          MultiSelectFieldInput,
          {
            disabled,
            readOnly,
            isHighlighted,
            inputProps: getInputProps({
              popoverTarget: `${id}-popover`,
              "aria-describedby": [hasHelperText && helperUid, moreInfo && moreInfoId].filter(Boolean).join(" ") || void 0,
              "aria-invalid": error ? true : void 0
            }),
            toggleButtonProps: getToggleButtonProps(),
            disableToggleButton: false,
            placeholder,
            disableClearButton,
            onClear: handleClear,
            id: `${id}-input`,
            inputWrapperRef,
            size,
            error: !!error,
            prefix,
            suffix,
            selectedOptions,
            onRemoveOption: handleRemoveOption,
            singleRow,
            maxChips,
            getChipProps,
            onWrapperClick: toggleMenu
          }
        ),
        hasHelperText ? /* @__PURE__ */ jsx(
          FieldMessage,
          {
            id: helperUid,
            hint,
            error: errorMessages,
            warning,
            description
          }
        ) : null,
        /* @__PURE__ */ jsx(
          OptionsPopover,
          {
            id: `${id}-popover`,
            referenceElement: inputWrapperRef,
            open: isOpen && displayAs === "popover",
            onClose: closeMenu,
            width: "reference",
            footer: addNewItemButton ?? void 0,
            children: /* @__PURE__ */ jsx(
              MultiSelectOptions,
              {
                isOpen,
                items,
                getMenuProps,
                ref: listRef,
                getItemProps,
                highlightedIndex,
                selectedOptions,
                hasMore,
                onLoadMore: handleLoadMore,
                loading,
                loadingMore,
                disabled: isDisabledOrReadOnly,
                sectionsMeta,
                virtualize
              }
            )
          }
        )
      ]
    }
  );
};

const MultiSelectFieldTrigger = ({
  placeholder,
  size,
  disableClearButton,
  disabled,
  readOnly,
  isHighlighted,
  error,
  onClear,
  id,
  inputWrapperRef,
  toggleButtonProps,
  prefix,
  suffix,
  selectedOptions = [],
  onRemoveOption,
  singleRow,
  maxChips,
  getChipProps,
  popoverTarget
}) => {
  const { ref: downshiftRef, ...restToggleButtonProps } = toggleButtonProps ?? {};
  const triggerRef = useRef(null);
  const mergedRef = useMergeRefs([inputWrapperRef, downshiftRef, triggerRef]);
  const { rowsRef, displayCount, hiddenCount } = useChipLayout({
    selectedOptionsLength: selectedOptions.length,
    singleRow,
    maxChips
  });
  const inputWrapperClassNames = cx(styles["input-wrapper"], {
    [styles["small"]]: size === "small",
    [styles["large"]]: size === "large",
    [styles["no-clear-button"]]: disableClearButton,
    [styles["disabled"]]: disabled || readOnly,
    [styles["highlight"]]: isHighlighted
  });
  return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
    /* @__PURE__ */ jsxs(
      "div",
      {
        ref: mergedRef,
        ...restToggleButtonProps,
        popoverTarget,
        id,
        className: cx(inputWrapperClassNames, restToggleButtonProps?.className),
        children: [
          prefix ? /* @__PURE__ */ jsx("div", { className: styles["prefix"], children: prefix }) : null,
          /* @__PURE__ */ jsxs("div", { className: styles["rows-wrapper"], ref: rowsRef, children: [
            selectedOptions.length > 0 && onRemoveOption ? selectedOptions.slice(0, displayCount).map((option, index) => /* @__PURE__ */ jsx(
              "div",
              {
                className: styles["chip-wrapper"],
                children: /* @__PURE__ */ jsx(
                  Chip,
                  {
                    ...getChipProps?.(option),
                    label: option.label,
                    onClose: disabled || readOnly ? void 0 : (e) => {
                      e.stopPropagation();
                      onRemoveOption(option);
                      triggerRef.current?.focus();
                    },
                    className: styles["chip"],
                    title: option.label
                  }
                )
              },
              `selected-item-${option.id}-${index}`
            )) : null,
            hiddenCount > 0 ? /* @__PURE__ */ jsx("div", { className: styles["chip-wrapper"], children: /* @__PURE__ */ jsx(
              Chip,
              {
                label: `+${hiddenCount}`,
                className: styles["chip"],
                title: selectedOptions.slice(displayCount).map((option) => option.label).join(", ")
              }
            ) }) : null,
            selectedOptions.length === 0 ? /* @__PURE__ */ jsxs(Flex, { className: styles["input-flex"], alignItems: "center", children: [
              /* @__PURE__ */ jsx(
                "div",
                {
                  className: cx(styles["input"], {
                    [styles["error"]]: error
                  }),
                  children: placeholder
                }
              ),
              suffix ? /* @__PURE__ */ jsx("div", { className: styles["suffix"], children: suffix }) : null
            ] }) : null
          ] }),
          /* @__PURE__ */ jsx("div", { className: styles["buttons-wrapper"], children: /* @__PURE__ */ jsx("div", { className: styles["toggle-button-wrapper"], children: /* @__PURE__ */ jsx(
            Button,
            {
              icon: SvgChevronRight,
              "aria-label": "toggle menu",
              appearance: "ghost",
              size: "small",
              disabled,
              tabIndex: -1,
              className: styles["toggle-button"]
            }
          ) }) })
        ]
      }
    ),
    disableClearButton ? null : /* @__PURE__ */ jsx(
      "div",
      {
        className: styles["buttons-wrapper"],
        style: { insetInlineEnd: "2rem" },
        children: /* @__PURE__ */ jsx("div", { className: styles["close-button-wrapper"], children: /* @__PURE__ */ jsx(
          Button,
          {
            icon: SvgClose,
            "aria-label": "clear selection",
            appearance: "ghost",
            size: "small",
            className: styles["close-button"],
            onClick: (e) => {
              e.stopPropagation();
              onClear?.();
            }
          }
        ) })
      }
    )
  ] });
};
MultiSelectFieldTrigger.displayName = "MultiSelectFieldTrigger";

const useSelectModeMultiple = ({
  options,
  pinned,
  groupToString,
  groupSorter,
  selectAll,
  bulkPending,
  onBulkActivate,
  selectedOptions,
  onSelectedOptionsChange,
  onIsOpenChange,
  displayAs = "popover",
  disabled,
  virtualize = false,
  onScrollToHighlight
}) => {
  const { pinnedSections, ungroupedItems, groupSections } = useProcessedOptions(
    {
      options,
      pinned,
      searchValue: "",
      groupToString,
      groupSorter
    }
  );
  const bulkActionItems = useMemo(() => {
    const items2 = [];
    if (selectAll) {
      items2.push({
        id: "select-all",
        type: "select-all",
        original: {
          id: "select-all",
          label: selectAll.label ?? "Select All"
        },
        checkState: selectAll.checkState
      });
    }
    return items2;
  }, [selectAll]);
  const { items, sectionsMeta } = useMemo(
    () => buildSelectItems({
      prefixItems: bulkActionItems,
      pinnedSections,
      groupSections,
      ungroupedItems
    }),
    [bulkActionItems, pinnedSections, groupSections, ungroupedItems]
  );
  const { ref: wrapperDivRef, environment } = useDownshiftEnvironment();
  const { handleItemClick } = useToggleSelection({
    options,
    pinnedSections,
    selectedOptions,
    onSelectedOptionsChange
  });
  const {
    isOpen,
    highlightedIndex,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getItemProps,
    closeMenu,
    openMenu
  } = useSelect({
    isItemDisabled: (item) => {
      if (!item) return false;
      if (bulkPending) return true;
      return (disabled || item.disabled) ?? false;
    },
    environment,
    selectedItem: null,
    onSelectedItemChange: ({
      selectedItem: si
    }) => {
      if (si) {
        if (si.type === "select-all") {
          onBulkActivate("selectAll", "");
        } else if (si.type === "option" || si.type === "pinned-option" || si.type === "grouped-option") {
          handleItemClick(si.original);
        }
      }
    },
    onHighlightedIndexChange: ({ type, highlightedIndex: idx }) => {
      if (type !== useSelect.stateChangeTypes.ItemMouseMove && idx >= 0) {
        onScrollToHighlight?.(idx);
      }
    },
    onIsOpenChange,
    items,
    itemToString(item) {
      return item?.original.label ?? "";
    },
    stateReducer: (state, actionAndChanges) => stateReducer(state, actionAndChanges, displayAs),
    ...virtualize && { scrollIntoView: () => {
    } }
  });
  return {
    wrapperDivRef,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getItemProps,
    highlightedIndex,
    isOpen,
    items,
    sectionsMeta,
    closeMenu,
    openMenu,
    toggleMenu: () => isOpen ? closeMenu() : openMenu(),
    selectedOptions
  };
};
function stateReducer(state, actionAndChanges, displayAs) {
  const { type, changes } = actionAndChanges;
  switch (type) {
    case useSelect.stateChangeTypes.ToggleButtonBlur:
      if (displayAs === "dialog" && state.isOpen) {
        return { ...changes, isOpen: state.isOpen, selectedItem: null };
      }
      return { ...changes, selectedItem: null };
    case useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
    case useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
    case useSelect.stateChangeTypes.ItemClick:
      return {
        ...changes,
        isOpen: state.isOpen,
        highlightedIndex: state.highlightedIndex
      };
    case useSelect.stateChangeTypes.ToggleButtonKeyDownEscape:
    case useSelect.stateChangeTypes.FunctionCloseMenu:
      return changes;
    case useSelect.stateChangeTypes.ToggleButtonClick:
      if (displayAs === "dialog" && state.isOpen) {
        return { ...changes, isOpen: state.isOpen };
      }
      return changes;
    default:
      return changes;
  }
}

const MultiSelectFieldSelectMode = ({
  labelAiMark,
  id,
  helperUid,
  selectedOptions,
  onSelectedOptionsChange,
  displayAs,
  isDisabledOrReadOnly,
  disabled,
  readOnly,
  isHighlighted,
  required,
  placeholder,
  size,
  error,
  hasHelperText,
  disableClearButton,
  prefix,
  suffix,
  label,
  hideLabel,
  hint,
  moreInfo,
  moreInfoId,
  errorMessages,
  warning,
  description,
  className,
  style,
  layoutStyles,
  pinned,
  groupToString,
  groupSorter,
  virtualize,
  options,
  loading,
  loadingMore,
  hasMore,
  loadOptions,
  loadMore,
  initialLoad,
  initialLoadPerformed,
  setInitialLoadPerformed,
  inputWrapperRef,
  selectAll,
  bulkPending,
  onBulkActivate,
  singleRow,
  maxChips,
  getChipProps,
  addItemLabel,
  onAddNewItem,
  handleRemoveOption,
  handleClear
}) => {
  const listRef = useRef(null);
  const {
    isOpen,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    wrapperDivRef,
    highlightedIndex,
    getItemProps,
    items,
    sectionsMeta,
    closeMenu
  } = useSelectModeMultiple({
    displayAs,
    onSelectedOptionsChange,
    disabled: isDisabledOrReadOnly,
    options,
    pinned,
    virtualize,
    groupToString,
    groupSorter,
    selectedOptions,
    selectAll,
    bulkPending,
    onBulkActivate,
    async onIsOpenChange(changes) {
      if (initialLoad === "open" && !initialLoadPerformed && changes.isOpen) {
        await loadOptions("", { initial: true });
        setInitialLoadPerformed(true);
      }
    },
    onScrollToHighlight: (i) => listRef.current?.scrollToIndex(i)
  });
  useEffect(() => {
    const performInitialLoad = async () => {
      if (initialLoad === "immediate" && !initialLoadPerformed) {
        await loadOptions("", { initial: true });
        setInitialLoadPerformed(true);
      }
    };
    performInitialLoad();
  }, [loadOptions, initialLoadPerformed, initialLoad, setInitialLoadPerformed]);
  const handleLoadMore = async () => {
    await loadMore("");
  };
  const addNewItemButton = shouldShowAddNewItem(
    onAddNewItem,
    addItemLabel,
    ""
  ) ? /* @__PURE__ */ jsx(
    AddNewItemButton,
    {
      searchText: "",
      addItemLabel,
      onAddNewItem,
      onCloseMenu: closeMenu
    }
  ) : null;
  const toggleButtonProps = getToggleButtonProps({
    disabled: !!disabled,
    "aria-required": required ? true : void 0,
    "aria-describedby": [hasHelperText && helperUid, moreInfo && moreInfoId].filter(Boolean).join(" ") || void 0,
    "aria-invalid": error ? true : void 0
  });
  if (displayAs === "dialog") {
    return /* @__PURE__ */ jsxs(
      "div",
      {
        className: className ? `${styles$1["search-field"]} ${className}` : styles$1["search-field"],
        style: { ...layoutStyles, ...style },
        ref: wrapperDivRef,
        children: [
          /* @__PURE__ */ jsx(
            SelectFieldLabel,
            {
              aiMark: labelAiMark,
              label,
              hideLabel,
              getLabelProps,
              required,
              moreInfo,
              moreInfoId
            }
          ),
          /* @__PURE__ */ jsx(
            MultiSelectFieldTrigger,
            {
              disabled,
              readOnly,
              isHighlighted,
              placeholder,
              disableClearButton,
              toggleButtonProps,
              onClear: handleClear,
              id: `${id}-trigger`,
              inputWrapperRef,
              size,
              error: !!error,
              prefix,
              suffix,
              selectedOptions,
              onRemoveOption: handleRemoveOption,
              singleRow,
              maxChips,
              getChipProps
            }
          ),
          hasHelperText ? /* @__PURE__ */ jsx(
            FieldMessage,
            {
              id: helperUid,
              hint,
              error: errorMessages,
              warning,
              description
            }
          ) : null,
          /* @__PURE__ */ jsx(
            OptionsDialog,
            {
              id: `${id}-dialog`,
              isOpen,
              onClose: closeMenu,
              title: label,
              footer: addNewItemButton ?? void 0,
              children: /* @__PURE__ */ jsx(
                MultiSelectOptions,
                {
                  ref: listRef,
                  isOpen: true,
                  items,
                  getMenuProps: (opts) => getMenuProps({
                    ...opts,
                    style: { ...opts?.style, outline: "none" },
                    onKeyDown: toggleButtonProps.onKeyDown,
                    tabIndex: 0,
                    "aria-activedescendant": toggleButtonProps["aria-activedescendant"]
                  }),
                  getItemProps,
                  highlightedIndex,
                  selectedOptions,
                  hasMore,
                  onLoadMore: handleLoadMore,
                  loading,
                  loadingMore,
                  disabled: isDisabledOrReadOnly,
                  sectionsMeta,
                  virtualize
                }
              )
            }
          )
        ]
      }
    );
  }
  return /* @__PURE__ */ jsxs(
    "div",
    {
      className: className ? `${styles$1["search-field"]} ${className}` : styles$1["search-field"],
      style: { ...layoutStyles, ...style },
      children: [
        /* @__PURE__ */ jsx(
          SelectFieldLabel,
          {
            aiMark: labelAiMark,
            label,
            hideLabel,
            getLabelProps,
            required,
            moreInfo,
            moreInfoId
          }
        ),
        /* @__PURE__ */ jsx(
          MultiSelectFieldTrigger,
          {
            disabled,
            readOnly,
            isHighlighted,
            placeholder,
            disableClearButton,
            toggleButtonProps,
            onClear: handleClear,
            id: `${id}-trigger`,
            popoverTarget: `${id}-popover`,
            inputWrapperRef,
            size,
            error: !!error,
            prefix,
            suffix,
            selectedOptions,
            onRemoveOption: handleRemoveOption,
            singleRow,
            maxChips,
            getChipProps
          }
        ),
        hasHelperText ? /* @__PURE__ */ jsx(
          FieldMessage,
          {
            id: helperUid,
            hint,
            error: errorMessages,
            warning,
            description
          }
        ) : null,
        /* @__PURE__ */ jsx(
          OptionsPopover,
          {
            id: `${id}-popover`,
            referenceElement: inputWrapperRef,
            open: isOpen && displayAs === "popover",
            onClose: closeMenu,
            width: "reference",
            footer: addNewItemButton ?? void 0,
            children: /* @__PURE__ */ jsx(
              MultiSelectOptions,
              {
                ref: listRef,
                isOpen,
                items,
                getMenuProps,
                getItemProps,
                highlightedIndex,
                selectedOptions,
                hasMore,
                onLoadMore: handleLoadMore,
                loading,
                loadingMore,
                disabled: isDisabledOrReadOnly,
                sectionsMeta,
                virtualize
              }
            )
          }
        )
      ]
    }
  );
};

const MultiSelectField = forwardRef((propsWithLayout, ref) => {
  const { layoutStyles, componentProps } = useLayoutPropsUtil(propsWithLayout);
  const inputWrapperRef = useRef(null);
  const {
    id: idProp,
    value: selectedOptions,
    initialLoad: initialLoadProp,
    displayMenuAs: displayMenuAsProp,
    lazy,
    loadOptions: loadOptionsProp,
    label,
    hideLabel,
    placeholder,
    debounceMs = 200,
    onSelectedOptionsChange,
    cache,
    size,
    error,
    hint,
    moreInfo,
    description,
    required,
    labelAiMark,
    disabled,
    readOnly,
    isHighlighted,
    prefix,
    suffix,
    selectAll: selectAllProp,
    selectFiltered: selectFilteredProp,
    singleRow,
    maxChips,
    warning,
    pinned,
    onSearchChange,
    className,
    style,
    virtualize,
    disableSearch,
    getChipProps,
    addItemLabel,
    onAddNewItem
  } = componentProps;
  const groupToString = "groupToString" in componentProps ? componentProps.groupToString : void 0;
  const groupSorter = "groupSorter" in componentProps ? componentProps.groupSorter : void 0;
  const autoId = useId();
  const id = idProp ?? autoId;
  const helperUid = useId();
  const moreInfoUid = useId();
  warnDeprecatedErrorUsage("MultiSelectField", error);
  if (disableSearch && selectFilteredProp) {
    warnOnce(
      "MultiSelectField: `selectFiltered` has no effect when `disableSearch` is true because there is no search input to produce filtered results."
    );
  }
  const errorMessages = typeof error === "boolean" || error === void 0 ? void 0 : error;
  const hasHelperText = !!(hint || errorMessages || warning || description);
  const isDisabledOrReadOnly = (disabled || readOnly) ?? false;
  const {
    displayAs,
    initialLoad,
    initialLoadPerformed,
    setInitialLoadPerformed,
    options,
    loading,
    loadingMore,
    hasMore,
    loadOptions,
    loadMore
  } = useSelectOrchestration({
    lazy,
    loadOptions: loadOptionsProp,
    cache,
    lazyOptions: "lazyOptions" in componentProps ? componentProps.lazyOptions : void 0,
    initialLoad: initialLoadProp,
    displayMenuAs: displayMenuAsProp,
    ref
  });
  const handleRemoveOption = useCallback(
    (option) => {
      onSelectedOptionsChange(
        selectedOptions.filter((opt) => opt.id !== option.id)
      );
    },
    [selectedOptions, onSelectedOptionsChange]
  );
  const handleClear = useCallback(() => {
    onSelectedOptionsChange([]);
  }, [onSelectedOptionsChange]);
  const disableClearButton = selectedOptions.length === 0 || isDisabledOrReadOnly;
  const { pending: bulkPending, runBulk } = useBulkActionRunner({
    setDraft: onSelectedOptionsChange
  });
  const handleBulkActivate = useCallback(
    (kind, searchValue) => {
      const config = kind === "selectAll" ? selectAllProp : selectFilteredProp?.(searchValue);
      if (!config) return;
      if (config.compute) {
        runBulk(config.compute, selectedOptions);
      } else if (config.onClick) {
        config.onClick();
      }
    },
    [runBulk, selectedOptions, selectAllProp, selectFilteredProp]
  );
  const selectAll = selectAllProp ? {
    label: resolveBulkActionLabel(selectAllProp.label, selectedOptions),
    checkState: bulkPending ? "loading" : resolveBulkActionCheckState(
      selectAllProp.checkState,
      selectedOptions
    )
  } : void 0;
  const selectFiltered = selectFilteredProp ? (searchValue) => {
    const config = selectFilteredProp(searchValue);
    return {
      label: resolveBulkActionLabel(
        config.label,
        selectedOptions,
        `Select items matching "${searchValue}"`
      ),
      checkState: bulkPending ? "loading" : resolveBulkActionCheckState(config.checkState, selectedOptions)
    };
  } : void 0;
  const baseProps = {
    id,
    helperUid,
    selectedOptions,
    onSelectedOptionsChange,
    displayAs,
    isDisabledOrReadOnly,
    disabled,
    readOnly,
    isHighlighted,
    required,
    placeholder,
    size,
    error,
    hasHelperText,
    disableClearButton,
    prefix,
    suffix,
    label,
    hideLabel,
    hint,
    moreInfo,
    moreInfoId: moreInfo ? moreInfoUid : void 0,
    labelAiMark,
    errorMessages,
    warning,
    description,
    className,
    style,
    layoutStyles,
    pinned,
    groupToString,
    groupSorter,
    virtualize,
    options,
    loading,
    loadingMore,
    hasMore,
    loadOptions,
    loadMore,
    initialLoad,
    initialLoadPerformed,
    setInitialLoadPerformed,
    inputWrapperRef,
    selectAll,
    bulkPending,
    onBulkActivate: handleBulkActivate,
    singleRow,
    maxChips,
    getChipProps,
    addItemLabel,
    onAddNewItem,
    handleRemoveOption,
    handleClear
  };
  if (disableSearch) {
    return /* @__PURE__ */ jsx(MultiSelectFieldSelectMode, { ...baseProps });
  }
  const comboboxProps = {
    ...baseProps,
    debounceMs,
    selectFiltered,
    onSearchChange
  };
  return /* @__PURE__ */ jsx(MultiSelectFieldComboboxMode, { ...comboboxProps });
});
MultiSelectField.displayName = "MultiSelectField";

const getEnabledSelectionStats = (options, current) => {
  const enabledOptions = options.filter((opt) => !opt.disabled);
  const enabledIds = new Set(enabledOptions.map((opt) => opt.id));
  const selectedCount = current.filter((v) => enabledIds.has(v.id)).length;
  const totalCount = enabledOptions.length;
  const allSelected = totalCount > 0 && selectedCount === totalCount;
  return { enabledOptions, enabledIds, selectedCount, allSelected };
};
const MultiSelectFieldSync = (props) => {
  const {
    options,
    filter: filterProp = defaultSyncFilter,
    selectAll: selectAllProp,
    selectFiltered: selectFilteredProp,
    value,
    onSelectedOptionsChange,
    ...rest
  } = props;
  const filter = useMemo(() => toSyncFilterFn(filterProp), [filterProp]);
  const selectAllConfig = useMemo(() => {
    if (!selectAllProp) return void 0;
    const labelProp = typeof selectAllProp === "object" ? selectAllProp.label : void 0;
    const checkState = (current) => {
      const { selectedCount, allSelected } = getEnabledSelectionStats(
        options,
        current
      );
      return allSelected ? "checked" : selectedCount > 0 ? "indeterminate" : "unchecked";
    };
    const label = typeof labelProp === "function" ? (current) => labelProp(getEnabledSelectionStats(options, current).allSelected) : labelProp;
    const handleClick = () => {
      const { enabledOptions, allSelected } = getEnabledSelectionStats(
        options,
        value
      );
      if (allSelected) {
        onSelectedOptionsChange([]);
      } else {
        onSelectedOptionsChange(enabledOptions);
      }
    };
    return {
      label,
      onClick: handleClick,
      checkState
    };
  }, [selectAllProp, options, value, onSelectedOptionsChange]);
  const selectFilteredConfig = useMemo(() => {
    if (!selectFilteredProp) return void 0;
    return (searchValue) => {
      const filteredOptions = filter(options, searchValue);
      const enabledFilteredOptions = filteredOptions.filter(
        (opt) => !opt.disabled
      );
      const enabledFilteredIds = new Set(
        enabledFilteredOptions.map((o) => o.id)
      );
      const label = (typeof selectFilteredProp === "function" ? selectFilteredProp(searchValue).label : void 0) ?? `Select items matching "${searchValue}"`;
      const checkState = (current) => {
        const currentIds = new Set(current.map((v) => v.id));
        const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((opt) => currentIds.has(opt.id));
        const someFilteredSelected = enabledFilteredOptions.some(
          (opt) => currentIds.has(opt.id)
        );
        return allFilteredSelected ? "checked" : someFilteredSelected ? "indeterminate" : "unchecked";
      };
      const handleClick = () => {
        const { allSelected: allFilteredSelected } = getEnabledSelectionStats(
          enabledFilteredOptions,
          value
        );
        if (allFilteredSelected) {
          onSelectedOptionsChange(
            value.filter((v) => !enabledFilteredIds.has(v.id))
          );
        } else {
          const currentIds = new Set(value.map((v) => v.id));
          const newSelections = enabledFilteredOptions.filter(
            (opt) => !currentIds.has(opt.id)
          );
          onSelectedOptionsChange([...value, ...newSelections]);
        }
      };
      return {
        label,
        onClick: handleClick,
        checkState
      };
    };
  }, [selectFilteredProp, options, value, onSelectedOptionsChange, filter]);
  const fieldRef = useRef(null);
  const prevOptionsRef = useRef(options);
  useEffect(() => {
    if (prevOptionsRef.current !== options) {
      prevOptionsRef.current = options;
      fieldRef.current?.invalidate();
    }
  }, [options]);
  return /* @__PURE__ */ jsx(
    MultiSelectField,
    {
      ref: fieldRef,
      lazy: false,
      loadOptions: (searchValue) => filter(options, searchValue),
      debounceMs: 0,
      value,
      onSelectedOptionsChange,
      selectAll: selectAllConfig,
      selectFiltered: selectFilteredConfig,
      ...rest
    }
  );
};

export { MultiSelectField as M, MultiSelectFieldSync as a };
//# sourceMappingURL=MultiSelectFieldSync-B1tkEtft.js.map
