Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the "loop" prop to the Dialog throws a console warning #91

Open
gchartier opened this issue Jul 19, 2024 · 0 comments
Open

Adding the "loop" prop to the Dialog throws a console warning #91

gchartier opened this issue Jul 19, 2024 · 0 comments

Comments

@gchartier
Copy link

Thanks for the port of this awesome library!

Issue:

I am using the Command.Dialog approach instead of the Command.Root approach and wanted to add the loop prop. It works as expected, which is great, but I am getting the following console warning in my browser dev tools:

command-dialog.svelte:13 <Dialog> was created with unknown prop 'loop'
warn @ client.js?v=b74c0922:2641
(anonymous) @ bits-ui.js?v=b74c0922:68707
instance115 @ bits-ui.js?v=b74c0922:68706
init @ chunk-JNWMTCM6.js?v=b74c0922:2137
Dialog @ bits-ui.js?v=b74c0922:68806
create_fragment @ command-dialog.svelte:13
init @ chunk-JNWMTCM6.js?v=b74c0922:2148
Command_dialog @ command-dialog.svelte:10
createProxiedComponent @ svelte-hooks.js?v=b74c0922:341
ProxyComponent @ proxy.js?v=b74c0922:242
Proxy<Command-dialog> @ proxy.js?v=b74c0922:349
create_fragment @ CommandSearch.svelte?t=1721368416803:1481
init @ chunk-JNWMTCM6.js?v=b74c0922:2148
CommandSearch @ CommandSearch.svelte?t=1721368416803:1759
createProxiedComponent @ svelte-hooks.js?v=b74c0922:341
ProxyComponent @ proxy.js?v=b74c0922:242
Proxy<CommandSearch> @ proxy.js?v=b74c0922:349
create_if_block_2 @ AppHeader.svelte:12
create_fragment @ AppHeader.svelte:35
init @ chunk-JNWMTCM6.js?v=b74c0922:2148
AppHeader @ AppHeader.svelte:45
createProxiedComponent @ svelte-hooks.js?v=b74c0922:341
ProxyComponent @ proxy.js?v=b74c0922:242
Proxy<AppHeader> @ proxy.js?v=b74c0922:349
create_fragment @ +layout.svelte:5
init @ chunk-JNWMTCM6.js?v=b74c0922:2148
Layout @ +layout.svelte:20
createProxiedComponent @ svelte-hooks.js?v=b74c0922:341
ProxyComponent @ proxy.js?v=b74c0922:242
Proxy<+layout> @ proxy.js?v=b74c0922:349
construct_svelte_component_dev @ chunk-JNWMTCM6.js?v=b74c0922:2569
create_if_block_3 @ root.svelte:47
create_default_slot @ root.svelte:46
create_slot @ chunk-JNWMTCM6.js?v=b74c0922:99
create_default_slot @ +layout.svelte:7
create_slot @ chunk-JNWMTCM6.js?v=b74c0922:99
create_fragment2 @ chunk-T2T2YZZK.js?v=b74c0922:3055
init @ chunk-JNWMTCM6.js?v=b74c0922:2148
QueryClientProvider @ chunk-T2T2YZZK.js?v=b74c0922:3159
create_fragment @ +layout.svelte:7
init @ chunk-JNWMTCM6.js?v=b74c0922:2148
Layout @ +layout.svelte:17
createProxiedComponent @ svelte-hooks.js?v=b74c0922:341
ProxyComponent @ proxy.js?v=b74c0922:242
Proxy<+layout> @ proxy.js?v=b74c0922:349
construct_svelte_component_dev @ chunk-JNWMTCM6.js?v=b74c0922:2569
create_if_block_2 @ root.svelte:45
create_fragment @ root.svelte:44
init @ chunk-JNWMTCM6.js?v=b74c0922:2148
Root @ root.svelte:22
createProxiedComponent @ svelte-hooks.js?v=b74c0922:341
ProxyComponent @ proxy.js?v=b74c0922:242
Proxy<Root> @ proxy.js?v=b74c0922:349
initialize @ client.js?v=b74c0922:434
_hydrate @ client.js?v=b74c0922:2388
await in _hydrate (async)
start @ client.js?v=b74c0922:293
(anonymous) @ (index):2644
Promise.then (async)
(anonymous) @ (index):2643
Show 39 more frames

Here is my component:

<script lang="ts">
	import Loading from './../../../lib/components/Loading.svelte';
	import { browser } from '$app/environment';
	import * as Command from '$lib/components/ui/command';
	import Search from '$lib/icons/Search.svelte';
	import type { DBFactStatement, Feed } from '$lib/types';
	import { onMount } from 'svelte';
	import { writable } from 'svelte/store';
	import FeedNameplate from './FeedNameplate.svelte';

	let open = false;
	let metaKey: '⌘' | 'Ctrl';
	let isMobile: boolean;
	let query = '';
	let isLoading = false;
	let debounceTimer: ReturnType<typeof setTimeout>;
	let results = writable<{ factStatements: DBFactStatement[]; feeds: Feed[] }>({
		factStatements: [],
		feeds: []
	});

	onMount(() => {
		metaKey = browser && window.navigator.userAgent.includes('Macintosh') ? '⌘' : 'Ctrl';
		isMobile = browser && window.matchMedia('(max-width: 640px)').matches;

		function handleKeydown(e: KeyboardEvent) {
			if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
				e.preventDefault();
				open = !open;
			}
		}

		document.addEventListener('keydown', handleKeydown);
		return () => {
			document.removeEventListener('keydown', handleKeydown);
		};
	});

	async function handleSearch(query: string): Promise<void> {
		console.log('Handle search triggered');
		if (!query) {
			if ($results.factStatements.length > 0 || $results.feeds.length > 0) {
				console.log('Resetting search results');
				results.set({ factStatements: [], feeds: [] });
			}
			isLoading = false;
			return;
		}

		try {
			console.log("Fetching search results for query: '" + query + "'");
			const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
			const data = await res.json();
			if (res.ok) {
				results.set(data);
			} else {
				console.error('Search error:', data.error);
				results.set({ factStatements: [], feeds: [] });
			}
		} catch (error) {
			console.error('Search request failed:', error);
			results.set({ factStatements: [], feeds: [] });
		} finally {
			isLoading = false;
		}
	}

	function debounce(func: Function, delay: number) {
		return (...args: any[]) => {
			clearTimeout(debounceTimer);
			isLoading = true;
			debounceTimer = setTimeout(() => {
				func(...args);
			}, delay);
		};
	}

	const debouncedSearch = debounce(handleSearch, 300);

	$: debouncedSearch(query);
</script>

<button
	type="button"
	on:click={() => (open = true)}
	class="flex h-10 w-full space-x-1 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
>
	<Search width="20" height="20" />
	<div class="text-sm text-muted-foreground">
		{#if isMobile}
			Tap
		{:else}
			Press
			{#if metaKey}
				<kbd
					class="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"
				>
					<span class="text-xs">{metaKey}</span>K
				</kbd>
			{/if}
		{/if}
		to search
	</div>
</button>

<Command.Dialog bind:open loop>
	<Command.Input placeholder="Search Orcfax..." bind:value={query} />
	{#if isLoading}
		<Command.Loading asChild>
			<Loading class="min-h-[300px]" />
		</Command.Loading>
	{:else}
		{#await $results}
			<Command.Loading asChild>
				<Loading class="min-h-[300px]" />
			</Command.Loading>
		{:then data}
			<Command.Empty>No results found</Command.Empty>
			{#if data && (data.factStatements.length > 0 || data.feeds.length > 0)}
				<Command.List>
					<Command.Group heading="Fact Statements">
						{#each data.factStatements as item}
							<Command.Item class="cursor-pointer">{item.fact_urn}</Command.Item>
						{/each}
					</Command.Group>
					<Command.Group heading="Feeds">
						{#each data.feeds as item}
							<Command.Item class="cursor-pointer" value={item.feed_id}>
								<FeedNameplate feed={item} size="sm" showFullID />
							</Command.Item>
						{/each}
					</Command.Group>
				</Command.List>
			{/if}
		{:catch error}
			<Command.Empty>{error.message}</Command.Empty>
		{/await}
	{/if}
</Command.Dialog>

I am using Svelte 4 and Sveltekit 2 fwiw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant