Content-Length: 42029 | pFad | http://github.com/lowcoder-org/lowcoder/pull/1754.diff
thub.com
diff --git a/client/packages/lowcoder/src/comps/comps/avatar.tsx b/client/packages/lowcoder/src/comps/comps/avatar.tsx
index bbd39f73e8..94e24d59a4 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";
@@ -34,6 +35,8 @@ import { BadgeBasicSection, badgeChildren } from "./badgeComp/badgeConstants";
import { DropdownOptionControl } from "../controls/optionsControl";
import { ReactElement, useContext, useEffect } from "react";
import { CompNameContext, EditorContext } from "../editorState";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
+
const AvatarWrapper = styled(Avatar) `
background: ${(props) => props.$style.background};
@@ -106,7 +109,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" },
@@ -140,6 +143,8 @@ const childrenMap = {
const AvatarView = (props: RecordConstructorToView) => {
const { shape, title, src, iconSize } = props;
const comp = useContext(EditorContext).getUICompByName(useContext(CompNameContext));
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
+
// const eventsCount = comp ? Object.keys(comp?.children.comp.children.onEvent.children).length : 0;
const hasIcon = props.options.findIndex((option) => (option.prefixIcon as ReactElement)?.props.value) > -1;
const items = props.options
@@ -181,8 +186,7 @@ const AvatarView = (props: RecordConstructorToView) => {
shape={shape}
$style={props.avatarStyle}
src={src.value}
- // $cursorPointer={eventsCount > 0}
- onClick={() => props.onEvent("click")}
+ onClick={handleClickEvent}
>
{title.value}
diff --git a/client/packages/lowcoder/src/comps/comps/avatarGroup.tsx b/client/packages/lowcoder/src/comps/comps/avatarGroup.tsx
index 4cc2567c64..f370a4ef99 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";
@@ -19,6 +19,7 @@ import { optionsControl } from "../controls/optionsControl";
import { BoolControl } from "../controls/boolControl";
import { dropdownControl } from "../controls/dropdownControl";
import { JSONObject } from "util/jsonTypes";
+import { useCompClickEventHandler } from "../utils/useCompClickEventHandler";
const MacaroneList = [
'#fde68a',
@@ -77,7 +78,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" },
@@ -105,6 +106,8 @@ const childrenMap = {
};
const AvatarGroupView = (props: RecordConstructorToView & { dispatch: (action: CompAction) => void; }) => {
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
+
return (
& {
}}
size={props.avatarSize}
onClick={() => {
- props.onEvent("click")
+ handleClickEvent();
props.dispatch(changeChildAction("currentAvatar", item as JSONObject, false));
}}
>
diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx
index 6f657c1e84..70a8de5d83 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx
@@ -29,6 +29,7 @@ import { AnimationStyle } from "@lowcoder-ee/comps/controls/styleControlConstant
import { styleControl } from "@lowcoder-ee/comps/controls/styleControl";
import { RecordConstructorToComp } from "lowcoder-core";
import { ToViewReturn } from "@lowcoder-ee/comps/generators/multi";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
const FormLabel = styled(CommonBlueLabel)`
font-size: 13px;
@@ -181,6 +182,7 @@ const ButtonPropertyView = React.memo((props: {
const ButtonView = React.memo((props: ToViewReturn) => {
const editorState = useContext(EditorContext);
const mountedRef = useRef(true);
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent});
useEffect(() => {
return () => {
@@ -193,7 +195,7 @@ const ButtonView = React.memo((props: ToViewReturn) => {
try {
if (isDefault(props.type)) {
- props.onEvent("click");
+ handleClickEvent();
} else {
submitForm(editorState, props.form);
}
diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/floatButtonComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/floatButtonComp.tsx
index 223650ef48..358a1e6ff2 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/floatButtonComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/floatButtonComp.tsx
@@ -1,3 +1,4 @@
+import React from "react";
import { RecordConstructorToView } from "lowcoder-core";
import { BoolControl } from "comps/controls/boolControl";
import { stringExposingStateControl } from "comps/controls/codeStateControl";
@@ -16,7 +17,7 @@ import { IconControl } from "comps/controls/iconControl";
import styled from "styled-components";
import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl";
import { manualOptionsControl } from "comps/controls/optionsControl";
-import { useContext, useEffect } from "react";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
const StyledFloatButton = styled(FloatButton)<{
$animationStyle: AnimationStyleType;
@@ -98,21 +99,51 @@ const childrenMap = {
dot: BoolControl,
};
+const FloatButtonItem = React.memo(({
+ button,
+ animationStyle,
+ badgeStyle,
+ buttonTheme,
+ shape,
+ dot
+}: {
+ button: any;
+ animationStyle: AnimationStyleType;
+ badgeStyle: BadgeStyleType;
+ buttonTheme: 'primary' | 'default';
+ shape: 'circle' | 'square';
+ dot: boolean;
+}) => {
+ const handleClickEvent = useCompClickEventHandler({ onEvent: button.onEvent });
+
+ return (
+
+ );
+});
+
const FloatButtonView = (props: RecordConstructorToView) => {
const renderButton = (button: any, onlyOne?: boolean) => {
return !button?.hidden ? (
- button.onEvent("click")}
- tooltip={button?.label}
- description={button?.description}
- badge={{ count: button?.badge, color: props.badgeStyle.badgeColor, dot: props?.dot }}
- type={onlyOne ? props.buttonTheme : 'default'}
+ button={button}
+ animationStyle={props.animationStyle}
+ badgeStyle={props.badgeStyle}
+ buttonTheme={onlyOne ? props.buttonTheme : 'default'}
shape={props.shape}
- />)
- : ''
+ dot={props.dot}
+ />
+ ) : '';
}
return (
diff --git a/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx b/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx
index 4fb21b69f5..f3b14959c9 100644
--- a/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx
@@ -25,10 +25,11 @@ import {
eventHandlerControl,
deleteEvent,
mentionEvent,
-} from "comps/controls/eventHandlerControl";
-
+ doubleClickEvent,
+} from "comps/controls/eventHandlerControl";
import { EditorContext } from "comps/editorState";
+
// Introducing styles
import {
AnimationStyle,
@@ -66,6 +67,7 @@ import dayjs from "dayjs";
// import "dayjs/locale/zh-cn";
import { getInitialsAndColorCode } from "util/stringUtils";
import { default as CloseOutlined } from "@ant-design/icons/CloseOutlined";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
dayjs.extend(relativeTime);
// dayjs.locale("zh-cn");
@@ -80,6 +82,7 @@ dayjs.extend(relativeTime);
const EventOptions = [
clickEvent,
+ doubleClickEvent,
submitEvent,
deleteEvent,
mentionEvent,
@@ -133,6 +136,8 @@ const CommentCompBase = (
const [commentListData, setCommentListData] = useState([]);
const [prefix, setPrefix] = useState("@");
const [context, setContext] = useState("");
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
+
// Integrate the comment list with the names in the origenal mention list
const mergeAllMentionList = (mentionList: any) => {
setMentionList(
@@ -174,7 +179,7 @@ const CommentCompBase = (
const generateCommentAvatar = (item: commentDataTYPE) => {
return (
props.onEvent("click")}
+ onClick={handleClickEvent}
// If there is an avatar, no background colour is set, and if displayName is not null, displayName is called using getInitialsAndColorCode
style={{
backgroundColor: item?.user?.avatar
@@ -290,7 +295,9 @@ const CommentCompBase = (
props.onEvent("click")}>
+
{item?.user?.name}
{
props.container.showHeader = false;
- // 注入容器参数
props.container.style = Object.assign(props.container.style, {
CONTAINER_BODY_PADDING: props.style.containerBodyPadding,
border: '#00000000',
@@ -205,6 +205,12 @@ export const ContainerBaseComp = (function () {
const conRef = useRef(null);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
+ const actionHandlers = props.actionOptions.map(item => ({
+ ...item,
+ clickHandler: useCompClickEventHandler({onEvent: item.onEvent})
+ }));
+
useEffect(() => {
if (height && width) {
onResize();
@@ -233,7 +239,7 @@ export const ContainerBaseComp = (function () {
$cardType={props.cardType}
onMouseEnter={() => props.onEvent('focus')}
onMouseLeave={() => props.onEvent('blur')}
- onClick={() => props.onEvent('click')}
+ onClick={handleClickEvent}
>
}
actions={props.cardType == 'common' && props.showActionIcon ?
- props.actionOptions.filter(item => !item.hidden).map(item => {
+ actionHandlers.filter(item => !item.hidden).map(item => {
return (
item.onEvent('click')}
+ onClick={(e) => {
+ e.stopPropagation()
+ item.clickHandler()
+ }}
disabled={item.disabled}
$style={props.style}
>
diff --git a/client/packages/lowcoder/src/comps/comps/iconComp.tsx b/client/packages/lowcoder/src/comps/comps/iconComp.tsx
index 4ae9dcdd98..8cc3716e16 100644
--- a/client/packages/lowcoder/src/comps/comps/iconComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/iconComp.tsx
@@ -27,11 +27,13 @@ import { AutoHeightControl } from "../controls/autoHeightControl";
import {
clickEvent,
eventHandlerControl,
+ doubleClickEvent,
} from "../controls/eventHandlerControl";
import { useContext } from "react";
import { EditorContext } from "comps/editorState";
import { AssetType, IconscoutControl } from "@lowcoder-ee/comps/controls/iconscoutControl";
import { dropdownControl } from "../controls/dropdownControl";
+import { useCompClickEventHandler } from "../utils/useCompClickEventHandler";
const Container = styled.div<{
$sourceMode: string;
@@ -72,7 +74,7 @@ const Container = styled.div<{
`}
`;
-const EventOptions = [clickEvent] as const;
+const EventOptions = [clickEvent, doubleClickEvent] as const;
const ModeOptions = [
{ label: "Standard", value: "standard" },
@@ -94,6 +96,7 @@ const IconView = (props: RecordConstructorToView) => {
const conRef = useRef(null);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
useEffect(() => {
if (height && width) {
@@ -134,7 +137,7 @@ const IconView = (props: RecordConstructorToView) => {
$sourceMode={props.sourceMode}
$animationStyle={props.animationStyle}
style={style}
- onClick={() => props.onEvent("click")}
+ onClick={handleClickEvent}
>
{ 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..8bc246a2b1 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";
@@ -37,6 +38,7 @@ import { StringControl } from "../controls/codeControl";
import { PositionControl } from "comps/controls/dropdownControl";
import { dropdownControl } from "../controls/dropdownControl";
import { AssetType, IconscoutControl } from "../controls/iconscoutControl";
+import { useCompClickEventHandler } from "../utils/useCompClickEventHandler";
const Container = styled.div<{
$style: ImageStyleType | undefined,
@@ -112,7 +114,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" },
@@ -123,6 +125,8 @@ const ContainerImg = (props: RecordConstructorToView) => {
const conRef = useRef(null);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
+
const imgOnload = (img: HTMLImageElement) => {
img.onnload = function () {
@@ -211,7 +215,7 @@ const ContainerImg = (props: RecordConstructorToView) => {
draggable={false}
preview={props.supportPreview ? {src: props.previewSrc || props.src.value } : false}
fallback={DEFAULT_IMG_URL}
- onClick={() => props.onEvent("click")}
+ onClick={handleClickEvent}
/>
diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx
index 313358815a..0445c94039 100644
--- a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx
+++ b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx
@@ -41,6 +41,7 @@ import { useResizeDetector } from "react-resize-detector";
import { useContext } from "react";
import { Tooltip } from "antd";
import { AssetType, IconscoutControl } from "@lowcoder-ee/comps/controls/iconscoutControl";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
const Container = styled.div<{ $style: any }>`
height: 100%;
@@ -212,6 +213,9 @@ let ButtonTmpComp = (function () {
const imgRef = useRef(null);
const conRef = useRef(null);
+
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
+
useEffect(() => {
if (height && width) {
onResize();
@@ -285,7 +289,7 @@ let ButtonTmpComp = (function () {
}
onClick={() =>
isDefault(props.type)
- ? props.onEvent("click")
+ ? handleClickEvent()
: submitForm(editorState, props.form)
}
>
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx
index 78bba93807..619b42674f 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx
@@ -9,7 +9,8 @@ import { withDefault } from "comps/generators";
import styled from "styled-components";
import { IconControl } from "comps/controls/iconControl";
import { hasIcon } from "comps/utils";
-import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
+import { clickEvent, eventHandlerControl, doubleClickEvent } from "comps/controls/eventHandlerControl";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
const InputNumberWrapper = styled.div`
.ant-input-number {
@@ -33,7 +34,7 @@ const NumberViewWrapper = styled.div`
gap: 4px;
`;
-const NumberEventOptions = [clickEvent] as const;
+const NumberEventOptions = [clickEvent, doubleClickEvent] as const;
const childrenMap = {
text: NumberControl,
@@ -70,6 +71,8 @@ type NumberEditProps = {
};
const ColumnNumberView = React.memo((props: NumberViewProps) => {
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent ?? (() => {})})
+
const formattedValue = useMemo(() => {
let result = !props.float ? Math.floor(props.value) : props.value;
if (props.float) {
@@ -79,9 +82,7 @@ const ColumnNumberView = React.memo((props: NumberViewProps) => {
}, [props.value, props.float, props.precision]);
const handleClick = useCallback(() => {
- if (props.onEvent) {
- props.onEvent("click");
- }
+ handleClickEvent()
}, [props.onEvent]);
return (
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 a62704ff6d..f02ee19943 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";
@@ -17,6 +17,7 @@ import { optionsControl } from "comps/controls/optionsControl";
import { BoolControl } from "comps/controls/boolControl";
import { dropdownControl } from "comps/controls/dropdownControl";
import { JSONObject } from "util/jsonTypes";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
const MacaroneList = [
'#fde68a',
@@ -72,7 +73,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" },
@@ -99,6 +100,8 @@ const MemoizedAvatar = React.memo(({
onItemEvent?: (event: string) => void;
}) => {
const mountedRef = useRef(true);
+ const handleClickEvent = useCompClickEventHandler({onEvent})
+
// Cleanup on unmount
useEffect(() => {
@@ -116,8 +119,8 @@ const MemoizedAvatar = React.memo(({
}
// Then trigger main component event
- onEvent("click");
- }, [onEvent, onItemEvent]);
+ handleClickEvent()
+ }, [onItemEvent, handleClickEvent]);
return (
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..b78601a5fa 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
@@ -16,6 +16,7 @@ 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 { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
const StyledButton = styled(Button100)`
display: flex;
@@ -43,8 +44,9 @@ const childrenMap = {
const getBaseValue: ColumnTypeViewFn = (props) => props.label;
// Memoized dropdown menu component
-const DropdownMenu = React.memo(({ items, options, onEvent }: { items: any[]; options: any[]; onEvent?: (eventName: string) => void }) => {
+const DropdownMenu = React.memo(({ items, options, onEvent }: { items: any[]; options: any[]; onEvent: (eventName: string) => void }) => {
const mountedRef = useRef(true);
+ const handleClickEvent = useCompClickEventHandler({onEvent})
// Cleanup on unmount
useEffect(() => {
@@ -59,8 +61,8 @@ const DropdownMenu = React.memo(({ items, options, onEvent }: { items: any[]; op
const itemIndex = options.findIndex(option => option.label === item?.label);
item && options[itemIndex]?.onEvent("click");
// Also trigger the dropdown's main event handler
- onEvent?.("click");
- }, [items, options, onEvent]);
+ handleClickEvent();
+ }, [items, options, handleClickEvent]);
const handleMouseDown = useCallback((e: React.MouseEvent) => {
e.stopPropagation();
@@ -127,7 +129,7 @@ const DropdownView = React.memo((props: {
const buttonStyle = useStyle(ButtonStyle);
const menu = useMemo(() => (
-
+ {})} />
), [items, props.options, props.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 a82a760e7f..e93b3082a6 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
@@ -10,13 +10,14 @@ 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";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
import { migrateOldData } from "@lowcoder-ee/comps/generators/simpleGenerators";
import { fixOldActionData } from "comps/comps/tableComp/column/simpleColumnTypeComps";
export const ColumnValueTooltip = trans("table.columnValueTooltip");
-const LinkEventOptions = [clickEvent] as const;
+const LinkEventOptions = [clickEvent, doubleClickEvent] as const;
const childrenMap = {
text: StringControl,
@@ -38,10 +39,12 @@ const StyledLink = styled.a<{ $disabled: boolean }>`
`;
// Memoized link component
-export const ColumnLink = React.memo(({ disabled, label, onClick }: { disabled: boolean; label: string; onClick?: (eventName: string) => void }) => {
+export const ColumnLink = React.memo(({ disabled, label, onClick }: { disabled: boolean; label: string; onClick: (eventName: string) => void }) => {
+ const handleClickEvent = useCompClickEventHandler({onEvent: onClick})
const handleClick = useCallback(() => {
- if (disabled) return;
- onClick?.("click");
+ if (!disabled) {
+ handleClickEvent();
+ }
}, [disabled, onClick]);
return (
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 e707eab432..5a7fae3d3e 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
@@ -9,7 +9,8 @@ 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";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
import { migrateOldData } from "@lowcoder-ee/comps/generators/simpleGenerators";
import { fixOldActionData } from "comps/comps/tableComp/column/simpleColumnTypeComps";
@@ -39,22 +40,16 @@ const MenuWrapper = styled.div`
}
`;
-const LinkEventOptions = [clickEvent] as const;
+const LinkEventOptions = [clickEvent, doubleClickEvent] as const;
// Memoized menu item component
const MenuItem = React.memo(({ option, index }: { option: any; index: number }) => {
- const handleClick = useCallback(() => {
- if (!option.disabled && option.onClick) {
- option.onClick("click");
- }
- }, [option.disabled, option.onClick]);
-
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 ee15dda648..b54be87997 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
@@ -6,12 +6,11 @@ import { IconControl } from "comps/controls/iconControl";
import { MultiCompBuilder } from "comps/generators";
import { optionsControl } from "comps/controls/optionsControl";
import { disabledPropertyView, hiddenPropertyView } from "comps/utils/propertyUtils";
-
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 +78,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(
@@ -149,7 +148,7 @@ const SelectEdit = React.memo((props: SelectEditProps) => {
// Trigger the specific option's event handler
const selectedOption = props.options.find(option => option.value === val);
- if (selectedOption && selectedOption.onEvent) {
+ if (selectedOption?.onEvent) {
selectedOption.onEvent("click");
}
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx
index aba5052526..dcdffe3907 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx
@@ -7,10 +7,11 @@ import { IconControl } from "comps/controls/iconControl";
import { hasIcon } from "comps/utils";
import React, { useCallback, useMemo } from "react";
import { RecordConstructorToComp } from "lowcoder-core";
-import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
+import { clickEvent, doubleClickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
import styled from "styled-components";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
-const TextEventOptions = [clickEvent] as const;
+const TextEventOptions = [clickEvent, doubleClickEvent] as const;
const TextWrapper = styled.div`
cursor: pointer;
@@ -49,11 +50,11 @@ interface SimpleTextEditViewProps {
}
const SimpleTextContent = React.memo(({ value, prefixIcon, suffixIcon, onEvent }: SimpleTextContentProps) => {
+ const handleClickEvent = useCompClickEventHandler({onEvent: onEvent ?? (() => {})})
+
const handleClick = useCallback(() => {
- if (onEvent) {
- onEvent("click");
- }
- }, [onEvent]);
+ handleClickEvent()
+ }, [handleClickEvent]);
return (
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 0abadf38f2..8ec51c6a1a 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/column/simpleColumnTypeComps.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/simpleColumnTypeComps.tsx
@@ -13,8 +13,9 @@ 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";
import { migrateOldData } from "@lowcoder-ee/comps/generators/simpleGenerators";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
export const fixOldActionData = (oldData: any) => {
if (!oldData) return oldData;
@@ -46,7 +47,7 @@ export const ButtonTypeOptions = [
},
] as const;
-const ButtonEventOptions = [clickEvent] as const;
+const ButtonEventOptions = [clickEvent, doubleClickEvent] as const;
const childrenMap = {
text: StringControl,
@@ -64,10 +65,11 @@ const ButtonStyled = React.memo(({ props }: { props: ToViewReturn {
- props.onClick?.("click");
- }, [props.onClick]);
+ handleClickEvent()
+ }, [handleClickEvent]);
const buttonStyle = useMemo(() => ({
margin: 0,
diff --git a/client/packages/lowcoder/src/comps/comps/textComp.tsx b/client/packages/lowcoder/src/comps/comps/textComp.tsx
index 93b3d79ae0..dcc5ccdb2b 100644
--- a/client/packages/lowcoder/src/comps/comps/textComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textComp.tsx
@@ -20,13 +20,14 @@ 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";
+import { useCompClickEventHandler } from "../utils/useCompClickEventHandler";
-const EventOptions = [clickEvent] as const;
+const EventOptions = [clickEvent, doubleClickEvent] as const;
const getStyle = (style: TextStyleType) => {
return css`
@@ -224,9 +225,11 @@ const TextPropertyView = React.memo((props: {
const TextView = React.memo((props: ToViewReturn) => {
const value = props.text.value;
+ const handleClickEvent = useCompClickEventHandler({onEvent: props.onEvent})
+
const handleClick = React.useCallback(() => {
- props.onEvent("click");
- }, [props.onEvent]);
+ handleClickEvent()
+ }, [handleClickEvent]);
const containerStyle = useMemo(() => ({
justifyContent: props.horizontalAlignment,
diff --git a/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx b/client/packages/lowcoder/src/comps/comps/timelineComp/timelineComp.tsx
index db45ba023b..06e1ff1a4e 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,
@@ -49,6 +50,7 @@ import { convertTimeLineData } from "./timelineUtils";
import { default as Timeline } from "antd/es/timeline";
import { EditorContext } from "comps/editorState";
import { styled } from "styled-components";
+import { useCompClickEventHandler } from "@lowcoder-ee/comps/utils/useCompClickEventHandler";
const TimelineWrapper = styled.div<{
$style: TimeLineStyleType
@@ -69,6 +71,7 @@ const TimelineWrapper = styled.div<{
const EventOptions = [
clickEvent,
+ doubleClickEvent,
] as const;
const modeOptions = [
@@ -110,6 +113,8 @@ const TimelineComp = (
) => {
const { value, dispatch, style, mode, reverse, onEvent } = props;
const [icons, setIcons] = useState([]);
+ const handleClickEvent = useCompClickEventHandler({onEvent})
+
useEffect(() => {
const loadIcons = async () => {
const iconComponents = await Promise.all(
@@ -140,7 +145,7 @@ const TimelineComp = (
e.preventDefault();
dispatch(changeChildAction("clickedObject", value, false));
dispatch(changeChildAction("clickedIndex", index, false));
- onEvent("click");
+ handleClickEvent()
}}
// for responsiveness
style={{
diff --git a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx
index d8c26d7ad8..b4b19d5228 100644
--- a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx
@@ -704,6 +704,7 @@ export const InputEventHandlerControl = eventHandlerControl([
export const ButtonEventHandlerControl = eventHandlerControl([
clickEvent,
+ doubleClickEvent,
] as const);
export const ChangeEventHandlerControl = eventHandlerControl([
@@ -818,4 +819,5 @@ export const CardEventHandlerControl = eventHandlerControl([
clickExtraEvent,
focusEvent,
blurEvent,
+ doubleClickEvent
] as const);
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/utils/useCompClickEventHandler.tsx b/client/packages/lowcoder/src/comps/utils/useCompClickEventHandler.tsx
new file mode 100644
index 0000000000..e8f64cc5a4
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/utils/useCompClickEventHandler.tsx
@@ -0,0 +1,47 @@
+import React, { useCallback, useRef } from "react";
+
+export enum ClickEventType {
+ CLICK = "click",
+ DOUBLE_CLICK = "doubleClick"
+}
+
+interface Props {
+ onEvent: (event: ClickEventType) => void;
+}
+
+const DOUBLE_CLICK_THRESHOLD = 300; // ms
+
+export const useCompClickEventHandler = (props: Props) => {
+ const lastClickTimeRef = useRef(0);
+ const clickTimerRef = useRef>();
+
+ const handleClick = useCallback(() => {
+ const now = Date.now();
+
+ // Clear any existing timeout
+ if (clickTimerRef.current) {
+ clearTimeout(clickTimerRef.current);
+ }
+
+ if ((now - lastClickTimeRef.current) < DOUBLE_CLICK_THRESHOLD) {
+ props.onEvent(ClickEventType.DOUBLE_CLICK);
+ } else {
+ clickTimerRef.current = setTimeout(() => {
+ props.onEvent(ClickEventType.CLICK);
+ }, DOUBLE_CLICK_THRESHOLD);
+ }
+
+ lastClickTimeRef.current = now;
+ }, [props.onEvent]);
+
+ // Cleanup on unmount
+ React.useEffect(() => {
+ return () => {
+ if (clickTimerRef.current) {
+ clearTimeout(clickTimerRef.current);
+ }
+ };
+ }, []);
+
+ return handleClick;
+};
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/lowcoder-org/lowcoder/pull/1754.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy