mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Reference picker: improve usability
- show tags for nonexistent references - click a badge to find the corresponding reference
This commit is contained in:
+35
-5
@@ -74,6 +74,7 @@ export default function ReferencePickerModal({
|
||||
const [query, setQuery] = useState('')
|
||||
const [selectedKeys, setSelectedKeys] = useState<string[]>([])
|
||||
const [results, setResults] = useState<{ _source: Bib2JsonEntry }[]>([])
|
||||
const [knownKeys, setKnownKeys] = useState<Set<string>>(() => new Set())
|
||||
|
||||
const pendingInitialKeysRef = useRef<string[]>([])
|
||||
const requestIdRef = useRef(0)
|
||||
@@ -109,9 +110,9 @@ export default function ReferencePickerModal({
|
||||
setResults(r.hits)
|
||||
|
||||
if (pendingInitialKeysRef.current.length > 0) {
|
||||
const knownKeys = new Set(r.hits.map(h => h._source.EntryKey))
|
||||
const matched = pendingInitialKeysRef.current.filter(k => knownKeys.has(k))
|
||||
if (matched.length > 0) setSelectedKeys(matched)
|
||||
const known = new Set(r.hits.map(h => h._source.EntryKey))
|
||||
setKnownKeys(known)
|
||||
setSelectedKeys([...pendingInitialKeysRef.current])
|
||||
pendingInitialKeysRef.current = []
|
||||
}
|
||||
}
|
||||
@@ -143,6 +144,26 @@ export default function ReferencePickerModal({
|
||||
const cancelButtonRef = useRef<HTMLButtonElement | null>(null)
|
||||
const insertButtonRef = useRef<HTMLButtonElement | null>(null)
|
||||
|
||||
const scrollToReference = useCallback((key: string) => {
|
||||
const index = results.findIndex(
|
||||
r => r._source.EntryKey === key
|
||||
)
|
||||
|
||||
if (index === -1) return
|
||||
|
||||
const el = document.getElementById(
|
||||
`reference-picker-item-${index}`
|
||||
)
|
||||
|
||||
el?.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'nearest',
|
||||
})
|
||||
|
||||
setFocusArea('list')
|
||||
setFocusedIndex(index)
|
||||
}, [results])
|
||||
|
||||
const removeOne = useCallback((key: string) => {
|
||||
setSelectedKeys(prev => {
|
||||
const index = prev.indexOf(key)
|
||||
@@ -300,14 +321,23 @@ export default function ReferencePickerModal({
|
||||
</OLRow>
|
||||
|
||||
<OLRow>
|
||||
<div className="selected-key-tag">
|
||||
<div className="selected-key-tags">
|
||||
{selectedKeys.map((key, idx) => (
|
||||
<OLTag
|
||||
<span
|
||||
key={`${key}-${idx}`}
|
||||
className={
|
||||
knownKeys.has(key)
|
||||
? 'existing-key-tag'
|
||||
: 'nonexistent-key-tag'
|
||||
}
|
||||
>
|
||||
<OLTag
|
||||
contentProps={{ onClick: () => scrollToReference(key) }}
|
||||
closeBtnProps={{ onClick: () => removeOne(key) }}
|
||||
>
|
||||
{key}
|
||||
</OLTag>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</OLRow>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.references-search-modal {
|
||||
.selected-key-tag {
|
||||
.selected-key-tags {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -13,10 +13,22 @@
|
||||
margin-bottom: 8px;
|
||||
box-shadow: 0 1px 0 var(--ds-color-neutral-100);
|
||||
padding-bottom: 6px;
|
||||
|
||||
.badge-tag {
|
||||
background-color:var(--ds-color-green-50) !important;
|
||||
}
|
||||
.selected-key-tags .existing-key-tag .badge-tag {
|
||||
background-color: var(--ds-color-green-50) !important;
|
||||
}
|
||||
.selected-key-tags .nonexistent-key-tag .badge-tag {
|
||||
background-color: var(--ds-color-red-50) !important;
|
||||
}
|
||||
.existing-key-tag .badge-tag-content-btn:hover {
|
||||
background-color: var(--ds-color-green-100);
|
||||
}
|
||||
.nonexistent-key-tag .badge-tag-content-btn:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
.badge-close:hover,
|
||||
.badge-close:focus {
|
||||
background-color: var(--ds-color-neutral-100);
|
||||
}
|
||||
|
||||
.search-results {
|
||||
|
||||
Reference in New Issue
Block a user