feat: Refactor tag drag and drop interactions
This commit is contained in:
@@ -9,7 +9,9 @@ interface DocumentTagsProps {
|
||||
tagLookupById?: Map<Identifier, DocumentTag> | null;
|
||||
onTagClick?: (tagId: Identifier) => void;
|
||||
docId: Identifier;
|
||||
maxTags?: number;
|
||||
onDocumentTagDetach?: (docId: Identifier, tagId: Identifier) => void;
|
||||
onTagDragStart?: (event: React.DragEvent<HTMLElement>, tagId: Identifier) => void;
|
||||
onTagDragEnd?: (event: React.DragEvent<HTMLElement>) => void;
|
||||
}
|
||||
|
||||
const DocumentTags: React.FC<DocumentTagsProps> = ({
|
||||
@@ -17,18 +19,17 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
|
||||
tagLookupById,
|
||||
onTagClick,
|
||||
docId,
|
||||
maxTags,
|
||||
onDocumentTagDetach,
|
||||
onTagDragStart,
|
||||
onTagDragEnd,
|
||||
}) => {
|
||||
const visibleTags = maxTags ? tags.slice(0, maxTags) : tags;
|
||||
const remainingTagCount = maxTags && tags.length > maxTags ? tags.length - maxTags : 0;
|
||||
|
||||
if (tags.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{visibleTags.map((tag, index) => {
|
||||
{tags.map((tag, index) => {
|
||||
const colorSource = tag?.color || tagLookupById?.get(tag.id)?.color;
|
||||
const style = getTagColorStyle(colorSource);
|
||||
const tagId = tag?.id ?? null;
|
||||
@@ -58,9 +59,16 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
|
||||
console.warn('[documents] Failed to configure drag effect', error);
|
||||
}
|
||||
writeTagTransferData(event.dataTransfer, tag, docId);
|
||||
if (tagId) {
|
||||
onTagDragStart?.(event, tagId);
|
||||
}
|
||||
}}
|
||||
onDragEnd={(event) => {
|
||||
event.stopPropagation();
|
||||
if (event.dataTransfer.dropEffect === 'move' && tagId && onDocumentTagDetach) {
|
||||
onDocumentTagDetach(docId, tagId);
|
||||
}
|
||||
onTagDragEnd?.(event);
|
||||
}}
|
||||
onKeyDown={clickable ? (event) => {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
@@ -75,9 +83,6 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
{remainingTagCount > 0 && (
|
||||
<span className="badge tag-chip tag-chip--more">+{remainingTagCount}</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -116,7 +116,9 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||
tagLookupById={props.tagLookupById}
|
||||
onTagClick={props.onTagClick}
|
||||
docId={doc.id}
|
||||
maxTags={3}
|
||||
onDocumentTagDetach={props.onDocumentTagDetach}
|
||||
onTagDragStart={logic.handlers.onTagDragStart}
|
||||
onTagDragEnd={logic.handlers.onTagDragEnd}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -128,6 +128,9 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
|
||||
tagLookupById={props.tagLookupById}
|
||||
onTagClick={props.onTagClick}
|
||||
docId={doc.id}
|
||||
onDocumentTagDetach={props.onDocumentTagDetach}
|
||||
onTagDragStart={logic.handlers.onTagDragStart}
|
||||
onTagDragEnd={logic.handlers.onTagDragEnd}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,9 @@ interface EntryTagsProps {
|
||||
tagLookupById?: Map<Identifier, DocumentTag> | null;
|
||||
onTagClick?: (tagId: Identifier) => void;
|
||||
docId: Identifier;
|
||||
maxTags?: number;
|
||||
onDocumentTagDetach?: (docId: Identifier, tagId: Identifier) => void;
|
||||
onTagDragStart?: (event: React.DragEvent<HTMLElement>, tagId: Identifier) => void;
|
||||
onTagDragEnd?: (event: React.DragEvent<HTMLElement>) => void;
|
||||
}
|
||||
|
||||
const EntryTags: React.FC<EntryTagsProps> = (props) => {
|
||||
@@ -22,7 +24,9 @@ const EntryTags: React.FC<EntryTagsProps> = (props) => {
|
||||
tagLookupById={props.tagLookupById}
|
||||
onTagClick={props.onTagClick}
|
||||
docId={props.docId}
|
||||
maxTags={props.maxTags}
|
||||
onDocumentTagDetach={props.onDocumentTagDetach}
|
||||
onTagDragStart={props.onTagDragStart}
|
||||
onTagDragEnd={props.onTagDragEnd}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user