1
0
mirror of https://github.com/pocket-id/pocket-id.git synced 2026-02-12 07:58:59 +00:00

feat: oidc client data preview (#624)

Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
Kyle Mendell
2025-06-09 10:46:03 -05:00
committed by GitHub
parent 61bf14225b
commit c111b79147
12 changed files with 626 additions and 113 deletions

View File

@@ -0,0 +1,56 @@
<script lang="ts">
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import { LucideChevronDown } from '@lucide/svelte';
import { Badge } from '../ui/badge';
import { Button } from '../ui/button';
let {
items,
selectedItems = $bindable(),
onSelect,
autoClose = false
}: {
items: {
value: string;
label: string;
}[];
selectedItems: string[];
onSelect?: (value: string) => void;
autoClose?: boolean;
} = $props();
function handleItemSelect(value: string) {
if (selectedItems.includes(value)) {
selectedItems = selectedItems.filter((item) => item !== value);
} else {
selectedItems = [...selectedItems, value];
}
onSelect?.(value);
}
</script>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<Button {...props} variant="outline">
{#each items.filter((item) => selectedItems.includes(item.value)) as item}
<Badge variant="secondary">
{item.label}
</Badge>
{/each}
<LucideChevronDown class="text-muted-foreground ml-2 size-4" />
</Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content align="start" class="w-[var(--bits-dropdown-menu-anchor-width)]">
{#each items as item}
<DropdownMenu.CheckboxItem
checked={selectedItems.includes(item.value)}
onCheckedChange={() => handleItemSelect(item.value)}
closeOnSelect={autoClose}
>
{item.label}
</DropdownMenu.CheckboxItem>
{/each}
</DropdownMenu.Content>
</DropdownMenu.Root>

View File

@@ -2,15 +2,19 @@
import { Button } from '$lib/components/ui/button';
import * as Command from '$lib/components/ui/command';
import * as Popover from '$lib/components/ui/popover';
import { m } from '$lib/paraglide/messages';
import { cn } from '$lib/utils/style';
import { LucideCheck, LucideChevronDown } from '@lucide/svelte';
import { LoaderCircle, LucideCheck, LucideChevronDown } from '@lucide/svelte';
import { tick } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
import type { FormEventHandler, HTMLAttributes } from 'svelte/elements';
let {
items,
value = $bindable(),
onSelect,
oninput,
isLoading,
selectText = m.select_an_option(),
...restProps
}: HTMLAttributes<HTMLButtonElement> & {
items: {
@@ -18,7 +22,10 @@
label: string;
}[];
value: string;
oninput?: FormEventHandler<HTMLInputElement>;
onSelect?: (value: string) => void;
isLoading?: boolean;
selectText?: string;
} = $props();
let open = $state(false);
@@ -53,21 +60,35 @@
</script>
<Popover.Root bind:open {...restProps}>
<Popover.Trigger class="w-full">
<Popover.Trigger>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
class={cn('justify-between', restProps.class)}
>
{items.find((item) => item.value === value)?.label || 'Select an option'}
{items.find((item) => item.value === value)?.label || selectText}
<LucideChevronDown class="ml-2 size-4 shrink-0 opacity-50" />
</Button>
</Popover.Trigger>
<Popover.Content class="p-0">
<Popover.Content class="p-0" sameWidth>
<Command.Root shouldFilter={false}>
<Command.Input placeholder="Search..." oninput={(e: any) => filterItems(e.target.value)} />
<Command.Empty>No results found.</Command.Empty>
<Command.Input
placeholder={m.search()}
oninput={(e) => {
filterItems(e.currentTarget.value);
oninput?.(e);
}}
/>
<Command.Empty>
{#if isLoading}
<div class="flex w-full justify-center">
<LoaderCircle class="size-4 animate-spin" />
</div>
{:else}
{m.no_items_found()}
{/if}
</Command.Empty>
<Command.Group>
{#each filteredItems as item}
<Command.Item