mirror of
https://github.com/SrIzan10/lofi.git
synced 2026-06-06 00:56:53 +00:00
feat: add tooltips to most buttons
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
{
|
||||
"$schema": "https://next.shadcn-svelte.com/schema.json",
|
||||
"style": "new-york",
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/app.css",
|
||||
"baseColor": "neutral"
|
||||
},
|
||||
@@ -10,8 +8,9 @@
|
||||
"components": "$lib/components",
|
||||
"utils": "$lib/utils",
|
||||
"ui": "$lib/components/ui",
|
||||
"hooks": "$lib/hooks"
|
||||
"hooks": "$lib/hooks",
|
||||
"lib": "$lib"
|
||||
},
|
||||
"typescript": true,
|
||||
"registry": "https://next.shadcn-svelte.com/registry"
|
||||
"registry": "https://tw3.shadcn-svelte.com/registry/new-york"
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@sveltejs/kit": "^2.16.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"bits-ui": "^1.3.19",
|
||||
"bits-ui": "^1.4.7",
|
||||
"clsx": "^2.1.1",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-svelte": "^3.3.3",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import VolumeZero from '@lucide/svelte/icons/volume';
|
||||
import VolumeOne from '@lucide/svelte/icons/volume-1';
|
||||
import VolumeTwo from '@lucide/svelte/icons/volume-2';
|
||||
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
|
||||
|
||||
function sliderChange(name: string, volume: number) {
|
||||
if (volume === 0) {
|
||||
@@ -24,9 +25,16 @@
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger class={buttonVariants({ variant: 'default', size: 'icon' })}>
|
||||
<AudioLines />
|
||||
</DropdownMenu.Trigger>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger>
|
||||
<DropdownMenu.Trigger class={buttonVariants({ variant: 'default', size: 'icon' })}>
|
||||
<AudioLines />
|
||||
</DropdownMenu.Trigger>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content>
|
||||
<p>Atmospheres</p>
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Root>
|
||||
<DropdownMenu.Content class="w-56 max-h-[50vh] overflow-y-auto">
|
||||
<DropdownMenu.Group>
|
||||
<DropdownMenu.GroupHeading>Atmospheres</DropdownMenu.GroupHeading>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { buttonVariants } from '$lib/components/ui/button/index.js';
|
||||
import { state as appState } from '@/state.svelte';
|
||||
import Image from '@lucide/svelte/icons/image';
|
||||
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
|
||||
|
||||
let selectedBackgroundId = $state(appState.currentBackgroundId!.toString());
|
||||
$effect(() => {
|
||||
@@ -13,9 +14,16 @@
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger class={buttonVariants({ variant: 'default', size: 'icon' })}>
|
||||
<Image />
|
||||
</DropdownMenu.Trigger>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger>
|
||||
<DropdownMenu.Trigger class={buttonVariants({ variant: 'default', size: 'icon' })}>
|
||||
<Image />
|
||||
</DropdownMenu.Trigger>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content>
|
||||
<p>Backgrounds</p>
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Root>
|
||||
<DropdownMenu.Content
|
||||
class="max-h-[50vh] overflow-y-auto custom-scrollbar"
|
||||
>
|
||||
|
||||
@@ -2,10 +2,18 @@
|
||||
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||
import Info from '@lucide/svelte/icons/info';
|
||||
import { Button } from '../ui/button';
|
||||
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
|
||||
</script>
|
||||
|
||||
<Dialog.Root>
|
||||
<Dialog.Trigger><Button size="icon"><Info /></Button></Dialog.Trigger>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger>
|
||||
<Dialog.Trigger>
|
||||
<Button size="icon"><Info /></Button>
|
||||
</Dialog.Trigger>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content>Info</Tooltip.Content>
|
||||
</Tooltip.Root>
|
||||
<Dialog.Content>
|
||||
<Dialog.Header>
|
||||
<Dialog.Title>Info & disclaimer</Dialog.Title>
|
||||
|
||||
@@ -3,36 +3,53 @@
|
||||
import MessageSquare from '@lucide/svelte/icons/message-square';
|
||||
import { Button } from '../ui/button';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
|
||||
let feedback = $state('');
|
||||
let open = $state(false);
|
||||
</script>
|
||||
|
||||
<Dialog.Root bind:open>
|
||||
<Dialog.Trigger><Button size="icon"><MessageSquare /></Button></Dialog.Trigger>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger>
|
||||
<Dialog.Trigger>
|
||||
<Button size="icon"><MessageSquare /></Button>
|
||||
</Dialog.Trigger>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content>Send Feedback</Tooltip.Content>
|
||||
</Tooltip.Root>
|
||||
<Dialog.Content>
|
||||
<Dialog.Header>
|
||||
<Dialog.Title>Send Feedback</Dialog.Title>
|
||||
</Dialog.Header>
|
||||
<p>
|
||||
Have suggestions or found a bug? Let me know!
|
||||
</p>
|
||||
<form class="mt-4 space-y-4" onsubmit={(e) => {
|
||||
e.preventDefault();
|
||||
fetch('https://cors.notesnook.com/https://echospace.dev/api/feedback/cma9juarn0000m40sko0qqt2t', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
message: feedback,
|
||||
})
|
||||
}).then(() => {
|
||||
open = false;
|
||||
feedback = '';
|
||||
toast('Thanks for your feedback!')
|
||||
})
|
||||
}}>
|
||||
<p>Have suggestions or found a bug? Let me know!</p>
|
||||
<form
|
||||
class="mt-4 space-y-4"
|
||||
onsubmit={(e) => {
|
||||
e.preventDefault();
|
||||
fetch(
|
||||
'https://cors.notesnook.com/https://echospace.dev/api/feedback/cma9juarn0000m40sko0qqt2t',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
message: feedback,
|
||||
}),
|
||||
}
|
||||
).then(() => {
|
||||
open = false;
|
||||
feedback = '';
|
||||
toast('Thanks for your feedback!');
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div class="grid w-full items-center gap-1.5">
|
||||
<textarea id="feedback" class="p-2 rounded-md bg-white/10 border border-white/20" rows="4" bind:value={feedback}></textarea>
|
||||
<textarea
|
||||
id="feedback"
|
||||
class="p-2 rounded-md bg-white/10 border border-white/20"
|
||||
rows="4"
|
||||
bind:value={feedback}
|
||||
></textarea>
|
||||
</div>
|
||||
<Button type="submit">Submit</Button>
|
||||
</form>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
</Dialog.Root>
|
||||
|
||||
@@ -3,18 +3,29 @@
|
||||
import Check from '@lucide/svelte/icons/check';
|
||||
import Button from '../ui/button/button.svelte';
|
||||
import Binoculars from '@lucide/svelte/icons/binoculars';
|
||||
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="absolute left-2 top-1/2 transform -translate-y-1/2 p-4 bg-white/10 backdrop-blur-lg rounded-xl shadow-lg flex flex-col space-y-2"
|
||||
>
|
||||
<Button size="icon" onclick={() => (appState.showTodoList = !appState.showTodoList)}>
|
||||
<Check class="size-4" />
|
||||
</Button>
|
||||
<Button
|
||||
size="icon"
|
||||
onclick={() => (appState.show202020 = !appState.show202020)}
|
||||
>
|
||||
<Binoculars class="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger>
|
||||
<Button size="icon" onclick={() => (appState.showTodoList = !appState.showTodoList)}>
|
||||
<Check class="size-4" />
|
||||
</Button>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content side="right" sideOffset={8} align="start">Todo List</Tooltip.Content>
|
||||
</Tooltip.Root>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger>
|
||||
<Button
|
||||
size="icon"
|
||||
onclick={() => (appState.show202020 = !appState.show202020)}
|
||||
>
|
||||
<Binoculars class="size-4" />
|
||||
</Button>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content side="right" sideOffset={8} align="start">20-20-20</Tooltip.Content>
|
||||
</Tooltip.Root>
|
||||
</div>
|
||||
@@ -3,6 +3,7 @@
|
||||
import { buttonVariants } from '$lib/components/ui/button/index.js';
|
||||
import { state as appState } from '@/state.svelte';
|
||||
import Radio from '@lucide/svelte/icons/radio';
|
||||
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
|
||||
|
||||
let selectedStationId = $state(appState.currentStation!.toString());
|
||||
$effect(() => {
|
||||
@@ -15,12 +16,17 @@
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger class={buttonVariants({ variant: 'default', size: 'icon' })}>
|
||||
<Radio />
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Content
|
||||
class="w-56"
|
||||
>
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger>
|
||||
<DropdownMenu.Trigger class={buttonVariants({ variant: 'default', size: 'icon' })}>
|
||||
<Radio />
|
||||
</DropdownMenu.Trigger>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content>
|
||||
<p>Stations</p>
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Root>
|
||||
<DropdownMenu.Content class="w-56">
|
||||
<DropdownMenu.Group>
|
||||
<DropdownMenu.GroupHeading>Select station</DropdownMenu.GroupHeading>
|
||||
<DropdownMenu.Separator />
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
{/if}
|
||||
</Button>
|
||||
</Popover.Trigger>
|
||||
<Popover.Content class="w-2 h-32" side="top">
|
||||
<Popover.Content class="h-32" side="top">
|
||||
<Slider type="single" orientation="vertical" bind:value max={1} step={0.01} />
|
||||
</Popover.Content>
|
||||
</Popover.Root>
|
||||
18
src/lib/components/ui/tooltip/index.ts
Normal file
18
src/lib/components/ui/tooltip/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
||||
import Content from "./tooltip-content.svelte";
|
||||
|
||||
const Root = TooltipPrimitive.Root;
|
||||
const Trigger = TooltipPrimitive.Trigger;
|
||||
const Provider = TooltipPrimitive.Provider;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Trigger,
|
||||
Content,
|
||||
Provider,
|
||||
//
|
||||
Root as Tooltip,
|
||||
Content as TooltipContent,
|
||||
Trigger as TooltipTrigger,
|
||||
Provider as TooltipProvider,
|
||||
};
|
||||
22
src/lib/components/ui/tooltip/tooltip-content.svelte
Normal file
22
src/lib/components/ui/tooltip/tooltip-content.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { Tooltip as TooltipPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
sideOffset = 4,
|
||||
...restProps
|
||||
}: TooltipPrimitive.ContentProps = $props();
|
||||
</script>
|
||||
|
||||
<TooltipPrimitive.Content
|
||||
bind:ref
|
||||
{sideOffset}
|
||||
class={cn(
|
||||
'animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md px-3 py-1.5 text-xs',
|
||||
'bg-white/10 backdrop-blur-md transition hover:bg-white/15 text-foreground border border-white/20 shadow-lg',
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
/>
|
||||
@@ -3,6 +3,7 @@
|
||||
import { ModeWatcher } from "mode-watcher";
|
||||
import { dev } from '$app/environment';
|
||||
import { Toaster } from "$lib/components/ui/sonner/index.js";
|
||||
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
@@ -11,4 +12,7 @@
|
||||
{#if !dev}
|
||||
<script defer src="https://analytics.srizan.dev/ua.js" data-website-id="02aba16d-f8eb-4363-973b-dab04db4de10"></script>
|
||||
{/if}
|
||||
{@render children()}
|
||||
|
||||
<Tooltip.Provider delayDuration={300}>
|
||||
{@render children()}
|
||||
</Tooltip.Provider>
|
||||
@@ -821,10 +821,10 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
||||
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
|
||||
|
||||
bits-ui@^1.3.19:
|
||||
version "1.3.19"
|
||||
resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-1.3.19.tgz#4ec4b1aaed33b19a659f8f9f2d7ff4a80a73dd69"
|
||||
integrity sha512-2blb6dkgedHUsDXqCjvmtUi4Advgd9MhaJDT8r7bEWDzHI8HGsOoYsLeh8CxpEWWEYPrlGN+7k+kpxRhIDdFrQ==
|
||||
bits-ui@^1.4.7:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-1.5.2.tgz#cf28588d4f5473dfffc979f2cafbb0f9c208c088"
|
||||
integrity sha512-6Dbx9BENvvEz7RDRsQn5C6pAO/75g40F4SMv6sNQXPhi0OyAe0ZMxRDGv+uqqr8ylJVkjkciSCrx062UniqyRg==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.6.4"
|
||||
"@floating-ui/dom" "^1.6.7"
|
||||
|
||||
Reference in New Issue
Block a user