Browse Source

feat: add select dialog component

Thomas Zhang 3 tháng trước cách đây
mục cha
commit
7a15ba7a85

+ 71 - 0
src/lib/components/common/select-dialog/dialog.svelte

@@ -0,0 +1,71 @@
+<script lang="ts">
+	import { RefreshCwIcon, Search } from '@lucide/svelte';
+	import type { Snippet } from 'svelte';
+
+	import { Button, buttonVariants } from '$lib/components/controls/button';
+	import * as Dialog from '$lib/components/controls/dialog';
+	import * as InputGroup from '$lib/components/controls/input-group';
+
+	let {
+		open = $bindable(false),
+		title,
+		query = $bindable(''),
+		selected = [],
+		onreload,
+		onsave,
+		content,
+	}: {
+		open?: boolean;
+		title?: string;
+		query?: string;
+		selected?: string[];
+		onreload?: () => void;
+		onsave?: () => void;
+		content: Snippet;
+	} = $props();
+</script>
+
+<Dialog.Root bind:open>
+	<Dialog.Content class="sm:max-w-3xl">
+		<Dialog.Header>
+			<Dialog.Title>{title}</Dialog.Title>
+		</Dialog.Header>
+		<div class="relative -mx-4 -mb-4">
+			<div
+				class="absolute top-0 z-10 w-full border-b border-b-white/10 bg-black/10 px-4 py-2 backdrop-blur-md backdrop-brightness-50"
+			>
+				<div class="flex items-center justify-between">
+					<InputGroup.Root class="max-w-64 flex-1">
+						<InputGroup.Addon>
+							<Search size={14} strokeWidth={2} />
+						</InputGroup.Addon>
+						<InputGroup.Input placeholder="Search by name…" bind:value={query} />
+					</InputGroup.Root>
+					<div class="flex items-center gap-1">
+						{#if onreload}
+							<Button size="icon" variant="ghost" onclick={() => onreload()}>
+								<RefreshCwIcon />
+							</Button>
+						{/if}
+					</div>
+				</div>
+				{#if selected.length > 0}
+					<div class="mt-2 text-xs text-wrap text-white/50">
+						Selected: {selected.join(', ')}
+					</div>
+				{/if}
+			</div>
+			<div class="h-100 overflow-y-auto px-4 pt-20 pb-8">
+				{@render content()}
+			</div>
+		</div>
+		{#if onsave}
+			<Dialog.Footer>
+				<Dialog.Close class={buttonVariants({ variant: 'outline' })} type="button">
+					Cancel
+				</Dialog.Close>
+				<Button type="submit" onclick={() => onsave()}>Save changes</Button>
+			</Dialog.Footer>
+		{/if}
+	</Dialog.Content>
+</Dialog.Root>

+ 3 - 0
src/lib/components/common/select-dialog/index.ts

@@ -0,0 +1,3 @@
+import SelectDialog from './dialog.svelte';
+
+export { SelectDialog };