Skip to content

Commit 0ef549c

Browse files
fix datepicker and timepicker
1 parent 94919ef commit 0ef549c

File tree

5 files changed

+148
-95
lines changed

5 files changed

+148
-95
lines changed

client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
} from "comps/utils/propertyUtils";
3838
import { trans } from "i18n";
3939
import { DATE_FORMAT, DATE_TIME_FORMAT, DateParser, PickerMode } from "util/dateTimeUtils";
40-
import React, { ReactNode, useContext, useEffect } from "react";
40+
import React, { ReactNode, useContext, useEffect, useState } from "react";
4141
import { IconControl } from "comps/controls/iconControl";
4242
import { hasIcon } from "comps/utils";
4343
import { Section, sectionNames } from "components/Section";
@@ -164,19 +164,27 @@ export type DateCompViewProps = Pick<
164164
};
165165

166166
export const datePickerControl = new UICompBuilder(childrenMap, (props, dispatch) => {
167-
useMergeCompStyles(props as Record<string, any>, dispatch);
168-
169-
let time = null;
167+
useMergeCompStyles(props as Record<string, any>, dispatch);
168+
169+
let time: dayjs.Dayjs | null = null;
170170
if (props.value.value !== '') {
171171
time = dayjs(props.value.value, DateParser);
172172
}
173+
174+
const [tempValue, setTempValue] = useState<dayjs.Dayjs | null>(time);
175+
176+
useEffect(() => {
177+
const value = props.value.value ? dayjs(props.value.value, DateParser) : null;
178+
setTempValue(value);
179+
}, [props.value.value])
173180

174181
return props.label({
175182
required: props.required,
176183
style: props.style,
177184
labelStyle: props.labelStyle,
178185
inputFieldStyle:props.inputFieldStyle,
179186
animationStyle:props.animationStyle,
187+
onMouseDown: (e) => e.stopPropagation(),
180188
children: (
181189
<DateUIView
182190
viewRef={props.viewRef}
@@ -188,7 +196,7 @@ export const datePickerControl = new UICompBuilder(childrenMap, (props, dispatch
188196
minDate={props.minDate}
189197
maxDate={props.maxDate}
190198
placeholder={props.placeholder}
191-
// value={time?.isValid() ? time : null}
199+
value={tempValue?.isValid() ? tempValue : null}
192200
onChange={(time) => {
193201
handleDateChange(
194202
time && time.isValid()
@@ -289,24 +297,37 @@ export const dateRangeControl = (function () {
289297
return new UICompBuilder(childrenMap, (props, dispatch) => {
290298
useMergeCompStyles(props as Record<string, any>, dispatch);
291299

292-
let start = null;
293-
let end = null;
300+
let start: dayjs.Dayjs | null = null;
294301
if (props.start.value !== '') {
295302
start = dayjs(props.start.value, DateParser);
296303
}
297-
304+
305+
let end: dayjs.Dayjs | null = null;
298306
if (props.end.value !== '') {
299307
end = dayjs(props.end.value, DateParser);
300308
}
301309

310+
const [tempStartValue, setTempStartValue] = useState<dayjs.Dayjs | null>(start);
311+
const [tempEndValue, setTempEndValue] = useState<dayjs.Dayjs | null>(end);
312+
313+
useEffect(() => {
314+
const value = props.start.value ? dayjs(props.start.value, DateParser) : null;
315+
setTempStartValue(value);
316+
}, [props.start.value])
317+
318+
useEffect(() => {
319+
const value = props.end.value ? dayjs(props.end.value, DateParser) : null;
320+
setTempEndValue(value);
321+
}, [props.end.value])
322+
302323
const children = (
303324
<DateRangeUIView
304325
viewRef={props.viewRef}
305326
$style={props.inputFieldStyle}
306327
disabled={props.disabled}
307328
{...datePickerProps(props)}
308-
start={start?.isValid() ? start : null}
309-
end={end?.isValid() ? end : null}
329+
start={tempStartValue?.isValid() ? tempStartValue : null}
330+
end={tempEndValue?.isValid() ? tempEndValue : null}
310331
minDate={props.minDate}
311332
maxDate={props.maxDate}
312333
placeholder={[props.placeholder, props.placeholder]}
@@ -341,6 +362,7 @@ export const dateRangeControl = (function () {
341362
labelStyle:props.labelStyle,
342363
children: children,
343364
inputFieldStyle:props.inputFieldStyle,
365+
onMouseDown: (e) => e.stopPropagation(),
344366
...(startResult.validateStatus !== "success"
345367
? startResult
346368
: endResult.validateStatus !== "success"

client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ const DatePickerStyled = styled(DatePicker<Dayjs>)<{ $style: DateTimeStyleType }
1818
${(props) => props.$style && getStyle(props.$style)}
1919
`;
2020

21+
2122
export interface DataUIViewProps extends DateCompViewProps {
22-
value?: dayjs.Dayjs | null;
23-
defaultValue?: dayjs.Dayjs | null;
24-
// onChange: (value: dayjs.Dayjs | null) => void;
23+
value?: DatePickerProps<Dayjs>['value'];
2524
onChange: DatePickerProps<Dayjs>['onChange'];
2625
onPanelChange: () => void;
2726
}

client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import {
4040
} from "comps/utils/propertyUtils";
4141
import { trans } from "i18n";
4242
import { TIME_FORMAT, TimeParser } from "util/dateTimeUtils";
43-
import React, { ReactNode, useContext, useEffect } from "react";
43+
import React, { ReactNode, useContext, useEffect, useState } from "react";
4444
import { IconControl } from "comps/controls/iconControl";
4545
import { hasIcon } from "comps/utils";
4646
import { Section, sectionNames } from "components/Section";
@@ -146,23 +146,31 @@ export type TimeCompViewProps = Pick<
146146
export const timePickerControl = new UICompBuilder(childrenMap, (props, dispatch) => {
147147
useMergeCompStyles(props as Record<string, any>, dispatch);
148148

149-
let time = null;
149+
let time: dayjs.Dayjs | null = null;
150150
if(props.value.value !== '') {
151151
time = dayjs(props.value.value, TimeParser);
152152
}
153+
154+
const [tempValue, setTempValue] = useState<dayjs.Dayjs | null>(time);
155+
156+
useEffect(() => {
157+
const value = props.value.value ? dayjs(props.value.value, TimeParser) : null;
158+
setTempValue(value);
159+
}, [props.value.value])
153160

154161
return props.label({
155162
required: props.required,
156163
style: props.style,
157164
labelStyle: props.labelStyle,
158165
inputFieldStyle:props.inputFieldStyle,
159166
animationStyle:props.animationStyle,
167+
onMouseDown: (e) => e.stopPropagation(),
160168
children: (
161169
<TimeUIView
162170
viewRef={props.viewRef}
163171
$style={props.inputFieldStyle}
164172
disabled={props.disabled}
165-
value={time?.isValid() ? time : null}
173+
value={tempValue?.isValid() ? tempValue : null}
166174
disabledTime={() => disabledTime(props.minTime, props.maxTime)}
167175
{...timePickerComps(props)}
168176
hourStep={props.hourStep as hourStepType}
@@ -258,22 +266,35 @@ export const timeRangeControl = (function () {
258266
return new UICompBuilder(childrenMap, (props, dispatch) => {
259267
useMergeCompStyles(props as Record<string, any>, dispatch);
260268

261-
let start = null;
269+
let start: dayjs.Dayjs | null = null;
262270
if(props.start.value !== '') {
263271
start = dayjs(props.start.value, TimeParser);
264272
}
265-
let end = null;
273+
let end: dayjs.Dayjs | null = null;
266274
if(props.end.value !== '') {
267275
end = dayjs(props.end.value, TimeParser);
268276
}
269277

278+
const [tempStartValue, setTempStartValue] = useState<dayjs.Dayjs | null>(start);
279+
const [tempEndValue, setTempEndValue] = useState<dayjs.Dayjs | null>(end);
280+
281+
useEffect(() => {
282+
const value = props.start.value ? dayjs(props.start.value, TimeParser) : null;
283+
setTempStartValue(value);
284+
}, [props.start.value])
285+
286+
useEffect(() => {
287+
const value = props.end.value ? dayjs(props.end.value, TimeParser) : null;
288+
setTempEndValue(value);
289+
}, [props.end.value])
290+
270291
const children = (
271292
<TimeRangeUIView
272293
viewRef={props.viewRef}
273294
$style={props.inputFieldStyle}
274295
disabled={props.disabled}
275-
start={start?.isValid() ? start : null}
276-
end={end?.isValid() ? end : null}
296+
start={tempStartValue?.isValid() ? tempStartValue : null}
297+
end={tempEndValue?.isValid() ? tempEndValue : null}
277298
disabledTime={() => disabledTime(props.minTime, props.maxTime)}
278299
{...timePickerComps(props)}
279300
hourStep={props.hourStep as hourStepType}
@@ -301,6 +322,7 @@ export const timeRangeControl = (function () {
301322
inputFieldStyle:props.inputFieldStyle,
302323
animationStyle:props.animationStyle,
303324
children: children,
325+
onMouseDown: (e) => e.stopPropagation(),
304326
...(startResult.validateStatus !== "success"
305327
? startResult
306328
: endResult.validateStatus !== "success"

client/packages/lowcoder/src/comps/controls/labelControl.tsx

Lines changed: 83 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type LabelViewProps = Pick<FormItemProps, "required" | "help" | "validateStatus"
2525
inputFieldStyle?: Record<string, string>;
2626
childrenInputFieldStyle?: Record<string, string>;
2727
animationStyle?: Record<string, string>;
28+
onMouseDown?: React.MouseEventHandler<HTMLDivElement>;
2829
};
2930

3031
const StyledStarIcon = styled(StarIcon)`
@@ -177,86 +178,94 @@ export const LabelControl = (function () {
177178

178179
return new MultiCompBuilder(childrenMap, (props) => (args: LabelViewProps) =>
179180
{
180-
return <LabelViewWrapper $style={args.style} $inputFieldStyle={args.inputFieldStyle} $animationStyle={args.animationStyle}>
181-
<MainWrapper
182-
$position={props.position}
183-
$hasLabel={!!props.text}
184-
style={{
185-
margin: args && args.inputFieldStyle ? args?.inputFieldStyle?.margin : 0,
186-
// padding: args && args.inputFieldStyle ? args?.inputFieldStyle?.padding : 0,
187-
width: widthCalculator(
188-
args && args.inputFieldStyle ? args?.inputFieldStyle?.margin : "0px"
189-
),
190-
height: heightCalculator(
191-
args && args.inputFieldStyle ? args?.inputFieldStyle?.margin : "0px"
192-
),
193-
}}
181+
return (
182+
<LabelViewWrapper
183+
$style={args.style}
184+
$inputFieldStyle={args.inputFieldStyle}
185+
$animationStyle={args.animationStyle}
186+
onMouseDown={args.onMouseDown}
194187
>
195-
{!props.hidden && !isEmpty(props.text) && (
196-
<LabelWrapper
197-
$align={props.align}
188+
<MainWrapper
189+
$position={props.position}
190+
$hasLabel={!!props.text}
191+
style={{
192+
margin: args && args.inputFieldStyle ? args?.inputFieldStyle?.margin : 0,
193+
// padding: args && args.inputFieldStyle ? args?.inputFieldStyle?.padding : 0,
194+
width: widthCalculator(
195+
args && args.inputFieldStyle ? args?.inputFieldStyle?.margin : "0px"
196+
),
197+
height: heightCalculator(
198+
args && args.inputFieldStyle ? args?.inputFieldStyle?.margin : "0px"
199+
),
200+
}}
201+
>
202+
{!props.hidden && !isEmpty(props.text) && (
203+
<LabelWrapper
204+
$align={props.align}
205+
style={{
206+
width:
207+
props.position === "row" ? getLabelWidth(props.width, props.widthUnit) : "100%",
208+
maxWidth: props.position === "row" ? "70%" : "100%",
209+
fontSize: args && args.style ? args?.style?.textSize : "14px",
210+
rotate:args?.labelStyle?.rotation
211+
}}
212+
$position={props.position}
213+
$hasToolTip={!!props.tooltip}
214+
>
215+
<Tooltip
216+
title={props.tooltip && <TooltipWrapper>{props.tooltip}</TooltipWrapper>}
217+
arrow={{
218+
pointAtCenter: true,
219+
}}
220+
placement="top"
221+
color="#2c2c2c"
222+
getPopupContainer={(node: any) => node.closest(".react-grid-item")}
223+
>
224+
<Label
225+
$border={!!props.tooltip}
226+
$validateStatus={args && args.validateStatus ? args.validateStatus : null}
227+
$labelStyle={{ ...args.labelStyle }}>
228+
{props.text}
229+
</Label>
230+
</Tooltip>
231+
{args.required && <StyledStarIcon />}
232+
</LabelWrapper>
233+
)}
234+
<ChildrenWrapper
198235
style={{
199236
width:
200-
props.position === "row" ? getLabelWidth(props.width, props.widthUnit) : "100%",
201-
maxWidth: props.position === "row" ? "70%" : "100%",
202-
fontSize: args && args.style ? args?.style?.textSize : "14px",
203-
rotate:args?.labelStyle?.rotation
237+
props.position === "row"
238+
? `calc(100% - ${getLabelWidth(props.width, props.widthUnit)} - 8px)`
239+
: "100%",
240+
height: props.position === "column" && !!props.text ? "calc(100% - 22px)" : "100%",
241+
rotate:args?.inputFieldStyle?.rotation,
204242
}}
205-
$position={props.position}
206-
$hasToolTip={!!props.tooltip}
207243
>
208-
<Tooltip
209-
title={props.tooltip && <TooltipWrapper>{props.tooltip}</TooltipWrapper>}
210-
arrow={{
211-
pointAtCenter: true,
212-
}}
213-
placement="top"
214-
color="#2c2c2c"
215-
getPopupContainer={(node: any) => node.closest(".react-grid-item")}
216-
>
217-
<Label
218-
$border={!!props.tooltip}
219-
$validateStatus={args && args.validateStatus ? args.validateStatus : null}
220-
$labelStyle={{ ...args.labelStyle }}>
221-
{props.text}
222-
</Label>
223-
</Tooltip>
224-
{args.required && <StyledStarIcon />}
225-
</LabelWrapper>
226-
)}
227-
<ChildrenWrapper
228-
style={{
229-
width:
230-
props.position === "row"
231-
? `calc(100% - ${getLabelWidth(props.width, props.widthUnit)} - 8px)`
232-
: "100%",
233-
height: props.position === "column" && !!props.text ? "calc(100% - 22px)" : "100%",
234-
rotate:args?.inputFieldStyle?.rotation,
235-
}}
236-
>
237-
{args.children}
238-
</ChildrenWrapper>
239-
</MainWrapper>
244+
{args.children}
245+
</ChildrenWrapper>
246+
</MainWrapper>
240247

241-
{args.help && Boolean((args.children as ReactElement)?.props.value) && (
242-
<HelpWrapper
243-
$marginLeft={
244-
props.position === "column" || isEmpty(props.text) || props.hidden
245-
? "0"
246-
: `calc(min(${getLabelWidth(props.width, props.widthUnit)} , 70%) + 8px)`
247-
}
248-
$color={
249-
args.validateStatus === "error"
250-
? red.primary
251-
: args.validateStatus === "warning"
252-
? yellow.primary
253-
: green.primary
254-
}
255-
>
256-
{args.help}
257-
</HelpWrapper>
258-
)}
259-
</LabelViewWrapper>}
248+
{args.help && Boolean((args.children as ReactElement)?.props.value) && (
249+
<HelpWrapper
250+
$marginLeft={
251+
props.position === "column" || isEmpty(props.text) || props.hidden
252+
? "0"
253+
: `calc(min(${getLabelWidth(props.width, props.widthUnit)} , 70%) + 8px)`
254+
}
255+
$color={
256+
args.validateStatus === "error"
257+
? red.primary
258+
: args.validateStatus === "warning"
259+
? yellow.primary
260+
: green.primary
261+
}
262+
>
263+
{args.help}
264+
</HelpWrapper>
265+
)}
266+
</LabelViewWrapper>
267+
);
268+
}
260269
)
261270
.setPropertyViewFn((children) => (
262271
<Section name={trans("label")}>

client/packages/lowcoder/src/layout/gridItem.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,14 @@ export function GridItem(props: GridItemProps) {
141141
onDrag={onDrag}
142142
onDragEnd={onDragEnd}
143143
onMouseDown={(e) => {
144+
e.stopPropagation();
145+
144146
// allow mouseDown event on lowcoder-comp-kanban to make drag/drop work
145147
if((props.compType as string).includes('lowcoder-comp-kanban')) return;
146148

147149
// allow mouseDown event on lowcoder-comp-excalidraw to make drag/drop work
148150
if((props.compType as string).includes('lowcoder-comp-excalidraw')) return;
149151

150-
e.stopPropagation();
151152
const event = new MouseEvent("mousedown");
152153
document.dispatchEvent(event);
153154
}}

0 commit comments

Comments
 (0)