@trackunit/react-date-and-time-components 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +19 -14
- package/index.esm.js +19 -14
- package/package.json +2 -2
- package/src/Timeline/Timeline.d.ts +1 -0
- package/src/Timeline/TimelineElement.d.ts +3 -2
package/index.cjs.js
CHANGED
|
@@ -388,9 +388,18 @@ const Timeline = ({ className, dataTestId, children, dateHeader, customHeader, t
|
|
|
388
388
|
const childProps = React.isValidElement(firstChild) ? firstChild.props : {};
|
|
389
389
|
const lastChild = remainingChildren.pop();
|
|
390
390
|
const middleChildren = remainingChildren;
|
|
391
|
+
React.useEffect(() => {
|
|
392
|
+
// Set maxHeight dynamically for smooth animation
|
|
393
|
+
if (ref.current) {
|
|
394
|
+
ref.current.style.maxHeight = isOpen ? `${ref.current.scrollHeight}px` : "0px";
|
|
395
|
+
}
|
|
396
|
+
}, [isOpen]);
|
|
391
397
|
const renderToggleButton = () => (jsxRuntime.jsxs("div", { className: cvaTimelineElement(), children: [childProps?.date ? (jsxRuntime.jsx("div", { className: cvaTimelineElementTime({
|
|
392
398
|
width: hourCycle === "h12" || hourCycle === "h11" ? "large" : "small",
|
|
393
|
-
}) })) : null, jsxRuntime.jsx("div", { className: cvaDotWrapper(), children: jsxRuntime.jsx("div", { className: cvaLine({ lineStyle: childProps?.lineStyle }) }) }), jsxRuntime.jsxs("div", { className: "
|
|
399
|
+
}) })) : null, jsxRuntime.jsx("div", { className: cvaDotWrapper(), children: jsxRuntime.jsx("div", { className: cvaLine({ lineStyle: childProps?.lineStyle }) }) }), jsxRuntime.jsxs("div", { className: "text-secondary-500 hover:text-secondary-600 flex min-h-8 cursor-pointer items-center text-sm", "data-testid": "timeline-toggle-btn", onClick: () => {
|
|
400
|
+
toggleButton?.onClick && toggleButton.onClick();
|
|
401
|
+
setIsOpen(!isOpen);
|
|
402
|
+
}, children: [jsxRuntime.jsx(reactComponents.Icon, { className: cvaToggleBtnIcon({ rotated: isOpen }), name: "ChevronDown", size: "small" }), jsxRuntime.jsx("span", { children: isOpen ? toggleButton?.collapsedLabel : toggleButton?.expandedLabel })] })] }));
|
|
394
403
|
const renderDateHeader = () => {
|
|
395
404
|
if (!dateHeader) {
|
|
396
405
|
return null;
|
|
@@ -401,7 +410,7 @@ const Timeline = ({ className, dataTestId, children, dateHeader, customHeader, t
|
|
|
401
410
|
const { date, dateRange, showTime } = dateHeader;
|
|
402
411
|
return (jsxRuntime.jsx("div", { className: "pb-4", "data-testid": "timeline-date-header", children: date ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactComponents.Text, { size: "medium", type: "span", weight: "thick", children: formatDate(date, { selectFormat: !showTime ? "dateOnly" : undefined }) }), jsxRuntime.jsx(reactComponents.Text, { className: "text-secondary-500", size: "medium", type: "span", weight: "thick", children: ` (${dateAndTimeUtils.timeSinceAuto(date, new Date())})` })] })) : (jsxRuntime.jsx(reactComponents.Text, { className: "pr-1", size: "medium", type: "span", weight: "thick", children: formatRange(dateRange, { dateStyle: !showTime ? "medium" : undefined }) })) }));
|
|
403
412
|
};
|
|
404
|
-
return (jsxRuntime.jsxs("div", { className: className, "data-testid": dataTestId, children: [renderDateHeader(), customHeader ? jsxRuntime.jsx("div", { className: "
|
|
413
|
+
return (jsxRuntime.jsxs("div", { className: className, "data-testid": dataTestId, children: [renderDateHeader(), customHeader ? jsxRuntime.jsx("div", { className: "text-sm font-semibold", children: customHeader }) : null, toggleButton && middleChildren.length > 0 ? (jsxRuntime.jsxs("div", { children: [firstChild, middleChildren.length > 0 ? renderToggleButton() : null, jsxRuntime.jsxs("div", { "aria-hidden": !isOpen, className: "overflow-hidden transition-all duration-300", ref: ref, children: [jsxRuntime.jsx("div", {}), middleChildren, jsxRuntime.jsx("div", {})] }), lastChild] })) : (jsxRuntime.jsx("div", { children: children }))] }));
|
|
405
414
|
};
|
|
406
415
|
|
|
407
416
|
/**
|
|
@@ -415,9 +424,7 @@ const TimelineElement = ({ date, children, className, dataTestId = "timeline-ele
|
|
|
415
424
|
const [isHovered, setIsHovered] = React.useState(false);
|
|
416
425
|
const { formatDate } = reactDateAndTimeHooks.useDateAndTime();
|
|
417
426
|
const locale = reactDateAndTimeHooks.useLocale();
|
|
418
|
-
const formattedDate = date
|
|
419
|
-
? formatDate(date, { selectFormat: "timeOnly", timeFormat: "short" })
|
|
420
|
-
: null;
|
|
427
|
+
const formattedDate = date ? formatDate(date, { selectFormat: "timeOnly", timeFormat: "short" }) : null;
|
|
421
428
|
const handleMouseEnter = () => {
|
|
422
429
|
if (hoverBehavior) {
|
|
423
430
|
setIsHovered(true);
|
|
@@ -428,24 +435,24 @@ const TimelineElement = ({ date, children, className, dataTestId = "timeline-ele
|
|
|
428
435
|
setIsHovered(false);
|
|
429
436
|
}
|
|
430
437
|
};
|
|
431
|
-
return (jsxRuntime.jsxs("div", { className: cvaTimelineElement({ className, selected, hoverBehavior }), "data-date": date, "data-testid": dataTestId, onClick: onClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [renderDate(formattedDate, locale), jsxRuntime.jsxs("div", { className: cvaDotWrapper(), children: [renderDot(customDot, isHovered, selected), jsxRuntime.jsx("div", { className: cvaLine({ lineStyle }) })] }), jsxRuntime.jsxs("div", { className: "
|
|
438
|
+
return (jsxRuntime.jsxs("div", { className: cvaTimelineElement({ className, selected, hoverBehavior }), "data-date": date, "data-testid": dataTestId, onClick: onClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [renderDate(formattedDate, locale), jsxRuntime.jsxs("div", { className: cvaDotWrapper(), children: [renderDot(customDot, isHovered, selected), jsxRuntime.jsx("div", { className: cvaLine({ lineStyle }) })] }), jsxRuntime.jsxs("div", { className: "pb-2 pt-2", children: [renderHeader(header), renderChildren(children), renderActionButton(actionButton)] })] }));
|
|
432
439
|
};
|
|
433
440
|
const renderDate = (formattedDate, locale) => {
|
|
434
441
|
if (!formattedDate) {
|
|
435
442
|
return null;
|
|
436
443
|
}
|
|
437
|
-
return
|
|
444
|
+
return jsxRuntime.jsx("div", { className: "items-center pt-2", children: timelineElementTime(formattedDate, locale) });
|
|
438
445
|
};
|
|
439
446
|
const renderDot = (customDot, isHovered, selected) => {
|
|
440
447
|
return customDot?.name
|
|
441
|
-
? customDotElement(customDot.name, isHovered, selected, customDot.color)
|
|
448
|
+
? customDotElement(customDot.name, isHovered, selected, customDot.color, customDot.keepOnSelection)
|
|
442
449
|
: defaultDot(isHovered, selected);
|
|
443
450
|
};
|
|
444
451
|
const renderHeader = (header) => {
|
|
445
452
|
if (!header) {
|
|
446
453
|
return null;
|
|
447
454
|
}
|
|
448
|
-
return jsxRuntime.jsx("div", { className: "
|
|
455
|
+
return jsxRuntime.jsx("div", { className: "mt-0.5 content-center text-sm font-medium", children: header });
|
|
449
456
|
};
|
|
450
457
|
const renderChildren = (children) => {
|
|
451
458
|
if (!children) {
|
|
@@ -462,15 +469,13 @@ const renderActionButton = (actionButton) => {
|
|
|
462
469
|
const timelineElementTime = (formattedDate, locale) => {
|
|
463
470
|
const hourCycle = dateAndTimeUtils.getHourCycle(locale);
|
|
464
471
|
return (jsxRuntime.jsx(reactComponents.Text, { align: "right", className: cvaTimelineElementTime({
|
|
465
|
-
width: hourCycle === "h12" || hourCycle === "h11" ? "large" : "small"
|
|
472
|
+
width: hourCycle === "h12" || hourCycle === "h11" ? "large" : "small",
|
|
466
473
|
}), size: "small", subtle: true, children: formattedDate }));
|
|
467
474
|
};
|
|
468
475
|
const CircleIcon = ({ selected, hovered }) => (jsxRuntime.jsxs("svg", { className: "relative z-[2]", "data-testid": "timeline-circle-icon", height: "24", viewBox: "0 0 24 24", width: "24", children: [jsxRuntime.jsx("circle", { cx: "12", cy: "12", fill: selected ? "#EFF6FF" : hovered ? "#F9FAFB" : "white", r: "10" }), jsxRuntime.jsx("circle", { cx: "12", cy: "12", fill: "#2563EB", r: "8" }), jsxRuntime.jsx("circle", { cx: "12", cy: "12", fill: "white", r: "3" })] }));
|
|
469
476
|
const DotIcon = () => (jsxRuntime.jsxs("svg", { className: "relative z-[2]", "data-testid": "timeline-dot-icon", height: "24", viewBox: "0 0 24 24", width: "24", children: [jsxRuntime.jsx("circle", { cx: "12", cy: "12", fill: "white", r: "6" }), jsxRuntime.jsx("circle", { cx: "12", cy: "12", fill: "#2563EB", r: "4" })] }));
|
|
470
|
-
const defaultDot = (hovered, selected) =>
|
|
471
|
-
const customDotElement = (name, hovered, selected, color) => (hovered || selected
|
|
472
|
-
? jsxRuntime.jsx(CircleIcon, { hovered: hovered, selected: selected })
|
|
473
|
-
: (jsxRuntime.jsx("div", { className: "w-6 h-6 flex items-center justify-center", children: jsxRuntime.jsx("div", { className: cvaCustomDot(), children: jsxRuntime.jsx(reactComponents.Icon, { className: "block", color: color, dataTestId: "timeline-custom-dot", name: name, size: "small" }) }) })));
|
|
477
|
+
const defaultDot = (hovered, selected) => hovered || selected ? jsxRuntime.jsx(CircleIcon, { hovered: hovered, selected: selected }) : jsxRuntime.jsx(DotIcon, {});
|
|
478
|
+
const customDotElement = (name, hovered, selected, color, keepOnSelection) => (hovered || selected) && !keepOnSelection ? (jsxRuntime.jsx(CircleIcon, { hovered: hovered, selected: selected })) : (jsxRuntime.jsx("div", { className: "flex h-6 w-6 items-center justify-center", children: jsxRuntime.jsx("div", { className: cvaCustomDot(), children: jsxRuntime.jsx(reactComponents.Icon, { className: "block", color: color, dataTestId: "timeline-custom-dot", name: name, size: "small" }) }) }));
|
|
474
479
|
|
|
475
480
|
/*
|
|
476
481
|
* ----------------------------
|
package/index.esm.js
CHANGED
|
@@ -386,9 +386,18 @@ const Timeline = ({ className, dataTestId, children, dateHeader, customHeader, t
|
|
|
386
386
|
const childProps = React.isValidElement(firstChild) ? firstChild.props : {};
|
|
387
387
|
const lastChild = remainingChildren.pop();
|
|
388
388
|
const middleChildren = remainingChildren;
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
// Set maxHeight dynamically for smooth animation
|
|
391
|
+
if (ref.current) {
|
|
392
|
+
ref.current.style.maxHeight = isOpen ? `${ref.current.scrollHeight}px` : "0px";
|
|
393
|
+
}
|
|
394
|
+
}, [isOpen]);
|
|
389
395
|
const renderToggleButton = () => (jsxs("div", { className: cvaTimelineElement(), children: [childProps?.date ? (jsx("div", { className: cvaTimelineElementTime({
|
|
390
396
|
width: hourCycle === "h12" || hourCycle === "h11" ? "large" : "small",
|
|
391
|
-
}) })) : null, jsx("div", { className: cvaDotWrapper(), children: jsx("div", { className: cvaLine({ lineStyle: childProps?.lineStyle }) }) }), jsxs("div", { className: "
|
|
397
|
+
}) })) : null, jsx("div", { className: cvaDotWrapper(), children: jsx("div", { className: cvaLine({ lineStyle: childProps?.lineStyle }) }) }), jsxs("div", { className: "text-secondary-500 hover:text-secondary-600 flex min-h-8 cursor-pointer items-center text-sm", "data-testid": "timeline-toggle-btn", onClick: () => {
|
|
398
|
+
toggleButton?.onClick && toggleButton.onClick();
|
|
399
|
+
setIsOpen(!isOpen);
|
|
400
|
+
}, children: [jsx(Icon, { className: cvaToggleBtnIcon({ rotated: isOpen }), name: "ChevronDown", size: "small" }), jsx("span", { children: isOpen ? toggleButton?.collapsedLabel : toggleButton?.expandedLabel })] })] }));
|
|
392
401
|
const renderDateHeader = () => {
|
|
393
402
|
if (!dateHeader) {
|
|
394
403
|
return null;
|
|
@@ -399,7 +408,7 @@ const Timeline = ({ className, dataTestId, children, dateHeader, customHeader, t
|
|
|
399
408
|
const { date, dateRange, showTime } = dateHeader;
|
|
400
409
|
return (jsx("div", { className: "pb-4", "data-testid": "timeline-date-header", children: date ? (jsxs(Fragment, { children: [jsx(Text, { size: "medium", type: "span", weight: "thick", children: formatDate(date, { selectFormat: !showTime ? "dateOnly" : undefined }) }), jsx(Text, { className: "text-secondary-500", size: "medium", type: "span", weight: "thick", children: ` (${timeSinceAuto(date, new Date())})` })] })) : (jsx(Text, { className: "pr-1", size: "medium", type: "span", weight: "thick", children: formatRange(dateRange, { dateStyle: !showTime ? "medium" : undefined }) })) }));
|
|
401
410
|
};
|
|
402
|
-
return (jsxs("div", { className: className, "data-testid": dataTestId, children: [renderDateHeader(), customHeader ? jsx("div", { className: "
|
|
411
|
+
return (jsxs("div", { className: className, "data-testid": dataTestId, children: [renderDateHeader(), customHeader ? jsx("div", { className: "text-sm font-semibold", children: customHeader }) : null, toggleButton && middleChildren.length > 0 ? (jsxs("div", { children: [firstChild, middleChildren.length > 0 ? renderToggleButton() : null, jsxs("div", { "aria-hidden": !isOpen, className: "overflow-hidden transition-all duration-300", ref: ref, children: [jsx("div", {}), middleChildren, jsx("div", {})] }), lastChild] })) : (jsx("div", { children: children }))] }));
|
|
403
412
|
};
|
|
404
413
|
|
|
405
414
|
/**
|
|
@@ -413,9 +422,7 @@ const TimelineElement = ({ date, children, className, dataTestId = "timeline-ele
|
|
|
413
422
|
const [isHovered, setIsHovered] = useState(false);
|
|
414
423
|
const { formatDate } = useDateAndTime();
|
|
415
424
|
const locale = useLocale$1();
|
|
416
|
-
const formattedDate = date
|
|
417
|
-
? formatDate(date, { selectFormat: "timeOnly", timeFormat: "short" })
|
|
418
|
-
: null;
|
|
425
|
+
const formattedDate = date ? formatDate(date, { selectFormat: "timeOnly", timeFormat: "short" }) : null;
|
|
419
426
|
const handleMouseEnter = () => {
|
|
420
427
|
if (hoverBehavior) {
|
|
421
428
|
setIsHovered(true);
|
|
@@ -426,24 +433,24 @@ const TimelineElement = ({ date, children, className, dataTestId = "timeline-ele
|
|
|
426
433
|
setIsHovered(false);
|
|
427
434
|
}
|
|
428
435
|
};
|
|
429
|
-
return (jsxs("div", { className: cvaTimelineElement({ className, selected, hoverBehavior }), "data-date": date, "data-testid": dataTestId, onClick: onClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [renderDate(formattedDate, locale), jsxs("div", { className: cvaDotWrapper(), children: [renderDot(customDot, isHovered, selected), jsx("div", { className: cvaLine({ lineStyle }) })] }), jsxs("div", { className: "
|
|
436
|
+
return (jsxs("div", { className: cvaTimelineElement({ className, selected, hoverBehavior }), "data-date": date, "data-testid": dataTestId, onClick: onClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [renderDate(formattedDate, locale), jsxs("div", { className: cvaDotWrapper(), children: [renderDot(customDot, isHovered, selected), jsx("div", { className: cvaLine({ lineStyle }) })] }), jsxs("div", { className: "pb-2 pt-2", children: [renderHeader(header), renderChildren(children), renderActionButton(actionButton)] })] }));
|
|
430
437
|
};
|
|
431
438
|
const renderDate = (formattedDate, locale) => {
|
|
432
439
|
if (!formattedDate) {
|
|
433
440
|
return null;
|
|
434
441
|
}
|
|
435
|
-
return
|
|
442
|
+
return jsx("div", { className: "items-center pt-2", children: timelineElementTime(formattedDate, locale) });
|
|
436
443
|
};
|
|
437
444
|
const renderDot = (customDot, isHovered, selected) => {
|
|
438
445
|
return customDot?.name
|
|
439
|
-
? customDotElement(customDot.name, isHovered, selected, customDot.color)
|
|
446
|
+
? customDotElement(customDot.name, isHovered, selected, customDot.color, customDot.keepOnSelection)
|
|
440
447
|
: defaultDot(isHovered, selected);
|
|
441
448
|
};
|
|
442
449
|
const renderHeader = (header) => {
|
|
443
450
|
if (!header) {
|
|
444
451
|
return null;
|
|
445
452
|
}
|
|
446
|
-
return jsx("div", { className: "
|
|
453
|
+
return jsx("div", { className: "mt-0.5 content-center text-sm font-medium", children: header });
|
|
447
454
|
};
|
|
448
455
|
const renderChildren = (children) => {
|
|
449
456
|
if (!children) {
|
|
@@ -460,15 +467,13 @@ const renderActionButton = (actionButton) => {
|
|
|
460
467
|
const timelineElementTime = (formattedDate, locale) => {
|
|
461
468
|
const hourCycle = getHourCycle(locale);
|
|
462
469
|
return (jsx(Text, { align: "right", className: cvaTimelineElementTime({
|
|
463
|
-
width: hourCycle === "h12" || hourCycle === "h11" ? "large" : "small"
|
|
470
|
+
width: hourCycle === "h12" || hourCycle === "h11" ? "large" : "small",
|
|
464
471
|
}), size: "small", subtle: true, children: formattedDate }));
|
|
465
472
|
};
|
|
466
473
|
const CircleIcon = ({ selected, hovered }) => (jsxs("svg", { className: "relative z-[2]", "data-testid": "timeline-circle-icon", height: "24", viewBox: "0 0 24 24", width: "24", children: [jsx("circle", { cx: "12", cy: "12", fill: selected ? "#EFF6FF" : hovered ? "#F9FAFB" : "white", r: "10" }), jsx("circle", { cx: "12", cy: "12", fill: "#2563EB", r: "8" }), jsx("circle", { cx: "12", cy: "12", fill: "white", r: "3" })] }));
|
|
467
474
|
const DotIcon = () => (jsxs("svg", { className: "relative z-[2]", "data-testid": "timeline-dot-icon", height: "24", viewBox: "0 0 24 24", width: "24", children: [jsx("circle", { cx: "12", cy: "12", fill: "white", r: "6" }), jsx("circle", { cx: "12", cy: "12", fill: "#2563EB", r: "4" })] }));
|
|
468
|
-
const defaultDot = (hovered, selected) =>
|
|
469
|
-
const customDotElement = (name, hovered, selected, color) => (hovered || selected
|
|
470
|
-
? jsx(CircleIcon, { hovered: hovered, selected: selected })
|
|
471
|
-
: (jsx("div", { className: "w-6 h-6 flex items-center justify-center", children: jsx("div", { className: cvaCustomDot(), children: jsx(Icon, { className: "block", color: color, dataTestId: "timeline-custom-dot", name: name, size: "small" }) }) })));
|
|
475
|
+
const defaultDot = (hovered, selected) => hovered || selected ? jsx(CircleIcon, { hovered: hovered, selected: selected }) : jsx(DotIcon, {});
|
|
476
|
+
const customDotElement = (name, hovered, selected, color, keepOnSelection) => (hovered || selected) && !keepOnSelection ? (jsx(CircleIcon, { hovered: hovered, selected: selected })) : (jsx("div", { className: "flex h-6 w-6 items-center justify-center", children: jsx("div", { className: cvaCustomDot(), children: jsx(Icon, { className: "block", color: color, dataTestId: "timeline-custom-dot", name: name, size: "small" }) }) }));
|
|
472
477
|
|
|
473
478
|
/*
|
|
474
479
|
* ----------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-date-and-time-components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"date-fns": "^2.30.0",
|
|
12
12
|
"tailwind-merge": "^2.0.0",
|
|
13
13
|
"react": "18.3.1",
|
|
14
|
-
"@trackunit/react-components": "^1.0
|
|
14
|
+
"@trackunit/react-components": "^1.1.0",
|
|
15
15
|
"@trackunit/react-date-and-time-hooks": "^1.0.8",
|
|
16
16
|
"@trackunit/react-core-hooks": "^1.0.5",
|
|
17
17
|
"@trackunit/date-and-time-utils": "^1.0.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { CommonProps, IconColors } from "@trackunit/react-components";
|
|
3
2
|
import { IconName } from "@trackunit/ui-icons";
|
|
3
|
+
import React from "react";
|
|
4
4
|
interface TimeLineElementProps extends CommonProps {
|
|
5
5
|
date?: Date;
|
|
6
6
|
header?: React.ReactNode;
|
|
@@ -8,8 +8,9 @@ interface TimeLineElementProps extends CommonProps {
|
|
|
8
8
|
customDot?: {
|
|
9
9
|
name: IconName;
|
|
10
10
|
color: IconColors;
|
|
11
|
+
keepOnSelection?: boolean;
|
|
11
12
|
};
|
|
12
|
-
onClick?: () => void;
|
|
13
|
+
onClick?: (e?: React.MouseEvent<HTMLDivElement>) => void;
|
|
13
14
|
actionButton?: {
|
|
14
15
|
label: string;
|
|
15
16
|
iconName: IconName;
|