From ad8e62c499fb1f522d849d4a2ec354ff14765362 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sat, 8 Jul 2023 13:51:43 +0800 Subject: [PATCH] Fix tagsInput event handling Properly handle events for focus, blur, and change. --- .../src/components/TagInput/TagInput.css | 13 +++ .../react/src/components/TagInput/index.tsx | 81 ++++++++++++++++++- packages/react-utils/src/event.ts | 17 ++-- .../src/pages/categories/option/index.tsx | 21 +++-- .../pages/categories/presentation/index.tsx | 2 +- 5 files changed, 113 insertions(+), 21 deletions(-) diff --git a/categories/multichoice/react/src/components/TagInput/TagInput.css b/categories/multichoice/react/src/components/TagInput/TagInput.css index 2f63dff..d53f9a5 100644 --- a/categories/multichoice/react/src/components/TagInput/TagInput.css +++ b/categories/multichoice/react/src/components/TagInput/TagInput.css @@ -80,6 +80,10 @@ background-color: rgb(var(--color-positive) / 25%); } +.tesseract-design-tag-input textarea + div > span:focus-within { + background-color: rgb(var(--color-secondary) / 25%); +} + .tesseract-design-tag-input textarea + div > span span { pointer-events: none; } @@ -91,6 +95,15 @@ margin-left: 0.25rem; } +.tesseract-design-tag-input textarea + div > span button:focus { + outline: none; + color: rgb(var(--color-secondary)); +} + +.tesseract-design-tag-input textarea + div > span button:focus:-moz-focusring { + display: none; +} + .tesseract-design-tag-input textarea + div > span button:hover { color: rgb(var(--color-primary)); } diff --git a/categories/multichoice/react/src/components/TagInput/index.tsx b/categories/multichoice/react/src/components/TagInput/index.tsx index ed1fed0..b1a1628 100644 --- a/categories/multichoice/react/src/components/TagInput/index.tsx +++ b/categories/multichoice/react/src/components/TagInput/index.tsx @@ -55,6 +55,7 @@ export interface TagInputProps extends Omit( defaultValue, disabled, id: idProp, + onFocus, + onBlur, + editOnRemove = false, + placeholder, ...etcProps }, forwardedRef, @@ -119,7 +124,19 @@ export const TagInput = React.forwardRef( }); }; - const handleBlur = () => { + const handleFocus: React.FocusEventHandler = (e) => { + if (!clientSide) { + onFocus?.(e); + } + }; + + const handleBlur: React.FocusEventHandler = (e) => { + if (!clientSide) { + onBlur?.(e); + } + }; + + const handleRemoveTag = () => { if (!(typeof ref === 'object' && ref)) { return; } @@ -128,10 +145,59 @@ export const TagInput = React.forwardRef( return; } setTimeout(() => { - delegateTriggerEvent('blur', input); + const sibling = input.nextElementSibling as HTMLDivElement; + const tagsInput = sibling.children[sibling.children.length - 1] as HTMLInputElement; + tagsInput.focus(); + }); + }; + + const handleInputBlur: React.FocusEventHandler = (e) => { + if (!(typeof ref === 'object' && ref)) { + return; + } + const { current: input } = ref; + if (!input) { + return; + } + onBlur?.({ + ...e, + target: input, + currentTarget: input, }); }; + const handleFocusCapture: React.FocusEventHandler = (e) => { + const { currentTarget } = e; + if (!clientSide) { + return; + } + const { activeElement } = window.document; + if (!activeElement) { + return; + } + const tagInputWrapper = currentTarget.children[1] as HTMLDivElement; + const tagInput = ( + tagInputWrapper.children[tagInputWrapper.children.length - 1] as HTMLInputElement + ); + if (activeElement !== tagInput) { + return; + } + if (!(typeof ref === 'object' && ref)) { + return; + } + const { current: input } = ref; + if (!input) { + return; + } + if (activeElement.tagName === 'INPUT') { + onFocus?.({ + ...e, + target: input, + currentTarget: input, + }); + } + }; + return (
( variant === 'alternate' && 'tag-input-alternate', className, )} + onFocusCapture={handleFocusCapture} >