@navikt/ds-react
Version:
React components from the Norwegian Labour and Welfare Administration.
77 lines • 2.96 kB
JavaScript
/**
* https://github.com/chakra-ui/chakra-ui/tree/5ec0be610b5a69afba01a9c22365155c1b519136/packages/components/descendant
*/
import React, { useRef, useState } from "react";
import { createContext } from "../../create-context.js";
import { useClientLayoutEffect } from "../useClientLayoutEffect.js";
import { mergeRefs } from "../useMergeRefs.js";
import { DescendantsManager } from "./descendant.js";
import { cast } from "./utils.js";
/**
* Provides strongly typed versions of the context provider and hooks above.
*/
export function createDescendantContext() {
const [DescendantsContextProvider, useDescendantsContext] = createContext({
name: "DescendantsProvider",
errorMessage: "useDescendantsContext must be used within DescendantsProvider",
});
const ContextProvider = cast((props) => (React.createElement(DescendantsContextProvider, Object.assign({}, props.value), props.children)));
/**
* @internal
* This hook provides information to descendant component:
* - Index compared to other descendants
* - ref callback to register the descendant
* - Its enabled index compared to other enabled descendants
*/
function useDescendant(options) {
const descendants = useDescendantsContext();
const [index, setIndex] = useState(-1);
const ref = useRef(null);
useClientLayoutEffect(() => {
return () => {
if (!ref.current)
return;
// eslint-disable-next-line react-hooks/exhaustive-deps
descendants.unregister(ref.current);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// eslint-disable-next-line react-hooks/exhaustive-deps
useClientLayoutEffect(() => {
if (!ref.current)
return;
const dataIndex = Number(ref.current.dataset.index);
if (index !== dataIndex && !Number.isNaN(dataIndex)) {
setIndex(dataIndex);
}
});
const refCallback = options
? cast(descendants.register(options))
: cast(descendants.register);
return {
descendants,
index,
enabledIndex: descendants.enabledIndexOf(ref.current),
register: mergeRefs([refCallback, ref]),
};
}
/**
* @internal
* Initializing DescendantsManager
*/
function useDescendants() {
const descendants = useRef(new DescendantsManager()).current;
return descendants;
}
return [
// context provider
ContextProvider,
// call this when you need to read from context
useDescendantsContext,
// descendants state information, to be called and passed to `ContextProvider`
useDescendants,
// descendant index information
useDescendant,
];
}
//# sourceMappingURL=useDescendant.js.map