chore: only show links container toggle if container can be truncated (#2326)
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
import { FormEventHandler, KeyboardEventHandler, useDeferredValue, useEffect, useRef } from 'react'
|
||||
import {
|
||||
FormEventHandler,
|
||||
ForwardedRef,
|
||||
KeyboardEventHandler,
|
||||
forwardRef,
|
||||
useDeferredValue,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { classNames } from '@standardnotes/utils'
|
||||
import { LinkingController } from '@/Controllers/LinkingController'
|
||||
@@ -13,6 +21,7 @@ import { Slot } from '@radix-ui/react-slot'
|
||||
import Icon from '../Icon/Icon'
|
||||
import { PremiumFeatureIconName } from '../Icon/PremiumFeatureIcon'
|
||||
import { KeyboardKey } from '@standardnotes/ui-services'
|
||||
import { mergeRefs } from '@/Hooks/mergeRefs'
|
||||
|
||||
type Props = {
|
||||
linkingController: LinkingController
|
||||
@@ -23,118 +32,116 @@ type Props = {
|
||||
item: DecryptedItem
|
||||
}
|
||||
|
||||
const ItemLinkAutocompleteInput = ({
|
||||
linkingController,
|
||||
focusPreviousItem,
|
||||
focusedId,
|
||||
setFocusedId,
|
||||
hoverLabel,
|
||||
item,
|
||||
}: Props) => {
|
||||
const application = useApplication()
|
||||
const ItemLinkAutocompleteInput = forwardRef(
|
||||
(
|
||||
{ linkingController, focusPreviousItem, focusedId, setFocusedId, hoverLabel, item }: Props,
|
||||
forwardedRef: ForwardedRef<HTMLInputElement>,
|
||||
) => {
|
||||
const application = useApplication()
|
||||
|
||||
const { getLinkedTagsForItem, linkItems, createAndAddNewTag, isEntitledToNoteLinking } = linkingController
|
||||
const { getLinkedTagsForItem, linkItems, createAndAddNewTag, isEntitledToNoteLinking } = linkingController
|
||||
|
||||
const tagsLinkedToItem = getLinkedTagsForItem(item) || []
|
||||
const tagsLinkedToItem = getLinkedTagsForItem(item) || []
|
||||
|
||||
const combobox = useComboboxStore()
|
||||
const value = combobox.useState('value')
|
||||
const searchQuery = useDeferredValue(value)
|
||||
const combobox = useComboboxStore()
|
||||
const value = combobox.useState('value')
|
||||
const searchQuery = useDeferredValue(value)
|
||||
|
||||
const { unlinkedItems, shouldShowCreateTag } = getLinkingSearchResults(searchQuery, application, item)
|
||||
const { unlinkedItems, shouldShowCreateTag } = getLinkingSearchResults(searchQuery, application, item)
|
||||
|
||||
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||
|
||||
const onFormSubmit: FormEventHandler = async (event) => {
|
||||
event.preventDefault()
|
||||
if (searchQuery !== '') {
|
||||
await createAndAddNewTag(searchQuery)
|
||||
combobox.setValue('')
|
||||
const onFormSubmit: FormEventHandler = async (event) => {
|
||||
event.preventDefault()
|
||||
if (searchQuery !== '') {
|
||||
await createAndAddNewTag(searchQuery)
|
||||
combobox.setValue('')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleFocus = () => {
|
||||
if (focusedId !== ElementIds.ItemLinkAutocompleteInput) {
|
||||
setFocusedId(ElementIds.ItemLinkAutocompleteInput)
|
||||
const handleFocus = () => {
|
||||
if (focusedId !== ElementIds.ItemLinkAutocompleteInput) {
|
||||
setFocusedId(ElementIds.ItemLinkAutocompleteInput)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onKeyDown: KeyboardEventHandler = (event) => {
|
||||
switch (event.key) {
|
||||
case KeyboardKey.Left:
|
||||
if (searchQuery.length === 0) {
|
||||
focusPreviousItem()
|
||||
}
|
||||
break
|
||||
const onKeyDown: KeyboardEventHandler = (event) => {
|
||||
switch (event.key) {
|
||||
case KeyboardKey.Left:
|
||||
if (searchQuery.length === 0) {
|
||||
focusPreviousItem()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (focusedId === ElementIds.ItemLinkAutocompleteInput) {
|
||||
inputRef.current?.focus()
|
||||
}
|
||||
}, [focusedId])
|
||||
useEffect(() => {
|
||||
if (focusedId === ElementIds.ItemLinkAutocompleteInput) {
|
||||
inputRef.current?.focus()
|
||||
}
|
||||
}, [focusedId])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={onFormSubmit}>
|
||||
<label>
|
||||
<VisuallyHidden>Link tags, notes or files</VisuallyHidden>
|
||||
<Combobox
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={onFormSubmit}>
|
||||
<label>
|
||||
<VisuallyHidden>Link tags, notes or files</VisuallyHidden>
|
||||
<Combobox
|
||||
store={combobox}
|
||||
placeholder="Link tags, notes, files..."
|
||||
className={classNames(
|
||||
`${tagsLinkedToItem.length > 0 ? 'w-80' : 'mr-10 w-70'}`,
|
||||
'h-7 w-70 bg-transparent text-sm text-text focus:border-b-2 focus:border-info focus:shadow-none focus:outline-none lg:text-xs',
|
||||
)}
|
||||
title={hoverLabel}
|
||||
id={ElementIds.ItemLinkAutocompleteInput}
|
||||
ref={mergeRefs([inputRef, forwardedRef])}
|
||||
onFocus={handleFocus}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
</label>
|
||||
<ComboboxPopover
|
||||
store={combobox}
|
||||
placeholder="Link tags, notes, files..."
|
||||
className={classNames(
|
||||
`${tagsLinkedToItem.length > 0 ? 'w-80' : 'mr-10 w-70'}`,
|
||||
'h-7 w-70 bg-transparent text-sm text-text focus:border-b-2 focus:border-info focus:shadow-none focus:outline-none lg:text-xs',
|
||||
'z-dropdown-menu max-h-[var(--popover-available-height)] w-[var(--popover-anchor-width)] overflow-y-auto rounded bg-default py-2 shadow-main',
|
||||
unlinkedItems.length === 0 && !shouldShowCreateTag && 'hidden',
|
||||
)}
|
||||
title={hoverLabel}
|
||||
id={ElementIds.ItemLinkAutocompleteInput}
|
||||
ref={inputRef}
|
||||
onFocus={handleFocus}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
</label>
|
||||
<ComboboxPopover
|
||||
store={combobox}
|
||||
className={classNames(
|
||||
'z-dropdown-menu max-h-[var(--popover-available-height)] w-[var(--popover-anchor-width)] overflow-y-auto rounded bg-default py-2 shadow-main',
|
||||
unlinkedItems.length === 0 && !shouldShowCreateTag && 'hidden',
|
||||
)}
|
||||
>
|
||||
{unlinkedItems.map((result) => {
|
||||
const cannotLinkItem = !isEntitledToNoteLinking && result instanceof SNNote
|
||||
>
|
||||
{unlinkedItems.map((result) => {
|
||||
const cannotLinkItem = !isEntitledToNoteLinking && result instanceof SNNote
|
||||
|
||||
return (
|
||||
return (
|
||||
<ComboboxItem
|
||||
key={result.uuid}
|
||||
className="flex w-full cursor-pointer items-center justify-between gap-4 overflow-hidden py-2 px-3 hover:bg-contrast hover:text-foreground [&[data-active-item]]:bg-info-backdrop"
|
||||
hideOnClick
|
||||
onClick={() => {
|
||||
linkItems(item, result).catch(console.error)
|
||||
combobox.setValue('')
|
||||
}}
|
||||
>
|
||||
<LinkedItemMeta item={result} searchQuery={searchQuery} />
|
||||
{cannotLinkItem && <Icon type={PremiumFeatureIconName} className="ml-auto flex-shrink-0 text-info" />}
|
||||
</ComboboxItem>
|
||||
)
|
||||
})}
|
||||
{shouldShowCreateTag && (
|
||||
<ComboboxItem
|
||||
key={result.uuid}
|
||||
className="flex w-full cursor-pointer items-center justify-between gap-4 overflow-hidden py-2 px-3 hover:bg-contrast hover:text-foreground [&[data-active-item]]:bg-info-backdrop"
|
||||
hideOnClick
|
||||
as={Slot}
|
||||
onClick={() => {
|
||||
linkItems(item, result).catch(console.error)
|
||||
void createAndAddNewTag(searchQuery)
|
||||
combobox.setValue('')
|
||||
}}
|
||||
>
|
||||
<LinkedItemMeta item={result} searchQuery={searchQuery} />
|
||||
{cannotLinkItem && <Icon type={PremiumFeatureIconName} className="ml-auto flex-shrink-0 text-info" />}
|
||||
<LinkedItemSearchResultsAddTagOption searchQuery={searchQuery} />
|
||||
</ComboboxItem>
|
||||
)
|
||||
})}
|
||||
{shouldShowCreateTag && (
|
||||
<ComboboxItem
|
||||
hideOnClick
|
||||
as={Slot}
|
||||
onClick={() => {
|
||||
void createAndAddNewTag(searchQuery)
|
||||
combobox.setValue('')
|
||||
}}
|
||||
>
|
||||
<LinkedItemSearchResultsAddTagOption searchQuery={searchQuery} />
|
||||
</ComboboxItem>
|
||||
)}
|
||||
</ComboboxPopover>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</ComboboxPopover>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
export default observer(ItemLinkAutocompleteInput)
|
||||
|
||||
Reference in New Issue
Block a user