@huin-core/react-collection 1.0.2 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.mts +34 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +72 -0
- package/dist/index.mjs.map +7 -0
- package/package.json +3 -2
package/dist/index.d.mts
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import React__default from 'react';
|
3
|
+
import { Slot } from '@huin-core/react-slot';
|
4
|
+
|
5
|
+
type Scope<C = any> = {
|
6
|
+
[scopeName: string]: React.Context<C>[];
|
7
|
+
} | undefined;
|
8
|
+
type ScopeHook = (scope: Scope) => {
|
9
|
+
[__scopeProp: string]: Scope;
|
10
|
+
};
|
11
|
+
interface CreateScope {
|
12
|
+
scopeName: string;
|
13
|
+
(): ScopeHook;
|
14
|
+
}
|
15
|
+
|
16
|
+
type SlotProps = React__default.ComponentPropsWithoutRef<typeof Slot>;
|
17
|
+
interface CollectionProps extends SlotProps {
|
18
|
+
scope: any;
|
19
|
+
}
|
20
|
+
declare function createCollection<ItemElement extends HTMLElement, ItemData = {}>(name: string): readonly [{
|
21
|
+
readonly Provider: React__default.FC<{
|
22
|
+
children?: React__default.ReactNode;
|
23
|
+
scope: any;
|
24
|
+
}>;
|
25
|
+
readonly Slot: React__default.ForwardRefExoticComponent<CollectionProps & React__default.RefAttributes<HTMLElement>>;
|
26
|
+
readonly ItemSlot: React__default.ForwardRefExoticComponent<React__default.PropsWithoutRef<ItemData & {
|
27
|
+
children: React__default.ReactNode;
|
28
|
+
scope: any;
|
29
|
+
}> & React__default.RefAttributes<ItemElement>>;
|
30
|
+
}, (scope: any) => () => ({
|
31
|
+
ref: React__default.RefObject<ItemElement>;
|
32
|
+
} & ItemData)[], CreateScope];
|
33
|
+
|
34
|
+
export { type CollectionProps, createCollection };
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import React__default from 'react';
|
3
|
+
import { Slot } from '@huin-core/react-slot';
|
4
|
+
|
5
|
+
type Scope<C = any> = {
|
6
|
+
[scopeName: string]: React.Context<C>[];
|
7
|
+
} | undefined;
|
8
|
+
type ScopeHook = (scope: Scope) => {
|
9
|
+
[__scopeProp: string]: Scope;
|
10
|
+
};
|
11
|
+
interface CreateScope {
|
12
|
+
scopeName: string;
|
13
|
+
(): ScopeHook;
|
14
|
+
}
|
15
|
+
|
16
|
+
type SlotProps = React__default.ComponentPropsWithoutRef<typeof Slot>;
|
17
|
+
interface CollectionProps extends SlotProps {
|
18
|
+
scope: any;
|
19
|
+
}
|
20
|
+
declare function createCollection<ItemElement extends HTMLElement, ItemData = {}>(name: string): readonly [{
|
21
|
+
readonly Provider: React__default.FC<{
|
22
|
+
children?: React__default.ReactNode;
|
23
|
+
scope: any;
|
24
|
+
}>;
|
25
|
+
readonly Slot: React__default.ForwardRefExoticComponent<CollectionProps & React__default.RefAttributes<HTMLElement>>;
|
26
|
+
readonly ItemSlot: React__default.ForwardRefExoticComponent<React__default.PropsWithoutRef<ItemData & {
|
27
|
+
children: React__default.ReactNode;
|
28
|
+
scope: any;
|
29
|
+
}> & React__default.RefAttributes<ItemElement>>;
|
30
|
+
}, (scope: any) => () => ({
|
31
|
+
ref: React__default.RefObject<ItemElement>;
|
32
|
+
} & ItemData)[], CreateScope];
|
33
|
+
|
34
|
+
export { type CollectionProps, createCollection };
|
package/dist/index.js
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
"use strict";
|
2
|
+
"use client";
|
3
|
+
var __create = Object.create;
|
4
|
+
var __defProp = Object.defineProperty;
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
9
|
+
var __export = (target, all) => {
|
10
|
+
for (var name in all)
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
12
|
+
};
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
15
|
+
for (let key of __getOwnPropNames(from))
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
18
|
+
}
|
19
|
+
return to;
|
20
|
+
};
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
27
|
+
mod
|
28
|
+
));
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
30
|
+
|
31
|
+
// packages/react/collection/src/index.ts
|
32
|
+
var src_exports = {};
|
33
|
+
__export(src_exports, {
|
34
|
+
createCollection: () => createCollection
|
35
|
+
});
|
36
|
+
module.exports = __toCommonJS(src_exports);
|
37
|
+
|
38
|
+
// packages/react/collection/src/Collection.tsx
|
39
|
+
var import_react = __toESM(require("react"));
|
40
|
+
var import_react_context = require("@huin-core/react-context");
|
41
|
+
var import_react_compose_refs = require("@huin-core/react-compose-refs");
|
42
|
+
var import_react_slot = require("@huin-core/react-slot");
|
43
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
44
|
+
function createCollection(name) {
|
45
|
+
const PROVIDER_NAME = name + "CollectionProvider";
|
46
|
+
const [createCollectionContext, createCollectionScope] = (0, import_react_context.createContextScope)(PROVIDER_NAME);
|
47
|
+
const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
|
48
|
+
PROVIDER_NAME,
|
49
|
+
{ collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
|
50
|
+
);
|
51
|
+
const CollectionProvider = (props) => {
|
52
|
+
const { scope, children } = props;
|
53
|
+
const ref = import_react.default.useRef(null);
|
54
|
+
const itemMap = import_react.default.useRef(/* @__PURE__ */ new Map()).current;
|
55
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
|
56
|
+
};
|
57
|
+
CollectionProvider.displayName = PROVIDER_NAME;
|
58
|
+
const COLLECTION_SLOT_NAME = name + "CollectionSlot";
|
59
|
+
const CollectionSlot = import_react.default.forwardRef(
|
60
|
+
(props, forwardedRef) => {
|
61
|
+
const { scope, children } = props;
|
62
|
+
const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
|
63
|
+
const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, context.collectionRef);
|
64
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_slot.Slot, { ref: composedRefs, children });
|
65
|
+
}
|
66
|
+
);
|
67
|
+
CollectionSlot.displayName = COLLECTION_SLOT_NAME;
|
68
|
+
const ITEM_SLOT_NAME = name + "CollectionItemSlot";
|
69
|
+
const ITEM_DATA_ATTR = "data-huin-core-collection-item";
|
70
|
+
const CollectionItemSlot = import_react.default.forwardRef(
|
71
|
+
(props, forwardedRef) => {
|
72
|
+
const { scope, children, ...itemData } = props;
|
73
|
+
const ref = import_react.default.useRef(null);
|
74
|
+
const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref);
|
75
|
+
const context = useCollectionContext(ITEM_SLOT_NAME, scope);
|
76
|
+
import_react.default.useEffect(() => {
|
77
|
+
context.itemMap.set(ref, { ref, ...itemData });
|
78
|
+
return () => void context.itemMap.delete(ref);
|
79
|
+
});
|
80
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_slot.Slot, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
|
81
|
+
}
|
82
|
+
);
|
83
|
+
CollectionItemSlot.displayName = ITEM_SLOT_NAME;
|
84
|
+
function useCollection(scope) {
|
85
|
+
const context = useCollectionContext(name + "CollectionConsumer", scope);
|
86
|
+
const getItems = import_react.default.useCallback(() => {
|
87
|
+
const collectionNode = context.collectionRef.current;
|
88
|
+
if (!collectionNode) return [];
|
89
|
+
const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
|
90
|
+
const items = Array.from(context.itemMap.values());
|
91
|
+
const orderedItems = items.sort(
|
92
|
+
(a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
|
93
|
+
);
|
94
|
+
return orderedItems;
|
95
|
+
}, [context.collectionRef, context.itemMap]);
|
96
|
+
return getItems;
|
97
|
+
}
|
98
|
+
return [
|
99
|
+
{ Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
|
100
|
+
useCollection,
|
101
|
+
createCollectionScope
|
102
|
+
];
|
103
|
+
}
|
104
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../src/index.ts", "../src/Collection.tsx"],
|
4
|
+
"sourcesContent": ["'use client';\nexport { createCollection } from './Collection';\nexport type { CollectionProps } from './Collection';\n", "import React from 'react';\nimport { createContextScope } from '@huin-core/react-context';\nimport { useComposedRefs } from '@huin-core/react-compose-refs';\nimport { Slot } from '@huin-core/react-slot';\n\ntype SlotProps = React.ComponentPropsWithoutRef<typeof Slot>;\ntype CollectionElement = HTMLElement;\ninterface CollectionProps extends SlotProps {\n scope: any;\n}\n\n// We have resorted to returning slots directly rather than exposing primitives that can then\n// be slotted like `<CollectionItem as={Slot}>\u2026</CollectionItem>`.\n// This is because we encountered issues with generic types that cannot be statically analysed\n// due to creating them dynamically via createCollection.\n\nfunction createCollection<ItemElement extends HTMLElement, ItemData = {}>(name: string) {\n /* -----------------------------------------------------------------------------------------------\n * CollectionProvider\n * ---------------------------------------------------------------------------------------------*/\n\n const PROVIDER_NAME = name + 'CollectionProvider';\n const [createCollectionContext, createCollectionScope] = createContextScope(PROVIDER_NAME);\n\n type ContextValue = {\n collectionRef: React.RefObject<CollectionElement>;\n itemMap: Map<React.RefObject<ItemElement>, { ref: React.RefObject<ItemElement> } & ItemData>;\n };\n\n const [CollectionProviderImpl, useCollectionContext] = createCollectionContext<ContextValue>(\n PROVIDER_NAME,\n { collectionRef: { current: null }, itemMap: new Map() }\n );\n\n const CollectionProvider: React.FC<{ children?: React.ReactNode; scope: any }> = (props) => {\n const { scope, children } = props;\n const ref = React.useRef<CollectionElement>(null);\n const itemMap = React.useRef<ContextValue['itemMap']>(new Map()).current;\n return (\n <CollectionProviderImpl scope={scope} itemMap={itemMap} collectionRef={ref}>\n {children}\n </CollectionProviderImpl>\n );\n };\n\n CollectionProvider.displayName = PROVIDER_NAME;\n\n /* -----------------------------------------------------------------------------------------------\n * CollectionSlot\n * ---------------------------------------------------------------------------------------------*/\n\n const COLLECTION_SLOT_NAME = name + 'CollectionSlot';\n\n const CollectionSlot = React.forwardRef<CollectionElement, CollectionProps>(\n (props, forwardedRef) => {\n const { scope, children } = props;\n const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);\n const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);\n return <Slot ref={composedRefs}>{children}</Slot>;\n }\n );\n\n CollectionSlot.displayName = COLLECTION_SLOT_NAME;\n\n /* -----------------------------------------------------------------------------------------------\n * CollectionItem\n * ---------------------------------------------------------------------------------------------*/\n\n const ITEM_SLOT_NAME = name + 'CollectionItemSlot';\n const ITEM_DATA_ATTR = 'data-huin-core-collection-item';\n\n type CollectionItemSlotProps = ItemData & {\n children: React.ReactNode;\n scope: any;\n };\n\n const CollectionItemSlot = React.forwardRef<ItemElement, CollectionItemSlotProps>(\n (props, forwardedRef) => {\n const { scope, children, ...itemData } = props;\n const ref = React.useRef<ItemElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const context = useCollectionContext(ITEM_SLOT_NAME, scope);\n\n React.useEffect(() => {\n context.itemMap.set(ref, { ref, ...(itemData as unknown as ItemData) });\n return () => void context.itemMap.delete(ref);\n });\n\n return (\n <Slot {...{ [ITEM_DATA_ATTR]: '' }} ref={composedRefs}>\n {children}\n </Slot>\n );\n }\n );\n\n CollectionItemSlot.displayName = ITEM_SLOT_NAME;\n\n /* -----------------------------------------------------------------------------------------------\n * useCollection\n * ---------------------------------------------------------------------------------------------*/\n\n function useCollection(scope: any) {\n const context = useCollectionContext(name + 'CollectionConsumer', scope);\n\n const getItems = React.useCallback(() => {\n const collectionNode = context.collectionRef.current;\n if (!collectionNode) return [];\n const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));\n const items = Array.from(context.itemMap.values());\n const orderedItems = items.sort(\n (a, b) => orderedNodes.indexOf(a.ref.current!) - orderedNodes.indexOf(b.ref.current!)\n );\n return orderedItems;\n }, [context.collectionRef, context.itemMap]);\n\n return getItems;\n }\n\n return [\n { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },\n useCollection,\n createCollectionScope,\n ] as const;\n}\n\nexport { createCollection };\nexport type { CollectionProps };\n"],
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAkB;AAClB,2BAAmC;AACnC,gCAAgC;AAChC,wBAAqB;AAoCf;AAvBN,SAAS,iBAAiE,MAAc;AAKtF,QAAM,gBAAgB,OAAO;AAC7B,QAAM,CAAC,yBAAyB,qBAAqB,QAAI,yCAAmB,aAAa;AAOzF,QAAM,CAAC,wBAAwB,oBAAoB,IAAI;AAAA,IACrD;AAAA,IACA,EAAE,eAAe,EAAE,SAAS,KAAK,GAAG,SAAS,oBAAI,IAAI,EAAE;AAAA,EACzD;AAEA,QAAM,qBAA2E,CAAC,UAAU;AAC1F,UAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,UAAM,MAAM,aAAAA,QAAM,OAA0B,IAAI;AAChD,UAAM,UAAU,aAAAA,QAAM,OAAgC,oBAAI,IAAI,CAAC,EAAE;AACjE,WACE,4CAAC,0BAAuB,OAAc,SAAkB,eAAe,KACpE,UACH;AAAA,EAEJ;AAEA,qBAAmB,cAAc;AAMjC,QAAM,uBAAuB,OAAO;AAEpC,QAAM,iBAAiB,aAAAA,QAAM;AAAA,IAC3B,CAAC,OAAO,iBAAiB;AACvB,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,YAAM,UAAU,qBAAqB,sBAAsB,KAAK;AAChE,YAAM,mBAAe,2CAAgB,cAAc,QAAQ,aAAa;AACxE,aAAO,4CAAC,0BAAK,KAAK,cAAe,UAAS;AAAA,IAC5C;AAAA,EACF;AAEA,iBAAe,cAAc;AAM7B,QAAM,iBAAiB,OAAO;AAC9B,QAAM,iBAAiB;AAOvB,QAAM,qBAAqB,aAAAA,QAAM;AAAA,IAC/B,CAAC,OAAO,iBAAiB;AACvB,YAAM,EAAE,OAAO,UAAU,GAAG,SAAS,IAAI;AACzC,YAAM,MAAM,aAAAA,QAAM,OAAoB,IAAI;AAC1C,YAAM,mBAAe,2CAAgB,cAAc,GAAG;AACtD,YAAM,UAAU,qBAAqB,gBAAgB,KAAK;AAE1D,mBAAAA,QAAM,UAAU,MAAM;AACpB,gBAAQ,QAAQ,IAAI,KAAK,EAAE,KAAK,GAAI,SAAiC,CAAC;AACtE,eAAO,MAAM,KAAK,QAAQ,QAAQ,OAAO,GAAG;AAAA,MAC9C,CAAC;AAED,aACE,4CAAC,0BAAM,GAAG,EAAE,CAAC,cAAc,GAAG,GAAG,GAAG,KAAK,cACtC,UACH;AAAA,IAEJ;AAAA,EACF;AAEA,qBAAmB,cAAc;AAMjC,WAAS,cAAc,OAAY;AACjC,UAAM,UAAU,qBAAqB,OAAO,sBAAsB,KAAK;AAEvE,UAAM,WAAW,aAAAA,QAAM,YAAY,MAAM;AACvC,YAAM,iBAAiB,QAAQ,cAAc;AAC7C,UAAI,CAAC,eAAgB,QAAO,CAAC;AAC7B,YAAM,eAAe,MAAM,KAAK,eAAe,iBAAiB,IAAI,cAAc,GAAG,CAAC;AACtF,YAAM,QAAQ,MAAM,KAAK,QAAQ,QAAQ,OAAO,CAAC;AACjD,YAAM,eAAe,MAAM;AAAA,QACzB,CAAC,GAAG,MAAM,aAAa,QAAQ,EAAE,IAAI,OAAQ,IAAI,aAAa,QAAQ,EAAE,IAAI,OAAQ;AAAA,MACtF;AACA,aAAO;AAAA,IACT,GAAG,CAAC,QAAQ,eAAe,QAAQ,OAAO,CAAC;AAE3C,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,EAAE,UAAU,oBAAoB,MAAM,gBAAgB,UAAU,mBAAmB;AAAA,IACnF;AAAA,IACA;AAAA,EACF;AACF;",
|
6
|
+
"names": ["React"]
|
7
|
+
}
|
package/dist/index.mjs
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
// packages/react/collection/src/Collection.tsx
|
4
|
+
import React from "react";
|
5
|
+
import { createContextScope } from "@huin-core/react-context";
|
6
|
+
import { useComposedRefs } from "@huin-core/react-compose-refs";
|
7
|
+
import { Slot } from "@huin-core/react-slot";
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
9
|
+
function createCollection(name) {
|
10
|
+
const PROVIDER_NAME = name + "CollectionProvider";
|
11
|
+
const [createCollectionContext, createCollectionScope] = createContextScope(PROVIDER_NAME);
|
12
|
+
const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
|
13
|
+
PROVIDER_NAME,
|
14
|
+
{ collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
|
15
|
+
);
|
16
|
+
const CollectionProvider = (props) => {
|
17
|
+
const { scope, children } = props;
|
18
|
+
const ref = React.useRef(null);
|
19
|
+
const itemMap = React.useRef(/* @__PURE__ */ new Map()).current;
|
20
|
+
return /* @__PURE__ */ jsx(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
|
21
|
+
};
|
22
|
+
CollectionProvider.displayName = PROVIDER_NAME;
|
23
|
+
const COLLECTION_SLOT_NAME = name + "CollectionSlot";
|
24
|
+
const CollectionSlot = React.forwardRef(
|
25
|
+
(props, forwardedRef) => {
|
26
|
+
const { scope, children } = props;
|
27
|
+
const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
|
28
|
+
const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
|
29
|
+
return /* @__PURE__ */ jsx(Slot, { ref: composedRefs, children });
|
30
|
+
}
|
31
|
+
);
|
32
|
+
CollectionSlot.displayName = COLLECTION_SLOT_NAME;
|
33
|
+
const ITEM_SLOT_NAME = name + "CollectionItemSlot";
|
34
|
+
const ITEM_DATA_ATTR = "data-huin-core-collection-item";
|
35
|
+
const CollectionItemSlot = React.forwardRef(
|
36
|
+
(props, forwardedRef) => {
|
37
|
+
const { scope, children, ...itemData } = props;
|
38
|
+
const ref = React.useRef(null);
|
39
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
40
|
+
const context = useCollectionContext(ITEM_SLOT_NAME, scope);
|
41
|
+
React.useEffect(() => {
|
42
|
+
context.itemMap.set(ref, { ref, ...itemData });
|
43
|
+
return () => void context.itemMap.delete(ref);
|
44
|
+
});
|
45
|
+
return /* @__PURE__ */ jsx(Slot, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
|
46
|
+
}
|
47
|
+
);
|
48
|
+
CollectionItemSlot.displayName = ITEM_SLOT_NAME;
|
49
|
+
function useCollection(scope) {
|
50
|
+
const context = useCollectionContext(name + "CollectionConsumer", scope);
|
51
|
+
const getItems = React.useCallback(() => {
|
52
|
+
const collectionNode = context.collectionRef.current;
|
53
|
+
if (!collectionNode) return [];
|
54
|
+
const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
|
55
|
+
const items = Array.from(context.itemMap.values());
|
56
|
+
const orderedItems = items.sort(
|
57
|
+
(a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
|
58
|
+
);
|
59
|
+
return orderedItems;
|
60
|
+
}, [context.collectionRef, context.itemMap]);
|
61
|
+
return getItems;
|
62
|
+
}
|
63
|
+
return [
|
64
|
+
{ Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
|
65
|
+
useCollection,
|
66
|
+
createCollectionScope
|
67
|
+
];
|
68
|
+
}
|
69
|
+
export {
|
70
|
+
createCollection
|
71
|
+
};
|
72
|
+
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../src/Collection.tsx"],
|
4
|
+
"sourcesContent": ["import React from 'react';\nimport { createContextScope } from '@huin-core/react-context';\nimport { useComposedRefs } from '@huin-core/react-compose-refs';\nimport { Slot } from '@huin-core/react-slot';\n\ntype SlotProps = React.ComponentPropsWithoutRef<typeof Slot>;\ntype CollectionElement = HTMLElement;\ninterface CollectionProps extends SlotProps {\n scope: any;\n}\n\n// We have resorted to returning slots directly rather than exposing primitives that can then\n// be slotted like `<CollectionItem as={Slot}>\u2026</CollectionItem>`.\n// This is because we encountered issues with generic types that cannot be statically analysed\n// due to creating them dynamically via createCollection.\n\nfunction createCollection<ItemElement extends HTMLElement, ItemData = {}>(name: string) {\n /* -----------------------------------------------------------------------------------------------\n * CollectionProvider\n * ---------------------------------------------------------------------------------------------*/\n\n const PROVIDER_NAME = name + 'CollectionProvider';\n const [createCollectionContext, createCollectionScope] = createContextScope(PROVIDER_NAME);\n\n type ContextValue = {\n collectionRef: React.RefObject<CollectionElement>;\n itemMap: Map<React.RefObject<ItemElement>, { ref: React.RefObject<ItemElement> } & ItemData>;\n };\n\n const [CollectionProviderImpl, useCollectionContext] = createCollectionContext<ContextValue>(\n PROVIDER_NAME,\n { collectionRef: { current: null }, itemMap: new Map() }\n );\n\n const CollectionProvider: React.FC<{ children?: React.ReactNode; scope: any }> = (props) => {\n const { scope, children } = props;\n const ref = React.useRef<CollectionElement>(null);\n const itemMap = React.useRef<ContextValue['itemMap']>(new Map()).current;\n return (\n <CollectionProviderImpl scope={scope} itemMap={itemMap} collectionRef={ref}>\n {children}\n </CollectionProviderImpl>\n );\n };\n\n CollectionProvider.displayName = PROVIDER_NAME;\n\n /* -----------------------------------------------------------------------------------------------\n * CollectionSlot\n * ---------------------------------------------------------------------------------------------*/\n\n const COLLECTION_SLOT_NAME = name + 'CollectionSlot';\n\n const CollectionSlot = React.forwardRef<CollectionElement, CollectionProps>(\n (props, forwardedRef) => {\n const { scope, children } = props;\n const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);\n const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);\n return <Slot ref={composedRefs}>{children}</Slot>;\n }\n );\n\n CollectionSlot.displayName = COLLECTION_SLOT_NAME;\n\n /* -----------------------------------------------------------------------------------------------\n * CollectionItem\n * ---------------------------------------------------------------------------------------------*/\n\n const ITEM_SLOT_NAME = name + 'CollectionItemSlot';\n const ITEM_DATA_ATTR = 'data-huin-core-collection-item';\n\n type CollectionItemSlotProps = ItemData & {\n children: React.ReactNode;\n scope: any;\n };\n\n const CollectionItemSlot = React.forwardRef<ItemElement, CollectionItemSlotProps>(\n (props, forwardedRef) => {\n const { scope, children, ...itemData } = props;\n const ref = React.useRef<ItemElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const context = useCollectionContext(ITEM_SLOT_NAME, scope);\n\n React.useEffect(() => {\n context.itemMap.set(ref, { ref, ...(itemData as unknown as ItemData) });\n return () => void context.itemMap.delete(ref);\n });\n\n return (\n <Slot {...{ [ITEM_DATA_ATTR]: '' }} ref={composedRefs}>\n {children}\n </Slot>\n );\n }\n );\n\n CollectionItemSlot.displayName = ITEM_SLOT_NAME;\n\n /* -----------------------------------------------------------------------------------------------\n * useCollection\n * ---------------------------------------------------------------------------------------------*/\n\n function useCollection(scope: any) {\n const context = useCollectionContext(name + 'CollectionConsumer', scope);\n\n const getItems = React.useCallback(() => {\n const collectionNode = context.collectionRef.current;\n if (!collectionNode) return [];\n const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));\n const items = Array.from(context.itemMap.values());\n const orderedItems = items.sort(\n (a, b) => orderedNodes.indexOf(a.ref.current!) - orderedNodes.indexOf(b.ref.current!)\n );\n return orderedItems;\n }, [context.collectionRef, context.itemMap]);\n\n return getItems;\n }\n\n return [\n { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },\n useCollection,\n createCollectionScope,\n ] as const;\n}\n\nexport { createCollection };\nexport type { CollectionProps };\n"],
|
5
|
+
"mappings": ";;;AAAA,OAAO,WAAW;AAClB,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,YAAY;AAoCf;AAvBN,SAAS,iBAAiE,MAAc;AAKtF,QAAM,gBAAgB,OAAO;AAC7B,QAAM,CAAC,yBAAyB,qBAAqB,IAAI,mBAAmB,aAAa;AAOzF,QAAM,CAAC,wBAAwB,oBAAoB,IAAI;AAAA,IACrD;AAAA,IACA,EAAE,eAAe,EAAE,SAAS,KAAK,GAAG,SAAS,oBAAI,IAAI,EAAE;AAAA,EACzD;AAEA,QAAM,qBAA2E,CAAC,UAAU;AAC1F,UAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,UAAM,MAAM,MAAM,OAA0B,IAAI;AAChD,UAAM,UAAU,MAAM,OAAgC,oBAAI,IAAI,CAAC,EAAE;AACjE,WACE,oBAAC,0BAAuB,OAAc,SAAkB,eAAe,KACpE,UACH;AAAA,EAEJ;AAEA,qBAAmB,cAAc;AAMjC,QAAM,uBAAuB,OAAO;AAEpC,QAAM,iBAAiB,MAAM;AAAA,IAC3B,CAAC,OAAO,iBAAiB;AACvB,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,YAAM,UAAU,qBAAqB,sBAAsB,KAAK;AAChE,YAAM,eAAe,gBAAgB,cAAc,QAAQ,aAAa;AACxE,aAAO,oBAAC,QAAK,KAAK,cAAe,UAAS;AAAA,IAC5C;AAAA,EACF;AAEA,iBAAe,cAAc;AAM7B,QAAM,iBAAiB,OAAO;AAC9B,QAAM,iBAAiB;AAOvB,QAAM,qBAAqB,MAAM;AAAA,IAC/B,CAAC,OAAO,iBAAiB;AACvB,YAAM,EAAE,OAAO,UAAU,GAAG,SAAS,IAAI;AACzC,YAAM,MAAM,MAAM,OAAoB,IAAI;AAC1C,YAAM,eAAe,gBAAgB,cAAc,GAAG;AACtD,YAAM,UAAU,qBAAqB,gBAAgB,KAAK;AAE1D,YAAM,UAAU,MAAM;AACpB,gBAAQ,QAAQ,IAAI,KAAK,EAAE,KAAK,GAAI,SAAiC,CAAC;AACtE,eAAO,MAAM,KAAK,QAAQ,QAAQ,OAAO,GAAG;AAAA,MAC9C,CAAC;AAED,aACE,oBAAC,QAAM,GAAG,EAAE,CAAC,cAAc,GAAG,GAAG,GAAG,KAAK,cACtC,UACH;AAAA,IAEJ;AAAA,EACF;AAEA,qBAAmB,cAAc;AAMjC,WAAS,cAAc,OAAY;AACjC,UAAM,UAAU,qBAAqB,OAAO,sBAAsB,KAAK;AAEvE,UAAM,WAAW,MAAM,YAAY,MAAM;AACvC,YAAM,iBAAiB,QAAQ,cAAc;AAC7C,UAAI,CAAC,eAAgB,QAAO,CAAC;AAC7B,YAAM,eAAe,MAAM,KAAK,eAAe,iBAAiB,IAAI,cAAc,GAAG,CAAC;AACtF,YAAM,QAAQ,MAAM,KAAK,QAAQ,QAAQ,OAAO,CAAC;AACjD,YAAM,eAAe,MAAM;AAAA,QACzB,CAAC,GAAG,MAAM,aAAa,QAAQ,EAAE,IAAI,OAAQ,IAAI,aAAa,QAAQ,EAAE,IAAI,OAAQ;AAAA,MACtF;AACA,aAAO;AAAA,IACT,GAAG,CAAC,QAAQ,eAAe,QAAQ,OAAO,CAAC;AAE3C,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,EAAE,UAAU,oBAAoB,MAAM,gBAAgB,UAAU,mBAAmB;AAAA,IACnF;AAAA,IACA;AAAA,EACF;AACF;",
|
6
|
+
"names": []
|
7
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@huin-core/react-collection",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.4",
|
4
4
|
"license": "MIT",
|
5
5
|
"exports": {
|
6
6
|
".": {
|
@@ -20,7 +20,8 @@
|
|
20
20
|
"types": "./dist/index.d.ts",
|
21
21
|
"files": [
|
22
22
|
"dist",
|
23
|
-
"README.md"
|
23
|
+
"README.md",
|
24
|
+
"package.json"
|
24
25
|
],
|
25
26
|
"sideEffects": false,
|
26
27
|
"scripts": {
|