react#ClipboardEvent TypeScript Examples
The following examples show how to use
react#ClipboardEvent.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts From anchor-web-app with Apache License 2.0 | 4 votes |
export function useRestrictedNumberInput({
type = 'decimal',
maxDecimalPoints,
maxIntegerPoinsts,
onChange: _onChange,
}: RestrictedNumberInputParams): RestrictedInputReturn {
const { onKeyPress: restrictCharacters } = useRestrictedInput(
type === 'integer' ? '0-9' : '0-9.',
);
const isInvalid = useCallback(
(nextValue: string): boolean => {
return (
Number.isNaN(+nextValue) ||
(typeof maxIntegerPoinsts === 'number' &&
new RegExp(`^[0-9]{${maxIntegerPoinsts + 1},}`).test(nextValue)) ||
(type === 'decimal' &&
typeof maxDecimalPoints === 'number' &&
new RegExp(`\\.[0-9]{${maxDecimalPoints + 1},}$`).test(nextValue))
);
},
[maxDecimalPoints, maxIntegerPoinsts, type],
);
const onKeyPress = useCallback(
(event: KeyboardEvent<HTMLInputElement>) => {
restrictCharacters(event);
if (event.isDefaultPrevented()) {
return;
}
const { value, selectionStart, selectionEnd } =
event.target as HTMLInputElement;
if (
typeof selectionStart !== 'number' ||
typeof selectionEnd !== 'number'
) {
event.preventDefault();
event.stopPropagation();
return;
}
const char = event.key;
const nextValue =
value.substring(0, selectionStart) +
char +
value.substring(selectionEnd);
if (isInvalid(nextValue)) {
event.preventDefault();
event.stopPropagation();
}
},
[restrictCharacters, isInvalid],
);
const onPaste = useCallback(
(event: ClipboardEvent<HTMLInputElement>) => {
const pastedText = event.clipboardData?.getData('text');
if (!/^[0-9.]+$/.test(pastedText)) {
event.preventDefault();
event.stopPropagation();
}
const { value, selectionStart, selectionEnd } =
event.target as HTMLInputElement;
if (
typeof selectionStart !== 'number' ||
typeof selectionEnd !== 'number'
) {
event.preventDefault();
event.stopPropagation();
return;
}
const nextValue =
value.substring(0, selectionStart) +
pastedText +
value.substring(selectionEnd);
if (isInvalid(nextValue)) {
event.preventDefault();
event.stopPropagation();
}
},
[isInvalid],
);
const onChange = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
if (_onChange) {
const hasNonNumeralCharacters = /[^0-9.]/g;
if (hasNonNumeralCharacters.test(event.target.value)) {
event.target.value = event.target.value.replace(/[^0-9.]/g, '');
}
_onChange(event);
}
},
[_onChange],
);
return { onKeyPress, onPaste, onChange };
}
Example #2
Source File: CommentBox.tsx From apps with GNU Affero General Public License v3.0 | 4 votes |
function CommentBox({
authorImage,
authorName,
publishDate,
contentHtml,
editContent,
editId,
input,
errorMessage,
sendingComment,
onInput,
onKeyDown,
sendComment,
parentSelector,
post,
}: CommentBoxProps): ReactElement {
const onTextareaInput = (content: string) =>
onInput(cleanupEmptySpaces(content));
const { user } = useContext(AuthContext);
const commentRef = useRef<HTMLDivElement>(null);
const {
onMentionClick,
onMentionKeypress,
offset,
mentions,
mentionQuery,
selected,
onInitializeMention,
onInputClick,
} = useUserMention({
postId: post.id,
commentRef,
onInput: onTextareaInput,
});
useEffect(() => {
commentRef.current?.focus();
if (commentRef.current && editContent) {
commentRef.current.innerText = editContent;
}
}, []);
const onPaste = (event: ClipboardEvent): void => {
event.preventDefault();
const text = event.clipboardData.getData('text/plain');
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text);
} else {
document.execCommand('paste', false, text);
}
};
const handleKeydown = (e: KeyboardEvent<HTMLDivElement>) => {
const defaultCallback = () => onMentionKeypress(e);
onKeyDown(e, defaultCallback);
};
return (
<>
<div className="overflow-auto" style={{ maxHeight: '31rem' }}>
<article
className={classNames(
'flex flex-col items-stretch',
commentBoxClassNames,
)}
>
<header className="flex items-center mb-2">
<RoundedImage
src={authorImage}
alt={`${authorName}'s profile`}
className="bg-theme-bg-secondary"
loading="lazy"
/>
<div className="flex flex-col ml-2">
<div className="truncate typo-callout">{authorName}</div>
<time
dateTime={publishDate.toString()}
className="text-theme-label-tertiary typo-callout"
>
{commentDateFormat(publishDate)}
</time>
</div>
</header>
<Markdown content={contentHtml} />
</article>
<div className="flex items-center px-2 h-11">
<div className="ml-3 w-px h-full bg-theme-divider-tertiary" />
<div className="ml-6 text-theme-label-secondary typo-caption1">
Reply to{' '}
<strong className="font-bold text-theme-label-primary">
{authorName}
</strong>
</div>
</div>
<div className="flex relative flex-1 pl-2">
<ProfilePicture user={user} size="small" nativeLazyLoading />
<div
className={classNames(
'ml-3 pr-2 flex-1 text-theme-label-primary bg-transparent whitespace-pre-line border-none caret-theme-label-link break-words typo-subhead resize-none',
styles.textarea,
)}
ref={commentRef}
contentEditable
role="textbox"
aria-multiline
aria-placeholder="Write your comment..."
onInput={(e) => onTextareaInput(e.currentTarget.innerText)}
onKeyDown={handleKeydown}
onClick={onInputClick}
onPaste={onPaste}
tabIndex={0}
aria-label="New comment box"
/>
</div>
<RecommendedMentionTooltip
elementRef={commentRef}
offset={offset}
mentions={mentions}
selected={selected}
query={mentionQuery}
appendTo={parentSelector}
onMentionClick={onMentionClick}
/>
<div
className="my-2 mx-3 text-theme-status-error typo-caption1"
style={{ minHeight: '1rem' }}
>
{errorMessage && <span role="alert">{errorMessage}</span>}
</div>
</div>
<footer className="flex items-center pt-3">
<Button
className="mx-1 btn-tertiary"
buttonSize="small"
icon={<AtIcon />}
onClick={onInitializeMention}
/>
<div className="ml-2 w-px h-6 border border-opacity-24 border-theme-divider-tertiary" />
<ClickableText
tag="a"
href="https://www.markdownguide.org/cheat-sheet/"
className="ml-4 typo-caption1"
defaultTypo={false}
target="_blank"
>
Markdown supported
</ClickableText>
<Button
disabled={!input?.trim().length || input === editContent}
loading={sendingComment}
onClick={sendComment}
className="ml-auto btn-primary-avocado"
>
{editId ? 'Update' : 'Comment'}
</Button>
</footer>
</>
);
}