diff --git a/client/packages/lowcoder/src/comps/comps/avatar.tsx b/client/packages/lowcoder/src/comps/comps/avatar.tsx index bbd39f73e8..f07de98cae 100644 --- a/client/packages/lowcoder/src/comps/comps/avatar.tsx +++ b/client/packages/lowcoder/src/comps/comps/avatar.tsx @@ -25,6 +25,7 @@ import { IconControl } from "comps/controls/iconControl"; import { clickEvent, eventHandlerControl, + doubleClickEvent, } from "../controls/eventHandlerControl"; import { Avatar, AvatarProps, Badge, Dropdown, Menu } from "antd"; import { LeftRightControl, dropdownControl } from "../controls/dropdownControl"; @@ -106,7 +107,7 @@ padding: ${props=>props.$style.padding}; background: ${props=>props.$style.background}; text-decoration: ${props => props.$style.textDecoration}; ` -const EventOptions = [clickEvent] as const; +const EventOptions = [clickEvent, doubleClickEvent] as const; const sharpOptions = [ { label: trans("avatarComp.square"), value: "square" }, { label: trans("avatarComp.circle"), value: "circle" }, @@ -183,6 +184,7 @@ const AvatarView = (props: RecordConstructorToView) => { src={src.value} // $cursorPointer={eventsCount > 0} onClick={() => props.onEvent("click")} + onDoubleClick={() => props.onEvent("doubleClick")} > {title.value} diff --git a/client/packages/lowcoder/src/comps/comps/avatarGroup.tsx b/client/packages/lowcoder/src/comps/comps/avatarGroup.tsx index 4cc2567c64..8f35bd4f4d 100644 --- a/client/packages/lowcoder/src/comps/comps/avatarGroup.tsx +++ b/client/packages/lowcoder/src/comps/comps/avatarGroup.tsx @@ -8,7 +8,7 @@ import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { trans } from "i18n"; import { NumberControl, StringControl } from "comps/controls/codeControl"; import { Avatar, Tooltip } from "antd"; -import { clickEvent, eventHandlerControl, refreshEvent } from "../controls/eventHandlerControl"; +import { clickEvent, doubleClickEvent, eventHandlerControl, refreshEvent } from "../controls/eventHandlerControl"; import styled from "styled-components"; import { useContext, ReactElement, useEffect } from "react"; import { MultiCompBuilder, stateComp, withDefault } from "../generators"; @@ -77,7 +77,7 @@ const DropdownOption = new MultiCompBuilder( )) .build(); -const EventOptions = [clickEvent, refreshEvent] as const; +const EventOptions = [clickEvent, refreshEvent, doubleClickEvent] as const; export const alignOptions = [ { label: , value: "flex-start" }, @@ -128,6 +128,9 @@ const AvatarGroupView = (props: RecordConstructorToView & { props.onEvent("click") props.dispatch(changeChildAction("currentAvatar", item as JSONObject, false)); }} + onDoubleClick={() => { + props.onEvent("doubleClick") + }} > {item.label} diff --git a/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx b/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx index 4fb21b69f5..d79fa542d2 100644 --- a/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx @@ -25,6 +25,7 @@ import { eventHandlerControl, deleteEvent, mentionEvent, + doubleClickEvent, } from "comps/controls/eventHandlerControl"; import { EditorContext } from "comps/editorState"; @@ -80,6 +81,7 @@ dayjs.extend(relativeTime); const EventOptions = [ clickEvent, + doubleClickEvent, submitEvent, deleteEvent, mentionEvent, @@ -290,7 +292,10 @@ const CommentCompBase = ( props.onEvent("click")}> +
props.onEvent("click")} + onDoubleClick={() => props.onEvent("doubleClick")} + > {item?.user?.name} ) => { $animationStyle={props.animationStyle} style={style} onClick={() => props.onEvent("click")} + onDoubleClick={() => props.onEvent("doubleClick")} > { props.sourceMode === 'standard' ? (props.icon || '') diff --git a/client/packages/lowcoder/src/comps/comps/imageComp.tsx b/client/packages/lowcoder/src/comps/comps/imageComp.tsx index ec4190bc6e..b0bd4d3dd6 100644 --- a/client/packages/lowcoder/src/comps/comps/imageComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/imageComp.tsx @@ -3,6 +3,7 @@ import { Section, sectionNames } from "lowcoder-design"; import { clickEvent, eventHandlerControl, + doubleClickEvent, } from "../controls/eventHandlerControl"; import { StringStateControl } from "../controls/codeStateControl"; import { UICompBuilder, withDefault } from "../generators"; @@ -112,7 +113,7 @@ const getStyle = (style: ImageStyleType) => { `; }; -const EventOptions = [clickEvent] as const; +const EventOptions = [clickEvent, doubleClickEvent] as const; const ModeOptions = [ { label: "URL", value: "standard" }, { label: "Asset Library", value: "asset-library" }, @@ -212,6 +213,7 @@ const ContainerImg = (props: RecordConstructorToView) => { preview={props.supportPreview ? {src: props.previewSrc || props.src.value } : false} fallback={DEFAULT_IMG_URL} onClick={() => props.onEvent("click")} + onDoubleClick={() => props.onEvent("doubleClick")} />
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnAvatarsComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnAvatarsComp.tsx index c34b6dfbb9..11141281fa 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnAvatarsComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnAvatarsComp.tsx @@ -9,7 +9,7 @@ import { avatarGroupStyle, AvatarGroupStyleType } from "comps/controls/styleCont import { AlignCenter, AlignLeft, AlignRight } from "lowcoder-design"; import { NumberControl } from "comps/controls/codeControl"; import { Avatar, Tooltip } from "antd"; -import { clickEvent, eventHandlerControl, refreshEvent } from "comps/controls/eventHandlerControl"; +import { clickEvent, eventHandlerControl, refreshEvent, doubleClickEvent } from "comps/controls/eventHandlerControl"; import React, { ReactElement, useCallback, useEffect, useRef } from "react"; import { IconControl } from "comps/controls/iconControl"; import { ColorControl } from "comps/controls/colorControl"; @@ -68,7 +68,7 @@ const DropdownOption = new MultiCompBuilder( }) .build(); -const EventOptions = [clickEvent, refreshEvent] as const; +const EventOptions = [clickEvent, refreshEvent, doubleClickEvent] as const; export const alignOptions = [ { label: , value: "flex-start" }, @@ -106,6 +106,11 @@ const MemoizedAvatar = React.memo(({ onEvent("click"); }, [onEvent]); + const handleDoubleClick = useCallback(() => { + if (!mountedRef.current) return; + onEvent("doubleClick"); + }, [onEvent]); + return ( {item.label} diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDropdownComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDropdownComp.tsx index 9055413de1..d7efb3afff 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDropdownComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDropdownComp.tsx @@ -15,7 +15,7 @@ import { ButtonStyle } from "comps/controls/styleControlConstants"; import { Button100 } from "comps/comps/buttonComp/buttonCompConstants"; import styled from "styled-components"; import { ButtonType } from "antd/es/button"; -import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl"; +import { clickEvent, eventHandlerControl, doubleClickEvent } from "comps/controls/eventHandlerControl"; const StyledButton = styled(Button100)` display: flex; @@ -29,7 +29,7 @@ const StyledIconWrapper = styled(IconWrapper)` margin: 0; `; -const DropdownEventOptions = [clickEvent] as const; +const DropdownEventOptions = [clickEvent, doubleClickEvent] as const; const childrenMap = { buttonType: dropdownControl(ButtonTypeOptions, "primary"), @@ -67,10 +67,16 @@ const DropdownMenu = React.memo(({ items, options, onEvent }: { items: any[]; op e.preventDefault(); }, []); + const handleDoubleClick = useCallback((e: React.MouseEvent) => { + if (!mountedRef.current) return; + onEvent?.("doubleClick"); + }, [onEvent]); + return ( ); diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx index 512329ee36..183d87889b 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinkComp.tsx @@ -11,11 +11,11 @@ import { disabledPropertyView } from "comps/utils/propertyUtils"; import styled, { css } from "styled-components"; import { styleControl } from "comps/controls/styleControl"; import { TableColumnLinkStyle } from "comps/controls/styleControlConstants"; -import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl"; +import { clickEvent, eventHandlerControl, doubleClickEvent } from "comps/controls/eventHandlerControl"; export const ColumnValueTooltip = trans("table.columnValueTooltip"); -const LinkEventOptions = [clickEvent] as const; +const LinkEventOptions = [clickEvent, doubleClickEvent] as const; const childrenMap = { text: StringControl, @@ -44,10 +44,17 @@ export const ColumnLink = React.memo(({ disabled, label, onEvent }: { disabled: } }, [disabled, onEvent]); + const handleDoubleClick = useCallback(() => { + if (!disabled && onEvent) { + onEvent("doubleClick"); + } + }, [disabled, onEvent]); + return ( {label} diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinksComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinksComp.tsx index b36f2acfcd..89ed76672f 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinksComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinksComp.tsx @@ -10,7 +10,7 @@ import { trans } from "i18n"; import styled from "styled-components"; import { ColumnLink } from "comps/comps/tableComp/column/columnTypeComps/columnLinkComp"; import { LightActiveTextColor, PrimaryColor } from "constants/style"; -import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl"; +import { clickEvent, eventHandlerControl, doubleClickEvent } from "comps/controls/eventHandlerControl"; const MenuLinkWrapper = styled.div` > a { @@ -38,7 +38,7 @@ const MenuWrapper = styled.div` } `; -const LinksEventOptions = [clickEvent] as const; +const LinksEventOptions = [clickEvent, doubleClickEvent] as const; // Update OptionItem to include event handlers const OptionItem = new MultiCompBuilder( @@ -76,11 +76,15 @@ const MenuItem = React.memo(({ option, index }: { option: any; index: number }) if (option.onClick) { option.onClick(); } + if (option.onDoubleClick) { + option.onDoubleClick(); + } if (option.onEvent) { option.onEvent("click"); } + } - }, [option.disabled, option.onClick, option.onEvent]); + }, [option.disabled, option.onClick, option.onEvent, option.onDoubleClick]); return ( diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx index 6162abea76..a751b033ab 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx @@ -11,7 +11,7 @@ import { trans } from "i18n"; import { ColumnTypeCompBuilder, ColumnTypeViewFn } from "../columnTypeCompBuilder"; import { ColumnValueTooltip } from "../simpleColumnTypeComps"; import { styled } from "styled-components"; -import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl"; +import { clickEvent, eventHandlerControl, doubleClickEvent } from "comps/controls/eventHandlerControl"; const Wrapper = styled.div` display: inline-flex; @@ -79,7 +79,7 @@ const Wrapper = styled.div` } `; -const SelectOptionEventOptions = [clickEvent] as const; +const SelectOptionEventOptions = [clickEvent, doubleClickEvent] as const; // Create a new option type with event handlers for each option const SelectOptionWithEvents = new MultiCompBuilder( @@ -144,11 +144,14 @@ const SelectEdit = React.memo((props: SelectEditProps) => { if (!mountedRef.current) return; props.onChange(val); setCurrentValue(val); - // Trigger the specific option's event handler const selectedOption = props.options.find(option => option.value === val); - if (selectedOption && selectedOption.onEvent) { - selectedOption.onEvent("click"); + if (selectedOption?.onEvent) { + if (selectedOption.onEvent.isBind("click")) { + selectedOption.onEvent("click"); + } else if (selectedOption.onEvent.isBind("doubleClick")) { + selectedOption.onEvent("doubleClick"); + } } }, [props.onChange, props.options]); diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/simpleColumnTypeComps.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/simpleColumnTypeComps.tsx index ba264c5e4f..0df62e2f0b 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/simpleColumnTypeComps.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/simpleColumnTypeComps.tsx @@ -13,7 +13,7 @@ import React, { useCallback, useEffect, useMemo } from "react"; import { CSSProperties } from "react"; import { RecordConstructorToComp } from "lowcoder-core"; import { ToViewReturn } from "@lowcoder-ee/comps/generators/multi"; -import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl"; +import { clickEvent, eventHandlerControl, doubleClickEvent } from "comps/controls/eventHandlerControl"; export const ColumnValueTooltip = trans("table.columnValueTooltip"); @@ -32,7 +32,7 @@ export const ButtonTypeOptions = [ }, ] as const; -const ButtonEventOptions = [clickEvent] as const; +const ButtonEventOptions = [clickEvent, doubleClickEvent] as const; const childrenMap = { text: StringControl, @@ -55,6 +55,10 @@ const ButtonStyled = React.memo(({ props }: { props: ToViewReturn { + props.onEvent("doubleClick"); + }, [props.onEvent]); + const buttonStyle = useMemo(() => ({ margin: 0, width: iconOnly ? 'auto' : undefined, @@ -71,6 +75,7 @@ const ButtonStyled = React.memo(({ props }: { props: ToViewReturn {/* prevent the button from disappearing */} {hasText ? props.text : (iconOnly ? null : " ")} diff --git a/client/packages/lowcoder/src/comps/comps/textComp.tsx b/client/packages/lowcoder/src/comps/comps/textComp.tsx index 93b3d79ae0..73f776ac37 100644 --- a/client/packages/lowcoder/src/comps/comps/textComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/textComp.tsx @@ -20,13 +20,13 @@ import { PaddingControl } from "../controls/paddingControl"; import React, { useContext, useEffect, useRef, useMemo } from "react"; import { EditorContext } from "comps/editorState"; -import { clickEvent, eventHandlerControl } from "../controls/eventHandlerControl"; +import { clickEvent, doubleClickEvent, eventHandlerControl } from "../controls/eventHandlerControl"; import { NewChildren } from "../generators/uiCompBuilder"; import { RecordConstructorToComp } from "lowcoder-core"; import { ToViewReturn } from "../generators/multi"; import { BoolControl } from "../controls/boolControl"; -const EventOptions = [clickEvent] as const; +const EventOptions = [clickEvent, doubleClickEvent] as const; const getStyle = (style: TextStyleType) => { return css` @@ -227,7 +227,9 @@ const TextView = React.memo((props: ToViewReturn) => { const handleClick = React.useCallback(() => { props.onEvent("click"); }, [props.onEvent]); - + const handleDoubleClick = React.useCallback(() => { + props.onEvent("doubleClick"); + }, [props.onEvent]); const containerStyle = useMemo(() => ({ justifyContent: props.horizontalAlignment, alignItems: props.autoHeight ? "center" : props.verticalAlignment, @@ -247,6 +249,7 @@ const TextView = React.memo((props: ToViewReturn) => { $styleConfig={props.style} style={containerStyle} onClick={handleClick} + onDoubleClick={handleDoubleClick} > {content} diff --git a/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx b/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx index db45ba023b..e7743f0f8e 100644 --- a/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx @@ -30,6 +30,7 @@ import { import { clickEvent, eventHandlerControl, + doubleClickEvent, } from "comps/controls/eventHandlerControl"; import { TimeLineStyle, @@ -69,6 +70,7 @@ const TimelineWrapper = styled.div<{ const EventOptions = [ clickEvent, + doubleClickEvent, ] as const; const modeOptions = [ @@ -142,6 +144,12 @@ const TimelineComp = ( dispatch(changeChildAction("clickedIndex", index, false)); onEvent("click"); }} + onDoubleClick={(e) => { + e.preventDefault(); + dispatch(changeChildAction("clickedObject", value, false)); + dispatch(changeChildAction("clickedIndex", index, false)); + onEvent("doubleClick"); + }} // for responsiveness style={{ cursor: "pointer", diff --git a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx index d8c26d7ad8..289a212eac 100644 --- a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx @@ -378,7 +378,7 @@ export const doubleClickEvent: EventConfigType = { }; export const rightClickEvent: EventConfigType = { label: trans("event.rightClick"), - value: "doubleClick", + value: "rightClick", description: trans("event.rightClickDesc"), }; @@ -704,6 +704,7 @@ export const InputEventHandlerControl = eventHandlerControl([ export const ButtonEventHandlerControl = eventHandlerControl([ clickEvent, + doubleClickEvent, ] as const); export const ChangeEventHandlerControl = eventHandlerControl([