swap tab buttons in hopium with custom ones
This commit is contained in:
parent
093196d1bc
commit
0d618d4088
6 changed files with 27 additions and 152 deletions
|
|
@ -1,16 +0,0 @@
|
||||||
import Root from "./tabs.svelte";
|
|
||||||
import Content from "./tabs-content.svelte";
|
|
||||||
import List from "./tabs-list.svelte";
|
|
||||||
import Trigger from "./tabs-trigger.svelte";
|
|
||||||
|
|
||||||
export {
|
|
||||||
Root,
|
|
||||||
Content,
|
|
||||||
List,
|
|
||||||
Trigger,
|
|
||||||
//
|
|
||||||
Root as Tabs,
|
|
||||||
Content as TabsContent,
|
|
||||||
List as TabsList,
|
|
||||||
Trigger as TabsTrigger,
|
|
||||||
};
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
|
||||||
import { cn } from "$lib/utils.js";
|
|
||||||
import { browser } from "$app/environment";
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
children,
|
|
||||||
...restProps
|
|
||||||
}: TabsPrimitive.ContentProps = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if browser}
|
|
||||||
<TabsPrimitive.Content
|
|
||||||
bind:ref
|
|
||||||
data-slot="tabs-content"
|
|
||||||
class={cn("flex-1 outline-none", className)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<div
|
|
||||||
data-slot="tabs-content"
|
|
||||||
class={cn("flex-1 outline-none", className)}
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
|
||||||
import { cn } from "$lib/utils.js";
|
|
||||||
import { browser } from "$app/environment";
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
children,
|
|
||||||
...restProps
|
|
||||||
}: TabsPrimitive.ListProps = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if browser}
|
|
||||||
<TabsPrimitive.List
|
|
||||||
bind:ref
|
|
||||||
data-slot="tabs-list"
|
|
||||||
class={cn(
|
|
||||||
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<div
|
|
||||||
data-slot="tabs-list"
|
|
||||||
class={cn(
|
|
||||||
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
|
||||||
import { cn } from "$lib/utils.js";
|
|
||||||
import { browser } from "$app/environment";
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
children,
|
|
||||||
...restProps
|
|
||||||
}: TabsPrimitive.TriggerProps = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if browser}
|
|
||||||
<TabsPrimitive.Trigger
|
|
||||||
bind:ref
|
|
||||||
data-slot="tabs-trigger"
|
|
||||||
class={cn(
|
|
||||||
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 text-sm font-medium transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<button
|
|
||||||
data-slot="tabs-trigger"
|
|
||||||
class={cn(
|
|
||||||
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 text-sm font-medium transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
|
||||||
import { cn } from "$lib/utils.js";
|
|
||||||
import { browser } from "$app/environment";
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
value = $bindable(""),
|
|
||||||
class: className,
|
|
||||||
children,
|
|
||||||
...restProps
|
|
||||||
}: TabsPrimitive.RootProps = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if browser}
|
|
||||||
<TabsPrimitive.Root
|
|
||||||
bind:ref
|
|
||||||
bind:value
|
|
||||||
data-slot="tabs"
|
|
||||||
class={cn("flex flex-col gap-2", className)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<div
|
|
||||||
data-slot="tabs"
|
|
||||||
class={cn("flex flex-col gap-2", className)}
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import * as Dialog from '$lib/components/ui/dialog';
|
import * as Dialog from '$lib/components/ui/dialog';
|
||||||
import * as Tabs from '$lib/components/ui/tabs';
|
|
||||||
import * as HoverCard from '$lib/components/ui/hover-card';
|
import * as HoverCard from '$lib/components/ui/hover-card';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import { Input } from '$lib/components/ui/input';
|
import { Input } from '$lib/components/ui/input';
|
||||||
|
|
@ -120,6 +119,13 @@
|
||||||
fetchQuestions();
|
fetchQuestions();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Custom tabs implementation
|
||||||
|
const tabs = [
|
||||||
|
{ value: 'active', label: 'Active' },
|
||||||
|
{ value: 'resolved', label: 'Resolved' },
|
||||||
|
{ value: 'all', label: 'All' }
|
||||||
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SEO
|
<SEO
|
||||||
|
|
@ -182,13 +188,23 @@
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<Tabs.Root bind:value={activeTab} class="w-full">
|
<!-- Custom Tabs Implementation -->
|
||||||
|
<div class="w-full">
|
||||||
<div class="mb-6 flex items-center justify-center gap-2">
|
<div class="mb-6 flex items-center justify-center gap-2">
|
||||||
<Tabs.List class="grid w-full max-w-md grid-cols-3">
|
<!-- Custom Tabs List -->
|
||||||
<Tabs.Trigger value="active">Active</Tabs.Trigger>
|
<div class="bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]">
|
||||||
<Tabs.Trigger value="resolved">Resolved</Tabs.Trigger>
|
<div class="grid w-full max-w-md grid-cols-3">
|
||||||
<Tabs.Trigger value="all">All</Tabs.Trigger>
|
{#each tabs as tab}
|
||||||
</Tabs.List>
|
<button
|
||||||
|
onclick={() => activeTab = tab.value}
|
||||||
|
class="data-[state=active]:bg-background data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 text-sm font-medium transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm"
|
||||||
|
data-state={activeTab === tab.value ? 'active' : 'inactive'}
|
||||||
|
>
|
||||||
|
{tab.label}
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{#if $USER_DATA}
|
{#if $USER_DATA}
|
||||||
<Button onclick={handleCreateQuestion}>
|
<Button onclick={handleCreateQuestion}>
|
||||||
<Plus class="h-4 w-4" />
|
<Plus class="h-4 w-4" />
|
||||||
|
|
@ -197,7 +213,8 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Tabs.Content value={activeTab}>
|
<!-- Custom Tabs Content -->
|
||||||
|
<div class="flex-1 outline-none">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<HopiumSkeleton />
|
<HopiumSkeleton />
|
||||||
{:else if questions.length === 0}
|
{:else if questions.length === 0}
|
||||||
|
|
@ -345,6 +362,6 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</Tabs.Content>
|
</div>
|
||||||
</Tabs.Root>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Reference in a new issue