I'm trying to build a component which allows a user the ability to search through categories using the autocomplete and have it appear as a chip within the Skeleton UI InputChip
component. I am also trying to utilise the AutoComplete
component. My issue is when I try and select a category from the AutoComplete
it doesn't update the chips on the UI.
<script lang="ts">
import { page } from "$app/stores";
import { createQuery } from "@tanstack/svelte-query";
import LoadingSpinner from "$lib/components/ui/LoadingSpinner.svelte";
import {
toastStore,
InputChip,
Autocomplete,
type AutocompleteOption
} from "@skeletonlabs/skeleton";
const { supabase } = $page.data;
export let selectedCategoryIds: string[] = [];
export let subcatPaths: string[] = [];
let whitelist: string[] = [];
let selectedCategoryLabels: string[] = [];
let selectedCategoryChips: string[] = [];
let categoryOptions: AutocompleteOption[] = [];
let inputChipCategory: string;
$: categories = createQuery({
queryKey: ["categories"],
queryFn: async () => {
const { data: cats, error } = await supabase.from("categories").select();
if (error) throw error;
return cats.map(
(category) =>
({
label: category.label,
value: category.id,
keywords: category.keywords
} as AutocompleteOption)
);
},
onSuccess: (data) => {
categoryOptions = data;
whitelist = data.map((category) => category.label);
},
onError: (err) => {
console.log(err);
toastStore.trigger({
message: "Error fetching categories.",
background: "variant-filled-error"
});
}
});
function onCategorySelect(event: CustomEvent<AutocompleteOption>) {
if (
!selectedCategoryIds.some((category) => category === event.detail.value)
) {
selectedCategoryIds = [
...selectedCategoryIds,
event.detail.value as string
];
selectedCategoryLabels = [
...selectedCategoryLabels,
event.detail.label as string
];
}
}
$: selectedCategoryChips = selectedCategoryLabels;
</script>
<div class="label">
<span>Categories</span>
<InputChip
{whitelist}
allowUpperCase
bind:input={inputChipCategory}
bind:value={selectedCategoryChips}
name="chips"
placeholder="Enter 3 categories..."
chips="variant-filled-primary"
min="3"
/>
</div>
<div
class="card w-full max-h-48 {$categories.isLoading
? 'p-4'
: 'p-1'} overflow-y-auto"
>
{#if $categories.isLoading}
<center>
<LoadingSpinner />
</center>
{:else if $categories.isSuccess}
<Autocomplete
options={categoryOptions}
denylist={selectedCategoryIds}
bind:input={inputChipCategory}
on:selection={onCategorySelect}
/>
{/if}
</div>
I know for sure that the selectedCategoryChips
string array is being updated and you might be wondering why I'm not using the selectedCategoryLabels
array instead, I was trying to take reference from this but it didn't work unfortunately.
If anyone can help out that would be great :)
i guess you are trying to do something like this
if that's the case you could adapt it like in the skeleton-ui documentation
js
html