convert folders to buttons & folder icons to buttons (accessibility) (#237)
* tabbable folders * fix spacing
This commit is contained in:
		
							parent
							
								
									b0c289f7a4
								
							
						
					
					
						commit
						a3eb247c3f
					
				|  | @ -104,7 +104,7 @@ export const ConversationComponent: FC<Props> = ({ | ||||||
| 
 | 
 | ||||||
|       {(isDeleting || isRenaming) && |       {(isDeleting || isRenaming) && | ||||||
|         selectedConversation.id === conversation.id && ( |         selectedConversation.id === conversation.id && ( | ||||||
|           <div className="visible absolute right-1 z-10 flex text-gray-300"> |           <div className="absolute right-1 z-10 flex text-gray-300"> | ||||||
|             <button |             <button | ||||||
|               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|  | @ -136,7 +136,7 @@ export const ConversationComponent: FC<Props> = ({ | ||||||
|       {selectedConversation.id === conversation.id && |       {selectedConversation.id === conversation.id && | ||||||
|         !isDeleting && |         !isDeleting && | ||||||
|         !isRenaming && ( |         !isRenaming && ( | ||||||
|           <div className="visible absolute right-1 z-10 flex text-gray-300"> |           <div className="absolute right-1 z-10 flex text-gray-300"> | ||||||
|             <button |             <button | ||||||
|               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|  |  | ||||||
|  | @ -100,37 +100,50 @@ export const ChatFolder: FC<Props> = ({ | ||||||
|   }, [searchTerm]); |   }, [searchTerm]); | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div> |     <> | ||||||
|       <div |       <div className="relative flex items-center"> | ||||||
|         className={`mb-1 flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-[14px] leading-normal transition-colors duration-200 hover:bg-[#343541]/90`} |  | ||||||
|         onClick={() => setIsOpen(!isOpen)} |  | ||||||
|         onDrop={(e) => handleDrop(e, currentFolder)} |  | ||||||
|         onDragOver={allowDrop} |  | ||||||
|         onDragEnter={highlightDrop} |  | ||||||
|         onDragLeave={removeHighlight} |  | ||||||
|       > |  | ||||||
|         {isOpen ? <IconCaretDown size={16} /> : <IconCaretRight size={16} />} |  | ||||||
| 
 |  | ||||||
|         {isRenaming ? ( |         {isRenaming ? ( | ||||||
|           <input |           <div className="flex w-full items-center gap-3 bg-[#343541]/90 p-3"> | ||||||
|             className="flex-1 overflow-hidden overflow-ellipsis border-b border-neutral-400 bg-transparent pr-1 text-left text-white outline-none focus:border-neutral-100" |             {isOpen ? ( | ||||||
|             type="text" |               <IconCaretDown size={18} /> | ||||||
|             value={renameValue} |             ) : ( | ||||||
|             onChange={(e) => setRenameValue(e.target.value)} |               <IconCaretRight size={18} /> | ||||||
|             onKeyDown={handleEnterDown} |             )} | ||||||
|             autoFocus | 
 | ||||||
|           /> |             <input | ||||||
|         ) : ( |               className="mr-12 flex-1 overflow-hidden overflow-ellipsis border-neutral-400 bg-transparent text-left text-[12.5px] leading-3 text-white outline-none focus:border-neutral-100" | ||||||
|           <div className="flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap pr-1 text-left"> |               type="text" | ||||||
|             {currentFolder.name} |               value={renameValue} | ||||||
|  |               onChange={(e) => setRenameValue(e.target.value)} | ||||||
|  |               onKeyDown={handleEnterDown} | ||||||
|  |               autoFocus | ||||||
|  |             /> | ||||||
|           </div> |           </div> | ||||||
|  |         ) : ( | ||||||
|  |           <button | ||||||
|  |             className={`flex w-full cursor-pointer items-center gap-3 rounded-lg p-3 text-sm transition-colors duration-200 hover:bg-[#343541]/90`} | ||||||
|  |             onClick={() => setIsOpen(!isOpen)} | ||||||
|  |             onDrop={(e) => handleDrop(e, currentFolder)} | ||||||
|  |             onDragOver={allowDrop} | ||||||
|  |             onDragEnter={highlightDrop} | ||||||
|  |             onDragLeave={removeHighlight} | ||||||
|  |           > | ||||||
|  |             {isOpen ? ( | ||||||
|  |               <IconCaretDown size={18} /> | ||||||
|  |             ) : ( | ||||||
|  |               <IconCaretRight size={18} /> | ||||||
|  |             )} | ||||||
|  | 
 | ||||||
|  |             <div className="relative max-h-5 flex-1 overflow-hidden text-ellipsis whitespace-nowrap break-all text-left text-[12.5px] leading-3"> | ||||||
|  |               {currentFolder.name} | ||||||
|  |             </div> | ||||||
|  |           </button> | ||||||
|         )} |         )} | ||||||
| 
 | 
 | ||||||
|         {(isDeleting || isRenaming) && ( |         {(isDeleting || isRenaming) && ( | ||||||
|           <div className="-ml-2 flex gap-1"> |           <div className="absolute right-1 z-10 flex text-gray-300"> | ||||||
|             <IconCheck |             <button | ||||||
|               className="min-w-[20px] text-neutral-400 hover:text-neutral-100" |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               size={16} |  | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
| 
 | 
 | ||||||
|  | @ -143,40 +156,43 @@ export const ChatFolder: FC<Props> = ({ | ||||||
|                 setIsDeleting(false); |                 setIsDeleting(false); | ||||||
|                 setIsRenaming(false); |                 setIsRenaming(false); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
| 
 |               <IconCheck size={18} /> | ||||||
|             <IconX |             </button> | ||||||
|               className="min-w-[20px] text-neutral-400 hover:text-neutral-100" |             <button | ||||||
|               size={16} |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
|                 setIsDeleting(false); |                 setIsDeleting(false); | ||||||
|                 setIsRenaming(false); |                 setIsRenaming(false); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
|  |               <IconX size={18} /> | ||||||
|  |             </button> | ||||||
|           </div> |           </div> | ||||||
|         )} |         )} | ||||||
| 
 | 
 | ||||||
|         {!isDeleting && !isRenaming && ( |         {!isDeleting && !isRenaming && ( | ||||||
|           <div className="ml-2 flex gap-1"> |           <div className="absolute right-1 z-10 flex text-gray-300"> | ||||||
|             <IconPencil |             <button | ||||||
|               className="min-w-[20px] text-neutral-400 hover:text-neutral-100" |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               size={18} |  | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
|                 setIsRenaming(true); |                 setIsRenaming(true); | ||||||
|                 setRenameValue(currentFolder.name); |                 setRenameValue(currentFolder.name); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
| 
 |               <IconPencil size={18} /> | ||||||
|             <IconTrash |             </button> | ||||||
|               className=" min-w-[20px] text-neutral-400 hover:text-neutral-100" |             <button | ||||||
|               size={18} |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
|                 setIsDeleting(true); |                 setIsDeleting(true); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
|  |               <IconTrash size={18} /> | ||||||
|  |             </button> | ||||||
|           </div> |           </div> | ||||||
|         )} |         )} | ||||||
|       </div> |       </div> | ||||||
|  | @ -185,7 +201,7 @@ export const ChatFolder: FC<Props> = ({ | ||||||
|         ? conversations.map((conversation, index) => { |         ? conversations.map((conversation, index) => { | ||||||
|             if (conversation.folderId === currentFolder.id) { |             if (conversation.folderId === currentFolder.id) { | ||||||
|               return ( |               return ( | ||||||
|                 <div key={index} className="ml-5 gap-2 border-l pl-2 pt-2"> |                 <div key={index} className="ml-5 gap-2 border-l pl-2"> | ||||||
|                   <ConversationComponent |                   <ConversationComponent | ||||||
|                     selectedConversation={selectedConversation} |                     selectedConversation={selectedConversation} | ||||||
|                     conversation={conversation} |                     conversation={conversation} | ||||||
|  | @ -199,6 +215,6 @@ export const ChatFolder: FC<Props> = ({ | ||||||
|             } |             } | ||||||
|           }) |           }) | ||||||
|         : null} |         : null} | ||||||
|     </div> |     </> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ export const ChatFolders: FC<Props> = ({ | ||||||
|   onUpdateConversation, |   onUpdateConversation, | ||||||
| }) => { | }) => { | ||||||
|   return ( |   return ( | ||||||
|     <div className="flex w-full flex-col gap-1 pt-2"> |     <div className="flex w-full flex-col pt-2"> | ||||||
|       {folders.map((folder, index) => ( |       {folders.map((folder, index) => ( | ||||||
|         <ChatFolder |         <ChatFolder | ||||||
|           key={index} |           key={index} | ||||||
|  |  | ||||||
|  | @ -96,37 +96,49 @@ export const PromptFolder: FC<Props> = ({ | ||||||
|   }, [searchTerm]); |   }, [searchTerm]); | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div> |     <> | ||||||
|       <div |       <div className="relative flex items-center"> | ||||||
|         className={`mb-1 flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-[14px] leading-normal transition-colors duration-200 hover:bg-[#343541]/90`} |  | ||||||
|         onClick={() => setIsOpen(!isOpen)} |  | ||||||
|         onDrop={(e) => handleDrop(e, currentFolder)} |  | ||||||
|         onDragOver={allowDrop} |  | ||||||
|         onDragEnter={highlightDrop} |  | ||||||
|         onDragLeave={removeHighlight} |  | ||||||
|       > |  | ||||||
|         {isOpen ? <IconCaretDown size={16} /> : <IconCaretRight size={16} />} |  | ||||||
| 
 |  | ||||||
|         {isRenaming ? ( |         {isRenaming ? ( | ||||||
|           <input |           <div className="flex w-full items-center gap-3 bg-[#343541]/90 p-3"> | ||||||
|             className="flex-1 overflow-hidden overflow-ellipsis border-b border-neutral-400 bg-transparent pr-1 text-left text-white outline-none focus:border-neutral-100" |             {isOpen ? ( | ||||||
|             type="text" |               <IconCaretDown size={18} /> | ||||||
|             value={renameValue} |             ) : ( | ||||||
|             onChange={(e) => setRenameValue(e.target.value)} |               <IconCaretRight size={18} /> | ||||||
|             onKeyDown={handleEnterDown} |             )} | ||||||
|             autoFocus |             <input | ||||||
|           /> |               className="mr-12 flex-1 overflow-hidden overflow-ellipsis border-neutral-400 bg-transparent text-left text-[12.5px] leading-3 text-white outline-none focus:border-neutral-100" | ||||||
|         ) : ( |               type="text" | ||||||
|           <div className="flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap pr-1 text-left"> |               value={renameValue} | ||||||
|             {currentFolder.name} |               onChange={(e) => setRenameValue(e.target.value)} | ||||||
|  |               onKeyDown={handleEnterDown} | ||||||
|  |               autoFocus | ||||||
|  |             /> | ||||||
|           </div> |           </div> | ||||||
|  |         ) : ( | ||||||
|  |           <button | ||||||
|  |             className={`flex w-full cursor-pointer items-center gap-3 rounded-lg p-3 text-sm transition-colors duration-200 hover:bg-[#343541]/90`} | ||||||
|  |             onClick={() => setIsOpen(!isOpen)} | ||||||
|  |             onDrop={(e) => handleDrop(e, currentFolder)} | ||||||
|  |             onDragOver={allowDrop} | ||||||
|  |             onDragEnter={highlightDrop} | ||||||
|  |             onDragLeave={removeHighlight} | ||||||
|  |           > | ||||||
|  |             {isOpen ? ( | ||||||
|  |               <IconCaretDown size={18} /> | ||||||
|  |             ) : ( | ||||||
|  |               <IconCaretRight size={18} /> | ||||||
|  |             )} | ||||||
|  | 
 | ||||||
|  |             <div className="relative max-h-5 flex-1 overflow-hidden text-ellipsis whitespace-nowrap break-all text-left text-[12.5px] leading-3"> | ||||||
|  |               {currentFolder.name} | ||||||
|  |             </div> | ||||||
|  |           </button> | ||||||
|         )} |         )} | ||||||
| 
 | 
 | ||||||
|         {(isDeleting || isRenaming) && ( |         {(isDeleting || isRenaming) && ( | ||||||
|           <div className="-ml-2 flex gap-1"> |           <div className="absolute right-1 z-10 flex text-gray-300"> | ||||||
|             <IconCheck |             <button | ||||||
|               className="min-w-[20px] text-neutral-400 hover:text-neutral-100" |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               size={16} |  | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
| 
 | 
 | ||||||
|  | @ -139,40 +151,43 @@ export const PromptFolder: FC<Props> = ({ | ||||||
|                 setIsDeleting(false); |                 setIsDeleting(false); | ||||||
|                 setIsRenaming(false); |                 setIsRenaming(false); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
| 
 |               <IconCheck size={18} /> | ||||||
|             <IconX |             </button> | ||||||
|               className="min-w-[20px] text-neutral-400 hover:text-neutral-100" |             <button | ||||||
|               size={16} |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
|                 setIsDeleting(false); |                 setIsDeleting(false); | ||||||
|                 setIsRenaming(false); |                 setIsRenaming(false); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
|  |               <IconX size={18} /> | ||||||
|  |             </button> | ||||||
|           </div> |           </div> | ||||||
|         )} |         )} | ||||||
| 
 | 
 | ||||||
|         {!isDeleting && !isRenaming && ( |         {!isDeleting && !isRenaming && ( | ||||||
|           <div className="ml-2 flex gap-1"> |           <div className="absolute right-1 z-10 flex text-gray-300"> | ||||||
|             <IconPencil |             <button | ||||||
|               className="min-w-[20px] text-neutral-400 hover:text-neutral-100" |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               size={18} |  | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
|                 setIsRenaming(true); |                 setIsRenaming(true); | ||||||
|                 setRenameValue(currentFolder.name); |                 setRenameValue(currentFolder.name); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
| 
 |               <IconPencil size={18} /> | ||||||
|             <IconTrash |             </button> | ||||||
|               className=" min-w-[20px] text-neutral-400 hover:text-neutral-100" |             <button | ||||||
|               size={18} |               className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100" | ||||||
|               onClick={(e) => { |               onClick={(e) => { | ||||||
|                 e.stopPropagation(); |                 e.stopPropagation(); | ||||||
|                 setIsDeleting(true); |                 setIsDeleting(true); | ||||||
|               }} |               }} | ||||||
|             /> |             > | ||||||
|  |               <IconTrash size={18} /> | ||||||
|  |             </button> | ||||||
|           </div> |           </div> | ||||||
|         )} |         )} | ||||||
|       </div> |       </div> | ||||||
|  | @ -181,7 +196,7 @@ export const PromptFolder: FC<Props> = ({ | ||||||
|         ? prompts.map((prompt, index) => { |         ? prompts.map((prompt, index) => { | ||||||
|             if (prompt.folderId === currentFolder.id) { |             if (prompt.folderId === currentFolder.id) { | ||||||
|               return ( |               return ( | ||||||
|                 <div key={index} className="ml-5 gap-2 border-l pl-2 pt-2"> |                 <div key={index} className="ml-5 gap-2 border-l pl-2"> | ||||||
|                   <PromptComponent |                   <PromptComponent | ||||||
|                     prompt={prompt} |                     prompt={prompt} | ||||||
|                     onDeletePrompt={onDeletePrompt} |                     onDeletePrompt={onDeletePrompt} | ||||||
|  | @ -192,6 +207,6 @@ export const PromptFolder: FC<Props> = ({ | ||||||
|             } |             } | ||||||
|           }) |           }) | ||||||
|         : null} |         : null} | ||||||
|     </div> |     </> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ export const PromptFolders: FC<Props> = ({ | ||||||
|   onUpdatePrompt, |   onUpdatePrompt, | ||||||
| }) => { | }) => { | ||||||
|   return ( |   return ( | ||||||
|     <div className="flex w-full flex-col gap-1 pt-2"> |     <div className="flex w-full flex-col pt-2"> | ||||||
|       {folders.map((folder, index) => ( |       {folders.map((folder, index) => ( | ||||||
|         <PromptFolder |         <PromptFolder | ||||||
|           key={index} |           key={index} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue