الإكمال التلقائي: خيارات قابلة للإنشاء
هذه الصفحة غير مترجمة بعد، وهي معروضة بالإنجليزية.
With creatable, a search in the Autocomplete that matches nothing offers a create row instead of “No results”. Picking it calls your onCreate with the typed text; you add the new option to options and select it.
Nothing selected.
import { useState } from "react";
import { Autocomplete, type OptionValue } from "slotsmith/autocomplete";
import { topics, type Topic } from "../shared/options";
export default function Creatable() {
const [options, setOptions] = useState<Topic[]>(topics.filter((topic) => !topic.archived));
const [tag, setTag] = useState<OptionValue | null>(null);
return (
<div style={{ display: "grid", gap: "1rem", maxWidth: 360 }}>
<Autocomplete
options={options}
value={tag}
onChange={setTag}
// A search that matches nothing offers a "Create" row; Enter or a click calls onCreate with the text.
creatable
onCreate={(name) => {
const created = { id: name.toLowerCase().replace(/\s+/g, "-"), label: name };
setOptions((all) => [created, ...all]);
setTag(created.id);
}}
aria-label="Tag"
/>
<p>{tag === null ? "Nothing selected." : `Selected: ${tag}`}</p>
</div>
);
}export type Country = { code: string; name: string };
/** Sorted by name, as a picker shows them. */
export const countries: Country[] = [
{ code: "ar", name: "Argentina" },
{ code: "au", name: "Australia" },
{ code: "br", name: "Brazil" },
{ code: "ca", name: "Canada" },
{ code: "eg", name: "Egypt" },
{ code: "fr", name: "France" },
{ code: "de", name: "Germany" },
{ code: "in", name: "India" },
{ code: "jp", name: "Japan" },
{ code: "jo", name: "Jordan" },
{ code: "ke", name: "Kenya" },
{ code: "mx", name: "Mexico" },
{ code: "ma", name: "Morocco" },
{ code: "nl", name: "Netherlands" },
{ code: "no", name: "Norway" },
{ code: "pt", name: "Portugal" },
{ code: "sa", name: "Saudi Arabia" },
{ code: "za", name: "South Africa" },
{ code: "es", name: "Spain" },
{ code: "se", name: "Sweden" },
{ code: "tr", name: "Türkiye" },
{ code: "ae", name: "United Arab Emirates" },
{ code: "gb", name: "United Kingdom" },
{ code: "us", name: "United States" },
];
/** `id` and `label` are the names the autocomplete reads by default, so topics need no getters. */
export type Topic = { id: string; label: string; archived?: boolean };
export const topics: Topic[] = [
{ id: "accessibility", label: "Accessibility" },
{ id: "animation", label: "Animation" },
{ id: "caching", label: "Caching" },
{ id: "design-systems", label: "Design systems" },
{ id: "forms", label: "Forms" },
{ id: "i18n", label: "Internationalisation" },
{ id: "performance", label: "Performance" },
{ id: "rtl", label: "Right-to-left" },
{ id: "server-components", label: "Server components" },
{ id: "state", label: "State" },
{ id: "testing", label: "Testing" },
{ id: "typescript", label: "TypeScript" },
{ id: "legacy", label: "Legacy browsers", archived: true },
];
/** A country with the region it is listed under; a `disabled` one stays in the list but cannot be picked. */
export type RegionCountry = Country & { region: string; disabled?: boolean };
/** A short list grouped by region. Groups show in the order of their first option, so the regions come in this order. */
export const countriesByRegion: RegionCountry[] = [
{ code: "de", name: "Germany", region: "Europe" },
{ code: "fr", name: "France", region: "Europe" },
{ code: "es", name: "Spain", region: "Europe" },
{ code: "ge", name: "Georgia", region: "Europe" },
{ code: "dz", name: "Algeria", region: "Africa" },
{ code: "eg", name: "Egypt", region: "Africa" },
{ code: "ng", name: "Nigeria", region: "Africa" },
{ code: "ne", name: "Niger", region: "Africa", disabled: true },
{ code: "jp", name: "Japan", region: "Asia" },
{ code: "sg", name: "Singapore", region: "Asia" },
{ code: "sa", name: "Saudi Arabia", region: "Asia" },
{ code: "sy", name: "Syria", region: "Asia" },
];Type a topic that is not in the list, such as “Zebra”, then press Enter or click the create row.
When the row shows
The create row is offered only once the search has settled on nothing: the search box has text, no option matches, and nothing is loading, failed or held back by minChars. While results may still arrive, it waits, so a record that was about to appear is not created twice.
Enter with no option highlighted creates, like a click on the row. The row’s text is the create label, “Create “Zebra””.
onCreate
onCreate receives the trimmed search text. The autocomplete does not add anything itself: you create the record, add it to options and set the value, as the demo does. A selected value stays labelled while the search changes.
When creating takes a request, pass createLoading while it runs: the row is disabled and shows the creating label. The Create slot replaces the row.