feat: Ultrasound Pleura B-line Annotation Mode & Extension (#5061)

This commit is contained in:
rodrigobasilio2022 authored and GitHub committed 2025-06-24 12:50:48 -04:00
1 parent 9b8eef9474
commit 226f9b0773
46 files changed
+7123 -3660

No files matched your search

@@ -0,0 +1,113 @@
import React, { useState, useEffect } from 'react';
import { Input } from '@ohif/ui-next';
/**
* Props for the MultiLabelInput component
*/
interface MultiLabelInputProps {
/** Placeholder text for the input field */
placeholder?: string;
/** Additional CSS class name for the input field */
className?: string;
/** Array of labels to display */
labels?: string[];
/** Callback function called when labels are added or removed */
onLabelsChange?: (labels: string[]) => void;
}
/**
* A component that allows users to input and manage multiple text labels
* @param props - Component props
* @returns The MultiLabelInput component
*/
const MultiLabelInput: React.FC<MultiLabelInputProps> = ({
placeholder = 'Enter a label and press Enter',
className,
labels = [],
onLabelsChange,
}) => {
// State for the current input value
const [inputValue, setInputValue] = useState<string>('');
// Internal state for labels that syncs with the external labels prop
const [internalLabels, setInternalLabels] = useState<string[]>(labels);
// Update internal labels when external labels change
useEffect(() => {
setInternalLabels(labels);
}, [labels]);
/**
* Handles changes to the input field
* @param e - The change event
*/
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
/**
* Adds the current input value as a new label if it's not empty and not a duplicate
*/
const handleAddLabel = () => {
if (inputValue.trim() && !internalLabels.includes(inputValue.trim())) {
const newLabels = [...internalLabels, inputValue.trim()];
setInternalLabels(newLabels);
if (onLabelsChange) {
onLabelsChange(newLabels);
}
setInputValue('');
}
};
/**
* Removes a label from the list
* @param label - The label to remove
*/
const handleRemoveLabel = (label: string) => {
const newLabels = internalLabels.filter(l => l !== label);
setInternalLabels(newLabels);
if (onLabelsChange) {
onLabelsChange(newLabels);
}
};
/**
* Handles key press events in the input field
* @param e - The keyboard event
*/
const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleAddLabel();
}
};
return (
<div>
<Input
type="text"
value={inputValue}
onChange={handleInputChange}
onKeyPress={handleKeyPress}
placeholder={placeholder}
className={className}
/>
<div className="flex flex-wrap">
{internalLabels.map((label, index) => (
<span
key={index}
className="m-1 inline-flex items-center rounded-full bg-[#2a2a4a] px-4 py-1 text-white"
>
{label}
<button
className="ml-2.5 cursor-pointer rounded-full bg-blue-800 px-2 py-0.5 text-xs text-white transition-colors hover:bg-blue-600"
onClick={() => handleRemoveLabel(label)}
>
×
</button>
</span>
))}
</div>
</div>
);
};
export default MultiLabelInput;