@servicetitan/anvil2-ext-common 0.3.0 → 0.3.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/CHANGELOG.md +16 -0
- package/dist/hooks/useInputGuards/useInputGuards.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{useInputGuards-DkzuBQaN.js → useInputGuards-CNyYcrvq.js} +5 -2
- package/dist/useInputGuards-CNyYcrvq.js.map +1 -0
- package/dist/useInputGuards.js +1 -1
- package/package.json +2 -2
- package/dist/useInputGuards-DkzuBQaN.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @servicetitan/anvil2-ext-common
|
|
2
2
|
|
|
3
|
+
## 0.3.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`a919352`](https://github.com/servicetitan/hammer/commit/a919352f3c13507010023aa0df5def4fa9f550c8), [`2deba8e`](https://github.com/servicetitan/hammer/commit/2deba8e0e1db1a47de16d552493993809aee0c93)]:
|
|
8
|
+
- @servicetitan/anvil2@2.5.0
|
|
9
|
+
|
|
10
|
+
## 0.3.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [#2083](https://github.com/servicetitan/hammer/pull/2083) [`e647744`](https://github.com/servicetitan/hammer/commit/e647744d1abd45f1bf2fae27a4856aa20daaf866) Thanks [@copilot-swe-agent](https://github.com/apps/copilot-swe-agent)! - [useInputGuards] Fix held `ArrowLeft`/`ArrowRight` keys being suppressed by repeat guard; fix re-commit suppressed after external value is cleared to `''`
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [[`623398f`](https://github.com/servicetitan/hammer/commit/623398f22d6c390a049c0968c4340dc82729331e), [`9736150`](https://github.com/servicetitan/hammer/commit/9736150539b2ed46a08808b19f9974b7f6bbf667), [`0a7d8c7`](https://github.com/servicetitan/hammer/commit/0a7d8c75028384f1ced3cc1051b68b4badc30163), [`edae603`](https://github.com/servicetitan/hammer/commit/edae60309b49c18e87ea2b3d3c02c915124a21d5), [`9736150`](https://github.com/servicetitan/hammer/commit/9736150539b2ed46a08808b19f9974b7f6bbf667), [`623398f`](https://github.com/servicetitan/hammer/commit/623398f22d6c390a049c0968c4340dc82729331e)]:
|
|
17
|
+
- @servicetitan/anvil2@2.4.0
|
|
18
|
+
|
|
3
19
|
## 0.3.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -28,7 +28,7 @@ export interface UseInputGuardsConfig {
|
|
|
28
28
|
* - Typing: visible value updates immediately; when `CommitTrigger.Typing` is active, `onCommit` fires after `delay` ms of inactivity
|
|
29
29
|
* - Paste: when `CommitTrigger.Paste` is active, commits immediately via a commit guard (rate-limited to one per `delay` ms)
|
|
30
30
|
* - Enter: when `CommitTrigger.Enter` is active, commits immediately via a commit guard (rate-limited to one per `delay` ms)
|
|
31
|
-
* - Repeated keys: held-key keydown events suppressed with `preventDefault()`
|
|
31
|
+
* - Repeated keys: held-key keydown events suppressed with `preventDefault()` (ArrowLeft/ArrowRight exempt so held arrows continuously move the cursor)
|
|
32
32
|
* - Clear: when `CommitTrigger.Clear` is active, commits `''` immediately; in all cases, clearing deactivates the guard
|
|
33
33
|
* - Deduplication: consecutive identical values never committed twice
|
|
34
34
|
* - External sync: when `value` changes externally, local state re-syncs and stale timers cancelled
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as ExampleComponent } from './ExampleComponent.js';
|
|
2
2
|
export { u as useConfirmDialog } from './useConfirmDialog-DaQ5Golt.js';
|
|
3
|
-
export { C as CommitTrigger, u as useInputGuards } from './useInputGuards-
|
|
3
|
+
export { C as CommitTrigger, u as useInputGuards } from './useInputGuards-CNyYcrvq.js';
|
|
4
4
|
export { default as ExampleProvider } from './ExampleProvider.js';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -139,6 +139,9 @@ function useInputGuards({
|
|
|
139
139
|
deactivateGuard(stateRef);
|
|
140
140
|
setLocalValue(value);
|
|
141
141
|
stateRef.current.localValue = value;
|
|
142
|
+
if (value === "") {
|
|
143
|
+
stateRef.current.lastCommitted = null;
|
|
144
|
+
}
|
|
142
145
|
}, [value]);
|
|
143
146
|
useEffect(() => {
|
|
144
147
|
return () => {
|
|
@@ -175,7 +178,7 @@ function useInputGuards({
|
|
|
175
178
|
);
|
|
176
179
|
const onKeyDown = useCallback(
|
|
177
180
|
(event) => {
|
|
178
|
-
if (event.repeat) {
|
|
181
|
+
if (event.repeat && event.key !== "ArrowLeft" && event.key !== "ArrowRight") {
|
|
179
182
|
event.preventDefault();
|
|
180
183
|
return;
|
|
181
184
|
}
|
|
@@ -193,4 +196,4 @@ function useInputGuards({
|
|
|
193
196
|
}
|
|
194
197
|
|
|
195
198
|
export { CommitTrigger as C, useInputGuards as u };
|
|
196
|
-
//# sourceMappingURL=useInputGuards-
|
|
199
|
+
//# sourceMappingURL=useInputGuards-CNyYcrvq.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInputGuards-CNyYcrvq.js","sources":["../src/hooks/useInputGuards/useInputGuards.ts"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type ChangeEventHandler,\n type ClipboardEventHandler,\n type KeyboardEventHandler,\n} from \"react\";\n\nexport enum CommitTrigger {\n Typing = \"typing\",\n Enter = \"enter\",\n Paste = \"paste\",\n Clear = \"clear\",\n}\n\nconst ALL_TRIGGERS = [\n CommitTrigger.Typing,\n CommitTrigger.Enter,\n CommitTrigger.Paste,\n CommitTrigger.Clear,\n] as const;\n\nfunction toTriggerSet(\n triggers?: CommitTrigger[],\n): ReadonlySet<CommitTrigger> {\n if (!triggers || triggers.length === 0) return new Set(ALL_TRIGGERS);\n return new Set(triggers);\n}\n\nexport interface UseInputGuardsProps {\n value: string;\n onChange: ChangeEventHandler<HTMLInputElement>;\n onPaste: ClipboardEventHandler<HTMLInputElement>;\n onKeyDown: KeyboardEventHandler<HTMLInputElement>;\n}\n\nexport interface UseInputGuardsConfig {\n value: string;\n delay: number;\n onCommit: (value: string) => void;\n /**\n * Which user actions trigger a commit. Defaults to all triggers when omitted or empty.\n * Omit `CommitTrigger.Typing` to disable the debounce auto-commit after inactivity\n * while still allowing Enter, paste, and clear to commit.\n */\n triggers?: [CommitTrigger, ...CommitTrigger[]];\n}\n\ninterface State {\n localValue: string;\n renderedLocalValue: string;\n lastCommitted: string | null;\n guardActive: boolean;\n externalValue: string;\n onCommit: (value: string) => void;\n delay: number;\n triggers: ReadonlySet<CommitTrigger>;\n typingTimer: ReturnType<typeof setTimeout> | null;\n deferredTimer: ReturnType<typeof setTimeout> | null;\n guardTimer: ReturnType<typeof setTimeout> | null;\n}\n\ninterface StateRef {\n current: State;\n}\n\nfunction clearTypingTimer(stateRef: StateRef) {\n if (stateRef.current.typingTimer !== null) {\n clearTimeout(stateRef.current.typingTimer);\n stateRef.current.typingTimer = null;\n }\n}\n\nfunction clearDeferredTimer(stateRef: StateRef) {\n if (stateRef.current.deferredTimer !== null) {\n clearTimeout(stateRef.current.deferredTimer);\n stateRef.current.deferredTimer = null;\n }\n}\n\nfunction clearGuardTimer(stateRef: StateRef) {\n if (stateRef.current.guardTimer !== null) {\n clearTimeout(stateRef.current.guardTimer);\n stateRef.current.guardTimer = null;\n }\n}\n\nfunction clearAllTimers(stateRef: StateRef) {\n clearTypingTimer(stateRef);\n clearDeferredTimer(stateRef);\n clearGuardTimer(stateRef);\n}\n\nfunction hasTrigger(stateRef: StateRef, trigger: CommitTrigger) {\n return stateRef.current.triggers.has(trigger);\n}\n\nfunction activateGuard(stateRef: StateRef) {\n stateRef.current.guardActive = true;\n clearGuardTimer(stateRef);\n\n stateRef.current.guardTimer = setTimeout(() => {\n stateRef.current.guardTimer = null;\n stateRef.current.guardActive = false;\n }, stateRef.current.delay);\n}\n\nfunction deactivateGuard(stateRef: StateRef) {\n stateRef.current.guardActive = false;\n clearGuardTimer(stateRef);\n}\n\nfunction doCommit(stateRef: StateRef, val: string) {\n if (stateRef.current.lastCommitted === val) return;\n\n stateRef.current.lastCommitted = val;\n activateGuard(stateRef);\n stateRef.current.onCommit(val);\n}\n\nfunction guardedCommit(stateRef: StateRef, val: string) {\n const wasDeferred = stateRef.current.deferredTimer !== null;\n clearDeferredTimer(stateRef);\n\n if (!wasDeferred && !stateRef.current.guardActive) {\n doCommit(stateRef, val);\n return;\n }\n\n stateRef.current.deferredTimer = setTimeout(() => {\n stateRef.current.deferredTimer = null;\n doCommit(stateRef, val);\n }, stateRef.current.delay);\n}\n\nfunction handleValueChange(\n stateRef: StateRef,\n setLocalValue: (value: string) => void,\n newValue: string,\n) {\n setLocalValue(newValue);\n stateRef.current.localValue = newValue;\n\n if (newValue === \"\") {\n clearAllTimers(stateRef);\n if (hasTrigger(stateRef, CommitTrigger.Clear)) {\n doCommit(stateRef, newValue);\n }\n deactivateGuard(stateRef);\n return;\n }\n\n clearTypingTimer(stateRef);\n if (!hasTrigger(stateRef, CommitTrigger.Typing)) return; // visible value updated above; no debounce commit\n stateRef.current.typingTimer = setTimeout(() => {\n stateRef.current.typingTimer = null;\n guardedCommit(stateRef, newValue);\n }, stateRef.current.delay);\n}\n\nfunction handlePasteValue(\n stateRef: StateRef,\n setLocalValue: (value: string) => void,\n pastedValue: string,\n) {\n setLocalValue(pastedValue);\n stateRef.current.localValue = pastedValue;\n\n clearTypingTimer(stateRef);\n if (hasTrigger(stateRef, CommitTrigger.Paste)) {\n guardedCommit(stateRef, pastedValue);\n } else {\n clearDeferredTimer(stateRef);\n if (hasTrigger(stateRef, CommitTrigger.Typing) && pastedValue !== \"\") {\n stateRef.current.typingTimer = setTimeout(() => {\n stateRef.current.typingTimer = null;\n guardedCommit(stateRef, pastedValue);\n }, stateRef.current.delay);\n }\n }\n}\n\n/**\n * Manages a debounced text input with rate-limited commits.\n *\n * - Typing: visible value updates immediately; when `CommitTrigger.Typing` is active, `onCommit` fires after `delay` ms of inactivity\n * - Paste: when `CommitTrigger.Paste` is active, commits immediately via a commit guard (rate-limited to one per `delay` ms)\n * - Enter: when `CommitTrigger.Enter` is active, commits immediately via a commit guard (rate-limited to one per `delay` ms)\n * - Repeated keys: held-key keydown events suppressed with `preventDefault()` (ArrowLeft/ArrowRight exempt so held arrows continuously move the cursor)\n * - Clear: when `CommitTrigger.Clear` is active, commits `''` immediately; in all cases, clearing deactivates the guard\n * - Deduplication: consecutive identical values never committed twice\n * - External sync: when `value` changes externally, local state re-syncs and stale timers cancelled\n * - Unmount: all pending timers cancelled; no trailing commit fires\n * - `triggers`: controls which user actions fire a commit (defaults to all)\n *\n * @returns An object with `inputProps` to spread onto the input element.\n */\nexport function useInputGuards({\n value,\n delay,\n onCommit,\n triggers,\n}: UseInputGuardsConfig): { inputProps: UseInputGuardsProps } {\n const [localValue, setLocalValue] = useState(value);\n\n const stateRef = useRef<State>({\n localValue: value,\n renderedLocalValue: value,\n lastCommitted: null,\n guardActive: false,\n externalValue: value,\n onCommit,\n delay,\n triggers: toTriggerSet(triggers),\n typingTimer: null,\n deferredTimer: null,\n guardTimer: null,\n });\n\n stateRef.current.renderedLocalValue = localValue;\n stateRef.current.onCommit = onCommit;\n stateRef.current.delay = delay;\n stateRef.current.triggers = toTriggerSet(triggers);\n\n useEffect(() => {\n if (value === stateRef.current.externalValue) return;\n\n stateRef.current.externalValue = value;\n\n if (value === stateRef.current.lastCommitted) return; // own commit bouncing back\n\n clearAllTimers(stateRef);\n deactivateGuard(stateRef);\n setLocalValue(value);\n stateRef.current.localValue = value;\n\n // External clear: reset deduplication so the same value can be\n // committed again after the store is cleared (e.g., after toggling\n // input modes).\n if (value === \"\") {\n stateRef.current.lastCommitted = null;\n }\n }, [value]);\n\n useEffect(() => {\n return () => {\n clearAllTimers(stateRef);\n };\n }, []);\n\n const onChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n const newValue = event.target.value;\n\n if (newValue === stateRef.current.localValue) return;\n if (newValue === stateRef.current.renderedLocalValue) return; // spurious post-paste event\n\n handleValueChange(stateRef, setLocalValue, newValue);\n },\n [],\n );\n\n const onPaste: ClipboardEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n event.preventDefault();\n\n if (!event.clipboardData) return;\n\n const pastedText = event.clipboardData.getData(\"text\");\n const { selectionStart, selectionEnd } = event.currentTarget;\n const currentValue = stateRef.current.localValue;\n const beforeCursor = currentValue.slice(0, selectionStart ?? 0);\n const afterCursor = currentValue.slice(\n selectionEnd ?? currentValue.length,\n );\n\n handlePasteValue(\n stateRef,\n setLocalValue,\n beforeCursor + pastedText + afterCursor,\n );\n },\n [],\n );\n\n const onKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n if (event.repeat && event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") {\n event.preventDefault();\n return;\n }\n if (event.key !== \"Enter\") return;\n\n if (hasTrigger(stateRef, CommitTrigger.Enter)) {\n clearTypingTimer(stateRef);\n guardedCommit(stateRef, stateRef.current.localValue);\n }\n },\n [],\n );\n\n return {\n inputProps: { value: localValue, onChange, onPaste, onKeyDown },\n };\n}\n"],"names":["CommitTrigger"],"mappings":"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"}
|
package/dist/useInputGuards.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { C as CommitTrigger, u as default, u as useInputGuards } from './useInputGuards-
|
|
1
|
+
export { C as CommitTrigger, u as default, u as useInputGuards } from './useInputGuards-CNyYcrvq.js';
|
|
2
2
|
//# sourceMappingURL=useInputGuards.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/anvil2-ext-common",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"tabbable": "^6.2.0",
|
|
32
32
|
"tinycolor2": "^1.6.0",
|
|
33
33
|
"uuid": "^10.0.0",
|
|
34
|
-
"@servicetitan/anvil2": "2.
|
|
34
|
+
"@servicetitan/anvil2": "2.5.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@types/react": "^18 || ^19",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useInputGuards-DkzuBQaN.js","sources":["../src/hooks/useInputGuards/useInputGuards.ts"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type ChangeEventHandler,\n type ClipboardEventHandler,\n type KeyboardEventHandler,\n} from \"react\";\n\nexport enum CommitTrigger {\n Typing = \"typing\",\n Enter = \"enter\",\n Paste = \"paste\",\n Clear = \"clear\",\n}\n\nconst ALL_TRIGGERS = [\n CommitTrigger.Typing,\n CommitTrigger.Enter,\n CommitTrigger.Paste,\n CommitTrigger.Clear,\n] as const;\n\nfunction toTriggerSet(\n triggers?: CommitTrigger[],\n): ReadonlySet<CommitTrigger> {\n if (!triggers || triggers.length === 0) return new Set(ALL_TRIGGERS);\n return new Set(triggers);\n}\n\nexport interface UseInputGuardsProps {\n value: string;\n onChange: ChangeEventHandler<HTMLInputElement>;\n onPaste: ClipboardEventHandler<HTMLInputElement>;\n onKeyDown: KeyboardEventHandler<HTMLInputElement>;\n}\n\nexport interface UseInputGuardsConfig {\n value: string;\n delay: number;\n onCommit: (value: string) => void;\n /**\n * Which user actions trigger a commit. Defaults to all triggers when omitted or empty.\n * Omit `CommitTrigger.Typing` to disable the debounce auto-commit after inactivity\n * while still allowing Enter, paste, and clear to commit.\n */\n triggers?: [CommitTrigger, ...CommitTrigger[]];\n}\n\ninterface State {\n localValue: string;\n renderedLocalValue: string;\n lastCommitted: string | null;\n guardActive: boolean;\n externalValue: string;\n onCommit: (value: string) => void;\n delay: number;\n triggers: ReadonlySet<CommitTrigger>;\n typingTimer: ReturnType<typeof setTimeout> | null;\n deferredTimer: ReturnType<typeof setTimeout> | null;\n guardTimer: ReturnType<typeof setTimeout> | null;\n}\n\ninterface StateRef {\n current: State;\n}\n\nfunction clearTypingTimer(stateRef: StateRef) {\n if (stateRef.current.typingTimer !== null) {\n clearTimeout(stateRef.current.typingTimer);\n stateRef.current.typingTimer = null;\n }\n}\n\nfunction clearDeferredTimer(stateRef: StateRef) {\n if (stateRef.current.deferredTimer !== null) {\n clearTimeout(stateRef.current.deferredTimer);\n stateRef.current.deferredTimer = null;\n }\n}\n\nfunction clearGuardTimer(stateRef: StateRef) {\n if (stateRef.current.guardTimer !== null) {\n clearTimeout(stateRef.current.guardTimer);\n stateRef.current.guardTimer = null;\n }\n}\n\nfunction clearAllTimers(stateRef: StateRef) {\n clearTypingTimer(stateRef);\n clearDeferredTimer(stateRef);\n clearGuardTimer(stateRef);\n}\n\nfunction hasTrigger(stateRef: StateRef, trigger: CommitTrigger) {\n return stateRef.current.triggers.has(trigger);\n}\n\nfunction activateGuard(stateRef: StateRef) {\n stateRef.current.guardActive = true;\n clearGuardTimer(stateRef);\n\n stateRef.current.guardTimer = setTimeout(() => {\n stateRef.current.guardTimer = null;\n stateRef.current.guardActive = false;\n }, stateRef.current.delay);\n}\n\nfunction deactivateGuard(stateRef: StateRef) {\n stateRef.current.guardActive = false;\n clearGuardTimer(stateRef);\n}\n\nfunction doCommit(stateRef: StateRef, val: string) {\n if (stateRef.current.lastCommitted === val) return;\n\n stateRef.current.lastCommitted = val;\n activateGuard(stateRef);\n stateRef.current.onCommit(val);\n}\n\nfunction guardedCommit(stateRef: StateRef, val: string) {\n const wasDeferred = stateRef.current.deferredTimer !== null;\n clearDeferredTimer(stateRef);\n\n if (!wasDeferred && !stateRef.current.guardActive) {\n doCommit(stateRef, val);\n return;\n }\n\n stateRef.current.deferredTimer = setTimeout(() => {\n stateRef.current.deferredTimer = null;\n doCommit(stateRef, val);\n }, stateRef.current.delay);\n}\n\nfunction handleValueChange(\n stateRef: StateRef,\n setLocalValue: (value: string) => void,\n newValue: string,\n) {\n setLocalValue(newValue);\n stateRef.current.localValue = newValue;\n\n if (newValue === \"\") {\n clearAllTimers(stateRef);\n if (hasTrigger(stateRef, CommitTrigger.Clear)) {\n doCommit(stateRef, newValue);\n }\n deactivateGuard(stateRef);\n return;\n }\n\n clearTypingTimer(stateRef);\n if (!hasTrigger(stateRef, CommitTrigger.Typing)) return; // visible value updated above; no debounce commit\n stateRef.current.typingTimer = setTimeout(() => {\n stateRef.current.typingTimer = null;\n guardedCommit(stateRef, newValue);\n }, stateRef.current.delay);\n}\n\nfunction handlePasteValue(\n stateRef: StateRef,\n setLocalValue: (value: string) => void,\n pastedValue: string,\n) {\n setLocalValue(pastedValue);\n stateRef.current.localValue = pastedValue;\n\n clearTypingTimer(stateRef);\n if (hasTrigger(stateRef, CommitTrigger.Paste)) {\n guardedCommit(stateRef, pastedValue);\n } else {\n clearDeferredTimer(stateRef);\n if (hasTrigger(stateRef, CommitTrigger.Typing) && pastedValue !== \"\") {\n stateRef.current.typingTimer = setTimeout(() => {\n stateRef.current.typingTimer = null;\n guardedCommit(stateRef, pastedValue);\n }, stateRef.current.delay);\n }\n }\n}\n\n/**\n * Manages a debounced text input with rate-limited commits.\n *\n * - Typing: visible value updates immediately; when `CommitTrigger.Typing` is active, `onCommit` fires after `delay` ms of inactivity\n * - Paste: when `CommitTrigger.Paste` is active, commits immediately via a commit guard (rate-limited to one per `delay` ms)\n * - Enter: when `CommitTrigger.Enter` is active, commits immediately via a commit guard (rate-limited to one per `delay` ms)\n * - Repeated keys: held-key keydown events suppressed with `preventDefault()`\n * - Clear: when `CommitTrigger.Clear` is active, commits `''` immediately; in all cases, clearing deactivates the guard\n * - Deduplication: consecutive identical values never committed twice\n * - External sync: when `value` changes externally, local state re-syncs and stale timers cancelled\n * - Unmount: all pending timers cancelled; no trailing commit fires\n * - `triggers`: controls which user actions fire a commit (defaults to all)\n *\n * @returns An object with `inputProps` to spread onto the input element.\n */\nexport function useInputGuards({\n value,\n delay,\n onCommit,\n triggers,\n}: UseInputGuardsConfig): { inputProps: UseInputGuardsProps } {\n const [localValue, setLocalValue] = useState(value);\n\n const stateRef = useRef<State>({\n localValue: value,\n renderedLocalValue: value,\n lastCommitted: null,\n guardActive: false,\n externalValue: value,\n onCommit,\n delay,\n triggers: toTriggerSet(triggers),\n typingTimer: null,\n deferredTimer: null,\n guardTimer: null,\n });\n\n stateRef.current.renderedLocalValue = localValue;\n stateRef.current.onCommit = onCommit;\n stateRef.current.delay = delay;\n stateRef.current.triggers = toTriggerSet(triggers);\n\n useEffect(() => {\n if (value === stateRef.current.externalValue) return;\n\n stateRef.current.externalValue = value;\n\n if (value === stateRef.current.lastCommitted) return; // own commit bouncing back\n\n clearAllTimers(stateRef);\n deactivateGuard(stateRef);\n setLocalValue(value);\n stateRef.current.localValue = value;\n }, [value]);\n\n useEffect(() => {\n return () => {\n clearAllTimers(stateRef);\n };\n }, []);\n\n const onChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n const newValue = event.target.value;\n\n if (newValue === stateRef.current.localValue) return;\n if (newValue === stateRef.current.renderedLocalValue) return; // spurious post-paste event\n\n handleValueChange(stateRef, setLocalValue, newValue);\n },\n [],\n );\n\n const onPaste: ClipboardEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n event.preventDefault();\n\n if (!event.clipboardData) return;\n\n const pastedText = event.clipboardData.getData(\"text\");\n const { selectionStart, selectionEnd } = event.currentTarget;\n const currentValue = stateRef.current.localValue;\n const beforeCursor = currentValue.slice(0, selectionStart ?? 0);\n const afterCursor = currentValue.slice(\n selectionEnd ?? currentValue.length,\n );\n\n handlePasteValue(\n stateRef,\n setLocalValue,\n beforeCursor + pastedText + afterCursor,\n );\n },\n [],\n );\n\n const onKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n if (event.repeat) {\n event.preventDefault();\n return;\n }\n if (event.key !== \"Enter\") return;\n\n if (hasTrigger(stateRef, CommitTrigger.Enter)) {\n clearTypingTimer(stateRef);\n guardedCommit(stateRef, stateRef.current.localValue);\n }\n },\n [],\n );\n\n return {\n inputProps: { value: localValue, onChange, onPaste, onKeyDown },\n };\n}\n"],"names":["CommitTrigger"],"mappings":"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"}
|