@contember/react-utils 1.1.0 → 1.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/development/context/createNonNullableContextFactory.js +17 -0
- package/dist/development/context/createNonNullableContextFactory.js.map +1 -0
- package/dist/development/debug-context/Constants.js +25 -0
- package/dist/development/debug-context/Constants.js.map +1 -0
- package/dist/development/debug-context/Context.js +67 -0
- package/dist/development/debug-context/Context.js.map +1 -0
- package/dist/development/hooks/unwrapRefValue.js +11 -0
- package/dist/development/hooks/unwrapRefValue.js.map +1 -0
- package/dist/development/hooks/useAddClassNameDuringResize.js +34 -0
- package/dist/development/hooks/useAddClassNameDuringResize.js.map +1 -0
- package/dist/development/hooks/useArrayMapMemo.js +0 -2
- package/dist/development/hooks/useArrayMapMemo.js.map +1 -1
- package/dist/development/hooks/useComposeRef.js +31 -0
- package/dist/development/hooks/useComposeRef.js.map +1 -0
- package/dist/development/hooks/useConstantLengthInvariant.js +0 -9
- package/dist/development/hooks/useConstantLengthInvariant.js.map +1 -1
- package/dist/development/hooks/useConstantValueInvariant.js +0 -9
- package/dist/development/hooks/useConstantValueInvariant.js.map +1 -1
- package/dist/development/hooks/useCountLayoutSlotChildren.js +31 -0
- package/dist/development/hooks/useCountLayoutSlotChildren.js.map +1 -0
- package/dist/development/hooks/useDebounceCallback.js +1 -1
- package/dist/development/hooks/useDebounceCallback.js.map +1 -1
- package/dist/development/hooks/useElementSize.js +47 -0
- package/dist/development/hooks/useElementSize.js.map +1 -0
- package/dist/development/hooks/useEventHandler.js +19 -0
- package/dist/development/hooks/useEventHandler.js.map +1 -0
- package/dist/development/hooks/useExpectSameValueReference.js +15 -0
- package/dist/development/hooks/useExpectSameValueReference.js.map +1 -0
- package/dist/development/hooks/useObjectMemo.js.map +1 -1
- package/dist/development/hooks/useOnElementMutation.js +35 -0
- package/dist/development/hooks/useOnElementMutation.js.map +1 -0
- package/dist/development/hooks/useOnElementResize.js +44 -0
- package/dist/development/hooks/useOnElementResize.js.map +1 -0
- package/dist/development/hooks/useOnScrollWithin.js +50 -0
- package/dist/development/hooks/useOnScrollWithin.js.map +1 -0
- package/dist/development/hooks/useOnWindowResize.js +36 -0
- package/dist/development/hooks/useOnWindowResize.js.map +1 -0
- package/dist/development/hooks/useScrollOffsets.js +68 -0
- package/dist/development/hooks/useScrollOffsets.js.map +1 -0
- package/dist/development/hooks/useStoredState.js.map +1 -1
- package/dist/development/hooks/useUpdatedRef.js +10 -0
- package/dist/development/hooks/useUpdatedRef.js.map +1 -0
- package/dist/development/hooks/useWindowSize.js +20 -0
- package/dist/development/hooks/useWindowSize.js.map +1 -0
- package/dist/development/index.js +41 -1
- package/dist/development/index.js.map +1 -1
- package/dist/development/referentiallyStable/useReferentiallyStableCallback.js +12 -0
- package/dist/development/referentiallyStable/useReferentiallyStableCallback.js.map +1 -0
- package/dist/production/context/createNonNullableContextFactory.js +17 -0
- package/dist/production/context/createNonNullableContextFactory.js.map +1 -0
- package/dist/production/debug-context/Constants.js +25 -0
- package/dist/production/debug-context/Constants.js.map +1 -0
- package/dist/production/debug-context/Context.js +67 -0
- package/dist/production/debug-context/Context.js.map +1 -0
- package/dist/production/hooks/unwrapRefValue.js +11 -0
- package/dist/production/hooks/unwrapRefValue.js.map +1 -0
- package/dist/production/hooks/useAddClassNameDuringResize.js +34 -0
- package/dist/production/hooks/useAddClassNameDuringResize.js.map +1 -0
- package/dist/production/hooks/useComposeRef.js +31 -0
- package/dist/production/hooks/useComposeRef.js.map +1 -0
- package/dist/production/hooks/useCountLayoutSlotChildren.js +31 -0
- package/dist/production/hooks/useCountLayoutSlotChildren.js.map +1 -0
- package/dist/production/hooks/useDebounceCallback.js +1 -1
- package/dist/production/hooks/useDebounceCallback.js.map +1 -1
- package/dist/production/hooks/useElementSize.js +47 -0
- package/dist/production/hooks/useElementSize.js.map +1 -0
- package/dist/production/hooks/useEventHandler.js +19 -0
- package/dist/production/hooks/useEventHandler.js.map +1 -0
- package/dist/production/hooks/useExpectSameValueReference.js +15 -0
- package/dist/production/hooks/useExpectSameValueReference.js.map +1 -0
- package/dist/production/hooks/useObjectMemo.js.map +1 -1
- package/dist/production/hooks/useOnElementMutation.js +35 -0
- package/dist/production/hooks/useOnElementMutation.js.map +1 -0
- package/dist/production/hooks/useOnElementResize.js +44 -0
- package/dist/production/hooks/useOnElementResize.js.map +1 -0
- package/dist/production/hooks/useOnScrollWithin.js +50 -0
- package/dist/production/hooks/useOnScrollWithin.js.map +1 -0
- package/dist/production/hooks/useOnWindowResize.js +36 -0
- package/dist/production/hooks/useOnWindowResize.js.map +1 -0
- package/dist/production/hooks/useScrollOffsets.js +68 -0
- package/dist/production/hooks/useScrollOffsets.js.map +1 -0
- package/dist/production/hooks/useStoredState.js.map +1 -1
- package/dist/production/hooks/useUpdatedRef.js +10 -0
- package/dist/production/hooks/useUpdatedRef.js.map +1 -0
- package/dist/production/hooks/useWindowSize.js +20 -0
- package/dist/production/hooks/useWindowSize.js.map +1 -0
- package/dist/production/index.js +41 -1
- package/dist/production/index.js.map +1 -1
- package/dist/production/referentiallyStable/useReferentiallyStableCallback.js +12 -0
- package/dist/production/referentiallyStable/useReferentiallyStableCallback.js.map +1 -0
- package/dist/types/context/createNonNullableContextFactory.d.ts +3 -0
- package/dist/types/context/createNonNullableContextFactory.d.ts.map +1 -0
- package/dist/types/context/index.d.ts +2 -0
- package/dist/types/context/index.d.ts.map +1 -0
- package/dist/types/debug-context/Constants.d.ts +6 -0
- package/dist/types/debug-context/Constants.d.ts.map +1 -0
- package/dist/types/debug-context/Context.d.ts +15 -0
- package/dist/types/debug-context/Context.d.ts.map +1 -0
- package/dist/types/debug-context/Types.d.ts +13 -0
- package/dist/types/debug-context/Types.d.ts.map +1 -0
- package/dist/types/debug-context/index.d.ts +4 -0
- package/dist/types/debug-context/index.d.ts.map +1 -0
- package/dist/types/hooks/index.d.ts +13 -0
- package/dist/types/hooks/index.d.ts.map +1 -1
- package/dist/types/hooks/unwrapRefValue.d.ts +9 -0
- package/dist/types/hooks/unwrapRefValue.d.ts.map +1 -0
- package/dist/types/hooks/useAddClassNameDuringResize.d.ts +13 -0
- package/dist/types/hooks/useAddClassNameDuringResize.d.ts.map +1 -0
- package/dist/types/hooks/useComposeRef.d.ts +16 -0
- package/dist/types/hooks/useComposeRef.d.ts.map +1 -0
- package/dist/types/hooks/useCountLayoutSlotChildren.d.ts +5 -0
- package/dist/types/hooks/useCountLayoutSlotChildren.d.ts.map +1 -0
- package/dist/types/hooks/useElementSize.d.ts +12 -0
- package/dist/types/hooks/useElementSize.d.ts.map +1 -0
- package/dist/types/hooks/useEventHandler.d.ts +10 -0
- package/dist/types/hooks/useEventHandler.d.ts.map +1 -0
- package/dist/types/hooks/useExpectSameValueReference.d.ts +2 -0
- package/dist/types/hooks/useExpectSameValueReference.d.ts.map +1 -0
- package/dist/types/hooks/useForceRender.d.ts +0 -1
- package/dist/types/hooks/useForceRender.d.ts.map +1 -1
- package/dist/types/hooks/useIsMounted.d.ts +0 -1
- package/dist/types/hooks/useIsMounted.d.ts.map +1 -1
- package/dist/types/hooks/useOnElementMutation.d.ts +3 -0
- package/dist/types/hooks/useOnElementMutation.d.ts.map +1 -0
- package/dist/types/hooks/useOnElementResize.d.ts +3 -0
- package/dist/types/hooks/useOnElementResize.d.ts.map +1 -0
- package/dist/types/hooks/useOnScrollWithin.d.ts +10 -0
- package/dist/types/hooks/useOnScrollWithin.d.ts.map +1 -0
- package/dist/types/hooks/useOnWindowResize.d.ts +2 -0
- package/dist/types/hooks/useOnWindowResize.d.ts.map +1 -0
- package/dist/types/hooks/useScrollOffsets.d.ts +14 -0
- package/dist/types/hooks/useScrollOffsets.d.ts.map +1 -0
- package/dist/types/hooks/useStoredState.d.ts +2 -3
- package/dist/types/hooks/useStoredState.d.ts.map +1 -1
- package/dist/types/hooks/useUpdatedRef.d.ts +8 -0
- package/dist/types/hooks/useUpdatedRef.d.ts.map +1 -0
- package/dist/types/hooks/useWindowSize.d.ts +5 -0
- package/dist/types/hooks/useWindowSize.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/referentiallyStable/index.d.ts +1 -0
- package/dist/types/referentiallyStable/index.d.ts.map +1 -1
- package/dist/types/referentiallyStable/useReferentiallyStableCallback.d.ts +2 -0
- package/dist/types/referentiallyStable/useReferentiallyStableCallback.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/types/PropsWithRequiredChildren.d.ts +5 -0
- package/dist/types/types/PropsWithRequiredChildren.d.ts.map +1 -0
- package/dist/types/{types.d.ts → types/Serializable.d.ts} +1 -1
- package/dist/types/types/Serializable.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +3 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/package.json +7 -2
- package/src/context/createNonNullableContextFactory.ts +19 -0
- package/src/context/index.ts +1 -0
- package/src/debug-context/Constants.ts +22 -0
- package/src/debug-context/Context.tsx +82 -0
- package/src/debug-context/Types.ts +13 -0
- package/src/debug-context/index.ts +3 -0
- package/src/hooks/index.ts +13 -0
- package/src/hooks/unwrapRefValue.ts +16 -0
- package/src/hooks/useAddClassNameDuringResize.ts +58 -0
- package/src/hooks/useComposeRef.ts +46 -0
- package/src/hooks/useCountLayoutSlotChildren.ts +46 -0
- package/src/hooks/useDebounceCallback.ts +1 -1
- package/src/hooks/useElementSize.ts +73 -0
- package/src/hooks/useEventHandler.ts +24 -0
- package/src/hooks/useExpectSameValueReference.ts +26 -0
- package/src/hooks/useOnElementMutation.ts +42 -0
- package/src/hooks/useOnElementResize.ts +52 -0
- package/src/hooks/useOnScrollWithin.ts +67 -0
- package/src/hooks/useOnWindowResize.ts +42 -0
- package/src/hooks/useScrollOffsets.ts +88 -0
- package/src/hooks/useStoredState.ts +2 -2
- package/src/hooks/useUpdatedRef.ts +14 -0
- package/src/hooks/useWindowSize.ts +20 -0
- package/src/index.ts +2 -0
- package/src/referentiallyStable/index.ts +1 -0
- package/src/referentiallyStable/useReferentiallyStableCallback.ts +11 -0
- package/src/tsconfig.json +4 -1
- package/src/types/PropsWithRequiredChildren.ts +3 -0
- package/src/types/index.ts +2 -0
- package/dist/types/types.d.ts.map +0 -1
- package/src/ambient.d.ts +0 -1
- /package/src/{types.ts → types/Serializable.ts} +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
function createNonNullableContextFactory(displayName, initialValue) {
|
|
3
|
+
const RequiredContext = createContext(initialValue ?? null);
|
|
4
|
+
RequiredContext.displayName = displayName;
|
|
5
|
+
const useRequiredContext = () => {
|
|
6
|
+
const context = useContext(RequiredContext);
|
|
7
|
+
if (context == null) {
|
|
8
|
+
throw new Error(`use${displayName} must be used within a ${displayName} provider`);
|
|
9
|
+
}
|
|
10
|
+
return context;
|
|
11
|
+
};
|
|
12
|
+
return [RequiredContext, useRequiredContext];
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
createNonNullableContextFactory
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=createNonNullableContextFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNonNullableContextFactory.js","sources":["../../../src/context/createNonNullableContextFactory.ts"],"sourcesContent":["import type { Context } from 'react'\nimport { createContext, useContext } from 'react'\n\nexport function createNonNullableContextFactory<T>(displayName: string, initialValue?: T): [Context<T>, () => NonNullable<T>] {\n const RequiredContext = createContext<T>((initialValue ?? null)!)\n RequiredContext.displayName = displayName\n\n const useRequiredContext = () => {\n const context = useContext(RequiredContext)\n\n if (context == null) {\n throw new Error(`use${displayName} must be used within a ${displayName} provider`)\n }\n\n return context\n }\n\n return [RequiredContext, useRequiredContext]\n}\n"],"names":[],"mappings":";AAGgB,SAAA,gCAAmC,aAAqB,cAAsD;AACtH,QAAA,kBAAkB,cAAkB,gBAAgB,IAAM;AAChE,kBAAgB,cAAc;AAE9B,QAAM,qBAAqB,MAAM;AACzB,UAAA,UAAU,WAAW,eAAe;AAE1C,QAAI,WAAW,MAAM;AACnB,YAAM,IAAI,MAAM,MAAM,qCAAqC,sBAAsB;AAAA,IACnF;AAEO,WAAA;AAAA,EAAA;AAGF,SAAA,CAAC,iBAAiB,kBAAkB;AAC7C;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function noopLog(...parameters) {
|
|
2
|
+
}
|
|
3
|
+
function noopLogged(message, value) {
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
const noopScopedConsole = Object.freeze({
|
|
7
|
+
log: noopLog,
|
|
8
|
+
logged: noopLogged,
|
|
9
|
+
warn: noopLog,
|
|
10
|
+
warned: noopLogged,
|
|
11
|
+
error: noopLog,
|
|
12
|
+
errored: noopLogged,
|
|
13
|
+
trace: noopLog,
|
|
14
|
+
traced: noopLogged
|
|
15
|
+
});
|
|
16
|
+
function isNoopScopedConsole(value) {
|
|
17
|
+
return value === noopScopedConsole;
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
isNoopScopedConsole,
|
|
21
|
+
noopLog,
|
|
22
|
+
noopLogged,
|
|
23
|
+
noopScopedConsole
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=Constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Constants.js","sources":["../../../src/debug-context/Constants.ts"],"sourcesContent":["import type { ScopedConsoleContextType } from './Types'\n\nexport function noopLog(...parameters: any[]) { }\n\nexport function noopLogged<T>(message: string, value: T): T {\n\treturn value\n}\n\nexport const noopScopedConsole: ScopedConsoleContextType = Object.freeze({\n\tlog: noopLog,\n\tlogged: noopLogged,\n\twarn: noopLog,\n\twarned: noopLogged,\n\terror: noopLog,\n\terrored: noopLogged,\n\ttrace: noopLog,\n\ttraced: noopLogged,\n})\n\nexport function isNoopScopedConsole(value: unknown): boolean {\n\treturn value === noopScopedConsole\n}\n"],"names":[],"mappings":"AAEO,SAAS,WAAW,YAAmB;AAAE;AAEhC,SAAA,WAAc,SAAiB,OAAa;AACpD,SAAA;AACR;AAEa,MAAA,oBAA8C,OAAO,OAAO;AAAA,EACxE,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AACT,CAAC;AAEM,SAAS,oBAAoB,OAAyB;AAC5D,SAAO,UAAU;AAClB;"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { assert, isNonEmptyString } from "@contember/utilities";
|
|
3
|
+
import { createContext, useContext, useMemo, useRef, memo } from "react";
|
|
4
|
+
import { noopScopedConsole, isNoopScopedConsole } from "./Constants.js";
|
|
5
|
+
function createPrefixedConsole(message, prefixedConsole) {
|
|
6
|
+
return {
|
|
7
|
+
error: function error(...parameters) {
|
|
8
|
+
(prefixedConsole ?? console).error(message, ...parameters);
|
|
9
|
+
},
|
|
10
|
+
errored: function errored(message2, value) {
|
|
11
|
+
(prefixedConsole ?? console).error(message2, value);
|
|
12
|
+
return value;
|
|
13
|
+
},
|
|
14
|
+
log: function log(...parameters) {
|
|
15
|
+
(prefixedConsole ?? console).log(message, ...parameters);
|
|
16
|
+
},
|
|
17
|
+
logged: function logged(message2, value) {
|
|
18
|
+
(prefixedConsole ?? console).log(message2, value);
|
|
19
|
+
return value;
|
|
20
|
+
},
|
|
21
|
+
trace: function trace(...parameters) {
|
|
22
|
+
(prefixedConsole ?? console).trace(message, ...parameters);
|
|
23
|
+
},
|
|
24
|
+
traced: function traced(message2, value) {
|
|
25
|
+
(prefixedConsole ?? console).trace(message2, value);
|
|
26
|
+
return value;
|
|
27
|
+
},
|
|
28
|
+
warn: function warn(...parameters) {
|
|
29
|
+
(prefixedConsole ?? console).warn(message, ...parameters);
|
|
30
|
+
},
|
|
31
|
+
warned: function warned(message2, value) {
|
|
32
|
+
(prefixedConsole ?? console).warn(message2, value);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const ScopedConsoleContext = createContext(null);
|
|
38
|
+
ScopedConsoleContext.displayName = "ScopedConsoleContext";
|
|
39
|
+
function parentScopedConsoleOrNone(parentConsole) {
|
|
40
|
+
return isNoopScopedConsole(parentConsole) ? void 0 : parentConsole;
|
|
41
|
+
}
|
|
42
|
+
const useScopedConsoleRef = (prefix) => {
|
|
43
|
+
assert("prefix is non-empty string", prefix, isNonEmptyString);
|
|
44
|
+
const parentConsole = parentScopedConsoleOrNone(useContext(ScopedConsoleContext));
|
|
45
|
+
const scopedConsole = useMemo(() => {
|
|
46
|
+
if (parentConsole) {
|
|
47
|
+
return createPrefixedConsole(prefix, parentConsole);
|
|
48
|
+
} else {
|
|
49
|
+
return noopScopedConsole;
|
|
50
|
+
}
|
|
51
|
+
}, [parentConsole, prefix]);
|
|
52
|
+
const ref = useRef(scopedConsole);
|
|
53
|
+
ref.current = scopedConsole;
|
|
54
|
+
return ref;
|
|
55
|
+
};
|
|
56
|
+
const DebugChildren = memo(({ active = true, children, id }) => {
|
|
57
|
+
const parentScopedConsole = parentScopedConsoleOrNone(useContext(ScopedConsoleContext));
|
|
58
|
+
const console2 = active && id ? createPrefixedConsole(id, parentScopedConsole) : noopScopedConsole;
|
|
59
|
+
return /* @__PURE__ */ jsx(ScopedConsoleContext.Provider, { value: active ? console2 : noopScopedConsole, children });
|
|
60
|
+
});
|
|
61
|
+
DebugChildren.displayName = "DebugChildren";
|
|
62
|
+
export {
|
|
63
|
+
DebugChildren,
|
|
64
|
+
ScopedConsoleContext,
|
|
65
|
+
useScopedConsoleRef
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=Context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Context.js","sources":["../../../src/debug-context/Context.tsx"],"sourcesContent":["import { assert, isNonEmptyString } from '@contember/utilities'\nimport { ReactNode, createContext, memo, useContext, useMemo, useRef } from 'react'\nimport { isNoopScopedConsole, noopScopedConsole } from './Constants'\nimport { ScopedConsoleContextType } from './Types'\n\nfunction createPrefixedConsole(message: string, prefixedConsole?: ScopedConsoleContextType): ScopedConsoleContextType {\n\treturn {\n\t\terror: function error(...parameters: any[]) {\n\t\t\t(prefixedConsole ?? console).error(message, ...parameters)\n\t\t},\n\t\terrored: function errored<T>(message: string, value: T): T {\n\t\t\t(prefixedConsole ?? console).error(message, value)\n\t\t\treturn value\n\t\t},\n\t\tlog: function log(...parameters: any[]) {\n\t\t\t(prefixedConsole ?? console).log(message, ...parameters)\n\t\t},\n\t\tlogged: function logged<T>(message: string, value: T): T {\n\t\t\t(prefixedConsole ?? console).log(message, value)\n\t\t\treturn value\n\t\t},\n\t\ttrace: function trace(...parameters: any[]) {\n\t\t\t(prefixedConsole ?? console).trace(message, ...parameters)\n\t\t},\n\t\ttraced: function traced<T>(message: string, value: T): T {\n\t\t\t(prefixedConsole ?? console).trace(message, value)\n\t\t\treturn value\n\t\t},\n\t\twarn: function warn(...parameters: any[]) {\n\t\t\t(prefixedConsole ?? console).warn(message, ...parameters)\n\t\t},\n\t\twarned: function warned<T>(message: string, value: T): T {\n\t\t\t(prefixedConsole ?? console).warn(message, value)\n\t\t\treturn value\n\t\t},\n\t}\n}\n\nexport const ScopedConsoleContext = createContext<ScopedConsoleContextType>(null!)\nScopedConsoleContext.displayName = 'ScopedConsoleContext'\n\nfunction parentScopedConsoleOrNone(parentConsole: ScopedConsoleContextType): ScopedConsoleContextType | undefined {\n\treturn isNoopScopedConsole(parentConsole) ? undefined : parentConsole\n}\n\nexport const useScopedConsoleRef = (prefix: string) => {\n\tassert('prefix is non-empty string', prefix, isNonEmptyString)\n\n\tconst parentConsole = parentScopedConsoleOrNone(useContext(ScopedConsoleContext))\n\n\tconst scopedConsole = useMemo(() => {\n\t\tif (parentConsole) {\n\t\t\treturn createPrefixedConsole(prefix, parentConsole)\n\t\t} else {\n\t\t\treturn noopScopedConsole\n\t\t}\n\t}, [parentConsole, prefix])\n\n\tconst ref = useRef(scopedConsole)\n\tref.current = scopedConsole\n\n\treturn ref\n}\n\nexport type DebugChildrenProps =\n\t| { active: true; children: ReactNode; id: string; }\n\t| { active?: false; children: ReactNode; id?: string; }\n\nexport const DebugChildren = memo<DebugChildrenProps>(({ active = true, children, id }) => {\n\tconst parentScopedConsole = parentScopedConsoleOrNone(useContext(ScopedConsoleContext))\n\n\tconst console = active && id\n\t\t? createPrefixedConsole(id, parentScopedConsole)\n\t\t: noopScopedConsole\n\n\treturn (\n\t\t<ScopedConsoleContext.Provider value={active ? console : noopScopedConsole}>\n\t\t\t{children}\n\t\t</ScopedConsoleContext.Provider>\n\t)\n})\nDebugChildren.displayName = 'DebugChildren'\n"],"names":["message","console"],"mappings":";;;;AAKA,SAAS,sBAAsB,SAAiB,iBAAsE;AAC9G,SAAA;AAAA,IACN,OAAO,SAAS,SAAS,YAAmB;AAC3C,OAAC,mBAAmB,SAAS,MAAM,SAAS,GAAG,UAAU;AAAA,IAC1D;AAAA,IACA,SAAS,SAAS,QAAWA,UAAiB,OAAa;AAC1D,OAAC,mBAAmB,SAAS,MAAMA,UAAS,KAAK;AAC1C,aAAA;AAAA,IACR;AAAA,IACA,KAAK,SAAS,OAAO,YAAmB;AACvC,OAAC,mBAAmB,SAAS,IAAI,SAAS,GAAG,UAAU;AAAA,IACxD;AAAA,IACA,QAAQ,SAAS,OAAUA,UAAiB,OAAa;AACxD,OAAC,mBAAmB,SAAS,IAAIA,UAAS,KAAK;AACxC,aAAA;AAAA,IACR;AAAA,IACA,OAAO,SAAS,SAAS,YAAmB;AAC3C,OAAC,mBAAmB,SAAS,MAAM,SAAS,GAAG,UAAU;AAAA,IAC1D;AAAA,IACA,QAAQ,SAAS,OAAUA,UAAiB,OAAa;AACxD,OAAC,mBAAmB,SAAS,MAAMA,UAAS,KAAK;AAC1C,aAAA;AAAA,IACR;AAAA,IACA,MAAM,SAAS,QAAQ,YAAmB;AACzC,OAAC,mBAAmB,SAAS,KAAK,SAAS,GAAG,UAAU;AAAA,IACzD;AAAA,IACA,QAAQ,SAAS,OAAUA,UAAiB,OAAa;AACxD,OAAC,mBAAmB,SAAS,KAAKA,UAAS,KAAK;AACzC,aAAA;AAAA,IACR;AAAA,EAAA;AAEF;AAEa,MAAA,uBAAuB,cAAwC,IAAK;AACjF,qBAAqB,cAAc;AAEnC,SAAS,0BAA0B,eAA+E;AAC1G,SAAA,oBAAoB,aAAa,IAAI,SAAY;AACzD;AAEa,MAAA,sBAAsB,CAAC,WAAmB;AAC/C,SAAA,8BAA8B,QAAQ,gBAAgB;AAE7D,QAAM,gBAAgB,0BAA0B,WAAW,oBAAoB,CAAC;AAE1E,QAAA,gBAAgB,QAAQ,MAAM;AACnC,QAAI,eAAe;AACX,aAAA,sBAAsB,QAAQ,aAAa;AAAA,IAAA,OAC5C;AACC,aAAA;AAAA,IACR;AAAA,EAAA,GACE,CAAC,eAAe,MAAM,CAAC;AAEpB,QAAA,MAAM,OAAO,aAAa;AAChC,MAAI,UAAU;AAEP,SAAA;AACR;AAMa,MAAA,gBAAgB,KAAyB,CAAC,EAAE,SAAS,MAAM,UAAU,SAAS;AAC1F,QAAM,sBAAsB,0BAA0B,WAAW,oBAAoB,CAAC;AAEtF,QAAMC,WAAU,UAAU,KACvB,sBAAsB,IAAI,mBAAmB,IAC7C;AAGF,SAAA,oBAAC,qBAAqB,UAArB,EAA8B,OAAO,SAASA,WAAU,mBACvD,SACF,CAAA;AAEF,CAAC;AACD,cAAc,cAAc;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unwrapRefValue.js","sources":["../../../src/hooks/unwrapRefValue.ts"],"sourcesContent":["import { RefObject } from 'react'\n\nexport type RefObjectOrElement<T> = T | RefObject<T>\n\n/**\n * Unwraps a ref object or returns the value if it is not a ref object.\n * @param value - Value to unwrap\n * @returns Unwrapped value\n */\nexport function unwrapRefValue<T>(value: RefObjectOrElement<T>): T | null {\n\tif (value && typeof value === 'object' && 'current' in value) {\n\t\treturn value.current\n\t} else {\n\t\treturn value\n\t}\n}\n"],"names":[],"mappings":"AASO,SAAS,eAAkB,OAAwC;AACzE,MAAI,SAAS,OAAO,UAAU,YAAY,aAAa,OAAO;AAC7D,WAAO,MAAM;AAAA,EAAA,OACP;AACC,WAAA;AAAA,EACR;AACD;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useRef, useLayoutEffect } from "react";
|
|
2
|
+
import { useOnWindowResize } from "./useOnWindowResize.js";
|
|
3
|
+
import { useReferentiallyStableCallback } from "../referentiallyStable/useReferentiallyStableCallback.js";
|
|
4
|
+
function intendedFlushOfCSSChangesToCauseImmediateReflow(element) {
|
|
5
|
+
element.offsetHeight;
|
|
6
|
+
}
|
|
7
|
+
function addClassName(className, element) {
|
|
8
|
+
if (element.classList.contains(className)) {
|
|
9
|
+
element.classList.remove(className);
|
|
10
|
+
intendedFlushOfCSSChangesToCauseImmediateReflow(element);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function removeClassName(className, element) {
|
|
14
|
+
if (!element.classList.contains(className)) {
|
|
15
|
+
element.classList.add(className);
|
|
16
|
+
intendedFlushOfCSSChangesToCauseImmediateReflow(element);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function useAddClassNameDuringResize(className, timeoutToRestore = 300, element) {
|
|
20
|
+
const timeoutID = useRef();
|
|
21
|
+
const addTemporaryClassName = useReferentiallyStableCallback(() => {
|
|
22
|
+
clearTimeout(timeoutID.current);
|
|
23
|
+
removeClassName(className, element ?? document.body);
|
|
24
|
+
timeoutID.current = setTimeout(() => {
|
|
25
|
+
addClassName(className, element ?? document.body);
|
|
26
|
+
}, timeoutToRestore);
|
|
27
|
+
});
|
|
28
|
+
useLayoutEffect(addTemporaryClassName, [addTemporaryClassName]);
|
|
29
|
+
useOnWindowResize(addTemporaryClassName);
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
useAddClassNameDuringResize
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=useAddClassNameDuringResize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAddClassNameDuringResize.js","sources":["../../../src/hooks/useAddClassNameDuringResize.ts"],"sourcesContent":["import { useLayoutEffect, useRef } from 'react'\nimport { useReferentiallyStableCallback } from '../referentiallyStable'\nimport { useOnWindowResize } from './useOnWindowResize'\n\nfunction intendedFlushOfCSSChangesToCauseImmediateReflow(element: HTMLElement) {\n\telement.offsetHeight\n}\n\nfunction addClassName(\n\tclassName: string,\n\telement: HTMLElement,\n) {\n\tif (element.classList.contains(className)) {\n\t\telement.classList.remove(className)\n\t\tintendedFlushOfCSSChangesToCauseImmediateReflow(element)\n\t}\n}\n\nfunction removeClassName(\n\tclassName: string,\n\telement: HTMLElement,\n) {\n\tif (!element.classList.contains(className)) {\n\t\telement.classList.add(className)\n\t\tintendedFlushOfCSSChangesToCauseImmediateReflow(element)\n\t}\n}\n\n/**\n * Adds CSS class during resize event to element\n *\n * - Falls back to document.body when no element is specified\n * - Adds CSS class to element also on the initial load\n * - Uses element.classList directly\n *\n * @param className - CSS class to apply during the resize event\n * @param timeoutToRestore - Timeout in milliseconds to wait before finally removing the CSS class\n * @param element - Optional HTML element to apply CSS class to\n */\nexport function useAddClassNameDuringResize(\n\tclassName: string,\n\ttimeoutToRestore: number = 300,\n\telement?: HTMLElement,\n) {\n\tconst timeoutID = useRef<number>()\n\n\tconst addTemporaryClassName = useReferentiallyStableCallback(() => {\n\t\tclearTimeout(timeoutID.current)\n\t\tremoveClassName(className, element ?? document.body)\n\n\t\ttimeoutID.current = setTimeout(() => {\n\t\t\taddClassName(className, element ?? document.body)\n\t\t}, timeoutToRestore)\n\t})\n\n\tuseLayoutEffect(addTemporaryClassName, [addTemporaryClassName])\n\tuseOnWindowResize(addTemporaryClassName)\n}\n"],"names":[],"mappings":";;;AAIA,SAAS,gDAAgD,SAAsB;AACtE,UAAA;AACT;AAEA,SAAS,aACR,WACA,SACC;AACD,MAAI,QAAQ,UAAU,SAAS,SAAS,GAAG;AAClC,YAAA,UAAU,OAAO,SAAS;AAClC,oDAAgD,OAAO;AAAA,EACxD;AACD;AAEA,SAAS,gBACR,WACA,SACC;AACD,MAAI,CAAC,QAAQ,UAAU,SAAS,SAAS,GAAG;AACnC,YAAA,UAAU,IAAI,SAAS;AAC/B,oDAAgD,OAAO;AAAA,EACxD;AACD;AAaO,SAAS,4BACf,WACA,mBAA2B,KAC3B,SACC;AACD,QAAM,YAAY;AAEZ,QAAA,wBAAwB,+BAA+B,MAAM;AAClE,iBAAa,UAAU,OAAO;AACd,oBAAA,WAAW,WAAW,SAAS,IAAI;AAEzC,cAAA,UAAU,WAAW,MAAM;AACvB,mBAAA,WAAW,WAAW,SAAS,IAAI;AAAA,OAC9C,gBAAgB;AAAA,EAAA,CACnB;AAEe,kBAAA,uBAAuB,CAAC,qBAAqB,CAAC;AAC9D,oBAAkB,qBAAqB;AACxC;"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
-
import { useConstantLengthInvariant } from "./useConstantLengthInvariant.js";
|
|
3
2
|
const useArrayMapMemo = (items, map) => {
|
|
4
|
-
useConstantLengthInvariant(items);
|
|
5
3
|
const mapped = useMemo(() => items.map(map), [map, ...items]);
|
|
6
4
|
return useMemo(() => mapped, mapped);
|
|
7
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useArrayMapMemo.js","sources":["../../../src/hooks/useArrayMapMemo.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { useConstantLengthInvariant } from './useConstantLengthInvariant'\n\n/**\n * ⚠️ ONLY USE THIS IF YOU *REALLY* KNOW WHAT YOU'RE DOING! ⚠️\n * ⚠ HERE BE DRAGONS THAT KNOW WHERE YOU LIVE! ⚠\n *\n * This is a bit of React naughtiness that allows us to memoize outputs of Array.prototype.map() based on the contents\n * of the original array, and not its referential equality. That way, if we create a new array with identical items,\n * we get an array that is referentially equal to the previous one.\n */\nexport const useArrayMapMemo = <Item, OutputItem>(\n\titems: Item[],\n\tmap: (value: Item, index: number, array: Item[]) => OutputItem,\n): OutputItem[] => {\n\tuseConstantLengthInvariant(items)\n\n\t// This is tricky. We don't want to exclude the map function from the dependency list because if it changes but the\n\t// items array remains the same, we still want to re-compute the new array. However, if that yields the same array,\n\t// in the sense that the items are identical, albeit computed via a different map function, we still want to\n\t// preserve the referential equality of the original. Hence the second memo.\n\n\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\tconst mapped = useMemo(() => items.map(map), [map, ...items])\n\n\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\treturn useMemo(() => mapped, mapped) // This is deliberately not `[mapped]`\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useArrayMapMemo.js","sources":["../../../src/hooks/useArrayMapMemo.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { useConstantLengthInvariant } from './useConstantLengthInvariant'\n\n/**\n * ⚠️ ONLY USE THIS IF YOU *REALLY* KNOW WHAT YOU'RE DOING! ⚠️\n * ⚠ HERE BE DRAGONS THAT KNOW WHERE YOU LIVE! ⚠\n *\n * This is a bit of React naughtiness that allows us to memoize outputs of Array.prototype.map() based on the contents\n * of the original array, and not its referential equality. That way, if we create a new array with identical items,\n * we get an array that is referentially equal to the previous one.\n */\nexport const useArrayMapMemo = <Item, OutputItem>(\n\titems: Item[],\n\tmap: (value: Item, index: number, array: Item[]) => OutputItem,\n): OutputItem[] => {\n\tuseConstantLengthInvariant(items)\n\n\t// This is tricky. We don't want to exclude the map function from the dependency list because if it changes but the\n\t// items array remains the same, we still want to re-compute the new array. However, if that yields the same array,\n\t// in the sense that the items are identical, albeit computed via a different map function, we still want to\n\t// preserve the referential equality of the original. Hence the second memo.\n\n\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\tconst mapped = useMemo(() => items.map(map), [map, ...items])\n\n\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\treturn useMemo(() => mapped, mapped) // This is deliberately not `[mapped]`\n}\n"],"names":[],"mappings":";AAWa,MAAA,kBAAkB,CAC9B,OACA,QACkB;AASZ,QAAA,SAAS,QAAQ,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;AAGrD,SAAA,QAAQ,MAAM,QAAQ,MAAM;AACpC;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useRef, useMemo } from "react";
|
|
2
|
+
function setRef(ref, instance) {
|
|
3
|
+
if (ref) {
|
|
4
|
+
if (typeof ref === "function") {
|
|
5
|
+
ref(instance);
|
|
6
|
+
} else if (instance) {
|
|
7
|
+
ref.current = instance;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function useComposeRef(...refs) {
|
|
12
|
+
const initialRefs = useRef(refs);
|
|
13
|
+
const composeRef = useMemo(() => {
|
|
14
|
+
function composedRefCallback(instance) {
|
|
15
|
+
initialRefs.current.forEach((ref) => setRef(ref, instance));
|
|
16
|
+
setCurrent(instance);
|
|
17
|
+
}
|
|
18
|
+
function setCurrent(instance) {
|
|
19
|
+
if (instance) {
|
|
20
|
+
composedRefCallback.current = instance;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
composedRefCallback.current = null;
|
|
24
|
+
return composedRefCallback;
|
|
25
|
+
}, []);
|
|
26
|
+
return composeRef;
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
useComposeRef
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=useComposeRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useComposeRef.js","sources":["../../../src/hooks/useComposeRef.ts"],"sourcesContent":["import { MutableRefObject, RefCallback, useMemo, useRef } from 'react'\n\nexport type MaybeRef<T> = ((instance: T | null) => void) | MutableRefObject<T | null> | null | undefined\nexport type ComposedRefCallback<T> = RefCallback<T> & { current: T | null };\n\nfunction setRef<T>(ref: MaybeRef<T>, instance: T | null): void {\n\tif (ref) {\n\t\tif (typeof ref === 'function') {\n\t\t\tref(instance)\n\t\t} else if (instance) {\n\t\t\tref.current = instance\n\t\t}\n\t}\n}\n\n/**\n * Fills any number of refs with an instance\n *\n * Useful when you need to use outer ref and inner in the same time, e.g. passing element\n * back to forwardedRef an also using the same value within the component locally.\n *\n * @param refs - Rest parameter of refs to fill with instance\n * @returns Returns a function similar to a RefCallback\n */\nexport function useComposeRef<T>(...refs: MaybeRef<T>[]): ComposedRefCallback<T> {\n\tconst initialRefs = useRef(refs)\n\n\tconst composeRef: ComposedRefCallback<T> = useMemo(() => {\n\t\tfunction composedRefCallback(instance: T | null) {\n\t\t\tinitialRefs.current.forEach(ref => setRef(ref, instance))\n\t\t\tsetCurrent(instance)\n\t\t}\n\n\t\tfunction setCurrent(instance: T | null) {\n\t\t\tif (instance) {\n\t\t\t\tcomposedRefCallback.current = instance\n\t\t\t}\n\t\t}\n\n\t\tcomposedRefCallback.current = null as T | null\n\n\t\treturn composedRefCallback\n\t}, [])\n\n\treturn composeRef\n}\n"],"names":[],"mappings":";AAKA,SAAS,OAAU,KAAkB,UAA0B;AAC9D,MAAI,KAAK;AACJ,QAAA,OAAO,QAAQ,YAAY;AAC9B,UAAI,QAAQ;AAAA,eACF,UAAU;AACpB,UAAI,UAAU;AAAA,IACf;AAAA,EACD;AACD;AAWO,SAAS,iBAAoB,MAA6C;AAC1E,QAAA,cAAc,OAAO,IAAI;AAEzB,QAAA,aAAqC,QAAQ,MAAM;AACxD,aAAS,oBAAoB,UAAoB;AAChD,kBAAY,QAAQ,QAAQ,CAAA,QAAO,OAAO,KAAK,QAAQ,CAAC;AACxD,iBAAW,QAAQ;AAAA,IACpB;AAEA,aAAS,WAAW,UAAoB;AACvC,UAAI,UAAU;AACb,4BAAoB,UAAU;AAAA,MAC/B;AAAA,IACD;AAEA,wBAAoB,UAAU;AAEvB,WAAA;AAAA,EACR,GAAG,CAAE,CAAA;AAEE,SAAA;AACR;"}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import { usePreviousValue } from "./usePreviousValue.js";
|
|
2
1
|
const useConstantLengthInvariant = (items, message) => {
|
|
3
|
-
{
|
|
4
|
-
const previous = usePreviousValue(items);
|
|
5
|
-
if (previous.length !== items.length) {
|
|
6
|
-
throw new Error(
|
|
7
|
-
`Invariant violation: ${message || "Changing the length of an array whose length must remain constant between renders."}`
|
|
8
|
-
);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
2
|
};
|
|
12
3
|
export {
|
|
13
4
|
useConstantLengthInvariant
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConstantLengthInvariant.js","sources":["../../../src/hooks/useConstantLengthInvariant.ts"],"sourcesContent":["import { usePreviousValue } from './usePreviousValue'\n\n// This entire hook should get optimized away for prod\nexport const useConstantLengthInvariant = <Item>(items: Item[], message?: string) => {\n\tif (import.meta.env.DEV) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst previous = usePreviousValue(items)\n\t\tif (previous.length !== items.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invariant violation: ${message || 'Changing the length of an array whose length must remain constant between renders.'\n\t\t\t\t}`,\n\t\t\t)\n\t\t}\n\t}\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useConstantLengthInvariant.js","sources":["../../../src/hooks/useConstantLengthInvariant.ts"],"sourcesContent":["import { usePreviousValue } from './usePreviousValue'\n\n// This entire hook should get optimized away for prod\nexport const useConstantLengthInvariant = <Item>(items: Item[], message?: string) => {\n\tif (import.meta.env.DEV) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst previous = usePreviousValue(items)\n\t\tif (previous.length !== items.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invariant violation: ${message || 'Changing the length of an array whose length must remain constant between renders.'\n\t\t\t\t}`,\n\t\t\t)\n\t\t}\n\t}\n}\n"],"names":[],"mappings":"AAGa,MAAA,6BAA6B,CAAO,OAAe,YAAqB;AAWrF;"}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import { usePreviousValue } from "./usePreviousValue.js";
|
|
2
1
|
const useConstantValueInvariant = (value, message) => {
|
|
3
|
-
{
|
|
4
|
-
const previous = usePreviousValue(value);
|
|
5
|
-
if (previous !== value) {
|
|
6
|
-
throw new Error(
|
|
7
|
-
`Invariant violation: ${message || "Changing a value which must remain constant between renders."}`
|
|
8
|
-
);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
2
|
};
|
|
12
3
|
export {
|
|
13
4
|
useConstantValueInvariant
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConstantValueInvariant.js","sources":["../../../src/hooks/useConstantValueInvariant.ts"],"sourcesContent":["import { usePreviousValue } from './usePreviousValue'\n\n// This entire hook should get optimized away for prod\nexport const useConstantValueInvariant = <Value>(value: Value, message?: string) => {\n\tif (import.meta.env.DEV) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst previous = usePreviousValue(value)\n\t\tif (previous !== value) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invariant violation: ${message || 'Changing a value which must remain constant between renders.'}`,\n\t\t\t)\n\t\t}\n\t}\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useConstantValueInvariant.js","sources":["../../../src/hooks/useConstantValueInvariant.ts"],"sourcesContent":["import { usePreviousValue } from './usePreviousValue'\n\n// This entire hook should get optimized away for prod\nexport const useConstantValueInvariant = <Value>(value: Value, message?: string) => {\n\tif (import.meta.env.DEV) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst previous = usePreviousValue(value)\n\t\tif (previous !== value) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invariant violation: ${message || 'Changing a value which must remain constant between renders.'}`,\n\t\t\t)\n\t\t}\n\t}\n}\n"],"names":[],"mappings":"AAGa,MAAA,4BAA4B,CAAQ,OAAc,YAAqB;AAUpF;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useState, useRef, useLayoutEffect } from "react";
|
|
2
|
+
import { unwrapRefValue } from "./unwrapRefValue.js";
|
|
3
|
+
import { useOnElementMutation } from "./useOnElementMutation.js";
|
|
4
|
+
function useCountLayoutSlotChildren(refOrElement, selector = ".layout-slot") {
|
|
5
|
+
const [count, setCount] = useState(Infinity);
|
|
6
|
+
const countChildren = useRef((element) => {
|
|
7
|
+
if (element) {
|
|
8
|
+
setCount(element.querySelectorAll(`${selector} > *`).length);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
useOnElementMutation(refOrElement, () => {
|
|
12
|
+
countChildren.current(unwrapRefValue(refOrElement));
|
|
13
|
+
}, { attributes: true, childList: true, subtree: true });
|
|
14
|
+
useLayoutEffect(() => {
|
|
15
|
+
countChildren.current(unwrapRefValue(refOrElement));
|
|
16
|
+
});
|
|
17
|
+
return count;
|
|
18
|
+
}
|
|
19
|
+
function useHasEmptySlotsClassName(refOrElement) {
|
|
20
|
+
const slotChildrenCount = useCountLayoutSlotChildren(refOrElement);
|
|
21
|
+
if (slotChildrenCount === 0) {
|
|
22
|
+
return "has-empty-slots";
|
|
23
|
+
} else {
|
|
24
|
+
return "has-non-empty-slots";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
useCountLayoutSlotChildren,
|
|
29
|
+
useHasEmptySlotsClassName
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=useCountLayoutSlotChildren.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCountLayoutSlotChildren.js","sources":["../../../src/hooks/useCountLayoutSlotChildren.ts"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from 'react'\nimport { RefObjectOrElement, unwrapRefValue } from './unwrapRefValue'\nimport { useOnElementMutation } from './useOnElementMutation'\n\n// TODO: Remove when Firefox supports :has selector, e.g.\n// when selectors like `:has(:not(.layout-slot:empty))` work\n// or below issue can be solved more easily:\n//\n// ISSUE:\n// Targeting containers that are visibly empty and hide them\n// or remove paddings without support for :has() is tedious.\n/** @deprecated Check support for :has() for Firefox before using. */\nexport function useCountLayoutSlotChildren(\n\trefOrElement: RefObjectOrElement<HTMLElement | undefined>,\n\tselector: string = '.layout-slot',\n) {\n\tconst [count, setCount] = useState(Infinity)\n\n\tconst countChildren = useRef((element: HTMLElement | null | undefined) => {\n\t\tif (element) {\n\t\t\tsetCount(element.querySelectorAll(`${selector} > *`).length)\n\t\t}\n\t})\n\n\tuseOnElementMutation(refOrElement, () => {\n\t\tcountChildren.current(unwrapRefValue(refOrElement))\n\t}, { attributes: true, childList: true, subtree: true })\n\n\tuseLayoutEffect(() => {\n\t\tcountChildren.current(unwrapRefValue(refOrElement))\n\t})\n\n\treturn count\n}\n\nexport function useHasEmptySlotsClassName(\n\trefOrElement: RefObjectOrElement<HTMLElement | undefined>,\n) {\n\tconst slotChildrenCount = useCountLayoutSlotChildren(refOrElement)\n\n\tif (slotChildrenCount === 0) {\n\t\treturn 'has-empty-slots'\n\t} else {\n\t\treturn 'has-non-empty-slots'\n\t}\n}\n"],"names":[],"mappings":";;;AAYgB,SAAA,2BACf,cACA,WAAmB,gBAClB;AACD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,QAAQ;AAErC,QAAA,gBAAgB,OAAO,CAAC,YAA4C;AACzE,QAAI,SAAS;AACZ,eAAS,QAAQ,iBAAiB,GAAG,cAAc,EAAE,MAAM;AAAA,IAC5D;AAAA,EAAA,CACA;AAED,uBAAqB,cAAc,MAAM;AAC1B,kBAAA,QAAQ,eAAe,YAAY,CAAC;AAAA,EAAA,GAChD,EAAE,YAAY,MAAM,WAAW,MAAM,SAAS,MAAM;AAEvD,kBAAgB,MAAM;AACP,kBAAA,QAAQ,eAAe,YAAY,CAAC;AAAA,EAAA,CAClD;AAEM,SAAA;AACR;AAEO,SAAS,0BACf,cACC;AACK,QAAA,oBAAoB,2BAA2B,YAAY;AAEjE,MAAI,sBAAsB,GAAG;AACrB,WAAA;AAAA,EAAA,OACD;AACC,WAAA;AAAA,EACR;AACD;"}
|
|
@@ -4,7 +4,7 @@ const useDebounceCallback = (cb, debounceMs) => {
|
|
|
4
4
|
const cbRef = useRef(cb);
|
|
5
5
|
cbRef.current = cb;
|
|
6
6
|
useEffect(() => {
|
|
7
|
-
return () =>
|
|
7
|
+
return () => clearTimeout(timerRef.current);
|
|
8
8
|
}, []);
|
|
9
9
|
return useCallback(() => {
|
|
10
10
|
timerRef.current && clearTimeout(timerRef.current);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDebounceCallback.js","sources":["../../../src/hooks/useDebounceCallback.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react'\n\nexport const useDebounceCallback = (cb: () => any, debounceMs: number) => {\n\tconst timerRef = useRef<ReturnType<typeof setTimeout>>()\n\tconst cbRef = useRef(cb)\n\tcbRef.current = cb\n\n\tuseEffect(() => {\n\t\treturn () =>
|
|
1
|
+
{"version":3,"file":"useDebounceCallback.js","sources":["../../../src/hooks/useDebounceCallback.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react'\n\nexport const useDebounceCallback = (cb: () => any, debounceMs: number) => {\n\tconst timerRef = useRef<ReturnType<typeof setTimeout>>()\n\tconst cbRef = useRef(cb)\n\tcbRef.current = cb\n\n\tuseEffect(() => {\n\t\treturn () => clearTimeout(timerRef.current)\n\t}, [])\n\n\treturn useCallback(() => {\n\t\ttimerRef.current && clearTimeout(timerRef.current)\n\n\t\ttimerRef.current = setTimeout(() => {\n\t\t\tcbRef.current()\n\t\t}, debounceMs)\n\t}, [debounceMs])\n}\n"],"names":[],"mappings":";AAEa,MAAA,sBAAsB,CAAC,IAAe,eAAuB;AACzE,QAAM,WAAW;AACX,QAAA,QAAQ,OAAO,EAAE;AACvB,QAAM,UAAU;AAEhB,YAAU,MAAM;AACR,WAAA,MAAM,aAAa,SAAS,OAAO;AAAA,EAC3C,GAAG,CAAE,CAAA;AAEL,SAAO,YAAY,MAAM;AACf,aAAA,WAAW,aAAa,SAAS,OAAO;AAExC,aAAA,UAAU,WAAW,MAAM;AACnC,YAAM,QAAQ;AAAA,OACZ,UAAU;AAAA,EAAA,GACX,CAAC,UAAU,CAAC;AAChB;"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getSizeFromResizeObserverEntryFactory } from "@contember/utilities";
|
|
2
|
+
import { useMemo, useState, useRef, useLayoutEffect } from "react";
|
|
3
|
+
import { unwrapRefValue } from "./unwrapRefValue.js";
|
|
4
|
+
import { useOnElementResize } from "./useOnElementResize.js";
|
|
5
|
+
import { useScopedConsoleRef } from "../debug-context/Context.js";
|
|
6
|
+
function getElementWidth(element) {
|
|
7
|
+
return element.offsetWidth;
|
|
8
|
+
}
|
|
9
|
+
function getElementHeight(element) {
|
|
10
|
+
return element.offsetHeight;
|
|
11
|
+
}
|
|
12
|
+
function useElementSize(refOrElement, options = {}, timeout = 300) {
|
|
13
|
+
const { logged } = useScopedConsoleRef("useElementSize").current;
|
|
14
|
+
const { box = "border-box" } = options;
|
|
15
|
+
const getSizeFromResizeObserverEntry = useMemo(() => getSizeFromResizeObserverEntryFactory(box), [box]);
|
|
16
|
+
const refValue = unwrapRefValue(refOrElement);
|
|
17
|
+
const [width, setWidth] = useState(refValue?.offsetWidth);
|
|
18
|
+
const [height, setHeight] = useState(refValue?.offsetHeight);
|
|
19
|
+
logged("dimensions", { width, height });
|
|
20
|
+
useOnElementResize(refOrElement, (entry) => {
|
|
21
|
+
const dimensions = logged("useOnElementResize => entry:dimensions", getSizeFromResizeObserverEntry(entry));
|
|
22
|
+
if (width !== dimensions.width) {
|
|
23
|
+
setWidth(dimensions.width);
|
|
24
|
+
}
|
|
25
|
+
if (height !== dimensions.height) {
|
|
26
|
+
setHeight(dimensions.height);
|
|
27
|
+
}
|
|
28
|
+
}, { box }, timeout);
|
|
29
|
+
const measure = useRef((element) => {
|
|
30
|
+
logged("measure(element)", element);
|
|
31
|
+
if (element instanceof HTMLElement) {
|
|
32
|
+
setWidth(logged("getElementWidth(element):", getElementWidth(element)));
|
|
33
|
+
setHeight(logged("getElementHeight(element):", getElementHeight(element)));
|
|
34
|
+
} else if (element) {
|
|
35
|
+
throw new Error("Exhaustive error: Expecting element to be instance of HTMLElement or Window");
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
useLayoutEffect(() => {
|
|
39
|
+
const element = unwrapRefValue(refOrElement);
|
|
40
|
+
logged("useLayoutEffect => measure", measure.current(element));
|
|
41
|
+
});
|
|
42
|
+
return { height, width };
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
useElementSize
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=useElementSize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useElementSize.js","sources":["../../../src/hooks/useElementSize.ts"],"sourcesContent":["import { getSizeFromResizeObserverEntryFactory } from '@contember/utilities'\nimport { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { useScopedConsoleRef } from '../debug-context'\nimport { RefObjectOrElement, unwrapRefValue } from './unwrapRefValue'\nimport { useOnElementResize } from './useOnElementResize'\n\nfunction getElementWidth(element: HTMLElement) {\n\treturn element.offsetWidth\n}\n\nfunction getElementHeight(element: HTMLElement) {\n\treturn element.offsetHeight\n}\n\n/**\n * Measure HTMLElement\n *\n * @param refOrElement - HTMLElement passed directly or indirectly as RefObject\n * @returns Size vector consisting of width and height properties\n */\nexport function useElementSize(\n\trefOrElement: RefObjectOrElement<HTMLElement>,\n\toptions: ResizeObserverOptions = {},\n\ttimeout: number = 300,\n): { height: number | undefined, width: number | undefined } {\n\tconst { logged } = useScopedConsoleRef('useElementSize').current\n\n\tconst { box = 'border-box' } = options\n\tconst getSizeFromResizeObserverEntry = useMemo(() => getSizeFromResizeObserverEntryFactory(box), [box])\n\n\tconst refValue = unwrapRefValue(refOrElement)\n\tconst [width, setWidth] = useState<number | undefined>(refValue?.offsetWidth)\n\tconst [height, setHeight] = useState<number | undefined>(refValue?.offsetHeight)\n\n\tlogged('dimensions', { width, height })\n\n\tuseOnElementResize(refOrElement, entry => {\n\t\tconst dimensions = logged('useOnElementResize => entry:dimensions', getSizeFromResizeObserverEntry(entry))\n\n\t\tif (width !== dimensions.width) {\n\t\t\tsetWidth(dimensions.width)\n\t\t}\n\t\tif (height !== dimensions.height) {\n\t\t\tsetHeight(dimensions.height)\n\t\t}\n\t}, { box }, timeout)\n\n\t// INTENTIONAL AVOID OF ESLint ERROR: We need measure on every Layout side-effect\n\t// otherwise the browser will paint and cause layout shifts.\n\t//\n\t// React Hook useLayoutEffect contains a call to 'setWidth'. Without a list of dependencies,\n\t// this can lead to an infinite chain of updates. To fix this, pass [element] as a second argument\n\t// to the useLayoutEffect Hook.\n\t//\n\t// Seems like only pure function lets us measure before the browser has a chance to paint\n\tconst measure = useRef((element: HTMLElement | null) => {\n\t\tlogged('measure(element)', element)\n\n\t\tif (element instanceof HTMLElement) {\n\t\t\tsetWidth(logged('getElementWidth(element):', getElementWidth(element)))\n\t\t\tsetHeight(logged('getElementHeight(element):', getElementHeight(element)))\n\t\t} else if (element) {\n\t\t\tthrow new Error('Exhaustive error: Expecting element to be instance of HTMLElement or Window')\n\t\t}\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tconst element = unwrapRefValue(refOrElement)\n\t\tlogged('useLayoutEffect => measure', measure.current(element))\n\t})\n\n\treturn { height, width }\n}\n"],"names":[],"mappings":";;;;;AAMA,SAAS,gBAAgB,SAAsB;AAC9C,SAAO,QAAQ;AAChB;AAEA,SAAS,iBAAiB,SAAsB;AAC/C,SAAO,QAAQ;AAChB;AAQO,SAAS,eACf,cACA,UAAiC,CAAA,GACjC,UAAkB,KAC0C;AAC5D,QAAM,EAAE,OAAW,IAAA,oBAAoB,gBAAgB,EAAE;AAEnD,QAAA,EAAE,MAAM,aAAiB,IAAA;AACzB,QAAA,iCAAiC,QAAQ,MAAM,sCAAsC,GAAG,GAAG,CAAC,GAAG,CAAC;AAEhG,QAAA,WAAW,eAAe,YAAY;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA6B,UAAU,WAAW;AAC5E,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA6B,UAAU,YAAY;AAE/E,SAAO,cAAc,EAAE,OAAO,OAAQ,CAAA;AAEtC,qBAAmB,cAAc,CAAS,UAAA;AACzC,UAAM,aAAa,OAAO,0CAA0C,+BAA+B,KAAK,CAAC;AAErG,QAAA,UAAU,WAAW,OAAO;AAC/B,eAAS,WAAW,KAAK;AAAA,IAC1B;AACI,QAAA,WAAW,WAAW,QAAQ;AACjC,gBAAU,WAAW,MAAM;AAAA,IAC5B;AAAA,EAAA,GACE,EAAE,OAAO,OAAO;AAUb,QAAA,UAAU,OAAO,CAAC,YAAgC;AACvD,WAAO,oBAAoB,OAAO;AAElC,QAAI,mBAAmB,aAAa;AACnC,eAAS,OAAO,6BAA6B,gBAAgB,OAAO,CAAC,CAAC;AACtE,gBAAU,OAAO,8BAA8B,iBAAiB,OAAO,CAAC,CAAC;AAAA,eAC/D,SAAS;AACb,YAAA,IAAI,MAAM,6EAA6E;AAAA,IAC9F;AAAA,EAAA,CACA;AAED,kBAAgB,MAAM;AACf,UAAA,UAAU,eAAe,YAAY;AAC3C,WAAO,8BAA8B,QAAQ,QAAQ,OAAO,CAAC;AAAA,EAAA,CAC7D;AAEM,SAAA,EAAE,QAAQ;AAClB;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
function useEventHandler(type, callback) {
|
|
3
|
+
const callbackRef = useRef(callback);
|
|
4
|
+
callbackRef.current = callback;
|
|
5
|
+
const stableHandler = useRef(function(event) {
|
|
6
|
+
return callbackRef.current(event);
|
|
7
|
+
}).current;
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
return () => {
|
|
10
|
+
callbackRef.current = () => {
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}, []);
|
|
14
|
+
return stableHandler;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
useEventHandler
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=useEventHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEventHandler.js","sources":["../../../src/hooks/useEventHandler.ts"],"sourcesContent":["import { EventHandler, SyntheticEvent, useEffect, useRef } from 'react'\n\n/**\n * Similar to useEvent with inferred type for the event parameter according to event type\n *\n * @param type - String, keyof DocumentEventMap, e.g. 'click', 'keydown',...\n * @param callback - EventHandler\n * @returns Stable reference callback\n */\nexport function useEventHandler<E extends SyntheticEvent<any>>(type: E['type'], callback: EventHandler<E>): EventHandler<E> {\n\tconst callbackRef = useRef(callback); callbackRef.current = callback\n\n\tconst stableHandler = useRef(function (event: any) {\n\t\treturn callbackRef.current(event)\n\t}).current\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tcallbackRef.current = () => { }\n\t\t}\n\t}, [])\n\n\treturn stableHandler\n}\n"],"names":[],"mappings":";AASgB,SAAA,gBAA+C,MAAiB,UAA4C;AACrH,QAAA,cAAc,OAAO,QAAQ;AAAG,cAAY,UAAU;AAEtD,QAAA,gBAAgB,OAAO,SAAU,OAAY;AAC3C,WAAA,YAAY,QAAQ,KAAK;AAAA,EAChC,CAAA,EAAE;AAEH,YAAU,MAAM;AACf,WAAO,MAAM;AACZ,kBAAY,UAAU,MAAM;AAAA,MAAA;AAAA,IAAE;AAAA,EAEhC,GAAG,CAAE,CAAA;AAEE,SAAA;AACR;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import deepEqual from "deep-equal";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
function useExpectSameValueReference(next, shouldThrow = false) {
|
|
4
|
+
const previous = useRef(next);
|
|
5
|
+
if (next !== previous.current && typeof next === "object" && typeof previous.current === "object" && deepEqual(next, previous.current)) {
|
|
6
|
+
if (shouldThrow) {
|
|
7
|
+
throw new Error("Expecting same reference for same values");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
previous.current = next;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
useExpectSameValueReference
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useExpectSameValueReference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useExpectSameValueReference.js","sources":["../../../src/hooks/useExpectSameValueReference.ts"],"sourcesContent":["import deepEqual from 'deep-equal'\nimport { useRef } from 'react'\n\n// TODO: Unify error behavior with useConstantValueInvariant() and maybe merge into one hook.\nexport function useExpectSameValueReference<T>(next: T, shouldThrow: boolean = false) {\n\tconst previous = useRef(next)\n\n\tif (next !== previous.current\n\t\t&& typeof next === 'object'\n\t\t&& typeof previous.current === 'object'\n\t\t&& deepEqual(next, previous.current)\n\t) {\n\t\tif (import.meta.env.DEV) {\n\t\t\tconsole.error('Previous and next next do not match in reference although match in value', {\n\t\t\t\tprevious: previous.current,\n\t\t\t\tnext,\n\t\t\t})\n\t\t}\n\n\t\tif (shouldThrow) {\n\t\t\tthrow new Error('Expecting same reference for same values')\n\t\t}\n\t}\n\n\tprevious.current = next\n}\n"],"names":[],"mappings":";;AAIgB,SAAA,4BAA+B,MAAS,cAAuB,OAAO;AAC/E,QAAA,WAAW,OAAO,IAAI;AAE5B,MAAI,SAAS,SAAS,WAClB,OAAO,SAAS,YAChB,OAAO,SAAS,YAAY,YAC5B,UAAU,MAAM,SAAS,OAAO,GAClC;AAQD,QAAI,aAAa;AACV,YAAA,IAAI,MAAM,0CAA0C;AAAA,IAC3D;AAAA,EACD;AAEA,WAAS,UAAU;AACpB;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useObjectMemo.js","sources":["../../../src/hooks/useObjectMemo.ts"],"sourcesContent":["import { useRef } from 'react'\n\nconst compareObjects = (a: object, b: object): boolean => {\n\tif (a === b) {\n\t\treturn true\n\t}\n\tconst aEntries = Object.entries(a)\n\tif (aEntries.length !== Object.keys(b).length) {\n\t\treturn false\n\t}\n\tfor (const [key, val] of aEntries) {\n\t\tif (!(key in b) || (b as any)[key] !== val) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nexport const useObjectMemo = <A extends object>(value: A): A => {\n\tconst valueRef = useRef(value)\n\tif (!compareObjects(valueRef.current, value)) {\n\t\tvalueRef.current = value\n\t}\n\treturn valueRef.current\n}\n"],"names":[],"mappings":";AAEA,MAAM,iBAAiB,CAAC,GAAW,MAAuB;AACzD,MAAI,MAAM,GAAG;AACL,WAAA;AAAA,EACR;AACM,QAAA,WAAW,OAAO,QAAQ,CAAC;AACjC,MAAI,SAAS,WAAW,OAAO,KAAK,CAAC,EAAE,QAAQ;AACvC,WAAA;AAAA,EACR;AACA,aAAW,CAAC,KAAK,GAAG,KAAK,UAAU;AAClC,QAAI,EAAE,OAAO,MAAO,EAAU,
|
|
1
|
+
{"version":3,"file":"useObjectMemo.js","sources":["../../../src/hooks/useObjectMemo.ts"],"sourcesContent":["import { useRef } from 'react'\n\nconst compareObjects = (a: object, b: object): boolean => {\n\tif (a === b) {\n\t\treturn true\n\t}\n\tconst aEntries = Object.entries(a)\n\tif (aEntries.length !== Object.keys(b).length) {\n\t\treturn false\n\t}\n\tfor (const [key, val] of aEntries) {\n\t\tif (!(key in b) || (b as any)[key] !== val) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nexport const useObjectMemo = <A extends object>(value: A): A => {\n\tconst valueRef = useRef(value)\n\tif (!compareObjects(valueRef.current, value)) {\n\t\tvalueRef.current = value\n\t}\n\treturn valueRef.current\n}\n"],"names":[],"mappings":";AAEA,MAAM,iBAAiB,CAAC,GAAW,MAAuB;AACzD,MAAI,MAAM,GAAG;AACL,WAAA;AAAA,EACR;AACM,QAAA,WAAW,OAAO,QAAQ,CAAC;AACjC,MAAI,SAAS,WAAW,OAAO,KAAK,CAAC,EAAE,QAAQ;AACvC,WAAA;AAAA,EACR;AACA,aAAW,CAAC,KAAK,GAAG,KAAK,UAAU;AAClC,QAAI,EAAE,OAAO,MAAO,EAAU,GAAG,MAAM,KAAK;AACpC,aAAA;AAAA,IACR;AAAA,EACD;AACO,SAAA;AACR;AAEa,MAAA,gBAAgB,CAAmB,UAAgB;AACzD,QAAA,WAAW,OAAO,KAAK;AAC7B,MAAI,CAAC,eAAe,SAAS,SAAS,KAAK,GAAG;AAC7C,aAAS,UAAU;AAAA,EACpB;AACA,SAAO,SAAS;AACjB;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import deepEqual from "deep-equal";
|
|
2
|
+
import { useRef, useState, useEffect, useLayoutEffect } from "react";
|
|
3
|
+
import { unwrapRefValue } from "./unwrapRefValue.js";
|
|
4
|
+
import { useScopedConsoleRef } from "../debug-context/Context.js";
|
|
5
|
+
function useOnElementMutation(refOrElement, callback, options = { attributes: true, childList: true, subtree: true }) {
|
|
6
|
+
const scopedConsoleRef = useScopedConsoleRef("useOnElementMutation");
|
|
7
|
+
const callbackRef = useRef(callback);
|
|
8
|
+
callbackRef.current = callback;
|
|
9
|
+
const optionsRef = useRef(options);
|
|
10
|
+
optionsRef.current = options;
|
|
11
|
+
const [optionsState, setOptionsState] = useState(options);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (!deepEqual(optionsRef.current, options)) {
|
|
14
|
+
setOptionsState(options);
|
|
15
|
+
}
|
|
16
|
+
}, [options]);
|
|
17
|
+
useLayoutEffect(() => {
|
|
18
|
+
const element = unwrapRefValue(refOrElement);
|
|
19
|
+
if (element) {
|
|
20
|
+
let handler = function(mutations, observer2) {
|
|
21
|
+
scopedConsoleRef.current.logged("element.mutations", mutations);
|
|
22
|
+
callbackRef.current(mutations, observer2);
|
|
23
|
+
};
|
|
24
|
+
const observer = new MutationObserver(handler);
|
|
25
|
+
observer.observe(element, optionsState);
|
|
26
|
+
return () => {
|
|
27
|
+
observer.disconnect();
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}, [optionsState, refOrElement, scopedConsoleRef]);
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
useOnElementMutation
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=useOnElementMutation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOnElementMutation.js","sources":["../../../src/hooks/useOnElementMutation.ts"],"sourcesContent":["import deepEqual from 'deep-equal'\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { useScopedConsoleRef } from '../debug-context'\nimport { RefObjectOrElement, unwrapRefValue } from './unwrapRefValue'\n\nexport function useOnElementMutation(\n\trefOrElement: RefObjectOrElement<HTMLElement | undefined>,\n\tcallback: MutationCallback,\n\toptions: MutationObserverInit = { attributes: true, childList: true, subtree: true },\n) {\n\tconst scopedConsoleRef = useScopedConsoleRef('useOnElementMutation')\n\n\tconst callbackRef = useRef(callback); callbackRef.current = callback\n\tconst optionsRef = useRef<MutationObserverInit>(options); optionsRef.current = options\n\n\tconst [optionsState, setOptionsState] = useState<MutationObserverInit>(options)\n\n\tuseEffect(() => {\n\t\tif (!deepEqual(optionsRef.current, options)) {\n\t\t\tsetOptionsState(options)\n\t\t}\n\t}, [options])\n\n\tuseLayoutEffect(() => {\n\t\tconst element = unwrapRefValue(refOrElement)\n\n\t\tif (element) {\n\t\t\tfunction handler(mutations: MutationRecord[], observer: MutationObserver) {\n\t\t\t\tscopedConsoleRef.current.logged('element.mutations', mutations)\n\t\t\t\tcallbackRef.current(mutations, observer)\n\t\t\t}\n\n\t\t\tconst observer = new MutationObserver(handler)\n\n\t\t\tobserver.observe(element, optionsState)\n\n\t\t\treturn () => {\n\t\t\t\tobserver.disconnect()\n\t\t\t}\n\t\t}\n\t}, [optionsState, refOrElement, scopedConsoleRef])\n}\n"],"names":["observer"],"mappings":";;;;AAKgB,SAAA,qBACf,cACA,UACA,UAAgC,EAAE,YAAY,MAAM,WAAW,MAAM,SAAS,KAAA,GAC7E;AACK,QAAA,mBAAmB,oBAAoB,sBAAsB;AAE7D,QAAA,cAAc,OAAO,QAAQ;AAAG,cAAY,UAAU;AACtD,QAAA,aAAa,OAA6B,OAAO;AAAG,aAAW,UAAU;AAE/E,QAAM,CAAC,cAAc,eAAe,IAAI,SAA+B,OAAO;AAE9E,YAAU,MAAM;AACf,QAAI,CAAC,UAAU,WAAW,SAAS,OAAO,GAAG;AAC5C,sBAAgB,OAAO;AAAA,IACxB;AAAA,EAAA,GACE,CAAC,OAAO,CAAC;AAEZ,kBAAgB,MAAM;AACf,UAAA,UAAU,eAAe,YAAY;AAE3C,QAAI,SAAS;AACH,UAAA,UAAT,SAAiB,WAA6BA,WAA4B;AACxD,yBAAA,QAAQ,OAAO,qBAAqB,SAAS;AAClD,oBAAA,QAAQ,WAAWA,SAAQ;AAAA,MAAA;AAGlC,YAAA,WAAW,IAAI,iBAAiB,OAAO;AAEpC,eAAA,QAAQ,SAAS,YAAY;AAEtC,aAAO,MAAM;AACZ,iBAAS,WAAW;AAAA,MAAA;AAAA,IAEtB;AAAA,EACE,GAAA,CAAC,cAAc,cAAc,gBAAgB,CAAC;AAClD;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useRef, useLayoutEffect } from "react";
|
|
2
|
+
import { unwrapRefValue } from "./unwrapRefValue.js";
|
|
3
|
+
import { useScopedConsoleRef } from "../debug-context/Context.js";
|
|
4
|
+
function useOnElementResize(refOrElement, callback, options = {}, timeout = 300) {
|
|
5
|
+
const scopedConsoleRef = useScopedConsoleRef("useOnElementResize");
|
|
6
|
+
const { box = "border-box" } = options;
|
|
7
|
+
const element = unwrapRefValue(refOrElement);
|
|
8
|
+
const callbackRef = useRef(callback);
|
|
9
|
+
callbackRef.current = callback;
|
|
10
|
+
const lastTimeStamp = useRef(0);
|
|
11
|
+
useLayoutEffect(() => {
|
|
12
|
+
let timeoutID = void 0;
|
|
13
|
+
function debouncedOnChange([entry]) {
|
|
14
|
+
const timeStamp = Date.now();
|
|
15
|
+
const delta = timeStamp - lastTimeStamp.current;
|
|
16
|
+
if (delta > timeout) {
|
|
17
|
+
scopedConsoleRef.current.warned("element.resize:immediate", null);
|
|
18
|
+
callbackRef.current(entry);
|
|
19
|
+
lastTimeStamp.current = timeStamp;
|
|
20
|
+
} else {
|
|
21
|
+
clearTimeout(timeoutID);
|
|
22
|
+
timeoutID = setTimeout(() => {
|
|
23
|
+
scopedConsoleRef.current.warned("element.resize:debounced", null);
|
|
24
|
+
callbackRef.current(entry);
|
|
25
|
+
lastTimeStamp.current = timeStamp;
|
|
26
|
+
}, timeout);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (element instanceof HTMLElement) {
|
|
30
|
+
const resizeObserver = new ResizeObserver(debouncedOnChange);
|
|
31
|
+
resizeObserver.observe(element, { box });
|
|
32
|
+
return () => {
|
|
33
|
+
clearTimeout(timeoutID);
|
|
34
|
+
resizeObserver.unobserve(element);
|
|
35
|
+
};
|
|
36
|
+
} else if (element) {
|
|
37
|
+
throw new Error("Exhaustive error: Expecting element to be instance of HTMLElement");
|
|
38
|
+
}
|
|
39
|
+
}, [box, element, scopedConsoleRef, timeout]);
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
useOnElementResize
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=useOnElementResize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOnElementResize.js","sources":["../../../src/hooks/useOnElementResize.ts"],"sourcesContent":["import { useLayoutEffect, useRef } from 'react'\nimport { useScopedConsoleRef } from '../debug-context'\nimport { RefObjectOrElement, unwrapRefValue } from './unwrapRefValue'\n\nexport function useOnElementResize(\n\trefOrElement: RefObjectOrElement<HTMLElement | null> | null,\n\tcallback: (entries: ResizeObserverEntry) => void,\n\toptions: ResizeObserverOptions = {},\n\ttimeout: number = 300,\n): void {\n\tconst scopedConsoleRef = useScopedConsoleRef('useOnElementResize')\n\n\tconst { box = 'border-box' } = options\n\tconst element = unwrapRefValue(refOrElement)\n\tconst callbackRef = useRef(callback); callbackRef.current = callback\n\tconst lastTimeStamp = useRef<number>(0)\n\n\tuseLayoutEffect(() => {\n\t\tlet timeoutID: number | undefined = undefined\n\n\t\tfunction debouncedOnChange([entry]: ResizeObserverEntry[]) {\n\t\t\tconst timeStamp = Date.now()\n\t\t\tconst delta = timeStamp - lastTimeStamp.current\n\n\t\t\tif (delta > timeout) {\n\t\t\t\tscopedConsoleRef.current.warned('element.resize:immediate', null)\n\t\t\t\tcallbackRef.current(entry)\n\t\t\t\tlastTimeStamp.current = timeStamp\n\t\t\t} else {\n\t\t\t\tclearTimeout(timeoutID)\n\t\t\t\ttimeoutID = setTimeout(() => {\n\t\t\t\t\tscopedConsoleRef.current.warned('element.resize:debounced', null)\n\t\t\t\t\tcallbackRef.current(entry)\n\t\t\t\t\tlastTimeStamp.current = timeStamp\n\t\t\t\t}, timeout)\n\t\t\t}\n\t\t}\n\n\t\tif (element instanceof HTMLElement) {\n\t\t\tconst resizeObserver = new ResizeObserver(debouncedOnChange)\n\n\t\t\tresizeObserver.observe(element, { box })\n\n\t\t\treturn () => {\n\t\t\t\tclearTimeout(timeoutID)\n\t\t\t\tresizeObserver.unobserve(element)\n\t\t\t}\n\t\t} else if (element) {\n\t\t\tthrow new Error('Exhaustive error: Expecting element to be instance of HTMLElement')\n\t\t}\n\t}, [box, element, scopedConsoleRef, timeout])\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,mBACf,cACA,UACA,UAAiC,CAAC,GAClC,UAAkB,KACX;AACD,QAAA,mBAAmB,oBAAoB,oBAAoB;AAE3D,QAAA,EAAE,MAAM,aAAiB,IAAA;AACzB,QAAA,UAAU,eAAe,YAAY;AACrC,QAAA,cAAc,OAAO,QAAQ;AAAG,cAAY,UAAU;AACtD,QAAA,gBAAgB,OAAe,CAAC;AAEtC,kBAAgB,MAAM;AACrB,QAAI,YAAgC;AAE3B,aAAA,kBAAkB,CAAC,KAAK,GAA0B;AACpD,YAAA,YAAY,KAAK;AACjB,YAAA,QAAQ,YAAY,cAAc;AAExC,UAAI,QAAQ,SAAS;AACH,yBAAA,QAAQ,OAAO,4BAA4B,IAAI;AAChE,oBAAY,QAAQ,KAAK;AACzB,sBAAc,UAAU;AAAA,MAAA,OAClB;AACN,qBAAa,SAAS;AACtB,oBAAY,WAAW,MAAM;AACX,2BAAA,QAAQ,OAAO,4BAA4B,IAAI;AAChE,sBAAY,QAAQ,KAAK;AACzB,wBAAc,UAAU;AAAA,WACtB,OAAO;AAAA,MACX;AAAA,IACD;AAEA,QAAI,mBAAmB,aAAa;AAC7B,YAAA,iBAAiB,IAAI,eAAe,iBAAiB;AAE3D,qBAAe,QAAQ,SAAS,EAAE,IAAK,CAAA;AAEvC,aAAO,MAAM;AACZ,qBAAa,SAAS;AACtB,uBAAe,UAAU,OAAO;AAAA,MAAA;AAAA,eAEvB,SAAS;AACb,YAAA,IAAI,MAAM,mEAAmE;AAAA,IACpF;AAAA,KACE,CAAC,KAAK,SAAS,kBAAkB,OAAO,CAAC;AAC7C;"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useRef, useLayoutEffect } from "react";
|
|
2
|
+
import { unwrapRefValue } from "./unwrapRefValue.js";
|
|
3
|
+
import { useScopedConsoleRef } from "../debug-context/Context.js";
|
|
4
|
+
function useOnScrollWithin(refOrElement, callback, interval = 1e3 / 60) {
|
|
5
|
+
const scopedConsoleRef = useScopedConsoleRef("useOnScrollWithin");
|
|
6
|
+
const callbackRef = useRef(callback);
|
|
7
|
+
callbackRef.current = callback;
|
|
8
|
+
const lastTimeStamp = useRef(0);
|
|
9
|
+
const element = unwrapRefValue(refOrElement);
|
|
10
|
+
useLayoutEffect(() => {
|
|
11
|
+
let timeoutID = void 0;
|
|
12
|
+
function debouncedHandler(event) {
|
|
13
|
+
clearTimeout(timeoutID);
|
|
14
|
+
const delta = event.timeStamp - lastTimeStamp.current;
|
|
15
|
+
scopedConsoleRef.current.logged("event:element.scroll:delta", delta);
|
|
16
|
+
if (delta > interval) {
|
|
17
|
+
scopedConsoleRef.current.warned("event:element.scroll:immediately", event);
|
|
18
|
+
callbackRef.current(event);
|
|
19
|
+
lastTimeStamp.current = event.timeStamp;
|
|
20
|
+
} else {
|
|
21
|
+
timeoutID = setTimeout(() => {
|
|
22
|
+
scopedConsoleRef.current.warned("event:element.scroll:debounced", event);
|
|
23
|
+
lastTimeStamp.current = event.timeStamp;
|
|
24
|
+
callbackRef.current(event);
|
|
25
|
+
}, interval);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (element && element instanceof HTMLElement) {
|
|
29
|
+
if (element instanceof HTMLBodyElement || element instanceof HTMLHtmlElement) {
|
|
30
|
+
window.addEventListener("scroll", debouncedHandler, { capture: true, passive: true });
|
|
31
|
+
window.addEventListener("resize", debouncedHandler);
|
|
32
|
+
return () => {
|
|
33
|
+
window.removeEventListener("scroll", debouncedHandler);
|
|
34
|
+
window.removeEventListener("resize", debouncedHandler);
|
|
35
|
+
};
|
|
36
|
+
} else {
|
|
37
|
+
element.addEventListener("scroll", debouncedHandler, { passive: true, capture: true });
|
|
38
|
+
return () => {
|
|
39
|
+
element.removeEventListener("scroll", debouncedHandler);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
} else if (element) {
|
|
43
|
+
throw new Error("Exhaustive error: Expecting element to be instance of HTMLElement");
|
|
44
|
+
}
|
|
45
|
+
}, [element, interval, scopedConsoleRef]);
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
useOnScrollWithin
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=useOnScrollWithin.js.map
|