feat: add search box and title above model list

This commit is contained in:
chenyu
2024-12-27 10:44:15 +08:00
parent 0c3d4462ca
commit 055ac64d89
4 changed files with 103 additions and 37 deletions

View File

@@ -78,7 +78,7 @@
.list {
border: var(--border-in-light);
border-radius: 10px;
border-radius: 0 0 10px 10px;
box-shadow: var(--card-shadow);
margin-bottom: 20px;
animation: slide-in ease 0.3s;
@@ -313,11 +313,37 @@
.selector-item-disabled {
opacity: 0.6;
}
.selector-bar {
background-color: var(--white);
border: solid var(--border-in-light);
border-top-left-radius: 10px;
border-top-right-radius: 10px;
min-height: 40px;
width: 100%;
}
.selector-title {
font-size: large;
font-weight: bold;
padding: 10px;
}
.selector-search-container {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border-bottom: solid var(--border-in-light);
}
.selector-search-input {
padding: 5px;
margin-right: 5px;
flex-grow: 1;
max-width: none;
}
&-content {
min-width: 300px;
.list {
max-height: 90vh;
max-height: 50vh;
overflow-x: hidden;
overflow-y: auto;
@@ -336,4 +362,3 @@
}
}
}

View File

@@ -507,44 +507,79 @@ export function Selector<T>(props: {
props.onClose?.();
}
};
const [searchText, setSearchText] = useState("");
const [filteredItems, setFilteredItems] = useState([...props.items]);
function onSearch(text: string) {
setSearchText(text);
if (text === "") {
setFilteredItems([...props.items]);
return;
}
// filter by items title
const newItems = props.items.filter((item) =>
item.title.toLowerCase().includes(text.toLowerCase()),
);
setFilteredItems([...newItems]);
}
return (
<div className={styles["selector"]} onClick={() => props.onClose?.()}>
<div className={styles["selector-content"]}>
{/* todo: add searchbox */}
<div className={styles["selector-bar"]}>
<div className={styles["selector-title"]}>
{Locale.UI.SelectorTitle}
</div>
<div className={styles["selector-search-container"]}>
<input
type="text"
className={styles["selector-search-input"]}
placeholder={Locale.UI.Search}
autoFocus
onInput={(e) => onSearch(e.currentTarget.value)}
/>
</div>
</div>
<List>
{props.items.map((item, i) => {
const selected = selectedValues.includes(item.value);
return (
<ListItem
className={clsx(styles["selector-item"], {
[styles["selector-item-disabled"]]: item.disable,
})}
key={i}
title={item.title}
subTitle={item.subTitle}
onClick={(e) => {
if (item.disable) {
e.stopPropagation();
} else {
handleSelection(e, item.value);
}
}}
>
{selected ? (
<div
style={{
height: 10,
width: 10,
backgroundColor: "var(--primary)",
borderRadius: 10,
}}
></div>
) : (
<></>
)}
</ListItem>
);
})}
{filteredItems.length ? (
filteredItems.map((item, i) => {
const selected = selectedValues.includes(item.value);
return (
<ListItem
className={clsx(styles["selector-item"], {
[styles["selector-item-disabled"]]: item.disable,
})}
key={i}
title={item.title}
subTitle={item.subTitle}
onClick={(e) => {
if (item.disable) {
e.stopPropagation();
} else {
handleSelection(e, item.value);
}
}}
>
{selected ? (
<div
style={{
height: 10,
width: 10,
backgroundColor: "var(--primary)",
borderRadius: 10,
}}
></div>
) : (
<></>
)}
</ListItem>
);
})
) : (
<ListItem
title={Locale.UI.NoResults}
className={styles["selector-item"]}
></ListItem>
)}
</List>
</div>
</div>