diff --git a/categories/web/multichoice/react/package.json b/categories/web/multichoice/react/package.json index d566642..007dcee 100644 --- a/categories/web/multichoice/react/package.json +++ b/categories/web/multichoice/react/package.json @@ -65,7 +65,6 @@ "@modal-sh/react-utils": "workspace:*", "@tesseract-design/web-base": "workspace:*", "clsx": "^1.2.1", - "react-tag-input-component": "^2.0.2", "tailwindcss": "3.3.2" }, "types": "./dist/types/index.d.ts", diff --git a/categories/web/multichoice/react/src/components/TagInput/index.tsx b/categories/web/multichoice/react/src/components/TagInput/index.tsx index 8689f62..90aa738 100644 --- a/categories/web/multichoice/react/src/components/TagInput/index.tsx +++ b/categories/web/multichoice/react/src/components/TagInput/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { TagsInput } from 'react-tag-input-component'; +import { TagsInput } from './internal'; import clsx from 'clsx'; import { useClientSide, useFallbackId, useProxyInput } from '@modal-sh/react-utils'; import { TextControl } from '@tesseract-design/web-base'; @@ -95,6 +95,9 @@ export interface TagInputProps extends Omit { addComponents({ '.tag-input': { + '&[data-size] label + * + div': { + 'background': 'red', + }, '& label + * + div > input': { 'flex': 'auto', }, @@ -462,10 +465,6 @@ export const TagInput = React.forwardRef( {clientSide && ( void, inputs: unknown[]) => { + const didMountRef = React.useRef(false); + + React.useEffect(() => { + if (didMountRef.current) fn(); + else didMountRef.current = true; + }, inputs); +} + +interface TagProps { + text: string; + remove: any; + disabled?: boolean; + className?: string; +} + +export const Tag = ({ text, remove, disabled }: TagProps) => { + const handleOnRemove: React.MouseEventHandler = (e) => { + e.stopPropagation(); + remove(text); + }; + + return ( + + {text} + {!disabled && ( + + )} + + ); +} + +export interface TagsInputProps { + name?: string; + placeHolder?: string; + value?: string[]; + onChange?: (tags: string[]) => void; + onBlur?: any; + separators?: string[]; + disableBackspaceRemove?: boolean; + onExisting?: (tag: string) => void; + onRemoved?: (tag: string) => void; + disabled?: boolean; + isEditOnRemove?: boolean; + beforeAddValidate?: (tag: string, existingTags: string[]) => boolean; + onKeyUp?: (e: React.KeyboardEvent) => void; + classNames?: { + input?: string; + tag?: string; + }; +} + +const defaultSeparators = ["Enter"]; + +export const TagsInput = ({ + name, + placeHolder, + value, + onChange, + onBlur, + separators, + disableBackspaceRemove, + onExisting, + onRemoved, + disabled, + isEditOnRemove, + beforeAddValidate, + onKeyUp, + classNames, +}: TagsInputProps) => { + const [tags, setTags] = React.useState(value || []); + + useDidUpdateEffect(() => { + onChange && onChange(tags); + }, [tags]); + + useDidUpdateEffect(() => { + if (JSON.stringify(value) !== JSON.stringify(tags)) { + setTags(value); + } + }, [value]); + + const handleOnKeyUp: React.KeyboardEventHandler = (e) => { + e.stopPropagation(); + + const text = e.currentTarget.value; + + if ( + !text && + !disableBackspaceRemove && + tags.length && + e.key === "Backspace" + ) { + e.currentTarget.value = isEditOnRemove ? `${tags.at(-1)} ` : ""; + setTags([...tags.slice(0, -1)]); + } + + if (text && (separators || defaultSeparators).includes(e.key)) { + e.preventDefault(); + if (beforeAddValidate && !beforeAddValidate(text, tags)) return; + + if (tags.includes(text)) { + onExisting && onExisting(text); + return; + } + setTags([...tags, text]); + e.currentTarget.value = ""; + } + }; + + const onTagRemove = (text: string) => { + setTags(tags.filter((tag: string) => tag !== text)); + onRemoved && onRemoved(text); + }; + + return ( +
+ {tags.map((tag: string) => ( + + ))} + + +
+ ); +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83adbc6..7e1ca0d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -516,9 +516,6 @@ importers: clsx: specifier: ^1.2.1 version: 1.2.1 - react-tag-input-component: - specifier: ^2.0.2 - version: 2.0.2(react-dom@18.2.0)(react@18.2.0) tailwindcss: specifier: 3.3.2 version: 3.3.2 @@ -7814,16 +7811,6 @@ packages: react-is: 18.2.0 dev: true - /react-tag-input-component@2.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-dydI9luVwwv9vrjE5u1TTnkcOVkOVL6mhFti8r6hLi78V2F2EKWQOLptURz79UYbDHLSk6tnbvGl8FE+sMpADg==} - peerDependencies: - react: ^16 || ^17 || ^18 - react-dom: ^16 || ^17 || ^18 - dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - dev: false - /react-test-renderer@18.2.0(react@18.2.0): resolution: {integrity: sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==} peerDependencies: