Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@react-aria/textfield

Package Overview
Dependencies
Maintainers
2
Versions
805
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@react-aria/textfield - npm Package Compare versions

Comparing version 3.0.0-nightly.992 to 3.0.0-nightly.994

src/useFormattedTextField.ts

141

dist/main.js
var {
useEffect,
useRef
} = require("react");
var {
useLabel

@@ -87,2 +92,138 @@ } = require("@react-aria/label");

exports.useTextField = useTextField;
function $e12a6959a5c62c5783c0140bc17c4eda$var$supportsNativeBeforeInputEvent() {
return typeof window !== 'undefined' && window.InputEvent && // @ts-ignore
typeof InputEvent.prototype.getTargetRanges === 'function';
}
function useFormattedTextField(props, state, inputRef) {
let stateRef = useRef(state);
stateRef.current = state; // All browsers implement the 'beforeinput' event natively except Firefox
// (currently behind a flag as of Firefox 84). React's polyfill does not
// run in all cases that the native event fires, e.g. when deleting text.
// Use the native event if available so that we can prevent invalid deletions.
// We do not attempt to polyfill this in Firefox since it would be very complicated,
// the benefit of doing so is fairly minor, and it's going to be natively supported soon.
useEffect(() => {
if (!$e12a6959a5c62c5783c0140bc17c4eda$var$supportsNativeBeforeInputEvent()) {
return;
}
let input = inputRef.current;
let onBeforeInput = e => {
let state = stateRef.current; // Compute the next value of the input if the event is allowed to proceed.
// See https://www.w3.org/TR/input-events-2/#interface-InputEvent-Attributes for a full list of input types.
let nextValue;
switch (e.inputType) {
case 'historyUndo':
case 'historyRedo':
// Explicitly allow undo/redo. e.data is null in this case, but there's no need to validate,
// because presumably the input would have already been validated previously.
return;
case 'deleteContent':
case 'deleteByCut':
case 'deleteByDrag':
nextValue = input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd);
break;
case 'deleteContentForward':
// This is potentially incorrect, since the browser may actually delete more than a single UTF-16
// character. In reality, a full Unicode grapheme cluster consisting of multiple UTF-16 characters
// or code points may be deleted. However, in our currently supported locales, there are no such cases.
// If we support additional locales in the future, this may need to change.
nextValue = input.selectionEnd === input.selectionStart ? input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd + 1) : input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd);
break;
case 'deleteContentBackward':
nextValue = input.selectionEnd === input.selectionStart ? input.value.slice(0, input.selectionStart - 1) + input.value.slice(input.selectionStart) : input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd);
break;
default:
if (e.data != null) {
nextValue = input.value.slice(0, input.selectionStart) + e.data + input.value.slice(input.selectionEnd);
}
break;
} // If we did not compute a value, or the new value is invalid, prevent the event
// so that the browser does not update the input text, move the selection, or add to
// the undo/redo stack.
if (nextValue == null || !state.validate(nextValue)) {
e.preventDefault();
}
};
input.addEventListener('beforeinput', onBeforeInput, false);
return () => {
input.removeEventListener('beforeinput', onBeforeInput, false);
};
}, [inputRef, stateRef]);
let onBeforeInput = !$e12a6959a5c62c5783c0140bc17c4eda$var$supportsNativeBeforeInputEvent() ? e => {
let nextValue = e.target.value.slice(0, e.target.selectionStart) + e.data + e.target.value.slice(e.target.selectionEnd);
if (!state.validate(nextValue)) {
e.preventDefault();
}
} : null;
let {
labelProps,
inputProps: textFieldProps
} = useTextField(props, inputRef);
let compositionStartState = useRef(null);
return {
inputProps: mergeProps(textFieldProps, {
onBeforeInput,
onCompositionStart() {
// Chrome does not implement Input Events Level 2, which specifies the insertFromComposition
// and deleteByComposition inputType values for the beforeinput event. These are meant to occur
// at the end of a composition (e.g. Pinyin IME, Android auto correct, etc.), and crucially, are
// cancelable. The insertCompositionText and deleteCompositionText input types are not cancelable,
// nor would we want to cancel them because the input from the user is incomplete at that point.
// In Safari, insertFromComposition/deleteFromComposition will fire, however, allowing us to cancel
// the final composition result if it is invalid. As a fallback for Chrome and Firefox, which either
// don't support Input Events Level 2, or beforeinput at all, we store the state of the input when
// the compositionstart event fires, and undo the changes in compositionend (below) if it is invalid.
// Unfortunately, this messes up the undo/redo stack, but until insertFromComposition/deleteByComposition
// are implemented, there is no other way to prevent composed input.
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1022204
let {
value,
selectionStart,
selectionEnd
} = inputRef.current;
compositionStartState.current = {
value,
selectionStart,
selectionEnd
};
},
onCompositionEnd() {
if (!state.validate(inputRef.current.value)) {
// Restore the input value in the DOM immediately so we can synchronously update the selection position.
// But also update the value in React state as well so it is correct for future updates.
let {
value,
selectionStart,
selectionEnd
} = compositionStartState.current;
inputRef.current.value = value;
inputRef.current.setSelectionRange(selectionStart, selectionEnd);
state.setInputValue(value);
}
}
}),
labelProps
};
}
exports.useFormattedTextField = useFormattedTextField;
//# sourceMappingURL=main.js.map

@@ -0,1 +1,2 @@

import { useEffect, useRef } from "react";
import { useLabel } from "@react-aria/label";

@@ -71,2 +72,136 @@ import { useFocusable } from "@react-aria/focus";

}
function $c7e32867b2abc7e2d776d5c060056cb7$var$supportsNativeBeforeInputEvent() {
return typeof window !== 'undefined' && window.InputEvent && // @ts-ignore
typeof InputEvent.prototype.getTargetRanges === 'function';
}
export function useFormattedTextField(props, state, inputRef) {
let stateRef = useRef(state);
stateRef.current = state; // All browsers implement the 'beforeinput' event natively except Firefox
// (currently behind a flag as of Firefox 84). React's polyfill does not
// run in all cases that the native event fires, e.g. when deleting text.
// Use the native event if available so that we can prevent invalid deletions.
// We do not attempt to polyfill this in Firefox since it would be very complicated,
// the benefit of doing so is fairly minor, and it's going to be natively supported soon.
useEffect(() => {
if (!$c7e32867b2abc7e2d776d5c060056cb7$var$supportsNativeBeforeInputEvent()) {
return;
}
let input = inputRef.current;
let onBeforeInput = e => {
let state = stateRef.current; // Compute the next value of the input if the event is allowed to proceed.
// See https://www.w3.org/TR/input-events-2/#interface-InputEvent-Attributes for a full list of input types.
let nextValue;
switch (e.inputType) {
case 'historyUndo':
case 'historyRedo':
// Explicitly allow undo/redo. e.data is null in this case, but there's no need to validate,
// because presumably the input would have already been validated previously.
return;
case 'deleteContent':
case 'deleteByCut':
case 'deleteByDrag':
nextValue = input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd);
break;
case 'deleteContentForward':
// This is potentially incorrect, since the browser may actually delete more than a single UTF-16
// character. In reality, a full Unicode grapheme cluster consisting of multiple UTF-16 characters
// or code points may be deleted. However, in our currently supported locales, there are no such cases.
// If we support additional locales in the future, this may need to change.
nextValue = input.selectionEnd === input.selectionStart ? input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd + 1) : input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd);
break;
case 'deleteContentBackward':
nextValue = input.selectionEnd === input.selectionStart ? input.value.slice(0, input.selectionStart - 1) + input.value.slice(input.selectionStart) : input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd);
break;
default:
if (e.data != null) {
nextValue = input.value.slice(0, input.selectionStart) + e.data + input.value.slice(input.selectionEnd);
}
break;
} // If we did not compute a value, or the new value is invalid, prevent the event
// so that the browser does not update the input text, move the selection, or add to
// the undo/redo stack.
if (nextValue == null || !state.validate(nextValue)) {
e.preventDefault();
}
};
input.addEventListener('beforeinput', onBeforeInput, false);
return () => {
input.removeEventListener('beforeinput', onBeforeInput, false);
};
}, [inputRef, stateRef]);
let onBeforeInput = !$c7e32867b2abc7e2d776d5c060056cb7$var$supportsNativeBeforeInputEvent() ? e => {
let nextValue = e.target.value.slice(0, e.target.selectionStart) + e.data + e.target.value.slice(e.target.selectionEnd);
if (!state.validate(nextValue)) {
e.preventDefault();
}
} : null;
let {
labelProps,
inputProps: textFieldProps
} = useTextField(props, inputRef);
let compositionStartState = useRef(null);
return {
inputProps: mergeProps(textFieldProps, {
onBeforeInput,
onCompositionStart() {
// Chrome does not implement Input Events Level 2, which specifies the insertFromComposition
// and deleteByComposition inputType values for the beforeinput event. These are meant to occur
// at the end of a composition (e.g. Pinyin IME, Android auto correct, etc.), and crucially, are
// cancelable. The insertCompositionText and deleteCompositionText input types are not cancelable,
// nor would we want to cancel them because the input from the user is incomplete at that point.
// In Safari, insertFromComposition/deleteFromComposition will fire, however, allowing us to cancel
// the final composition result if it is invalid. As a fallback for Chrome and Firefox, which either
// don't support Input Events Level 2, or beforeinput at all, we store the state of the input when
// the compositionstart event fires, and undo the changes in compositionend (below) if it is invalid.
// Unfortunately, this messes up the undo/redo stack, but until insertFromComposition/deleteByComposition
// are implemented, there is no other way to prevent composed input.
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1022204
let {
value,
selectionStart,
selectionEnd
} = inputRef.current;
compositionStartState.current = {
value,
selectionStart,
selectionEnd
};
},
onCompositionEnd() {
if (!state.validate(inputRef.current.value)) {
// Restore the input value in the DOM immediately so we can synchronously update the selection position.
// But also update the value in React state as well so it is correct for future updates.
let {
value,
selectionStart,
selectionEnd
} = compositionStartState.current;
inputRef.current.value = value;
inputRef.current.setSelectionRange(selectionStart, selectionEnd);
state.setInputValue(value);
}
}
}),
labelProps
};
}
//# sourceMappingURL=module.js.map

7

dist/types.d.ts
import { AriaTextFieldProps } from "@react-types/textfield";
import { InputHTMLAttributes, LabelHTMLAttributes, RefObject, TextareaHTMLAttributes, ElementType } from "react";
interface TextFieldAria {
export interface TextFieldAria {
/** Props for the input element. */

@@ -24,3 +24,8 @@ inputProps: InputHTMLAttributes<HTMLInputElement> | TextareaHTMLAttributes<HTMLTextAreaElement>;

export function useTextField(props: AriaTextFieldOptions, ref: RefObject<HTMLInputElement | HTMLTextAreaElement>): TextFieldAria;
interface FormattedTextFieldState {
validate: (val: string) => boolean;
setInputValue: (val: string) => void;
}
export function useFormattedTextField(props: AriaTextFieldProps, state: FormattedTextFieldState, inputRef: RefObject<HTMLInputElement>): TextFieldAria;
//# sourceMappingURL=types.d.ts.map

14

package.json
{
"name": "@react-aria/textfield",
"version": "3.0.0-nightly.992+d1844573",
"version": "3.0.0-nightly.994+faa93480",
"description": "Spectrum UI components in React",

@@ -21,7 +21,7 @@ "license": "Apache-2.0",

"@babel/runtime": "^7.6.2",
"@react-aria/focus": "3.0.0-nightly.992+d1844573",
"@react-aria/label": "3.0.0-nightly.992+d1844573",
"@react-aria/utils": "3.0.0-nightly.992+d1844573",
"@react-types/shared": "3.0.0-nightly.992+d1844573",
"@react-types/textfield": "3.0.0-nightly.992+d1844573"
"@react-aria/focus": "3.0.0-nightly.994+faa93480",
"@react-aria/label": "3.0.0-nightly.994+faa93480",
"@react-aria/utils": "3.0.0-nightly.994+faa93480",
"@react-types/shared": "3.0.0-nightly.994+faa93480",
"@react-types/textfield": "3.0.0-nightly.994+faa93480"
},

@@ -34,3 +34,3 @@ "peerDependencies": {

},
"gitHead": "d1844573fa992f7a34285ebafdc08cb407829095"
"gitHead": "faa9348097bf62403e37e32daf897cdad5512e09"
}

@@ -14,1 +14,2 @@ /*

export * from './useTextField';
export * from './useFormattedTextField';

@@ -20,3 +20,3 @@ /*

interface TextFieldAria {
export interface TextFieldAria {
/** Props for the input element. */

@@ -23,0 +23,0 @@ inputProps: InputHTMLAttributes<HTMLInputElement> | TextareaHTMLAttributes<HTMLTextAreaElement>,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc