From 9a977b4723b41aacd333fde94b7cb28aefbab200 Mon Sep 17 00:00:00 2001 From: darausi Date: Tue, 9 Jul 2024 13:07:06 +0100 Subject: [PATCH 01/23] ignore negative time lapse --- src/cmem/DateTimeDisplay/ElapsedDateTimeDisplay.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cmem/DateTimeDisplay/ElapsedDateTimeDisplay.tsx b/src/cmem/DateTimeDisplay/ElapsedDateTimeDisplay.tsx index b198c84c0..c9e7885bc 100644 --- a/src/cmem/DateTimeDisplay/ElapsedDateTimeDisplay.tsx +++ b/src/cmem/DateTimeDisplay/ElapsedDateTimeDisplay.tsx @@ -22,7 +22,8 @@ export interface ElapsedDateTimeDisplayProps extends TestableComponent { const dateTimeToElapsedTimeInMs = (dateTime: string | number) => { const absoluteMs = typeof dateTime === "number" ? dateTime : new Date(dateTime).getTime(); - return new Date().getTime() - absoluteMs; + const elapsed = new Date().getTime() - absoluteMs; + return elapsed < 0 ? 0 : elapsed; }; /** From eff2d4c068b9621390a63e2ddd72e63cb4e183e1 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 29 Jul 2024 12:31:36 +0200 Subject: [PATCH 02/23] Generate class attached to body element based on the data transfer type of drag over events --- .../Application/ApplicationContainer.tsx | 6 ++- src/components/Application/helper.ts | 48 ++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/components/Application/ApplicationContainer.tsx b/src/components/Application/ApplicationContainer.tsx index 7292c1376..cc8f96d60 100644 --- a/src/components/Application/ApplicationContainer.tsx +++ b/src/components/Application/ApplicationContainer.tsx @@ -2,13 +2,17 @@ import React from "react"; import { OverlaysProvider } from "@blueprintjs/core"; import { CLASSPREFIX as eccgui } from "../../configuration/constants"; +import {useGlobalAppDragMonitor} from "./helper"; export type ApplicationContainerProps = React.HTMLAttributes; +export const APPLICATION_CONTAINER_ID = "gui-elements-application-container" export const ApplicationContainer = ({ children, className = "", ...otherDivProps }: ApplicationContainerProps) => { + useGlobalAppDragMonitor() + return ( -
+
{children}
diff --git a/src/components/Application/helper.ts b/src/components/Application/helper.ts index 64222f8a0..0b2c7ddb2 100644 --- a/src/components/Application/helper.ts +++ b/src/components/Application/helper.ts @@ -1,6 +1,7 @@ import React from "react"; -import { CLASSPREFIX as eccgui } from "../../configuration/constants"; +import {CLASSPREFIX as eccgui} from "../../configuration/constants"; +import {APPLICATION_CONTAINER_ID} from "./ApplicationContainer"; export const useApplicationHeaderOverModals = (elevate: boolean, className: string) => { return React.useEffect(() => { @@ -19,3 +20,48 @@ export const useApplicationHeaderOverModals = (elevate: boolean, className: stri } }, [elevate, className]); }; + +// Prefix of the generated class. This will be combined with the data transfer type. +const APP_DRAG_OVER_CLASS_PREFIX = "appDragOver"; +const nonClassChars = /[^-_a-zA-Z0-9]/g; +const DRAG_CLASS_REMOVAL_DELAY = 500 + +/** Tracks drag operations over the application. Sets different classes to the root div. */ +export const useGlobalAppDragMonitor = () => { + React.useEffect(() => { + const applicationContainer = document.getElementById(APPLICATION_CONTAINER_ID); + const body = document.getElementsByTagName("body").item(0) + let currentTimer: any = undefined; + let currentClass: string | undefined = undefined; + + const removeDragClass = () => { + currentClass && body?.classList.remove(currentClass); + currentClass = undefined; + }; + + const onDragOver = (event: DragEvent) => { + if (currentTimer) { + clearTimeout(currentTimer); + } + const types = new Set(event.dataTransfer?.types); + if (types.size === 1) { + const type = types.values().next().value; + currentClass = `${APP_DRAG_OVER_CLASS_PREFIX}_${type}`.replaceAll(nonClassChars, ""); + body?.classList.add(currentClass); + currentTimer = setTimeout(removeDragClass, DRAG_CLASS_REMOVAL_DELAY); + } + }; + + const onDrop = () => { + if (currentTimer) { + clearTimeout(currentTimer); + } + removeDragClass(); + }; + + if (applicationContainer) { + applicationContainer.addEventListener("dragover", onDragOver); + applicationContainer.addEventListener("drop", onDrop); + } + }, []); +}; From 0ccc19767ba515f93c1ce55f5855ce17e0c03beb Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 29 Jul 2024 12:33:30 +0200 Subject: [PATCH 03/23] Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e976c5088..879565d55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - `intent` property to set the state, formerly used `hasStatePrimary`, `hasStateSuccess`, `hasStateWarning` and `hasStateDanger` properties are now deprecated - `leftIcon`: set the left aligned icon - `rightElement`: renders on right side +- ``: + - Track application wide drag over events via generated class attached to body element. The class name is based on the data transfer type of drag over events. ### Fixed From 694f05e2a08ab22c12e8d1619a6e862968c929b2 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 29 Jul 2024 17:18:28 +0200 Subject: [PATCH 04/23] reduce whitespace around icon button contained directly in textarea options --- src/components/TextField/TextArea.tsx | 2 +- src/components/TextField/textfield.scss | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/TextField/TextArea.tsx b/src/components/TextField/TextArea.tsx index f8514a3df..01ae7103b 100644 --- a/src/components/TextField/TextArea.tsx +++ b/src/components/TextField/TextArea.tsx @@ -116,7 +116,7 @@ export const TextArea = ({ ); leftIconElement.addEventListener("click", (_event: MouseEvent) => { textAreaElement.focus(); - }); //onclick((_event: MouseEvent) => {textAreaElement.dispatchEvent("click")}) + }); } if (rightElement && wrapperElement) { diff --git a/src/components/TextField/textfield.scss b/src/components/TextField/textfield.scss index e25e3d25f..9b2c23f03 100644 --- a/src/components/TextField/textfield.scss +++ b/src/components/TextField/textfield.scss @@ -184,6 +184,21 @@ $eccgui-map-intent-bgcolors: ( position: absolute; top: 0; right: 0; + + & > .#{$eccgui}-button--icon { + margin-top: -1 * $eccgui-size-textfield-padding-horizontal-regular; + + &:last-of-type { + margin-right: -1 * $eccgui-size-textfield-padding-horizontal-regular; + } + } +} +.#{$ns}-input.#{$ns}-small ~ .#{$eccgui}-textarea__options > .#{$eccgui}-button--icon { + margin-top: -1 * $eccgui-size-textfield-padding-horizontal-small; + + &:last-of-type { + margin-right: -1 * $eccgui-size-textfield-padding-horizontal-small; + } } .#{$eccgui}-textfield--justifyclearance { From 04c534357368025bd729ca2344982a57436ea37b Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 29 Jul 2024 17:40:37 +0200 Subject: [PATCH 05/23] use colors on textarea options only for hover and focus --- .../TextField/stories/TextArea.stories.tsx | 7 ++++++- src/components/TextField/textfield.scss | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/components/TextField/stories/TextArea.stories.tsx b/src/components/TextField/stories/TextArea.stories.tsx index 708d0799e..24bfd90ad 100644 --- a/src/components/TextField/stories/TextArea.stories.tsx +++ b/src/components/TextField/stories/TextArea.stories.tsx @@ -25,7 +25,12 @@ export default { ), "2 Icon buttons": ( <> - alert("1 clicked")} text="Button 1" /> + alert("1 clicked")} + text="Button 1" + affirmative + /> alert("2 clicked")} text="Button 2" /> ), diff --git a/src/components/TextField/textfield.scss b/src/components/TextField/textfield.scss index 9b2c23f03..bd73d22f8 100644 --- a/src/components/TextField/textfield.scss +++ b/src/components/TextField/textfield.scss @@ -184,6 +184,12 @@ $eccgui-map-intent-bgcolors: ( position: absolute; top: 0; right: 0; + filter: grayscale(1); + + &:hover, + .#{$eccgui}-textarea:focus ~ & { + filter: none; + } & > .#{$eccgui}-button--icon { margin-top: -1 * $eccgui-size-textfield-padding-horizontal-regular; @@ -192,12 +198,13 @@ $eccgui-map-intent-bgcolors: ( margin-right: -1 * $eccgui-size-textfield-padding-horizontal-regular; } } -} -.#{$ns}-input.#{$ns}-small ~ .#{$eccgui}-textarea__options > .#{$eccgui}-button--icon { - margin-top: -1 * $eccgui-size-textfield-padding-horizontal-small; - &:last-of-type { - margin-right: -1 * $eccgui-size-textfield-padding-horizontal-small; + .#{$ns}-input.#{$ns}-small ~ & > .#{$eccgui}-button--icon { + margin-top: -1 * $eccgui-size-textfield-padding-horizontal-small; + + &:last-of-type { + margin-right: -1 * $eccgui-size-textfield-padding-horizontal-small; + } } } From a45eb1caeb806fe7d5b54f2ad2530a4aa2a7f1e6 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 29 Jul 2024 17:43:29 +0200 Subject: [PATCH 06/23] update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 518f02481..52fa62515 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Fixed + +- `