"use strict"; "use client"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { createCollection: () => createCollection, unstable_createCollection: () => createCollection2 }); module.exports = __toCommonJS(index_exports); // src/collection-legacy.tsx var import_react = __toESM(require("react")); var import_react_context = require("@radix-ui/react-context"); var import_react_compose_refs = require("@radix-ui/react-compose-refs"); var import_react_slot = require("@radix-ui/react-slot"); var import_jsx_runtime = require("react/jsx-runtime"); function createCollection(name) { const PROVIDER_NAME = name + "CollectionProvider"; const [createCollectionContext, createCollectionScope] = (0, import_react_context.createContextScope)(PROVIDER_NAME); const [CollectionProviderImpl, useCollectionContext] = createCollectionContext( PROVIDER_NAME, { collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() } ); const CollectionProvider = (props) => { const { scope, children } = props; const ref = import_react.default.useRef(null); const itemMap = import_react.default.useRef(/* @__PURE__ */ new Map()).current; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children }); }; CollectionProvider.displayName = PROVIDER_NAME; const COLLECTION_SLOT_NAME = name + "CollectionSlot"; const CollectionSlotImpl = (0, import_react_slot.createSlot)(COLLECTION_SLOT_NAME); const CollectionSlot = import_react.default.forwardRef( (props, forwardedRef) => { const { scope, children } = props; const context = useCollectionContext(COLLECTION_SLOT_NAME, scope); const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, context.collectionRef); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollectionSlotImpl, { ref: composedRefs, children }); } ); CollectionSlot.displayName = COLLECTION_SLOT_NAME; const ITEM_SLOT_NAME = name + "CollectionItemSlot"; const ITEM_DATA_ATTR = "data-radix-collection-item"; const CollectionItemSlotImpl = (0, import_react_slot.createSlot)(ITEM_SLOT_NAME); const CollectionItemSlot = import_react.default.forwardRef( (props, forwardedRef) => { const { scope, children, ...itemData } = props; const ref = import_react.default.useRef(null); const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref); const context = useCollectionContext(ITEM_SLOT_NAME, scope); import_react.default.useEffect(() => { context.itemMap.set(ref, { ref, ...itemData }); return () => void context.itemMap.delete(ref); }); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children }); } ); CollectionItemSlot.displayName = ITEM_SLOT_NAME; function useCollection(scope) { const context = useCollectionContext(name + "CollectionConsumer", scope); const getItems = import_react.default.useCallback(() => { const collectionNode = context.collectionRef.current; if (!collectionNode) return []; const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`)); const items = Array.from(context.itemMap.values()); const orderedItems = items.sort( (a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current) ); return orderedItems; }, [context.collectionRef, context.itemMap]); return getItems; } return [ { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot }, useCollection, createCollectionScope ]; } // src/collection.tsx var import_react2 = __toESM(require("react")); var import_react_context2 = require("@radix-ui/react-context"); var import_react_compose_refs2 = require("@radix-ui/react-compose-refs"); var import_react_slot2 = require("@radix-ui/react-slot"); // src/ordered-dictionary.ts var __instanciated = /* @__PURE__ */ new WeakMap(); var OrderedDict = class _OrderedDict extends Map { #keys; constructor(entries) { super(entries); this.#keys = [...super.keys()]; __instanciated.set(this, true); } set(key, value) { if (__instanciated.get(this)) { if (this.has(key)) { this.#keys[this.#keys.indexOf(key)] = key; } else { this.#keys.push(key); } } super.set(key, value); return this; } insert(index, key, value) { const has = this.has(key); const length = this.#keys.length; const relativeIndex = toSafeInteger(index); let actualIndex = relativeIndex >= 0 ? relativeIndex : length + relativeIndex; const safeIndex = actualIndex < 0 || actualIndex >= length ? -1 : actualIndex; if (safeIndex === this.size || has && safeIndex === this.size - 1 || safeIndex === -1) { this.set(key, value); return this; } const size = this.size + (has ? 0 : 1); if (relativeIndex < 0) { actualIndex++; } const keys = [...this.#keys]; let nextValue; let shouldSkip = false; for (let i = actualIndex; i < size; i++) { if (actualIndex === i) { let nextKey = keys[i]; if (keys[i] === key) { nextKey = keys[i + 1]; } if (has) { this.delete(key); } nextValue = this.get(nextKey); this.set(key, value); } else { if (!shouldSkip && keys[i - 1] === key) { shouldSkip = true; } const currentKey = keys[shouldSkip ? i : i - 1]; const currentValue = nextValue; nextValue = this.get(currentKey); this.delete(currentKey); this.set(currentKey, currentValue); } } return this; } with(index, key, value) { const copy = new _OrderedDict(this); copy.insert(index, key, value); return copy; } before(key) { const index = this.#keys.indexOf(key) - 1; if (index < 0) { return void 0; } return this.entryAt(index); } /** * Sets a new key-value pair at the position before the given key. */ setBefore(key, newKey, value) { const index = this.#keys.indexOf(key); if (index === -1) { return this; } return this.insert(index, newKey, value); } after(key) { let index = this.#keys.indexOf(key); index = index === -1 || index === this.size - 1 ? -1 : index + 1; if (index === -1) { return void 0; } return this.entryAt(index); } /** * Sets a new key-value pair at the position after the given key. */ setAfter(key, newKey, value) { const index = this.#keys.indexOf(key); if (index === -1) { return this; } return this.insert(index + 1, newKey, value); } first() { return this.entryAt(0); } last() { return this.entryAt(-1); } clear() { this.#keys = []; return super.clear(); } delete(key) { const deleted = super.delete(key); if (deleted) { this.#keys.splice(this.#keys.indexOf(key), 1); } return deleted; } deleteAt(index) { const key = this.keyAt(index); if (key !== void 0) { return this.delete(key); } return false; } at(index) { const key = at(this.#keys, index); if (key !== void 0) { return this.get(key); } } entryAt(index) { const key = at(this.#keys, index); if (key !== void 0) { return [key, this.get(key)]; } } indexOf(key) { return this.#keys.indexOf(key); } keyAt(index) { return at(this.#keys, index); } from(key, offset) { const index = this.indexOf(key); if (index === -1) { return void 0; } let dest = index + offset; if (dest < 0) dest = 0; if (dest >= this.size) dest = this.size - 1; return this.at(dest); } keyFrom(key, offset) { const index = this.indexOf(key); if (index === -1) { return void 0; } let dest = index + offset; if (dest < 0) dest = 0; if (dest >= this.size) dest = this.size - 1; return this.keyAt(dest); } find(predicate, thisArg) { let index = 0; for (const entry of this) { if (Reflect.apply(predicate, thisArg, [entry, index, this])) { return entry; } index++; } return void 0; } findIndex(predicate, thisArg) { let index = 0; for (const entry of this) { if (Reflect.apply(predicate, thisArg, [entry, index, this])) { return index; } index++; } return -1; } filter(predicate, thisArg) { const entries = []; let index = 0; for (const entry of this) { if (Reflect.apply(predicate, thisArg, [entry, index, this])) { entries.push(entry); } index++; } return new _OrderedDict(entries); } map(callbackfn, thisArg) { const entries = []; let index = 0; for (const entry of this) { entries.push([entry[0], Reflect.apply(callbackfn, thisArg, [entry, index, this])]); index++; } return new _OrderedDict(entries); } reduce(...args) { const [callbackfn, initialValue] = args; let index = 0; let accumulator = initialValue ?? this.at(0); for (const entry of this) { if (index === 0 && args.length === 1) { accumulator = entry; } else { accumulator = Reflect.apply(callbackfn, this, [accumulator, entry, index, this]); } index++; } return accumulator; } reduceRight(...args) { const [callbackfn, initialValue] = args; let accumulator = initialValue ?? this.at(-1); for (let index = this.size - 1; index >= 0; index--) { const entry = this.at(index); if (index === this.size - 1 && args.length === 1) { accumulator = entry; } else { accumulator = Reflect.apply(callbackfn, this, [accumulator, entry, index, this]); } } return accumulator; } toSorted(compareFn) { const entries = [...this.entries()].sort(compareFn); return new _OrderedDict(entries); } toReversed() { const reversed = new _OrderedDict(); for (let index = this.size - 1; index >= 0; index--) { const key = this.keyAt(index); const element = this.get(key); reversed.set(key, element); } return reversed; } toSpliced(...args) { const entries = [...this.entries()]; entries.splice(...args); return new _OrderedDict(entries); } slice(start, end) { const result = new _OrderedDict(); let stop = this.size - 1; if (start === void 0) { return result; } if (start < 0) { start = start + this.size; } if (end !== void 0 && end > 0) { stop = end - 1; } for (let index = start; index <= stop; index++) { const key = this.keyAt(index); const element = this.get(key); result.set(key, element); } return result; } every(predicate, thisArg) { let index = 0; for (const entry of this) { if (!Reflect.apply(predicate, thisArg, [entry, index, this])) { return false; } index++; } return true; } some(predicate, thisArg) { let index = 0; for (const entry of this) { if (Reflect.apply(predicate, thisArg, [entry, index, this])) { return true; } index++; } return false; } }; function at(array, index) { if ("at" in Array.prototype) { return Array.prototype.at.call(array, index); } const actualIndex = toSafeIndex(array, index); return actualIndex === -1 ? void 0 : array[actualIndex]; } function toSafeIndex(array, index) { const length = array.length; const relativeIndex = toSafeInteger(index); const actualIndex = relativeIndex >= 0 ? relativeIndex : length + relativeIndex; return actualIndex < 0 || actualIndex >= length ? -1 : actualIndex; } function toSafeInteger(number) { return number !== number || number === 0 ? 0 : Math.trunc(number); } // src/collection.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); function createCollection2(name) { const PROVIDER_NAME = name + "CollectionProvider"; const [createCollectionContext, createCollectionScope] = (0, import_react_context2.createContextScope)(PROVIDER_NAME); const [CollectionContextProvider, useCollectionContext] = createCollectionContext( PROVIDER_NAME, { collectionElement: null, collectionRef: { current: null }, collectionRefObject: { current: null }, itemMap: new OrderedDict(), setItemMap: () => void 0 } ); const CollectionProvider = ({ state, ...props }) => { return state ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CollectionInit, { ...props }); }; CollectionProvider.displayName = PROVIDER_NAME; const CollectionInit = (props) => { const state = useInitCollection(); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CollectionProviderImpl, { ...props, state }); }; CollectionInit.displayName = PROVIDER_NAME + "Init"; const CollectionProviderImpl = (props) => { const { scope, children, state } = props; const ref = import_react2.default.useRef(null); const [collectionElement, setCollectionElement] = import_react2.default.useState( null ); const composeRefs = (0, import_react_compose_refs2.useComposedRefs)(ref, setCollectionElement); const [itemMap, setItemMap] = state; import_react2.default.useEffect(() => { if (!collectionElement) return; const observer = getChildListObserver(() => { }); observer.observe(collectionElement, { childList: true, subtree: true }); return () => { observer.disconnect(); }; }, [collectionElement]); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( CollectionContextProvider, { scope, itemMap, setItemMap, collectionRef: composeRefs, collectionRefObject: ref, collectionElement, children } ); }; CollectionProviderImpl.displayName = PROVIDER_NAME + "Impl"; const COLLECTION_SLOT_NAME = name + "CollectionSlot"; const CollectionSlotImpl = (0, import_react_slot2.createSlot)(COLLECTION_SLOT_NAME); const CollectionSlot = import_react2.default.forwardRef( (props, forwardedRef) => { const { scope, children } = props; const context = useCollectionContext(COLLECTION_SLOT_NAME, scope); const composedRefs = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, context.collectionRef); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CollectionSlotImpl, { ref: composedRefs, children }); } ); CollectionSlot.displayName = COLLECTION_SLOT_NAME; const ITEM_SLOT_NAME = name + "CollectionItemSlot"; const ITEM_DATA_ATTR = "data-radix-collection-item"; const CollectionItemSlotImpl = (0, import_react_slot2.createSlot)(ITEM_SLOT_NAME); const CollectionItemSlot = import_react2.default.forwardRef( (props, forwardedRef) => { const { scope, children, ...itemData } = props; const ref = import_react2.default.useRef(null); const [element, setElement] = import_react2.default.useState(null); const composedRefs = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, ref, setElement); const context = useCollectionContext(ITEM_SLOT_NAME, scope); const { setItemMap } = context; const itemDataRef = import_react2.default.useRef(itemData); if (!shallowEqual(itemDataRef.current, itemData)) { itemDataRef.current = itemData; } const memoizedItemData = itemDataRef.current; import_react2.default.useEffect(() => { const itemData2 = memoizedItemData; setItemMap((map) => { if (!element) { return map; } if (!map.has(element)) { map.set(element, { ...itemData2, element }); return map.toSorted(sortByDocumentPosition); } return map.set(element, { ...itemData2, element }).toSorted(sortByDocumentPosition); }); return () => { setItemMap((map) => { if (!element || !map.has(element)) { return map; } map.delete(element); return new OrderedDict(map); }); }; }, [element, memoizedItemData, setItemMap]); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children }); } ); CollectionItemSlot.displayName = ITEM_SLOT_NAME; function useInitCollection() { return import_react2.default.useState(new OrderedDict()); } function useCollection(scope) { const { itemMap } = useCollectionContext(name + "CollectionConsumer", scope); return itemMap; } const functions = { createCollectionScope, useCollection, useInitCollection }; return [ { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot }, functions ]; } function shallowEqual(a, b) { if (a === b) return true; if (typeof a !== "object" || typeof b !== "object") return false; if (a == null || b == null) return false; const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; for (const key of keysA) { if (!Object.prototype.hasOwnProperty.call(b, key)) return false; if (a[key] !== b[key]) return false; } return true; } function isElementPreceding(a, b) { return !!(b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING); } function sortByDocumentPosition(a, b) { return !a[1].element || !b[1].element ? 0 : isElementPreceding(a[1].element, b[1].element) ? -1 : 1; } function getChildListObserver(callback) { const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === "childList") { callback(); return; } } }); return observer; } //# sourceMappingURL=index.js.map