Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
### Added

- Extended existing height and readOnly props from `CodeEditorProps` to `AutoSuggestionProps` & `ExtendedCodeEditorProps` to be configurable from `<CodeAutocompleteField />`
- Added additional actions to `<ActivityControlWidget />`
- `<ActivityControlWidget />`
- `additionalActions` property to include other more complex components between the action buttons and the context menu of the widget
- `<Tooltip />`
- `swapPlaceholderDelay` property to allow configuration of the delay time before the placeholder element is replaced by the actual tooltip component

### Changed

- `<NodeContent />`
- prevent start of a react flow drag action of a node when user clicks in the node menu section

## [24.3.0] - 2025-06-05

Expand Down
2 changes: 2 additions & 0 deletions src/cmem/ActivityControl/ActivityControlWidget.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ const actions: ActivityControlWidgetAction[] = [
{
"data-test-id": "activity-start-activity",
icon: "item-start",
// eslint-disable-next-line no-console
action: () => console.log("start"),
tooltip: "Start Activity",
disabled: false,
},
{
"data-test-id": "activity-stop-activity",
icon: "item-stop",
// eslint-disable-next-line no-console
action: () => console.log("cancel"),
tooltip: "Stop Activity",
disabled: false,
Expand Down
1 change: 1 addition & 0 deletions src/components/Icon/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const IconButton = ({
const defaultIconTooltipProps = {
hoverOpenDelay: 1000,
openOnTargetFocus: restProps.disabled || (restProps.tabIndex ?? 0) < 0 ? false : undefined,
swapPlaceholderDelay: 1,
};
const iconProps = {
small: restProps.small,
Expand Down
22 changes: 17 additions & 5 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export interface TooltipProps extends Omit<BlueprintTooltipProps, "position"> {
* You can prevent it in any case by setting it to `false`.
*/
usePlaceholder?: boolean;
/**
* Time after the placeholder element is replaced by the actual tooltip component.
* Must be greater than 0.
* For the first display of the tooltip this time adds up to `hoverOpenDelay`.
*/
swapPlaceholderDelay?: number;
}

export const Tooltip = ({
Expand All @@ -53,18 +59,21 @@ export const Tooltip = ({
markdownEnabler = "\n\n",
markdownProps,
usePlaceholder,
hoverOpenDelay = 500,
swapPlaceholderDelay = 100,
hoverOpenDelay = 450,
...otherTooltipProps
}: TooltipProps) => {
const placeholderRef = React.useRef(null);
const eventMemory = React.useRef<null | "afterhover" | "afterfocus">(null);
const searchId = React.useRef<null | string>(null);
const swapDelayTime = 100;
const swapDelay = React.useRef<null | NodeJS.Timeout>(null);
const swapDelayTime = swapPlaceholderDelay;
const [placeholder, setPlaceholder] = React.useState<boolean>(
!otherTooltipProps.disabled &&
!otherTooltipProps.defaultIsOpen &&
!otherTooltipProps.isOpen &&
otherTooltipProps.renderTarget === undefined &&
swapDelayTime > 0 &&
hoverOpenDelay > swapDelayTime &&
(usePlaceholder === true || (typeof content === "string" && usePlaceholder !== false))
);
Expand All @@ -77,7 +86,10 @@ export const Tooltip = ({
React.useEffect(() => {
if (placeholderRef.current !== null) {
const swap = (ev: MouseEvent | globalThis.FocusEvent) => {
const swapDelay = setTimeout(() => {
if (swapDelay.current) {
clearTimeout(swapDelay.current);
}
swapDelay.current = setTimeout(() => {
// we delay the swap to prevent unwanted effects
// (e.g. forced mouseover after the swap but the cursor is already somewhere else)
eventMemory.current = ev.type === "focusin" ? "afterfocus" : "afterhover";
Expand All @@ -93,7 +105,7 @@ export const Tooltip = ({
) {
eventMemory.current = null;
}
clearTimeout(swapDelay);
clearTimeout(swapDelay.current as NodeJS.Timeout);
});
}
};
Expand Down Expand Up @@ -166,7 +178,7 @@ export const Tooltip = ({
) : (
<BlueprintTooltip
lazy={true}
hoverOpenDelay={hoverOpenDelay - swapDelayTime}
hoverOpenDelay={hoverOpenDelay}
{...otherTooltipProps}
content={tooltipContent}
className={targetClassName}
Expand Down
2 changes: 1 addition & 1 deletion src/extensions/react-flow/nodes/NodeContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ export function NodeContent<CONTENT_PROPS = any>({
)}
</div>
{(menuButtons || (showExecutionButtons && executionButtons)) && (
<div className={`${eccgui}-graphviz__node__header-menu`}>
<div className={`${eccgui}-graphviz__node__header-menu nodrag`}>
{showExecutionButtons && typeof executionButtons === "function"
? executionButtons(adjustedContentProps, setAdjustedContentProps)
: null}
Expand Down