From dbeb742568b9b404b3c1ff44efd0f8b7669aca4f Mon Sep 17 00:00:00 2001 From: Prince Rajpoot <44585452+princerajpoot20@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:31:14 +0530 Subject: [PATCH] Add ChipInput component (#808) --- .../src/components/ChipInput.stories.tsx | 76 ++++++++++++++++++ packages/ui/components/ChipInput.tsx | 80 +++++++++++++++++++ packages/ui/components/index.tsx | 1 + 3 files changed, 157 insertions(+) create mode 100644 apps/design-system/src/components/ChipInput.stories.tsx create mode 100644 packages/ui/components/ChipInput.tsx diff --git a/apps/design-system/src/components/ChipInput.stories.tsx b/apps/design-system/src/components/ChipInput.stories.tsx new file mode 100644 index 000000000..fa129f7f3 --- /dev/null +++ b/apps/design-system/src/components/ChipInput.stories.tsx @@ -0,0 +1,76 @@ +import { useState } from "react"; +import { ChipInput } from "@asyncapi/studio-ui"; + +const meta = { + component: ChipInput, + parameters: { + layout: 'fullscreen', + backgrounds: { + default: 'light' + } + }, +}; + +export default meta; + +export const Default = () => { + const [currentChips, setCurrentChips] = useState([]); + + return ( +
+ +
+ ); +}; + +export const WithTags = () => { + const [currentChips, setCurrentChips] = useState(['production', 'platform']); + + return ( +
+ +
+ ); + }; + +export const WithSomeDefaultText = () => { + const [currentChips, setCurrentChips] = useState(['production', 'platform']); + + return ( +
+ +
+ ); +}; + +export const WithCustomPlaceholder = () => { + const [currentChips, setCurrentChips] = useState([]); + + return ( +
+ +
+ ); +}; diff --git a/packages/ui/components/ChipInput.tsx b/packages/ui/components/ChipInput.tsx new file mode 100644 index 000000000..f3d45c694 --- /dev/null +++ b/packages/ui/components/ChipInput.tsx @@ -0,0 +1,80 @@ +import { FunctionComponent, KeyboardEvent, useRef } from 'react'; + +interface ChipInputProps { + name: string; + id: string; + className?: string; + chips: string[]; + onChange: (chips: string[]) => void; + isDisabled?: boolean; + placeholder?: string; + defaultValue?: string; +} + +export const ChipInput: FunctionComponent = ({ + name, + id, + className, + chips, + onChange, + isDisabled = false, + placeholder = 'Add Tags', + defaultValue = '' +}) => { + const inputRef = useRef(null); + const firstChipRef = useRef(null); + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === 'Enter' && event.currentTarget.value.trim()) { + onChange([...chips, event.currentTarget.value.trim()]); + event.currentTarget.value = ''; + } else if (event.key === 'Backspace' && !event.currentTarget.value) { + onChange(chips.slice(0, -1)); + } else if (event.key === 'Tab' && !event.shiftKey) { + event.preventDefault(); + firstChipRef.current?.focus(); + } + }; + + const handleChipKeyDown = (index: number) => (event: KeyboardEvent) => { + if (event.key === 'Backspace') { + const updatedChips = [...chips]; + updatedChips.splice(index, 1); + onChange(updatedChips); + } + }; + + const handleDelete = (chipToDelete: string) => () => { + const updatedChips = chips.filter(chip => chip !== chipToDelete); + onChange(updatedChips); + }; + + return ( +
+ {chips.map((chip, index) => ( +
+ {chip} + +
+ ))} + +
+ ); +}; diff --git a/packages/ui/components/index.tsx b/packages/ui/components/index.tsx index 50e048646..a1058b7ad 100644 --- a/packages/ui/components/index.tsx +++ b/packages/ui/components/index.tsx @@ -2,6 +2,7 @@ import './styles.css' // components +export * from './ChipInput' export * from './EditorSwitch' export * from './DropdownMenu' export * from './Logo'