Merge dee9c94534
into 28cbe56cec
This commit is contained in:
commit
1ad58f1c4b
|
@ -78,10 +78,10 @@
|
|||
|
||||
.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;
|
||||
|
||||
background: var(--white);
|
||||
}
|
||||
|
||||
|
@ -313,11 +313,38 @@
|
|||
.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;
|
||||
animation: slide-in ease 0.3s;
|
||||
width: 30rem;
|
||||
height: 60vh;
|
||||
.list {
|
||||
max-height: 90vh;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
|
@ -336,4 +363,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -507,12 +507,45 @@ 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"]}>
|
||||
<div
|
||||
className={styles["selector-content"]}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* title and search box */}
|
||||
<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 content */}
|
||||
<List>
|
||||
{props.items.map((item, i) => {
|
||||
{filteredItems.length ? (
|
||||
filteredItems.map((item, i) => {
|
||||
const selected = selectedValues.includes(item.value);
|
||||
return (
|
||||
<ListItem
|
||||
|
@ -544,7 +577,13 @@ export function Selector<T>(props: {
|
|||
)}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
})
|
||||
) : (
|
||||
<ListItem
|
||||
title={Locale.UI.NoResults}
|
||||
className={styles["selector-item"]}
|
||||
></ListItem>
|
||||
)}
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -784,6 +784,9 @@ const cn = {
|
|||
Import: "导入",
|
||||
Sync: "同步",
|
||||
Config: "配置",
|
||||
Search: "搜索",
|
||||
SelectorTitle: "选择",
|
||||
NoResults: "没有结果",
|
||||
},
|
||||
Exporter: {
|
||||
Description: {
|
||||
|
|
|
@ -790,6 +790,9 @@ const en: LocaleType = {
|
|||
Import: "Import",
|
||||
Sync: "Sync",
|
||||
Config: "Config",
|
||||
Search: "Search",
|
||||
SelectorTitle: "Select",
|
||||
NoResults: "No Results",
|
||||
},
|
||||
Exporter: {
|
||||
Description: {
|
||||
|
|
Loading…
Reference in New Issue