@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.
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/onMount.js +20 -0
- package/dist/onMount.js.map +1 -0
- package/dist/onUpdate.js +19 -0
- package/dist/onUpdate.js.map +1 -0
- package/dist/useBooleanToggle.js +25 -0
- package/dist/useBooleanToggle.js.map +1 -0
- package/dist/useComponentTestId.js +47 -0
- package/dist/useComponentTestId.js.map +1 -0
- package/dist/useConditionalState.js +27 -0
- package/dist/useConditionalState.js.map +1 -0
- package/dist/useDebounce.js +28 -0
- package/dist/useDebounce.js.map +1 -0
- package/dist/useDebounceCallback.js +42 -0
- package/dist/useDebounceCallback.js.map +1 -0
- package/dist/useDerivedRef.js +20 -0
- package/dist/useDerivedRef.js.map +1 -0
- package/dist/useDerivedState.js +28 -0
- package/dist/useDerivedState.js.map +1 -0
- package/dist/useEffectOnce.js +18 -0
- package/dist/useEffectOnce.js.map +1 -0
- package/dist/useFilteredList.js +24 -0
- package/dist/useFilteredList.js.map +1 -0
- package/dist/useForceRender.js +16 -0
- package/dist/useForceRender.js.map +1 -0
- package/dist/useId.js +18 -0
- package/dist/useId.js.map +1 -0
- package/dist/useInterval.js +49 -0
- package/dist/useInterval.js.map +1 -0
- package/dist/useIsMounted.js +39 -0
- package/dist/useIsMounted.js.map +1 -0
- package/dist/useLazyStore.js +20 -0
- package/dist/useLazyStore.js.map +1 -0
- package/dist/useModal.js +34 -0
- package/dist/useModal.js.map +1 -0
- package/dist/useOptions.js +28 -0
- package/dist/useOptions.js.map +1 -0
- package/dist/usePartialState.js +26 -0
- package/dist/usePartialState.js.map +1 -0
- package/dist/usePlaces.js +82 -0
- package/dist/usePlaces.js.map +1 -0
- package/dist/usePlacesAutocompleteUtils.js +65 -0
- package/dist/usePlacesAutocompleteUtils.js.map +1 -0
- package/dist/usePrevious.js +23 -0
- package/dist/usePrevious.js.map +1 -0
- package/dist/usePromise.js +66 -0
- package/dist/usePromise.js.map +1 -0
- package/dist/useRenderCall.js +13 -0
- package/dist/useRenderCall.js.map +1 -0
- package/dist/useSearch/index.js +83 -0
- package/dist/useSearch/index.js.map +1 -0
- package/dist/useSearch/types.js +3 -0
- package/dist/useSearch/types.js.map +1 -0
- package/dist/useStableReference.js +15 -0
- package/dist/useStableReference.js.map +1 -0
- package/dist/useToggle.js +21 -0
- package/dist/useToggle.js.map +1 -0
- package/dist/useUncontrolled.js +58 -0
- package/dist/useUncontrolled.js.map +1 -0
- package/dist/useUnmount.js +23 -0
- package/dist/useUnmount.js.map +1 -0
- 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 @@
|
|
|
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.
|
|
4
|
-
"main": "
|
|
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.
|
|
26
|
-
"@codeleap/types": "7.0.
|
|
27
|
-
"@codeleap/utils": "7.0.
|
|
28
|
-
"@codeleap/logger": "7.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.
|
|
37
|
-
"@codeleap/utils": "7.0.
|
|
38
|
-
"@codeleap/logger": "7.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",
|