forked from open-webui/open-webui
		
	feat: tooltip
Co-Authored-By: Jannik S. <69747628+jannikstdl@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									edb63c2280
								
							
						
					
					
						commit
						63c0927022
					
				
					 2 changed files with 139 additions and 95 deletions
				
			
		|  | @ -12,6 +12,7 @@ | |||
| 	import Documents from './MessageInput/Documents.svelte'; | ||||
| 	import Models from './MessageInput/Models.svelte'; | ||||
| 	import { transcribeAudio } from '$lib/apis/audio'; | ||||
| 	import Tooltip from '../common/Tooltip.svelte'; | ||||
| 
 | ||||
| 	export let submitPrompt: Function; | ||||
| 	export let stopResponse: Function; | ||||
|  | @ -637,24 +638,26 @@ | |||
| 					<div class=" flex"> | ||||
| 						{#if fileUploadEnabled} | ||||
| 							<div class=" self-end mb-2 ml-1"> | ||||
| 								<button | ||||
| 									class="bg-gray-50 hover:bg-gray-100 text-gray-800 dark:bg-gray-850 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5" | ||||
| 									type="button" | ||||
| 									on:click={() => { | ||||
| 										filesInputElement.click(); | ||||
| 									}} | ||||
| 								> | ||||
| 									<svg | ||||
| 										xmlns="http://www.w3.org/2000/svg" | ||||
| 										viewBox="0 0 16 16" | ||||
| 										fill="currentColor" | ||||
| 										class="w-[1.2rem] h-[1.2rem]" | ||||
| 								<Tooltip content="Upload files"> | ||||
| 									<button | ||||
| 										class="bg-gray-50 hover:bg-gray-100 text-gray-800 dark:bg-gray-850 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5" | ||||
| 										type="button" | ||||
| 										on:click={() => { | ||||
| 											filesInputElement.click(); | ||||
| 										}} | ||||
| 									> | ||||
| 										<path | ||||
| 											d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z" | ||||
| 										/> | ||||
| 									</svg> | ||||
| 								</button> | ||||
| 										<svg | ||||
| 											xmlns="http://www.w3.org/2000/svg" | ||||
| 											viewBox="0 0 16 16" | ||||
| 											fill="currentColor" | ||||
| 											class="w-[1.2rem] h-[1.2rem]" | ||||
| 										> | ||||
| 											<path | ||||
| 												d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z" | ||||
| 											/> | ||||
| 										</svg> | ||||
| 									</button> | ||||
| 								</Tooltip> | ||||
| 							</div> | ||||
| 						{/if} | ||||
| 
 | ||||
|  | @ -806,87 +809,97 @@ | |||
| 
 | ||||
| 						<div class="self-end mb-2 flex space-x-1 mr-1"> | ||||
| 							{#if messages.length == 0 || messages.at(-1).done == true} | ||||
| 								{#if speechRecognitionEnabled} | ||||
| 								<Tooltip content="Record voice"> | ||||
| 									{#if speechRecognitionEnabled} | ||||
| 										<button | ||||
| 											id="voice-input-button" | ||||
| 											class=" text-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-850 transition rounded-full p-1.5 mr-0.5 self-center" | ||||
| 											type="button" | ||||
| 											on:click={() => { | ||||
| 												speechRecognitionHandler(); | ||||
| 											}} | ||||
| 										> | ||||
| 											{#if isRecording} | ||||
| 												<svg | ||||
| 													class=" w-5 h-5 translate-y-[0.5px]" | ||||
| 													fill="currentColor" | ||||
| 													viewBox="0 0 24 24" | ||||
| 													xmlns="http://www.w3.org/2000/svg" | ||||
| 													><style> | ||||
| 														.spinner_qM83 { | ||||
| 															animation: spinner_8HQG 1.05s infinite; | ||||
| 														} | ||||
| 														.spinner_oXPr { | ||||
| 															animation-delay: 0.1s; | ||||
| 														} | ||||
| 														.spinner_ZTLf { | ||||
| 															animation-delay: 0.2s; | ||||
| 														} | ||||
| 														@keyframes spinner_8HQG { | ||||
| 															0%, | ||||
| 															57.14% { | ||||
| 																animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1); | ||||
| 																transform: translate(0); | ||||
| 															} | ||||
| 															28.57% { | ||||
| 																animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33); | ||||
| 																transform: translateY(-6px); | ||||
| 															} | ||||
| 															100% { | ||||
| 																transform: translate(0); | ||||
| 															} | ||||
| 														} | ||||
| 													</style><circle class="spinner_qM83" cx="4" cy="12" r="2.5" /><circle | ||||
| 														class="spinner_qM83 spinner_oXPr" | ||||
| 														cx="12" | ||||
| 														cy="12" | ||||
| 														r="2.5" | ||||
| 													/><circle | ||||
| 														class="spinner_qM83 spinner_ZTLf" | ||||
| 														cx="20" | ||||
| 														cy="12" | ||||
| 														r="2.5" | ||||
| 													/></svg | ||||
| 												> | ||||
| 											{:else} | ||||
| 												<svg | ||||
| 													xmlns="http://www.w3.org/2000/svg" | ||||
| 													viewBox="0 0 20 20" | ||||
| 													fill="currentColor" | ||||
| 													class="w-5 h-5 translate-y-[0.5px]" | ||||
| 												> | ||||
| 													<path d="M7 4a3 3 0 016 0v6a3 3 0 11-6 0V4z" /> | ||||
| 													<path | ||||
| 														d="M5.5 9.643a.75.75 0 00-1.5 0V10c0 3.06 2.29 5.585 5.25 5.954V17.5h-1.5a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-1.5v-1.546A6.001 6.001 0 0016 10v-.357a.75.75 0 00-1.5 0V10a4.5 4.5 0 01-9 0v-.357z" | ||||
| 													/> | ||||
| 												</svg> | ||||
| 											{/if} | ||||
| 										</button> | ||||
| 									{/if} | ||||
| 								</Tooltip> | ||||
| 
 | ||||
| 								<Tooltip content="Send message"> | ||||
| 									<button | ||||
| 										id="voice-input-button" | ||||
| 										class=" text-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-850 transition rounded-full p-1.5 mr-0.5 self-center" | ||||
| 										type="button" | ||||
| 										on:click={() => { | ||||
| 											speechRecognitionHandler(); | ||||
| 										}} | ||||
| 										class="{prompt !== '' | ||||
| 											? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 ' | ||||
| 											: 'text-white bg-gray-100 dark:text-gray-900 dark:bg-gray-800 disabled'} transition rounded-full p-1.5 self-center" | ||||
| 										type="submit" | ||||
| 										disabled={prompt === ''} | ||||
| 									> | ||||
| 										{#if isRecording} | ||||
| 											<svg | ||||
| 												class=" w-5 h-5 translate-y-[0.5px]" | ||||
| 												fill="currentColor" | ||||
| 												viewBox="0 0 24 24" | ||||
| 												xmlns="http://www.w3.org/2000/svg" | ||||
| 												><style> | ||||
| 													.spinner_qM83 { | ||||
| 														animation: spinner_8HQG 1.05s infinite; | ||||
| 													} | ||||
| 													.spinner_oXPr { | ||||
| 														animation-delay: 0.1s; | ||||
| 													} | ||||
| 													.spinner_ZTLf { | ||||
| 														animation-delay: 0.2s; | ||||
| 													} | ||||
| 													@keyframes spinner_8HQG { | ||||
| 														0%, | ||||
| 														57.14% { | ||||
| 															animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1); | ||||
| 															transform: translate(0); | ||||
| 														} | ||||
| 														28.57% { | ||||
| 															animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33); | ||||
| 															transform: translateY(-6px); | ||||
| 														} | ||||
| 														100% { | ||||
| 															transform: translate(0); | ||||
| 														} | ||||
| 													} | ||||
| 												</style><circle class="spinner_qM83" cx="4" cy="12" r="2.5" /><circle | ||||
| 													class="spinner_qM83 spinner_oXPr" | ||||
| 													cx="12" | ||||
| 													cy="12" | ||||
| 													r="2.5" | ||||
| 												/><circle class="spinner_qM83 spinner_ZTLf" cx="20" cy="12" r="2.5" /></svg | ||||
| 											> | ||||
| 										{:else} | ||||
| 											<svg | ||||
| 												xmlns="http://www.w3.org/2000/svg" | ||||
| 												viewBox="0 0 20 20" | ||||
| 												fill="currentColor" | ||||
| 												class="w-5 h-5 translate-y-[0.5px]" | ||||
| 											> | ||||
| 												<path d="M7 4a3 3 0 016 0v6a3 3 0 11-6 0V4z" /> | ||||
| 												<path | ||||
| 													d="M5.5 9.643a.75.75 0 00-1.5 0V10c0 3.06 2.29 5.585 5.25 5.954V17.5h-1.5a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-1.5v-1.546A6.001 6.001 0 0016 10v-.357a.75.75 0 00-1.5 0V10a4.5 4.5 0 01-9 0v-.357z" | ||||
| 												/> | ||||
| 											</svg> | ||||
| 										{/if} | ||||
| 										<svg | ||||
| 											xmlns="http://www.w3.org/2000/svg" | ||||
| 											viewBox="0 0 16 16" | ||||
| 											fill="currentColor" | ||||
| 											class="w-5 h-5" | ||||
| 										> | ||||
| 											<path | ||||
| 												fill-rule="evenodd" | ||||
| 												d="M8 14a.75.75 0 0 1-.75-.75V4.56L4.03 7.78a.75.75 0 0 1-1.06-1.06l4.5-4.5a.75.75 0 0 1 1.06 0l4.5 4.5a.75.75 0 0 1-1.06 1.06L8.75 4.56v8.69A.75.75 0 0 1 8 14Z" | ||||
| 												clip-rule="evenodd" | ||||
| 											/> | ||||
| 										</svg> | ||||
| 									</button> | ||||
| 								{/if} | ||||
| 								<button | ||||
| 									class="{prompt !== '' | ||||
| 										? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 ' | ||||
| 										: 'text-white bg-gray-100 dark:text-gray-900 dark:bg-gray-800 disabled'} transition rounded-full p-1.5 self-center" | ||||
| 									type="submit" | ||||
| 									disabled={prompt === ''} | ||||
| 								> | ||||
| 									<svg | ||||
| 										xmlns="http://www.w3.org/2000/svg" | ||||
| 										viewBox="0 0 16 16" | ||||
| 										fill="currentColor" | ||||
| 										class="w-5 h-5" | ||||
| 									> | ||||
| 										<path | ||||
| 											fill-rule="evenodd" | ||||
| 											d="M8 14a.75.75 0 0 1-.75-.75V4.56L4.03 7.78a.75.75 0 0 1-1.06-1.06l4.5-4.5a.75.75 0 0 1 1.06 0l4.5 4.5a.75.75 0 0 1-1.06 1.06L8.75 4.56v8.69A.75.75 0 0 1 8 14Z" | ||||
| 											clip-rule="evenodd" | ||||
| 										/> | ||||
| 									</svg> | ||||
| 								</button> | ||||
| 								</Tooltip> | ||||
| 							{:else} | ||||
| 								<button | ||||
| 									class="bg-white hover:bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5" | ||||
|  |  | |||
							
								
								
									
										31
									
								
								src/lib/components/common/Tooltip.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/lib/components/common/Tooltip.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| <script lang="ts"> | ||||
| 	import { onDestroy } from 'svelte'; | ||||
| 	import tippy from 'tippy.js'; | ||||
| 
 | ||||
| 	export let placement = 'top'; | ||||
| 	export let content = `I'm a tooltip!`; | ||||
| 
 | ||||
| 	let tooltipElement; | ||||
| 	let tooltipInstance; | ||||
| 
 | ||||
| 	$: if (tooltipElement && content) { | ||||
| 		if (tooltipInstance) { | ||||
| 			tooltipInstance[0]?.destroy(); | ||||
| 		} | ||||
| 		tooltipInstance = tippy(tooltipElement, { | ||||
| 			content: content, | ||||
| 			placement: placement, | ||||
| 			allowHTML: true | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	onDestroy(() => { | ||||
| 		if (tooltipInstance) { | ||||
| 			tooltipInstance[0]?.destroy(); | ||||
| 		} | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <div bind:this={tooltipElement}> | ||||
| 	<slot /> | ||||
| </div> | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek