@boxcustodia/library 2.0.0-alpha.19 → 2.0.0-alpha.20
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/components/button/button.cjs.js +1 -1
- package/dist/components/button/button.es.js +19 -18
- package/dist/components/button/components/base-button.cjs.js +1 -1
- package/dist/components/button/components/base-button.es.js +20 -20
- package/dist/components/calendar/calendar.cjs.js +1 -1
- package/dist/components/calendar/calendar.es.js +1 -0
- package/dist/components/date-picker/date-input.cjs.js +1 -1
- package/dist/components/date-picker/date-input.es.js +92 -75
- package/dist/components/date-picker/date-picker.cjs.js +1 -1
- package/dist/components/date-picker/date-picker.es.js +104 -95
- package/dist/components/date-picker/date-picker.utils.cjs.js +1 -1
- package/dist/components/date-picker/date-picker.utils.es.js +51 -43
- package/dist/components/date-picker/use-hidden-field-value.cjs.js +1 -0
- package/dist/components/date-picker/use-hidden-field-value.es.js +11 -0
- package/dist/components/menu/menu.es.js +1 -9
- package/dist/components/otp/otp.cjs.js +2 -0
- package/dist/components/otp/otp.es.js +93 -0
- package/dist/components/password/password.cjs.js +1 -1
- package/dist/components/password/password.es.js +2 -2
- package/dist/components/select/select.cjs.js +1 -1
- package/dist/components/select/select.es.js +68 -60
- package/dist/hooks/internal/is-apple-device.cjs.js +1 -0
- package/dist/hooks/internal/is-apple-device.es.js +9 -0
- package/dist/hooks/internal/use-latest-ref.cjs.js +1 -0
- package/dist/hooks/internal/use-latest-ref.es.js +11 -0
- package/dist/hooks/use-array/use-array.cjs.js +1 -1
- package/dist/hooks/use-array/use-array.es.js +54 -42
- package/dist/hooks/use-async/use-async.cjs.js +1 -1
- package/dist/hooks/use-async/use-async.es.js +53 -20
- package/dist/hooks/use-boolean/use-boolean.cjs.js +1 -0
- package/dist/hooks/use-boolean/use-boolean.es.js +25 -0
- package/dist/hooks/use-click-outside/use-click-outside.cjs.js +1 -1
- package/dist/hooks/use-click-outside/use-click-outside.es.js +26 -12
- package/dist/hooks/use-debounce-callback/use-debounced-callback.cjs.js +1 -1
- package/dist/hooks/use-debounce-callback/use-debounced-callback.es.js +27 -10
- package/dist/hooks/use-debounce-value/use-debounced-value.cjs.js +1 -1
- package/dist/hooks/use-debounce-value/use-debounced-value.es.js +7 -9
- package/dist/hooks/use-disclosure/use-disclosure.cjs.js +1 -1
- package/dist/hooks/use-disclosure/use-disclosure.es.js +21 -11
- package/dist/hooks/use-document-title/use-document-title.cjs.js +1 -1
- package/dist/hooks/use-document-title/use-document-title.es.js +14 -12
- package/dist/hooks/use-event-listener/use-event-listener.cjs.js +1 -1
- package/dist/hooks/use-event-listener/use-event-listener.es.js +17 -9
- package/dist/hooks/use-hotkey/use-hotkey.cjs.js +1 -1
- package/dist/hooks/use-hotkey/use-hotkey.es.js +30 -14
- package/dist/hooks/use-hotkey/utils/is-input-field.cjs.js +1 -1
- package/dist/hooks/use-hotkey/utils/is-input-field.es.js +4 -2
- package/dist/hooks/use-hotkey/utils/match-and-run.cjs.js +1 -0
- package/dist/hooks/use-hotkey/utils/match-and-run.es.js +12 -0
- package/dist/hooks/use-hotkey/utils/match-key-modifiers.cjs.js +1 -1
- package/dist/hooks/use-hotkey/utils/match-key-modifiers.es.js +13 -12
- package/dist/hooks/use-hover/use-hover.cjs.js +1 -1
- package/dist/hooks/use-hover/use-hover.es.js +32 -17
- package/dist/hooks/use-is-visible/use-is-visible.cjs.js +1 -1
- package/dist/hooks/use-is-visible/use-is-visible.es.js +31 -27
- package/dist/hooks/use-local-storage/use-local-storage.cjs.js +1 -1
- package/dist/hooks/use-local-storage/use-local-storage.es.js +52 -20
- package/dist/hooks/use-media-query/use-media-query.cjs.js +1 -1
- package/dist/hooks/use-media-query/use-media-query.es.js +21 -11
- package/dist/hooks/use-mutation/use-mutation.cjs.js +1 -1
- package/dist/hooks/use-mutation/use-mutation.es.js +36 -22
- package/dist/hooks/use-object/use-object.cjs.js +1 -1
- package/dist/hooks/use-object/use-object.es.js +26 -22
- package/dist/hooks/use-prevent-page-close/use-prevent-page-close.cjs.js +1 -0
- package/dist/hooks/use-prevent-page-close/use-prevent-page-close.es.js +14 -0
- package/dist/hooks/use-step/use-step.cjs.js +1 -1
- package/dist/hooks/use-step/use-step.es.js +25 -24
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +308 -300
- package/dist/src/components/date-picker/date-picker.utils.d.ts +17 -0
- package/dist/src/components/date-picker/use-hidden-field-value.d.ts +12 -0
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/hooks/index.d.ts +2 -2
- package/dist/src/hooks/internal/index.d.ts +2 -0
- package/dist/src/hooks/internal/is-apple-device.d.ts +12 -0
- package/dist/src/hooks/internal/use-latest-ref.d.ts +12 -0
- package/dist/src/hooks/use-array/use-array.d.ts +24 -11
- package/dist/src/hooks/use-async/use-async.d.ts +16 -13
- package/dist/src/hooks/use-boolean/index.d.ts +1 -0
- package/dist/src/hooks/use-boolean/use-boolean.d.ts +15 -0
- package/dist/src/hooks/use-boolean/use-boolean.test.d.ts +1 -0
- package/dist/src/hooks/use-click-outside/use-click-outside.d.ts +23 -1
- package/dist/src/hooks/use-debounce-callback/use-debounced-callback.d.ts +19 -1
- package/dist/src/hooks/use-debounce-value/use-debounced-value.d.ts +10 -1
- package/dist/src/hooks/use-disclosure/use-disclosure.d.ts +17 -8
- package/dist/src/hooks/use-document-title/use-document-title.d.ts +11 -0
- package/dist/src/hooks/use-event-listener/use-event-listener.d.ts +18 -1
- package/dist/src/hooks/use-hotkey/index.d.ts +2 -1
- package/dist/src/hooks/use-hotkey/use-hotkey.d.ts +62 -5
- package/dist/src/hooks/use-hotkey/utils/index.d.ts +4 -3
- package/dist/src/hooks/use-hotkey/utils/is-input-field.d.ts +12 -2
- package/dist/src/hooks/use-hotkey/utils/is-input-field.test.d.ts +1 -0
- package/dist/src/hooks/use-hotkey/utils/match-and-run.d.ts +36 -0
- package/dist/src/hooks/use-hotkey/utils/match-and-run.test.d.ts +1 -0
- package/dist/src/hooks/use-hotkey/utils/match-key-modifiers.d.ts +20 -6
- package/dist/src/hooks/use-hotkey/utils/match-key-modifiers.test.d.ts +1 -0
- package/dist/src/hooks/use-hover/use-hover.d.ts +8 -4
- package/dist/src/hooks/use-is-visible/use-is-visible.d.ts +28 -4
- package/dist/src/hooks/use-local-storage/use-local-storage.d.ts +13 -2
- package/dist/src/hooks/use-media-query/use-media-query.d.ts +10 -1
- package/dist/src/hooks/use-media-query/use-media-query.test.d.ts +1 -0
- package/dist/src/hooks/use-mutation/use-mutation.d.ts +18 -11
- package/dist/src/hooks/use-object/use-object.d.ts +15 -6
- package/dist/src/hooks/use-prevent-page-close/index.d.ts +1 -0
- package/dist/src/hooks/use-prevent-page-close/use-prevent-page-close.d.ts +10 -0
- package/dist/src/hooks/use-prevent-page-close/use-prevent-page-close.test.d.ts +1 -0
- package/dist/src/hooks/use-step/use-step.d.ts +18 -11
- package/dist/src/utils/form.d.ts +10 -0
- package/package.json +1 -1
- package/src/components/alert-dialog/alert-dialog.test.tsx +13 -9
- package/src/components/auto-complete/auto-complete.test.tsx +4 -14
- package/src/components/avatar/avatar.test.tsx +7 -12
- package/src/components/button/button.test.tsx +10 -15
- package/src/components/button/button.tsx +14 -9
- package/src/components/button/components/base-button.tsx +2 -4
- package/src/components/calendar/calendar.test.tsx +12 -19
- package/src/components/calendar/calendar.tsx +4 -0
- package/src/components/card/card.test.tsx +4 -6
- package/src/components/checkbox/checkbox.test.tsx +12 -8
- package/src/components/checkbox-group/checkbox-group.test.tsx +7 -8
- package/src/components/combobox/combobox.test.tsx +24 -21
- package/src/components/date-picker/date-input-form.test.tsx +77 -0
- package/src/components/date-picker/date-input.stories.tsx +30 -18
- package/src/components/date-picker/date-input.tsx +77 -44
- package/src/components/date-picker/date-picker.stories.tsx +31 -1
- package/src/components/date-picker/date-picker.test.tsx +3 -13
- package/src/components/date-picker/date-picker.tsx +35 -16
- package/src/components/date-picker/date-picker.utils.test.ts +32 -14
- package/src/components/date-picker/date-picker.utils.ts +33 -0
- package/src/components/date-picker/use-date-input-popover.test.ts +3 -1
- package/src/components/date-picker/use-hidden-field-value.ts +23 -0
- package/src/components/dialog/dialog.test.tsx +10 -8
- package/src/components/dropzone/dropzone.test.tsx +11 -13
- package/src/components/empty/empty.test.tsx +4 -3
- package/src/components/field/field.test.tsx +12 -13
- package/src/components/form/form.stories.tsx +16 -1
- package/src/components/index.ts +1 -0
- package/src/components/label/label.test.tsx +3 -3
- package/src/components/menu/menu.tsx +1 -5
- package/src/components/number-input/number-input.test.tsx +6 -2
- package/src/components/password/password.test.tsx +20 -6
- package/src/components/password/password.tsx +2 -2
- package/src/components/popover/popover.test.tsx +4 -4
- package/src/components/progress/progress.test.tsx +7 -8
- package/src/components/radio-group/radio-group.test.tsx +17 -11
- package/src/components/select/select.test.tsx +10 -10
- package/src/components/select/select.tsx +9 -1
- package/src/components/stepper/stepper.stories.tsx +11 -15
- package/src/components/stepper/stepper.test.tsx +6 -4
- package/src/components/switch/switch.test.tsx +3 -3
- package/src/components/table/table.test.tsx +9 -3
- package/src/components/tabs/tabs.test.tsx +6 -2
- package/src/components/tag/tag.test.tsx +1 -3
- package/src/components/textarea/textarea.test.tsx +4 -1
- package/src/components/timeline/timeline.test.tsx +10 -5
- package/src/components/toast/toast.test.tsx +11 -14
- package/src/components/tooltip/tooltip.test.tsx +1 -5
- package/src/components/tree/tree.test.tsx +3 -1
- package/src/hooks/index.ts +2 -2
- package/src/hooks/internal/index.ts +2 -0
- package/src/hooks/internal/is-apple-device.test.ts +41 -0
- package/src/hooks/internal/is-apple-device.ts +33 -0
- package/src/hooks/internal/use-isomorphic-layout-effect.ts +3 -1
- package/src/hooks/internal/use-latest-ref.ts +21 -0
- package/src/hooks/use-array/use-array.stories.tsx +435 -64
- package/src/hooks/use-array/use-array.test.tsx +398 -15
- package/src/hooks/use-array/use-array.ts +105 -66
- package/src/hooks/use-async/use-async.stories.tsx +255 -131
- package/src/hooks/use-async/use-async.test.ts +397 -0
- package/src/hooks/use-async/use-async.ts +117 -39
- package/src/hooks/use-boolean/index.ts +1 -0
- package/src/hooks/use-boolean/use-boolean.stories.tsx +377 -0
- package/src/hooks/use-boolean/use-boolean.test.tsx +177 -0
- package/src/hooks/use-boolean/use-boolean.ts +50 -0
- package/src/hooks/use-click-outside/use-click-outside.stories.tsx +188 -18
- package/src/hooks/use-click-outside/use-click-outside.test.tsx +89 -10
- package/src/hooks/use-click-outside/use-click-outside.ts +62 -16
- package/src/hooks/use-debounce-callback/use-debounced-callback.stories.tsx +141 -41
- package/src/hooks/use-debounce-callback/use-debounced-callback.test.ts +217 -9
- package/src/hooks/use-debounce-callback/use-debounced-callback.ts +71 -11
- package/src/hooks/use-debounce-value/use-debounced-value.stories.tsx +247 -47
- package/src/hooks/use-debounce-value/use-debounced-value.test.ts +105 -10
- package/src/hooks/use-debounce-value/use-debounced-value.ts +19 -10
- package/src/hooks/use-disclosure/use-disclosure.stories.tsx +305 -14
- package/src/hooks/use-disclosure/use-disclosure.test.ts +198 -50
- package/src/hooks/use-disclosure/use-disclosure.ts +49 -29
- package/src/hooks/use-document-title/use-document-title.stories.tsx +54 -0
- package/src/hooks/use-document-title/use-document-title.test.tsx +26 -0
- package/src/hooks/use-document-title/{use-document-title.tsx → use-document-title.ts} +17 -3
- package/src/hooks/use-event-listener/use-event-listener.stories.tsx +105 -9
- package/src/hooks/use-event-listener/use-event-listener.test.tsx +77 -10
- package/src/hooks/use-event-listener/use-event-listener.ts +71 -11
- package/src/hooks/use-focus-trap/use-focus-trap.test.ts +31 -6
- package/src/hooks/use-focus-trap/use-focus-trap.ts +3 -2
- package/src/hooks/use-hotkey/index.ts +9 -1
- package/src/hooks/use-hotkey/use-hotkey.stories.tsx +279 -74
- package/src/hooks/use-hotkey/use-hotkey.test.tsx +286 -34
- package/src/hooks/use-hotkey/use-hotkey.ts +141 -17
- package/src/hooks/use-hotkey/utils/index.ts +8 -3
- package/src/hooks/use-hotkey/utils/is-input-field.test.ts +78 -0
- package/src/hooks/use-hotkey/utils/is-input-field.ts +31 -10
- package/src/hooks/use-hotkey/utils/match-and-run.test.ts +203 -0
- package/src/hooks/use-hotkey/utils/match-and-run.ts +62 -0
- package/src/hooks/use-hotkey/utils/match-key-modifiers.test.ts +65 -0
- package/src/hooks/use-hotkey/utils/match-key-modifiers.ts +39 -12
- package/src/hooks/use-hover/use-hover.stories.tsx +258 -80
- package/src/hooks/use-hover/use-hover.test.tsx +266 -26
- package/src/hooks/use-hover/use-hover.tsx +93 -28
- package/src/hooks/use-is-visible/use-is-visible.stories.tsx +193 -46
- package/src/hooks/use-is-visible/use-is-visible.test.tsx +235 -7
- package/src/hooks/use-is-visible/use-is-visible.ts +114 -0
- package/src/hooks/use-local-storage/use-local-storage.stories.tsx +129 -29
- package/src/hooks/use-local-storage/use-local-storage.test.ts +106 -41
- package/src/hooks/use-local-storage/use-local-storage.ts +100 -31
- package/src/hooks/use-media-query/use-media-query.stories.tsx +86 -26
- package/src/hooks/use-media-query/use-media-query.test.ts +132 -0
- package/src/hooks/use-media-query/use-media-query.ts +39 -14
- package/src/hooks/use-memoized-fn/use-memoized-fn.ts +0 -1
- package/src/hooks/use-mutation/use-mutation.stories.tsx +260 -94
- package/src/hooks/use-mutation/use-mutation.test.ts +359 -0
- package/src/hooks/use-mutation/use-mutation.ts +97 -0
- package/src/hooks/use-object/use-object.stories.tsx +310 -79
- package/src/hooks/use-object/use-object.test.tsx +235 -56
- package/src/hooks/use-object/use-object.ts +59 -0
- package/src/hooks/use-pagination/use-pagination.tsx +0 -1
- package/src/hooks/use-prevent-page-close/index.ts +1 -0
- package/src/hooks/use-prevent-page-close/use-prevent-page-close.stories.tsx +39 -0
- package/src/hooks/use-prevent-page-close/use-prevent-page-close.test.ts +89 -0
- package/src/hooks/use-prevent-page-close/use-prevent-page-close.ts +27 -0
- package/src/hooks/use-range-pagination/use-range-pagination.test.tsx +1 -1
- package/src/hooks/use-range-pagination/use-range-pagination.tsx +1 -1
- package/src/hooks/use-selection/use-selection.ts +0 -1
- package/src/hooks/use-step/use-step.stories.tsx +178 -65
- package/src/hooks/use-step/use-step.test.ts +178 -53
- package/src/hooks/use-step/use-step.ts +57 -49
- package/src/utils/form.test.tsx +13 -8
- package/src/utils/form.tsx +10 -0
- package/src/utils/functions/getFormData.test.ts +1 -1
- package/dist/hooks/use-hotkey/utils/create-hotkey-listener.cjs.js +0 -1
- package/dist/hooks/use-hotkey/utils/create-hotkey-listener.es.js +0 -10
- package/dist/hooks/use-prevent-close-window/use-prevent-close-window.cjs.js +0 -1
- package/dist/hooks/use-prevent-close-window/use-prevent-close-window.es.js +0 -15
- package/dist/hooks/use-toggle/use-toggle.cjs.js +0 -1
- package/dist/hooks/use-toggle/use-toggle.es.js +0 -10
- package/dist/src/hooks/use-hotkey/utils/create-hotkey-listener.d.ts +0 -1
- package/dist/src/hooks/use-prevent-close-window/index.d.ts +0 -1
- package/dist/src/hooks/use-prevent-close-window/use-prevent-close-window.d.ts +0 -13
- package/dist/src/hooks/use-toggle/index.d.ts +0 -1
- package/dist/src/hooks/use-toggle/use-toggle.d.ts +0 -3
- package/src/hooks/use-async/use-async.test.tsx +0 -68
- package/src/hooks/use-hotkey/utils/create-hotkey-listener.ts +0 -25
- package/src/hooks/use-is-visible/use-is-visible.tsx +0 -49
- package/src/hooks/use-mutation/use-mutation.test.tsx +0 -83
- package/src/hooks/use-mutation/use-mutation.tsx +0 -59
- package/src/hooks/use-object/use-object.tsx +0 -46
- package/src/hooks/use-prevent-close-window/index.ts +0 -1
- package/src/hooks/use-prevent-close-window/use-prevent-close-window.stories.tsx +0 -32
- package/src/hooks/use-prevent-close-window/use-prevent-close-window.test.ts +0 -79
- package/src/hooks/use-prevent-close-window/use-prevent-close-window.ts +0 -33
- package/src/hooks/use-toggle/index.ts +0 -1
- package/src/hooks/use-toggle/use-toggle.stories.tsx +0 -25
- package/src/hooks/use-toggle/use-toggle.test.tsx +0 -64
- package/src/hooks/use-toggle/use-toggle.ts +0 -14
- /package/dist/src/{hooks/use-prevent-close-window/use-prevent-close-window.test.d.ts → components/date-picker/date-input-form.test.d.ts} +0 -0
- /package/dist/src/hooks/{use-toggle/use-toggle.test.d.ts → internal/is-apple-device.test.d.ts} +0 -0
package/src/utils/form.test.tsx
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
fireEvent,
|
|
3
|
+
render,
|
|
4
|
+
renderHook,
|
|
5
|
+
screen,
|
|
6
|
+
waitFor,
|
|
7
|
+
} from "@testing-library/react";
|
|
2
8
|
import { describe, expect, it, vi } from "vitest";
|
|
3
9
|
import { z } from "zod";
|
|
4
10
|
import { HookField, HookForm, parseFormValues, useHookForm } from "./form";
|
|
5
|
-
import { renderHook } from "@testing-library/react";
|
|
6
11
|
|
|
7
12
|
// ─── parseFormValues ──────────────────────────────────────────────────────────
|
|
8
13
|
|
|
@@ -48,7 +53,11 @@ describe("useHookForm", () => {
|
|
|
48
53
|
|
|
49
54
|
const loginSchema = z.object({ username: z.string().min(1, "required") });
|
|
50
55
|
|
|
51
|
-
function LoginForm({
|
|
56
|
+
function LoginForm({
|
|
57
|
+
onSubmit,
|
|
58
|
+
}: {
|
|
59
|
+
onSubmit: (v: { username: string }) => void;
|
|
60
|
+
}) {
|
|
52
61
|
const form = useHookForm(loginSchema);
|
|
53
62
|
return (
|
|
54
63
|
<HookForm form={form} onFormSubmit={onSubmit}>
|
|
@@ -89,11 +98,7 @@ describe("HookForm", () => {
|
|
|
89
98
|
|
|
90
99
|
// ─── HookField ────────────────────────────────────────────────────────────────
|
|
91
100
|
|
|
92
|
-
function FieldForm({
|
|
93
|
-
onSubmit,
|
|
94
|
-
}: {
|
|
95
|
-
onSubmit: (v: { email: string }) => void;
|
|
96
|
-
}) {
|
|
101
|
+
function FieldForm({ onSubmit }: { onSubmit: (v: { email: string }) => void }) {
|
|
97
102
|
const schema = z.object({ email: z.string().email("invalid email") });
|
|
98
103
|
const form = useHookForm(schema);
|
|
99
104
|
return (
|
package/src/utils/form.tsx
CHANGED
|
@@ -22,6 +22,16 @@ import { Field, type FieldProps, Form as LibraryForm } from "../components";
|
|
|
22
22
|
*
|
|
23
23
|
* - `data` is the typed, parsed value, or `null` when validation fails.
|
|
24
24
|
* - `errors` is the flattened `fieldErrors` object (empty on success).
|
|
25
|
+
*
|
|
26
|
+
* Value conventions worth knowing when writing the schema (these hold whether
|
|
27
|
+
* or not you use Zod):
|
|
28
|
+
* - `DateInput` and `DatePicker` submit an **ISO date string** (`yyyy-MM-dd`),
|
|
29
|
+
* or `""` when empty. The format is locale-agnostic, sortable, and parseable
|
|
30
|
+
* by `new Date()` or any backend without a custom parser. The displayed text
|
|
31
|
+
* stays `dd/MM/yyyy` — display and value are different layers. To reformat,
|
|
32
|
+
* it is a plain split: `iso.split("-").reverse().join("-")` → `dd-MM-yyyy`.
|
|
33
|
+
* Avoid round-tripping through `new Date(iso)` + local getters (timezone
|
|
34
|
+
* shift); split the string or use `parseISO`.
|
|
25
35
|
*/
|
|
26
36
|
export function parseFormValues<T extends z.ZodType>(
|
|
27
37
|
schema: T,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("./is-input-field.cjs.js"),s=require("./match-key-modifiers.cjs.js"),u=(e,t,i,o,a)=>r=>{if(!a||n.shouldIgnoreEvent(r,o))return;(Array.isArray(e)?e:[e]).some(c=>s.matchKeyModifiers(r,c))&&(i&&r.preventDefault(),t(r))};exports.createListener=u;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { shouldIgnoreEvent as c } from "./is-input-field.es.js";
|
|
2
|
-
import { matchKeyModifiers as f } from "./match-key-modifiers.es.js";
|
|
3
|
-
const h = (t, o, e, a, i) => (r) => {
|
|
4
|
-
if (!i || c(r, a))
|
|
5
|
-
return;
|
|
6
|
-
(Array.isArray(t) ? t : [t]).some((m) => f(r, m)) && (e && r.preventDefault(), o(r));
|
|
7
|
-
};
|
|
8
|
-
export {
|
|
9
|
-
h as createListener
|
|
10
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const u=require("react");function t({shouldPrevent:n,message:e="Es posible que no se guarden los cambios hayas hecho."}){const o=r=>{if(n)return r.preventDefault(),r.returnValue=e,e};u.useEffect(()=>(window.addEventListener("beforeunload",o),()=>window.removeEventListener("beforeunload",o)),[e,n])}exports.default=t;exports.usePreventCloseWindow=t;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { useEffect as t } from "react";
|
|
2
|
-
function a({
|
|
3
|
-
shouldPrevent: n,
|
|
4
|
-
message: e = "Es posible que no se guarden los cambios hayas hecho."
|
|
5
|
-
}) {
|
|
6
|
-
const o = (r) => {
|
|
7
|
-
if (n)
|
|
8
|
-
return r.preventDefault(), r.returnValue = e, e;
|
|
9
|
-
};
|
|
10
|
-
t(() => (window.addEventListener("beforeunload", o), () => window.removeEventListener("beforeunload", o)), [e, n]);
|
|
11
|
-
}
|
|
12
|
-
export {
|
|
13
|
-
a as default,
|
|
14
|
-
a as usePreventCloseWindow
|
|
15
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react");function l(t=!1){const[o,g]=u.useState(t);return[o,e=>{g(s=>e===void 0?!s:e)}]}exports.useToggle=l;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const createListener: (keys: string | string[], handler: (event: KeyboardEvent) => void, preventDefault: boolean, ignoreInputFields: boolean, watch: boolean) => (event: KeyboardEvent) => void;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './use-prevent-close-window';
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
interface UsePreventCloseWindowProps {
|
|
2
|
-
/**
|
|
3
|
-
* Propiedad que determina si la ventana se puede cerrar o no
|
|
4
|
-
*/
|
|
5
|
-
shouldPrevent: boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Mensaje que se va a mostrar al usuario antes de cerrar la ventana
|
|
8
|
-
* @deprecated ya no es soportado por los navegadores modernos
|
|
9
|
-
*/
|
|
10
|
-
message?: string;
|
|
11
|
-
}
|
|
12
|
-
export declare function usePreventCloseWindow({ shouldPrevent, message, }: UsePreventCloseWindowProps): void;
|
|
13
|
-
export default usePreventCloseWindow;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './use-toggle';
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { renderHook, waitFor } from "@testing-library/react";
|
|
2
|
-
import { describe, expect, it, vi } from "vitest";
|
|
3
|
-
import { useAsync } from "../use-async";
|
|
4
|
-
|
|
5
|
-
const mockFetchSuccess = async (data: any) => {
|
|
6
|
-
return new Promise((resolve) => setTimeout(() => resolve(data), 100));
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const mockFetchError = async () => {
|
|
10
|
-
return new Promise((_, reject) =>
|
|
11
|
-
setTimeout(() => reject(new Error("Fetch error")), 100),
|
|
12
|
-
);
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
describe("useAsync hook", () => {
|
|
16
|
-
it("should initialize with default state", () => {
|
|
17
|
-
const { result } = renderHook(() =>
|
|
18
|
-
useAsync({ fn: () => Promise.resolve("test") }),
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
expect(result.current.loading).toBe(true);
|
|
22
|
-
expect(result.current.error).toBeNull();
|
|
23
|
-
expect(result.current.data).toBeNull();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("should handle success", async () => {
|
|
27
|
-
const { result } = renderHook(() =>
|
|
28
|
-
useAsync({ fn: () => mockFetchSuccess("success") }),
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
await waitFor(() => result.current.data);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should handle error", async () => {
|
|
35
|
-
const { result } = renderHook(() =>
|
|
36
|
-
useAsync({ fn: () => mockFetchError() }),
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
await waitFor(() => expect(result.current.error).not.toBeNull());
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("should call onSuccess callback", async () => {
|
|
43
|
-
const onSuccess = vi.fn();
|
|
44
|
-
renderHook(() =>
|
|
45
|
-
useAsync({ fn: () => mockFetchSuccess("success"), onSuccess }),
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
await waitFor(() => expect(onSuccess).toHaveBeenCalledWith("success"));
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("should call onError callback", async () => {
|
|
52
|
-
const onError = vi.fn();
|
|
53
|
-
renderHook(() => useAsync({ fn: () => mockFetchError(), onError }));
|
|
54
|
-
|
|
55
|
-
await waitFor(() =>
|
|
56
|
-
expect(onError).toHaveBeenCalledWith(expect.any(Error)),
|
|
57
|
-
);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("should call onFinish callback", async () => {
|
|
61
|
-
const onFinish = vi.fn();
|
|
62
|
-
renderHook(() =>
|
|
63
|
-
useAsync({ fn: () => mockFetchSuccess("success"), onFinish }),
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
await waitFor(() => expect(onFinish).toHaveBeenCalled());
|
|
67
|
-
});
|
|
68
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { shouldIgnoreEvent } from "./is-input-field";
|
|
2
|
-
import { matchKeyModifiers } from "./match-key-modifiers";
|
|
3
|
-
|
|
4
|
-
export const createListener = (
|
|
5
|
-
keys: string | string[],
|
|
6
|
-
handler: (event: KeyboardEvent) => void,
|
|
7
|
-
preventDefault: boolean,
|
|
8
|
-
ignoreInputFields: boolean,
|
|
9
|
-
watch: boolean,
|
|
10
|
-
) => {
|
|
11
|
-
return (event: KeyboardEvent) => {
|
|
12
|
-
if (!watch) return;
|
|
13
|
-
if (shouldIgnoreEvent(event, ignoreInputFields)) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const keyArray = Array.isArray(keys) ? keys : [keys];
|
|
18
|
-
const match = keyArray.some((key) => matchKeyModifiers(event, key));
|
|
19
|
-
|
|
20
|
-
if (match) {
|
|
21
|
-
preventDefault && event.preventDefault();
|
|
22
|
-
handler(event);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { RefObject, useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
-
|
|
3
|
-
interface UseIsVisibleProps extends IntersectionObserverInit {
|
|
4
|
-
onVisible?: () => void;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
interface UseIsVisibleReturn<T> {
|
|
8
|
-
ref: RefObject<T | null>;
|
|
9
|
-
isVisible: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function useIsVisible<T extends HTMLElement>({
|
|
13
|
-
onVisible,
|
|
14
|
-
root = null,
|
|
15
|
-
rootMargin = "0px",
|
|
16
|
-
threshold = 0,
|
|
17
|
-
}: UseIsVisibleProps = {}): UseIsVisibleReturn<T> {
|
|
18
|
-
const [isVisible, setIsVisible] = useState<boolean>(false);
|
|
19
|
-
const ref = useRef<T | null>(null);
|
|
20
|
-
|
|
21
|
-
const handleIntersect: IntersectionObserverCallback = useCallback(
|
|
22
|
-
([entry]) => {
|
|
23
|
-
const isIntersecting = entry.isIntersecting;
|
|
24
|
-
setIsVisible(isIntersecting);
|
|
25
|
-
},
|
|
26
|
-
[onVisible],
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
if (ref.current == null) return;
|
|
31
|
-
const observer = new IntersectionObserver(handleIntersect, {
|
|
32
|
-
root,
|
|
33
|
-
rootMargin,
|
|
34
|
-
threshold,
|
|
35
|
-
});
|
|
36
|
-
observer.observe(ref.current);
|
|
37
|
-
return () => {
|
|
38
|
-
if (ref.current == null) return;
|
|
39
|
-
observer.unobserve(ref.current);
|
|
40
|
-
};
|
|
41
|
-
}, [ref, root, rootMargin, threshold, handleIntersect]);
|
|
42
|
-
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
isVisible && onVisible?.();
|
|
45
|
-
}, [isVisible]);
|
|
46
|
-
|
|
47
|
-
return { ref, isVisible };
|
|
48
|
-
}
|
|
49
|
-
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { renderHook, waitFor } from "@testing-library/react";
|
|
2
|
-
import { describe, expect, it, vi } from "vitest";
|
|
3
|
-
import { useMutation } from "../use-mutation";
|
|
4
|
-
|
|
5
|
-
const mockMutationSuccess = async (data: any) => {
|
|
6
|
-
return new Promise((resolve) => setTimeout(() => resolve(data), 100));
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const mockMutationError = async () => {
|
|
10
|
-
return new Promise((_, reject) =>
|
|
11
|
-
setTimeout(() => reject(new Error("Mutation error")), 100),
|
|
12
|
-
);
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
describe("useMutation hook", () => {
|
|
16
|
-
it("should initialize with default state", () => {
|
|
17
|
-
const { result } = renderHook(() =>
|
|
18
|
-
useMutation({ fn: () => Promise.resolve("test") }),
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
expect(result.current.loading).toBe(false);
|
|
22
|
-
expect(result.current.error).toBeNull();
|
|
23
|
-
expect(result.current.data).toBeNull();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("should handle success", async () => {
|
|
27
|
-
const { result } = renderHook(() =>
|
|
28
|
-
useMutation({ fn: () => mockMutationSuccess("success") }),
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
result.current.mutate();
|
|
32
|
-
await waitFor(() => expect(result.current.data).toBe("success"));
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("should handle error", async () => {
|
|
36
|
-
const { result } = renderHook(() =>
|
|
37
|
-
useMutation({ fn: () => mockMutationError() }),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
await result.current.mutate();
|
|
42
|
-
} catch (e) {
|
|
43
|
-
console.log(e);
|
|
44
|
-
await waitFor(() => expect(result.current.error).not.toBeNull());
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("should call onSuccess callback", async () => {
|
|
49
|
-
const onSuccess = vi.fn();
|
|
50
|
-
const { result } = renderHook(() =>
|
|
51
|
-
useMutation({ fn: () => mockMutationSuccess("success"), onSuccess }),
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
result.current.mutate();
|
|
55
|
-
await waitFor(() => expect(onSuccess).toHaveBeenCalledWith("success"));
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("should call onError callback", async () => {
|
|
59
|
-
const onError = vi.fn();
|
|
60
|
-
const { result } = renderHook(() =>
|
|
61
|
-
useMutation({ fn: () => mockMutationError(), onError }),
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
await result.current.mutate();
|
|
66
|
-
} catch (e) {
|
|
67
|
-
console.log(e);
|
|
68
|
-
await waitFor(() =>
|
|
69
|
-
expect(onError).toHaveBeenCalledWith(expect.any(Error)),
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("should call onFinish callback", async () => {
|
|
75
|
-
const onFinish = vi.fn();
|
|
76
|
-
const { result } = renderHook(() =>
|
|
77
|
-
useMutation({ fn: () => mockMutationSuccess("success"), onFinish }),
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
result.current.mutate();
|
|
81
|
-
await waitFor(() => expect(onFinish).toHaveBeenCalled());
|
|
82
|
-
});
|
|
83
|
-
});
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { useCallback, useState } from "react";
|
|
2
|
-
|
|
3
|
-
type Mutation<TArgs extends any[], TReturn> = (
|
|
4
|
-
...args: TArgs
|
|
5
|
-
) => Promise<TReturn>;
|
|
6
|
-
|
|
7
|
-
interface UseMutationOptions<TArgs extends any[], TReturn> {
|
|
8
|
-
fn: Mutation<TArgs, TReturn>;
|
|
9
|
-
onError?: (error: Error) => void;
|
|
10
|
-
onSuccess?: (data: TReturn) => void;
|
|
11
|
-
onFinish?: () => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface UseMutationReturn<TArgs extends any[], TReturn> {
|
|
15
|
-
mutate: Mutation<TArgs, TReturn>;
|
|
16
|
-
loading: boolean;
|
|
17
|
-
error: Error | null;
|
|
18
|
-
data: TReturn | null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const useMutation = <TArgs extends any[], TReturn>(
|
|
22
|
-
opts: UseMutationOptions<TArgs, TReturn>,
|
|
23
|
-
): UseMutationReturn<TArgs, TReturn> => {
|
|
24
|
-
const [loading, setLoading] = useState(false);
|
|
25
|
-
const [error, setError] = useState<Error | null>(null);
|
|
26
|
-
const [data, setData] = useState<TReturn | null>(null);
|
|
27
|
-
|
|
28
|
-
const mutate = useCallback(
|
|
29
|
-
async (...args: TArgs) => {
|
|
30
|
-
setLoading(true);
|
|
31
|
-
setError(null);
|
|
32
|
-
setData(null);
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
const result = await opts.fn(...args);
|
|
36
|
-
opts.onSuccess?.(result);
|
|
37
|
-
setData(result);
|
|
38
|
-
return result;
|
|
39
|
-
} catch (err) {
|
|
40
|
-
const error = err as Error;
|
|
41
|
-
opts.onError?.(error);
|
|
42
|
-
setError(error);
|
|
43
|
-
throw error;
|
|
44
|
-
} finally {
|
|
45
|
-
opts.onFinish?.();
|
|
46
|
-
setLoading(false);
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
[opts],
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
mutate,
|
|
54
|
-
loading,
|
|
55
|
-
error,
|
|
56
|
-
data,
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { useCallback, useState } from "react";
|
|
2
|
-
|
|
3
|
-
type GenericObject = Record<string, any>;
|
|
4
|
-
type Return<
|
|
5
|
-
TState,
|
|
6
|
-
TArgs = ((state: TState) => Partial<TState>) | Partial<TState>,
|
|
7
|
-
> = [TState, (arg: TArgs) => void, () => void];
|
|
8
|
-
type MaybeReturn<TState> = Return<
|
|
9
|
-
TState | undefined,
|
|
10
|
-
((state: TState | undefined) => Partial<TState>) | Partial<TState>
|
|
11
|
-
>;
|
|
12
|
-
|
|
13
|
-
export function useObject<T extends GenericObject>(): MaybeReturn<T>;
|
|
14
|
-
export function useObject<T extends GenericObject>(initialValue: T): Return<T>;
|
|
15
|
-
export function useObject<T extends GenericObject>(initialValue?: T) {
|
|
16
|
-
const [state, setState] = useState<T | undefined>(initialValue);
|
|
17
|
-
|
|
18
|
-
const reset = useCallback(() => setState(initialValue), [initialValue]);
|
|
19
|
-
|
|
20
|
-
const setNewState = useCallback(
|
|
21
|
-
(arg: ((state: T | undefined) => Partial<T>) | Partial<T>) => {
|
|
22
|
-
setState((prevState) => {
|
|
23
|
-
if (typeof arg === "function") {
|
|
24
|
-
const newState = arg(prevState);
|
|
25
|
-
if (newState !== null && typeof newState === "object") {
|
|
26
|
-
return {
|
|
27
|
-
...prevState,
|
|
28
|
-
...newState,
|
|
29
|
-
} as T;
|
|
30
|
-
}
|
|
31
|
-
return prevState;
|
|
32
|
-
} else if (arg !== null && typeof arg === "object") {
|
|
33
|
-
return {
|
|
34
|
-
...prevState,
|
|
35
|
-
...arg,
|
|
36
|
-
} as T;
|
|
37
|
-
}
|
|
38
|
-
return prevState;
|
|
39
|
-
});
|
|
40
|
-
},
|
|
41
|
-
[],
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
return [state, setNewState, reset] as const;
|
|
45
|
-
}
|
|
46
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./use-prevent-close-window";
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Meta } from "@storybook/react-vite";
|
|
2
|
-
import { usePreventCloseWindow } from "./use-prevent-close-window";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Hook que permite prevenir que se cierre la ventana (muestra mensaje de aviso)
|
|
6
|
-
* Es útil para evitar que el usuario cierre la ventana accidentalmente mientras tiene cambios pendientes de guardar
|
|
7
|
-
*/
|
|
8
|
-
const meta: Meta = {
|
|
9
|
-
title: "hooks/usePreventCloseWindow",
|
|
10
|
-
args: {
|
|
11
|
-
shouldPrevent: true,
|
|
12
|
-
message: "No te vayas 😞",
|
|
13
|
-
},
|
|
14
|
-
argTypes: {
|
|
15
|
-
shouldPrevent: {
|
|
16
|
-
description: "Propiedad que determina si la ventana se puede cerrar",
|
|
17
|
-
},
|
|
18
|
-
message: {
|
|
19
|
-
description:
|
|
20
|
-
"Mensaje que se muestra al cerrar la ventana, no soportado por navegadores modernos",
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export default meta;
|
|
26
|
-
|
|
27
|
-
export const Default = {
|
|
28
|
-
render: (args: any) => {
|
|
29
|
-
usePreventCloseWindow(args);
|
|
30
|
-
return <div>Intenta cerrar ventana</div>;
|
|
31
|
-
},
|
|
32
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { renderHook } from "@testing-library/react";
|
|
2
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
-
import usePreventCloseWindow from "./use-prevent-close-window";
|
|
4
|
-
|
|
5
|
-
describe("usePreventCloseWindow", () => {
|
|
6
|
-
let addSpy: ReturnType<typeof vi.spyOn>;
|
|
7
|
-
let removeSpy: ReturnType<typeof vi.spyOn>;
|
|
8
|
-
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
addSpy = vi.spyOn(window, "addEventListener");
|
|
11
|
-
removeSpy = vi.spyOn(window, "removeEventListener");
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
afterEach(() => {
|
|
15
|
-
addSpy.mockRestore();
|
|
16
|
-
removeSpy.mockRestore();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("registers beforeunload listener on mount", () => {
|
|
20
|
-
renderHook(() => usePreventCloseWindow({ shouldPrevent: true }));
|
|
21
|
-
expect(addSpy).toHaveBeenCalledWith("beforeunload", expect.any(Function));
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("removes beforeunload listener on unmount", () => {
|
|
25
|
-
const { unmount } = renderHook(() =>
|
|
26
|
-
usePreventCloseWindow({ shouldPrevent: true }),
|
|
27
|
-
);
|
|
28
|
-
unmount();
|
|
29
|
-
expect(removeSpy).toHaveBeenCalledWith(
|
|
30
|
-
"beforeunload",
|
|
31
|
-
expect.any(Function),
|
|
32
|
-
);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("calls event.preventDefault when shouldPrevent is true", () => {
|
|
36
|
-
renderHook(() => usePreventCloseWindow({ shouldPrevent: true }));
|
|
37
|
-
|
|
38
|
-
const handler = addSpy.mock.calls.find(
|
|
39
|
-
([event]: [string, EventListenerOrEventListenerObject]) =>
|
|
40
|
-
event === "beforeunload",
|
|
41
|
-
)?.[1] as EventListener;
|
|
42
|
-
|
|
43
|
-
const event = new Event("beforeunload");
|
|
44
|
-
const preventSpy = vi.spyOn(event, "preventDefault");
|
|
45
|
-
handler(event);
|
|
46
|
-
|
|
47
|
-
expect(preventSpy).toHaveBeenCalled();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("does not call event.preventDefault when shouldPrevent is false", () => {
|
|
51
|
-
renderHook(() => usePreventCloseWindow({ shouldPrevent: false }));
|
|
52
|
-
|
|
53
|
-
const handler = addSpy.mock.calls.find(
|
|
54
|
-
([event]: [string, EventListenerOrEventListenerObject]) =>
|
|
55
|
-
event === "beforeunload",
|
|
56
|
-
)?.[1] as EventListener;
|
|
57
|
-
|
|
58
|
-
const event = new Event("beforeunload");
|
|
59
|
-
const preventSpy = vi.spyOn(event, "preventDefault");
|
|
60
|
-
handler(event);
|
|
61
|
-
|
|
62
|
-
expect(preventSpy).not.toHaveBeenCalled();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("re-registers listener when shouldPrevent changes", () => {
|
|
66
|
-
const { rerender } = renderHook(
|
|
67
|
-
({ shouldPrevent }) => usePreventCloseWindow({ shouldPrevent }),
|
|
68
|
-
{ initialProps: { shouldPrevent: false } },
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
rerender({ shouldPrevent: true });
|
|
72
|
-
|
|
73
|
-
expect(removeSpy).toHaveBeenCalledWith(
|
|
74
|
-
"beforeunload",
|
|
75
|
-
expect.any(Function),
|
|
76
|
-
);
|
|
77
|
-
expect(addSpy).toHaveBeenCalledTimes(2);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
|
|
3
|
-
interface UsePreventCloseWindowProps {
|
|
4
|
-
/**
|
|
5
|
-
* Propiedad que determina si la ventana se puede cerrar o no
|
|
6
|
-
*/
|
|
7
|
-
shouldPrevent: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* Mensaje que se va a mostrar al usuario antes de cerrar la ventana
|
|
10
|
-
* @deprecated ya no es soportado por los navegadores modernos
|
|
11
|
-
*/
|
|
12
|
-
message?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function usePreventCloseWindow({
|
|
16
|
-
shouldPrevent,
|
|
17
|
-
message = "Es posible que no se guarden los cambios hayas hecho.",
|
|
18
|
-
}: UsePreventCloseWindowProps) {
|
|
19
|
-
const handleBeforeUnload = (event: BeforeUnloadEvent): void | string => {
|
|
20
|
-
if (!shouldPrevent) return;
|
|
21
|
-
|
|
22
|
-
event.preventDefault();
|
|
23
|
-
event.returnValue = message;
|
|
24
|
-
return message;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
29
|
-
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
30
|
-
}, [message, shouldPrevent]);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default usePreventCloseWindow;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./use-toggle";
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Meta } from "@storybook/react-vite";
|
|
2
|
-
import { Button, Checkbox } from "../../components";
|
|
3
|
-
import { useToggle } from "../use-toggle";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Hook que facilita el manejo de un estado booleano. Provee métodos para abrir, cerrar y toggle el estado
|
|
7
|
-
*/
|
|
8
|
-
const meta: Meta = {
|
|
9
|
-
title: "hooks/useToggle",
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export default meta;
|
|
13
|
-
|
|
14
|
-
export const Default = {
|
|
15
|
-
render: () => {
|
|
16
|
-
const [isOpen, toggle] = useToggle();
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<div className="space-y-2">
|
|
20
|
-
<Checkbox name="open" checked={isOpen} />
|
|
21
|
-
<Button onClick={() => toggle()}>Toggle</Button>
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
},
|
|
25
|
-
};
|