@codeleap/hooks 7.0.0 → 7.0.2

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.
Files changed (63) hide show
  1. package/dist/index.js +58 -0
  2. package/dist/index.js.map +1 -0
  3. package/dist/onMount.js +20 -0
  4. package/dist/onMount.js.map +1 -0
  5. package/dist/onUpdate.js +19 -0
  6. package/dist/onUpdate.js.map +1 -0
  7. package/dist/useBooleanToggle.js +25 -0
  8. package/dist/useBooleanToggle.js.map +1 -0
  9. package/dist/useComponentTestId.js +47 -0
  10. package/dist/useComponentTestId.js.map +1 -0
  11. package/dist/useConditionalState.js +27 -0
  12. package/dist/useConditionalState.js.map +1 -0
  13. package/dist/useDebounce.js +28 -0
  14. package/dist/useDebounce.js.map +1 -0
  15. package/dist/useDebounceCallback.js +42 -0
  16. package/dist/useDebounceCallback.js.map +1 -0
  17. package/dist/useDerivedRef.js +20 -0
  18. package/dist/useDerivedRef.js.map +1 -0
  19. package/dist/useDerivedState.js +28 -0
  20. package/dist/useDerivedState.js.map +1 -0
  21. package/dist/useEffectOnce.js +18 -0
  22. package/dist/useEffectOnce.js.map +1 -0
  23. package/dist/useFilteredList.js +24 -0
  24. package/dist/useFilteredList.js.map +1 -0
  25. package/dist/useForceRender.js +16 -0
  26. package/dist/useForceRender.js.map +1 -0
  27. package/dist/useId.js +18 -0
  28. package/dist/useId.js.map +1 -0
  29. package/dist/useInterval.js +49 -0
  30. package/dist/useInterval.js.map +1 -0
  31. package/dist/useIsMounted.js +39 -0
  32. package/dist/useIsMounted.js.map +1 -0
  33. package/dist/useLazyStore.js +20 -0
  34. package/dist/useLazyStore.js.map +1 -0
  35. package/dist/useModal.js +34 -0
  36. package/dist/useModal.js.map +1 -0
  37. package/dist/useOptions.js +28 -0
  38. package/dist/useOptions.js.map +1 -0
  39. package/dist/usePartialState.js +26 -0
  40. package/dist/usePartialState.js.map +1 -0
  41. package/dist/usePlaces.js +82 -0
  42. package/dist/usePlaces.js.map +1 -0
  43. package/dist/usePlacesAutocompleteUtils.js +65 -0
  44. package/dist/usePlacesAutocompleteUtils.js.map +1 -0
  45. package/dist/usePrevious.js +23 -0
  46. package/dist/usePrevious.js.map +1 -0
  47. package/dist/usePromise.js +66 -0
  48. package/dist/usePromise.js.map +1 -0
  49. package/dist/useRenderCall.js +13 -0
  50. package/dist/useRenderCall.js.map +1 -0
  51. package/dist/useSearch/index.js +83 -0
  52. package/dist/useSearch/index.js.map +1 -0
  53. package/dist/useSearch/types.js +3 -0
  54. package/dist/useSearch/types.js.map +1 -0
  55. package/dist/useStableReference.js +15 -0
  56. package/dist/useStableReference.js.map +1 -0
  57. package/dist/useToggle.js +21 -0
  58. package/dist/useToggle.js.map +1 -0
  59. package/dist/useUncontrolled.js +58 -0
  60. package/dist/useUncontrolled.js.map +1 -0
  61. package/dist/useUnmount.js +23 -0
  62. package/dist/useUnmount.js.map +1 -0
  63. package/package.json +9 -9
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useOptions = useOptions;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Hook that manages selected option state with boolean flags for each option.
7
+ *
8
+ * @example
9
+ * const { selectedOption, setSelectedOption, isSelected } = useOptions(['light', 'dark'] as const)
10
+ * // isSelected = { light: true, dark: false }
11
+ * setSelectedOption('dark')
12
+ * // isSelected = { light: false, dark: true }
13
+ */
14
+ function useOptions(options, initialOptions = options[0]) {
15
+ const [selectedOption, setSelectedOption] = (0, react_1.useState)(initialOptions);
16
+ const isSelected = (0, react_1.useMemo)(() => {
17
+ return options.reduce((acc, option) => {
18
+ acc[option] = option === selectedOption;
19
+ return acc;
20
+ }, {});
21
+ }, [selectedOption, options]);
22
+ return {
23
+ selectedOption,
24
+ setSelectedOption,
25
+ isSelected,
26
+ };
27
+ }
28
+ //# sourceMappingURL=useOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOptions.js","sourceRoot":"","sources":["../src/useOptions.ts"],"names":[],"mappings":";;AAWA,gCAeC;AA1BD,iCAAyC;AAEzC;;;;;;;;GAQG;AACH,SAAgB,UAAU,CAAmB,OAAqB,EAAE,iBAAoB,OAAO,CAAC,CAAC,CAAC;IAChG,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,gBAAQ,EAAI,cAAc,CAAC,CAAA;IAEvE,MAAM,UAAU,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAC9B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YACpC,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,KAAK,cAAc,CAAA;YACvC,OAAO,GAAG,CAAA;QACZ,CAAC,EAAE,EAAwB,CAAC,CAAA;IAC9B,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAA;IAE7B,OAAO;QACL,cAAc;QACd,iBAAiB;QACjB,UAAU;KACX,CAAA;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePartialState = usePartialState;
4
+ const react_1 = require("react");
5
+ const utils_1 = require("@codeleap/utils");
6
+ /**
7
+ * Hook that manages state with partial updates using deep merge.
8
+ *
9
+ * @example
10
+ * const [user, setUser] = usePartialState({ name: 'John', age: 30 })
11
+ * setUser({ age: 31 }) // Only updates age, keeps name
12
+ * setUser(prev => ({ age: prev.age + 1 })) // Functional update
13
+ */
14
+ function usePartialState(initial) {
15
+ const [state, setState] = (0, react_1.useState)(initial);
16
+ function setPartial(value) {
17
+ if (typeof value === 'function') {
18
+ setState((v) => (0, utils_1.deepMerge)(v, value(v)));
19
+ }
20
+ else {
21
+ setState((0, utils_1.deepMerge)(state, value));
22
+ }
23
+ }
24
+ return [state, setPartial];
25
+ }
26
+ //# sourceMappingURL=usePartialState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePartialState.js","sourceRoot":"","sources":["../src/usePartialState.ts"],"names":[],"mappings":";;AAcA,0CAcC;AA5BD,iCAAgC;AAEhC,2CAA2C;AAI3C;;;;;;;GAOG;AACH,SAAgB,eAAe,CAAyB,OAAsB;IAC5E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAC,OAAO,CAAC,CAAA;IAE3C,SAAS,UAAU,CACjB,KAAkD;QAElD,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,iBAAS,EAAC,CAAC,EAAE,KAAK,CAAC,CAAM,CAAC,CAAC,CAAC,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAA,iBAAS,EAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,KAAU,EAAE,UAAU,CAAU,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.usePlaces = exports.retrievePlaces = exports.retrievePlaceDetails = void 0;
16
+ const axios_1 = __importDefault(require("axios"));
17
+ const react_query_1 = require("@tanstack/react-query");
18
+ const BASE_URL = 'https://maps.googleapis.com/maps/api/place/autocomplete/json';
19
+ const BASE_URL_DETAILS = 'https://maps.googleapis.com/maps/api/place/details/json';
20
+ const BASE_URL_GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json';
21
+ const latLngRegex = /^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/;
22
+ /**
23
+ * Retrieves detailed information for a specific Google Place.
24
+ */
25
+ const retrievePlaceDetails = (placeId, apiKey) => __awaiter(void 0, void 0, void 0, function* () {
26
+ var _a;
27
+ const response = yield axios_1.default.get(BASE_URL_DETAILS, {
28
+ params: {
29
+ place_id: placeId,
30
+ key: apiKey,
31
+ },
32
+ });
33
+ return (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.result;
34
+ });
35
+ exports.retrievePlaceDetails = retrievePlaceDetails;
36
+ /**
37
+ * Retrieves places from Google Places API or Geocoding API.
38
+ * Supports both text search and lat/lng coordinates.
39
+ */
40
+ const retrievePlaces = (params) => __awaiter(void 0, void 0, void 0, function* () {
41
+ var _a, _b, _c, _d, _e;
42
+ let response;
43
+ const inputWithoutSpaces = (_b = (_a = params === null || params === void 0 ? void 0 : params.input) === null || _a === void 0 ? void 0 : _a.replace(/\s/g, '')) !== null && _b !== void 0 ? _b : '';
44
+ const isLatLng = latLngRegex === null || latLngRegex === void 0 ? void 0 : latLngRegex.test(inputWithoutSpaces);
45
+ if (isLatLng) {
46
+ response = yield (axios_1.default === null || axios_1.default === void 0 ? void 0 : axios_1.default.get(BASE_URL_GEOCODING, { params: { latlng: params === null || params === void 0 ? void 0 : params.input, key: params === null || params === void 0 ? void 0 : params.key } }));
47
+ }
48
+ else {
49
+ response = yield (axios_1.default === null || axios_1.default === void 0 ? void 0 : axios_1.default.get(BASE_URL, { params }));
50
+ }
51
+ let places = ((_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.results) || ((_d = response === null || response === void 0 ? void 0 : response.data) === null || _d === void 0 ? void 0 : _d.predictions);
52
+ if (params === null || params === void 0 ? void 0 : params.showDetails) {
53
+ const apiKey = (_e = params === null || params === void 0 ? void 0 : params.key) !== null && _e !== void 0 ? _e : '';
54
+ places = yield Promise.all(places === null || places === void 0 ? void 0 : places.map((place) => __awaiter(void 0, void 0, void 0, function* () {
55
+ const placeId = place === null || place === void 0 ? void 0 : place.place_id;
56
+ const details = yield (0, exports.retrievePlaceDetails)(placeId, apiKey);
57
+ return Object.assign(Object.assign({}, place), { details });
58
+ })));
59
+ }
60
+ return places;
61
+ });
62
+ exports.retrievePlaces = retrievePlaces;
63
+ /**
64
+ * Hook that fetches Google Places using React Query.
65
+ * Automatically handles caching and refetching.
66
+ *
67
+ * @example
68
+ * const places = usePlaces({
69
+ * input: 'New York',
70
+ * key: 'YOUR_API_KEY',
71
+ * showDetails: true
72
+ * })
73
+ */
74
+ const usePlaces = (params) => {
75
+ const places = (0, react_query_1.useQuery)({
76
+ queryKey: ['places', params],
77
+ queryFn: () => (0, exports.retrievePlaces)(params),
78
+ });
79
+ return places;
80
+ };
81
+ exports.usePlaces = usePlaces;
82
+ //# sourceMappingURL=usePlaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePlaces.js","sourceRoot":"","sources":["../src/usePlaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.usePlacesAutocompleteUtils = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const types_1 = require("@codeleap/types");
9
+ /**
10
+ * Hook that manages address autocomplete state with debounced input handling.
11
+ * Useful for Google Places autocomplete implementations.
12
+ *
13
+ * @example
14
+ * const {
15
+ * address,
16
+ * handleChangeAddress,
17
+ * handlePressAddress,
18
+ * isTyping
19
+ * } = usePlacesAutocompleteUtils({
20
+ * debounce: 500,
21
+ * onValueChange: (addr) => fetchPlaces(addr),
22
+ * onPress: (addr, item) => console.log('Selected:', item)
23
+ * })
24
+ */
25
+ const usePlacesAutocompleteUtils = (props) => {
26
+ const { debounce = 250, onValueChange, onPress, } = props;
27
+ const [address, setAddress] = react_1.default.useState('');
28
+ const [isTyping, setIsTyping] = react_1.default.useState(false);
29
+ const setSearchTimeout = react_1.default.useRef(null);
30
+ const handleChangeAddress = (address) => {
31
+ setAddress(address);
32
+ if (types_1.TypeGuards.isNil(debounce)) {
33
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(address);
34
+ setTimeout(() => setIsTyping(false), 250);
35
+ }
36
+ else {
37
+ if (setSearchTimeout.current) {
38
+ clearTimeout(setSearchTimeout.current);
39
+ setSearchTimeout.current = null;
40
+ }
41
+ setSearchTimeout.current = setTimeout(() => {
42
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(address);
43
+ setIsTyping(false);
44
+ }, debounce !== null && debounce !== void 0 ? debounce : 0);
45
+ }
46
+ };
47
+ const handlePressAddress = (address, item) => {
48
+ setAddress(address);
49
+ onPress === null || onPress === void 0 ? void 0 : onPress(address, item);
50
+ };
51
+ const handleClearAddress = () => {
52
+ setAddress('');
53
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange('');
54
+ };
55
+ return {
56
+ handleChangeAddress,
57
+ handlePressAddress,
58
+ handleClearAddress,
59
+ address,
60
+ isTyping,
61
+ setIsTyping,
62
+ };
63
+ };
64
+ exports.usePlacesAutocompleteUtils = usePlacesAutocompleteUtils;
65
+ //# sourceMappingURL=usePlacesAutocompleteUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePlacesAutocompleteUtils.js","sourceRoot":"","sources":["../src/usePlacesAutocompleteUtils.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AACzB,2CAA4C;AAQ5C;;;;;;;;;;;;;;;GAeG;AACI,MAAM,0BAA0B,GAAG,CAAgC,KAAyC,EAAE,EAAE;IACrH,MAAM,EACJ,QAAQ,GAAG,GAAG,EACd,aAAa,EACb,OAAO,GACR,GAAG,KAAK,CAAA;IAET,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAChD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAErD,MAAM,gBAAgB,GAAG,eAAK,CAAC,MAAM,CAAuC,IAAI,CAAC,CAAA;IAEjF,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,EAAE;QAC9C,UAAU,CAAC,OAAO,CAAC,CAAA;QAEnB,IAAI,kBAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,OAAO,CAAC,CAAA;YACxB,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAA;QAC3C,CAAC;aAAM,CAAC;YACN,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC7B,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;gBACtC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAA;YACjC,CAAC;YAED,gBAAgB,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBACzC,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,OAAO,CAAC,CAAA;gBACxB,WAAW,CAAC,KAAK,CAAC,CAAA;YACpB,CAAC,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,CAAC,CAAC,CAAA;QACnB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAE,IAAO,EAAE,EAAE;QACtD,UAAU,CAAC,OAAO,CAAC,CAAA;QACnB,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,OAAO,EAAE,IAAI,CAAC,CAAA;IAC1B,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,UAAU,CAAC,EAAE,CAAC,CAAA;QACd,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,EAAE,CAAC,CAAA;IACrB,CAAC,CAAA;IAED,OAAO;QACL,mBAAmB;QACnB,kBAAkB;QAClB,kBAAkB;QAClB,OAAO;QACP,QAAQ;QACR,WAAW;KACZ,CAAA;AACH,CAAC,CAAA;AAjDY,QAAA,0BAA0B,8BAiDtC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePrevious = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Hook that returns the previous value of a variable.
7
+ * The value is updated after render is committed to the DOM.
8
+ *
9
+ * @example
10
+ * const [count, setCount] = useState(0)
11
+ * const prevCount = usePrevious(count)
12
+ * // On first render: count=0, prevCount=null
13
+ * // After setCount(1): count=1, prevCount=0
14
+ */
15
+ const usePrevious = (value) => {
16
+ const ref = (0, react_1.useRef)(null);
17
+ (0, react_1.useEffect)(() => {
18
+ ref.current = value;
19
+ });
20
+ return ref.current;
21
+ };
22
+ exports.usePrevious = usePrevious;
23
+ //# sourceMappingURL=usePrevious.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePrevious.js","sourceRoot":"","sources":["../src/usePrevious.ts"],"names":[],"mappings":";;;AAAA,iCAAyC;AAEzC;;;;;;;;;GASG;AACI,MAAM,WAAW,GAAG,CAAI,KAAQ,EAAE,EAAE;IACzC,MAAM,GAAG,GAAG,IAAA,cAAM,EAAI,IAAI,CAAC,CAAA;IAC3B,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;IACrB,CAAC,CAAC,CAAA;IACF,OAAO,GAAG,CAAC,OAAO,CAAA;AACpB,CAAC,CAAA;AANY,QAAA,WAAW,eAMvB"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.usePromise = void 0;
13
+ const react_1 = require("react");
14
+ const types_1 = require("@codeleap/types");
15
+ /**
16
+ * Hook that creates a deferred promise with manual resolve/reject control.
17
+ * Useful for coordinating asynchronous operations across component lifecycle.
18
+ *
19
+ * @example
20
+ * const promise = usePromise({ timeout: 5000 })
21
+ * const handleClick = async () => {
22
+ * const result = await promise._await()
23
+ * console.log(result)
24
+ * }
25
+ * // Later, from another callback:
26
+ * promise.resolve('success')
27
+ */
28
+ const usePromise = (options) => {
29
+ const rejectRef = (0, react_1.useRef)(null);
30
+ const resolveRef = (0, react_1.useRef)(null);
31
+ const timeoutRef = (0, react_1.useRef)(null);
32
+ const reject = (err) => __awaiter(void 0, void 0, void 0, function* () {
33
+ var _a, _b;
34
+ yield ((_a = rejectRef.current) === null || _a === void 0 ? void 0 : _a.call(rejectRef, err));
35
+ (_b = options === null || options === void 0 ? void 0 : options.onReject) === null || _b === void 0 ? void 0 : _b.call(options, err);
36
+ if (timeoutRef.current)
37
+ clearTimeout(timeoutRef.current);
38
+ rejectRef.current = null;
39
+ });
40
+ const resolve = (value) => __awaiter(void 0, void 0, void 0, function* () {
41
+ var _a, _b;
42
+ yield ((_a = resolveRef.current) === null || _a === void 0 ? void 0 : _a.call(resolveRef, value));
43
+ (_b = options === null || options === void 0 ? void 0 : options.onResolve) === null || _b === void 0 ? void 0 : _b.call(options, value);
44
+ if (timeoutRef.current)
45
+ clearTimeout(timeoutRef.current);
46
+ resolveRef.current = null;
47
+ });
48
+ const _await = () => {
49
+ return new Promise((resolve, reject) => {
50
+ rejectRef.current = reject;
51
+ resolveRef.current = resolve;
52
+ if (types_1.TypeGuards.isNumber(options === null || options === void 0 ? void 0 : options.timeout) && (options === null || options === void 0 ? void 0 : options.timeout) > 0) {
53
+ timeoutRef.current = setTimeout(() => {
54
+ reject(new Error(`usePromise: ${(options === null || options === void 0 ? void 0 : options.debugName) || ''} timed out after ${options === null || options === void 0 ? void 0 : options.timeout}ms`));
55
+ }, options === null || options === void 0 ? void 0 : options.timeout);
56
+ }
57
+ });
58
+ };
59
+ return {
60
+ _await,
61
+ resolve,
62
+ reject,
63
+ };
64
+ };
65
+ exports.usePromise = usePromise;
66
+ //# sourceMappingURL=usePromise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePromise.js","sourceRoot":"","sources":["../src/usePromise.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iCAA8B;AAC9B,2CAAyD;AASzD;;;;;;;;;;;;GAYG;AACI,MAAM,UAAU,GAAG,CAAU,OAA8B,EAAE,EAAE;IACpE,MAAM,SAAS,GAAG,IAAA,cAAM,EAAc,IAAI,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAG,IAAA,cAAM,EAAe,IAAI,CAAC,CAAA;IAC7C,MAAM,UAAU,GAAG,IAAA,cAAM,EAAuC,IAAI,CAAC,CAAA;IAErE,MAAM,MAAM,GAAG,CAAO,GAAQ,EAAE,EAAE;;QAChC,MAAM,CAAA,MAAA,SAAS,CAAC,OAAO,0DAAG,GAAG,CAAC,CAAA,CAAA;QAC9B,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,wDAAG,GAAG,CAAC,CAAA;QACxB,IAAI,UAAU,CAAC,OAAO;YAAE,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACxD,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;IAC1B,CAAC,CAAA,CAAA;IAED,MAAM,OAAO,GAAG,CAAO,KAAQ,EAAE,EAAE;;QACjC,MAAM,CAAA,MAAA,UAAU,CAAC,OAAO,2DAAG,KAAK,CAAC,CAAA,CAAA;QACjC,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,wDAAG,KAAK,CAAC,CAAA;QAC3B,IAAI,UAAU,CAAC,OAAO;YAAE,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACxD,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;IAC3B,CAAC,CAAA,CAAA;IAED,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAA;YAC1B,UAAU,CAAC,OAAO,GAAG,OAAO,CAAA;YAC5B,IAAI,kBAAU,CAAC,QAAQ,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,IAAG,CAAC,EAAE,CAAC;gBAClE,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;oBACnC,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,KAAI,EAAE,oBAAoB,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,IAAI,CAAC,CAAC,CAAA;gBACpG,CAAC,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,CAAA;YACtB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,OAAO;QACL,MAAM;QACN,OAAO;QACP,MAAM;KACP,CAAA;AACH,CAAC,CAAA;AApCY,QAAA,UAAU,cAoCtB"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useRenderCall = useRenderCall;
4
+ const react_1 = require("react");
5
+ /** Calls `fn` synchronously during render, capped at `maxRunCount` renders (default 1). Does not use effects — execution happens inline during the render phase. */
6
+ function useRenderCall(fn, maxRunCount = 1) {
7
+ const callCount = (0, react_1.useRef)(0);
8
+ if (callCount.current < maxRunCount) {
9
+ callCount.current++;
10
+ fn();
11
+ }
12
+ }
13
+ //# sourceMappingURL=useRenderCall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRenderCall.js","sourceRoot":"","sources":["../src/useRenderCall.ts"],"names":[],"mappings":";;AAGA,sCAMC;AATD,iCAA8B;AAE9B,oKAAoK;AACpK,SAAgB,aAAa,CAAC,EAAc,EAAE,WAAW,GAAG,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAA,cAAM,EAAC,CAAC,CAAC,CAAA;IAC3B,IAAI,SAAS,CAAC,OAAO,GAAG,WAAW,EAAE,CAAC;QACpC,SAAS,CAAC,OAAO,EAAE,CAAA;QACnB,EAAE,EAAE,CAAA;IACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.useSearch = useSearch;
13
+ const react_1 = require("react");
14
+ const useBooleanToggle_1 = require("../useBooleanToggle");
15
+ const types_1 = require("@codeleap/types");
16
+ /**
17
+ * Hook that manages searchable select/autocomplete state with async loading support.
18
+ * Handles both local filtering and remote data fetching.
19
+ *
20
+ * @example
21
+ * const search = useSearch({
22
+ * value: 'selected-value',
23
+ * multiple: false,
24
+ * defaultOptions: [...],
25
+ * loadOptions: async (query) => fetchOptions(query),
26
+ * filterItems: (query, opts) => opts.filter(o => o.label.includes(query))
27
+ * })
28
+ *
29
+ * search.onChangeSearch('query')
30
+ * search.load()
31
+ */
32
+ function useSearch(props) {
33
+ const { value, multiple, options, filterItems, debugName, defaultOptions, loadOptions, onLoadOptionsError, } = Object.assign({}, props);
34
+ const [loading, setLoading] = (0, useBooleanToggle_1.useBooleanToggle)(false);
35
+ const isValueArray = types_1.TypeGuards.isArray(value) && multiple;
36
+ const [labelOptions, setLabelOptions] = (0, react_1.useState)(() => {
37
+ if (isValueArray) {
38
+ return defaultOptions.filter(o => value.includes(o.value));
39
+ }
40
+ const _option = defaultOptions.find(o => o.value === value);
41
+ if (!_option) {
42
+ return [];
43
+ }
44
+ return [_option];
45
+ });
46
+ const [filteredOptions, setFilteredOptions] = (0, react_1.useState)(defaultOptions);
47
+ const [, setSearchInput] = (0, react_1.useState)('');
48
+ function load() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ setLoading(true);
51
+ try {
52
+ const options = yield loadOptions('');
53
+ setFilteredOptions(options);
54
+ }
55
+ catch (e) {
56
+ onLoadOptionsError(e);
57
+ }
58
+ setLoading(false);
59
+ });
60
+ }
61
+ const onChangeSearch = (searchValue) => __awaiter(this, void 0, void 0, function* () {
62
+ setSearchInput(searchValue);
63
+ if (!!loadOptions) {
64
+ setLoading(true);
65
+ try {
66
+ const _opts = yield loadOptions(searchValue);
67
+ setFilteredOptions(_opts);
68
+ }
69
+ catch (e) {
70
+ console.error(`Error loading select options [${debugName}], e`);
71
+ onLoadOptionsError === null || onLoadOptionsError === void 0 ? void 0 : onLoadOptionsError(e);
72
+ }
73
+ setTimeout(() => {
74
+ setLoading(false);
75
+ }, 0);
76
+ return;
77
+ }
78
+ const _opts = filterItems(searchValue, options);
79
+ setFilteredOptions(_opts);
80
+ });
81
+ return { loading, setLoading, labelOptions, setLabelOptions, filteredOptions, load, onChangeSearch };
82
+ }
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/useSearch/index.ts"],"names":[],"mappings":";;;;;;;;;;;AAqBA,8BAiEC;AAtFD,iCAAgC;AAChC,0DAAsD;AAEtD,2CAA4C;AAE5C;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,SAAS,CAAkE,KAAgC;IACzH,MAAM,EACJ,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,SAAS,EACT,cAAc,EAEd,WAAW,EACX,kBAAkB,GACnB,qBAAQ,KAAK,CAAE,CAAA;IAEhB,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,mCAAgB,EAAC,KAAK,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,kBAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAA;IAC1D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE;QACpD,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5D,CAAC;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;QAE3D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,CAAA;QACX,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,IAAA,gBAAQ,EAAC,cAAc,CAAC,CAAA;IACtE,MAAM,CAAC,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,EAAE,CAAC,CAAA;IAEvC,SAAe,IAAI;;YACjB,UAAU,CAAC,IAAI,CAAC,CAAA;YAChB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAA;gBACrC,kBAAkB,CAAC,OAAO,CAAC,CAAA;YAC7B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,kBAAkB,CAAC,CAAC,CAAC,CAAA;YACvB,CAAC;YACD,UAAU,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC;KAAA;IAED,MAAM,cAAc,GAAG,CAAO,WAAkB,EAAE,EAAE;QAClD,cAAc,CAAC,WAAW,CAAC,CAAA;QAE3B,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAClB,UAAU,CAAC,IAAI,CAAC,CAAA;YAChB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAA;gBAC5C,kBAAkB,CAAC,KAAK,CAAC,CAAA;YAC3B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,SAAS,MAAM,CAAC,CAAA;gBAC/D,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAG,CAAC,CAAC,CAAA;YACzB,CAAC;YACD,UAAU,CAAC,GAAG,EAAE;gBACd,UAAU,CAAC,KAAK,CAAC,CAAA;YACnB,CAAC,EAAE,CAAC,CAAC,CAAA;YACL,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAC/C,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC,CAAA,CAAA;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,CAAA;AACtG,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/useSearch/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useStableReference = useStableReference;
4
+ const utils_1 = require("@codeleap/utils");
5
+ const react_1 = require("react");
6
+ /** Returns the previous ref value when the object is deeply equal to the last render, preventing unnecessary re-renders caused by referential inequality. */
7
+ function useStableReference(value) {
8
+ const ref = (0, react_1.useRef)(value);
9
+ const hasChanged = !(0, utils_1.deepEqual)(ref.current, value);
10
+ if (hasChanged) {
11
+ ref.current = value;
12
+ }
13
+ return ref.current;
14
+ }
15
+ //# sourceMappingURL=useStableReference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStableReference.js","sourceRoot":"","sources":["../src/useStableReference.ts"],"names":[],"mappings":";;AAIA,gDAUC;AAdD,2CAA2C;AAC3C,iCAA8B;AAE9B,6JAA6J;AAC7J,SAAgB,kBAAkB,CAAgC,KAAQ;IACxE,MAAM,GAAG,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAA;IAEzB,MAAM,UAAU,GAAG,CAAC,IAAA,iBAAS,EAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAEjD,IAAI,UAAU,EAAE,CAAC;QACf,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;IACrB,CAAC;IAED,OAAO,GAAG,CAAC,OAAO,CAAA;AACpB,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useToggle = useToggle;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Hook that toggles between two values.
7
+ *
8
+ * @example
9
+ * const [theme, toggleTheme] = useToggle(['light', 'dark'] as const, 'light')
10
+ * toggleTheme() // Switches to 'dark'
11
+ * toggleTheme('light') // Sets to 'light'
12
+ */
13
+ function useToggle(options, initial) {
14
+ const [value, setValue] = (0, react_1.useState)(initial);
15
+ function toggleOrSetValue(newValue) {
16
+ const v = newValue || (value === options[0] ? options[1] : options[0]);
17
+ setValue(v);
18
+ }
19
+ return [value, toggleOrSetValue];
20
+ }
21
+ //# sourceMappingURL=useToggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useToggle.js","sourceRoot":"","sources":["../src/useToggle.ts"],"names":[],"mappings":";;AAUA,8BAaC;AAvBD,iCAAgC;AAEhC;;;;;;;GAOG;AACH,SAAgB,SAAS,CACvB,OAAU,EACV,OAAU;IAEV,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAC,OAAO,CAAC,CAAA;IAE3C,SAAS,gBAAgB,CAAC,QAAY;QACpC,MAAM,CAAC,GAAM,QAAQ,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;QAEzE,QAAQ,CAAC,CAAC,CAAC,CAAA;IACb,CAAC;IAED,OAAO,CAAC,KAAK,EAAE,gBAAgB,CAAU,CAAA;AAC3C,CAAC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useUncontrolled = useUncontrolled;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Hook that manages controlled/uncontrolled component pattern with smooth transitions.
7
+ *
8
+ * @example
9
+ * const [value, handleChange, mode] = useUncontrolled({
10
+ * value: props.value,
11
+ * defaultValue: 'default',
12
+ * finalValue: '',
13
+ * rule: (v) => v !== undefined,
14
+ * onChange: (v) => props.onChange?.(v)
15
+ * })
16
+ */
17
+ function useUncontrolled({ value, defaultValue, finalValue, rule, onChange, onValueUpdate, }) {
18
+ var _a;
19
+ // determine, whether new props indicate controlled state
20
+ const shouldBeControlled = rule(value);
21
+ // initialize state
22
+ const modeRef = (0, react_1.useRef)('initial');
23
+ const initialValue = rule(defaultValue) ? defaultValue : finalValue;
24
+ const [uncontrolledValue, setUncontrolledValue] = (0, react_1.useState)(initialValue);
25
+ // compute effective value
26
+ let effectiveValue = (_a = (shouldBeControlled ? value : uncontrolledValue)) !== null && _a !== void 0 ? _a : null;
27
+ if (!shouldBeControlled && modeRef.current === 'controlled') {
28
+ // We are transitioning from controlled to uncontrolled
29
+ // this transition is special as it happens when clearing out
30
+ // the input using "invalid" value (typically null or undefined).
31
+ //
32
+ // Since the value is invalid, doing nothing would mean just
33
+ // transitioning to uncontrolled state and using whatever value
34
+ // it currently holds which is likely not the behavior
35
+ // user expects, so lets change the state to finalValue.
36
+ //
37
+ // The value will be propagated to internal state by useEffect below.
38
+ effectiveValue = finalValue;
39
+ }
40
+ modeRef.current = shouldBeControlled ? 'controlled' : 'uncontrolled';
41
+ const mode = modeRef.current;
42
+ const handleChange = (nextValue) => {
43
+ typeof onChange === 'function' && onChange(nextValue);
44
+ // Controlled input only triggers onChange event and expects
45
+ // the controller to propagate new value back.
46
+ if (mode === 'uncontrolled') {
47
+ setUncontrolledValue(nextValue);
48
+ }
49
+ };
50
+ (0, react_1.useEffect)(() => {
51
+ if (mode === 'uncontrolled') {
52
+ setUncontrolledValue(effectiveValue);
53
+ }
54
+ typeof onValueUpdate === 'function' && onValueUpdate(effectiveValue);
55
+ }, [mode, effectiveValue]);
56
+ return [effectiveValue, handleChange, modeRef.current];
57
+ }
58
+ //# sourceMappingURL=useUncontrolled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUncontrolled.js","sourceRoot":"","sources":["../src/useUncontrolled.ts"],"names":[],"mappings":";;AAyBA,0CAuDC;AAhFD,iCAAmD;AAanD;;;;;;;;;;;GAWG;AACH,SAAgB,eAAe,CAAI,EACjC,KAAK,EACL,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,aAAa,GACU;;IACvB,yDAAyD;IACzD,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;IAEtC,mBAAmB;IACnB,MAAM,OAAO,GAAG,IAAA,cAAM,EAAmB,SAAS,CAAC,CAAA;IACnD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAA;IACnE,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,IAAA,gBAAQ,EAAC,YAAY,CAAC,CAAA;IAExE,0BAA0B;IAC1B,IAAI,cAAc,GAAa,MAAA,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,mCAAI,IAAI,CAAA;IAEvF,IAAI,CAAC,kBAAkB,IAAI,OAAO,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;QAC5D,uDAAuD;QACvD,6DAA6D;QAC7D,iEAAiE;QACjE,EAAE;QACF,4DAA4D;QAC5D,+DAA+D;QAC/D,sDAAsD;QACtD,wDAAwD;QACxD,EAAE;QACF,qEAAqE;QAErE,cAAc,GAAG,UAAU,CAAA;IAC7B,CAAC;IAED,OAAO,CAAC,OAAO,GAAG,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAA;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAA;IAE5B,MAAM,YAAY,GAAG,CAAC,SAAmB,EAAE,EAAE;QAC3C,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAA;QAErD,4DAA4D;QAC5D,8CAA8C;QAC9C,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YAC5B,oBAAoB,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC;IACH,CAAC,CAAA;IAED,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YAC5B,oBAAoB,CAAC,cAAc,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,aAAa,KAAK,UAAU,IAAI,aAAa,CAAC,cAAc,CAAC,CAAA;IACtE,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAA;IAE1B,OAAO,CAAC,cAAc,EAAE,YAAY,EAAE,OAAO,CAAC,OAAO,CAAU,CAAA;AACjE,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useUnmount = void 0;
4
+ const react_1 = require("react");
5
+ const useEffectOnce_1 = require("./useEffectOnce");
6
+ /**
7
+ * Hook that runs a cleanup function when the component unmounts.
8
+ * The function reference is updated on each render to always use the latest version.
9
+ *
10
+ * @example
11
+ * useUnmount(() => {
12
+ * console.log('Component unmounting')
13
+ * // Cleanup logic here
14
+ * })
15
+ */
16
+ const useUnmount = (fn) => {
17
+ const fnRef = (0, react_1.useRef)(fn);
18
+ // update the ref each render so if it change the newest callback will be invoked
19
+ fnRef.current = fn;
20
+ (0, useEffectOnce_1.useEffectOnce)(() => () => fnRef.current());
21
+ };
22
+ exports.useUnmount = useUnmount;
23
+ //# sourceMappingURL=useUnmount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUnmount.js","sourceRoot":"","sources":["../src/useUnmount.ts"],"names":[],"mappings":";;;AAAA,iCAA8B;AAC9B,mDAA+C;AAE/C;;;;;;;;;GASG;AACI,MAAM,UAAU,GAAG,CAAC,EAAa,EAAQ,EAAE;IAChD,MAAM,KAAK,GAAG,IAAA,cAAM,EAAC,EAAE,CAAC,CAAA;IAExB,iFAAiF;IACjF,KAAK,CAAC,OAAO,GAAG,EAAE,CAAA;IAElB,IAAA,6BAAa,EAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;AAC5C,CAAC,CAAA;AAPY,QAAA,UAAU,cAOtB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@codeleap/hooks",
3
- "version": "7.0.0",
4
- "main": "src/index.ts",
3
+ "version": "7.0.2",
4
+ "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
7
7
  ".": {
@@ -22,10 +22,10 @@
22
22
  "directory": "packages/hooks"
23
23
  },
24
24
  "devDependencies": {
25
- "@codeleap/config": "7.0.0",
26
- "@codeleap/types": "7.0.0",
27
- "@codeleap/utils": "7.0.0",
28
- "@codeleap/logger": "7.0.0",
25
+ "@codeleap/config": "7.0.1",
26
+ "@codeleap/types": "7.0.1",
27
+ "@codeleap/utils": "7.0.1",
28
+ "@codeleap/logger": "7.0.1",
29
29
  "ts-node-dev": "1.1.8"
30
30
  },
31
31
  "scripts": {
@@ -33,9 +33,9 @@
33
33
  "typecheck": "bun tsc --noEmit -p ./tsconfig.json"
34
34
  },
35
35
  "peerDependencies": {
36
- "@codeleap/types": "7.0.0",
37
- "@codeleap/utils": "7.0.0",
38
- "@codeleap/logger": "7.0.0",
36
+ "@codeleap/types": "7.0.1",
37
+ "@codeleap/utils": "7.0.1",
38
+ "@codeleap/logger": "7.0.1",
39
39
  "axios": "^1.7.9",
40
40
  "typescript": "6.0.3",
41
41
  "react": "19.1.0",