From f3227da47c36002742c452b450fa75c7f0569d41 Mon Sep 17 00:00:00 2001
From: shadowusr <58862284+shadowusr@users.noreply.github.com>
Date: Wed, 18 Sep 2024 02:03:31 +0300
Subject: [PATCH] feat(new-ui): implement drag to hide hint card (#602)
* chore(new-ui): implement drag to hide hint card
* chore(new-ui): expand right side to full height
* chore(new-ui): add transitions to section width changes and animate gutter handle
* chore(new-ui): fix attempt picker margins
---
.../Card/KeepDraggingToHideCard.module.css | 55 ++++++++++++++++
.../Card/KeepDraggingToHideCard.tsx | 12 ++++
.../new-ui/components/Card/index.module.css | 11 +++-
lib/static/new-ui/components/Card/index.tsx | 6 +-
.../components/SplitViewLayout.module.css | 62 ++++++++++++++++---
.../new-ui/components/SplitViewLayout.tsx | 56 +++++++++++++++--
.../components/SuitesPage/index.module.css | 13 ++--
.../suites/components/SuitesPage/index.tsx | 46 +++++++-------
lib/static/styles.css | 4 +-
9 files changed, 217 insertions(+), 48 deletions(-)
create mode 100644 lib/static/new-ui/components/Card/KeepDraggingToHideCard.module.css
create mode 100644 lib/static/new-ui/components/Card/KeepDraggingToHideCard.tsx
diff --git a/lib/static/new-ui/components/Card/KeepDraggingToHideCard.module.css b/lib/static/new-ui/components/Card/KeepDraggingToHideCard.module.css
new file mode 100644
index 000000000..4be02a50b
--- /dev/null
+++ b/lib/static/new-ui/components/Card/KeepDraggingToHideCard.module.css
@@ -0,0 +1,55 @@
+
+@keyframes appear {
+ 0% { opacity: 0; visibility: hidden; }
+ 100% { opacity: 1; visibility: visible; }
+}
+
+.overlay-container {
+ align-items: center;
+ background: #9176ffa9;
+ box-shadow: inset 0 0 0 4px #9176ff;
+ display: flex;
+ height: 100%;
+ justify-content: center;
+ opacity: 0;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ transition: opacity .5s ease, visibility .5s ease;
+ width: 100%;
+ visibility: hidden;
+ z-index: 999;
+}
+
+@keyframes overlay-pulse {
+ 0% { box-shadow: inset 0 0 0 0 #9176ff; }
+ 95% { box-shadow: inset 0 0 0 30px #9176ff; }
+ 100% { opacity: 0; }
+}
+
+.pulsing {
+ animation: overlay-pulse 2s ease infinite;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+@container (max-width: 400px) {
+ :global(.is-resizing) .overlay-container {
+ visibility: visible;
+ opacity: 1;
+ }
+}
+
+:global(.is-collapsed) .hint {
+ opacity: 0
+}
+
+.hint {
+ font-size: 18px;
+ color: white;
+ font-weight: 500;
+ opacity: 1;
+ white-space: nowrap;
+ transition: opacity .1s ease;
+}
diff --git a/lib/static/new-ui/components/Card/KeepDraggingToHideCard.tsx b/lib/static/new-ui/components/Card/KeepDraggingToHideCard.tsx
new file mode 100644
index 000000000..7ef5aec01
--- /dev/null
+++ b/lib/static/new-ui/components/Card/KeepDraggingToHideCard.tsx
@@ -0,0 +1,12 @@
+import classNames from 'classnames';
+import React, {ReactNode} from 'react';
+
+import cardStyles from './index.module.css';
+import styles from './KeepDraggingToHideCard.module.css';
+
+export function KeepDraggingToHideCard(): ReactNode {
+ return
+
+
Keep dragging to hide
+
;
+}
diff --git a/lib/static/new-ui/components/Card/index.module.css b/lib/static/new-ui/components/Card/index.module.css
index d3a1bb8ee..87848e2f7 100644
--- a/lib/static/new-ui/components/Card/index.module.css
+++ b/lib/static/new-ui/components/Card/index.module.css
@@ -1,3 +1,12 @@
+.common-card {
+ border-radius: 10px;
+ position: relative;
+}
+
.card {
- box-shadow: rgb(255, 255, 255) 0px 0px 0px 0px, rgba(9, 9, 11, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;
+ box-shadow: rgb(255, 255, 255) 0 0 0 0, rgba(9, 9, 11, 0.05) 0 0 0 1px, rgba(0, 0, 0, 0.05) 0 1px 2px 0;
+}
+
+.wrapper {
+ overflow: hidden;
}
diff --git a/lib/static/new-ui/components/Card/index.tsx b/lib/static/new-ui/components/Card/index.tsx
index b752b4063..fecc3b7fa 100644
--- a/lib/static/new-ui/components/Card/index.tsx
+++ b/lib/static/new-ui/components/Card/index.tsx
@@ -9,5 +9,9 @@ interface CardProps {
}
export function Card(props: CardProps): React.ReactNode {
- return {props.children}
;
+ return ;
}
diff --git a/lib/static/new-ui/components/SplitViewLayout.module.css b/lib/static/new-ui/components/SplitViewLayout.module.css
index 01e7b0a9c..fb05f806b 100644
--- a/lib/static/new-ui/components/SplitViewLayout.module.css
+++ b/lib/static/new-ui/components/SplitViewLayout.module.css
@@ -2,19 +2,67 @@
display: flex;
flex-direction: row;
height: 100vh;
+ padding: 0 10px;
}
- .split > div {
- overflow-y: scroll;
- }
-
.split :global(.gutter) {
background-color: #eee;
background-repeat: no-repeat;
background-position: 50%;
}
- .split :global(.gutter.gutter-horizontal) {
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
- cursor: col-resize;
+.gutter {
+ cursor: col-resize;
+ min-width: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.gutter-handle {
+ background: var(--g-color-private-black-200);
+ height: 40px;
+ border-radius: 10px;
+ width: 8px;
+}
+
+@keyframes gutter-activate {
+ 100% {
+ transform: scale(1.1);
+ background: var(--g-color-private-black-400);
+ }
+}
+
+:global(.is-resizing) .gutter-handle {
+ animation: gutter-activate 0.3s forwards ease-in;
+}
+
+@keyframes gutter-deactivate {
+ 0% {
+ transform: scale(1.1);
+ background: var(--g-color-private-black-400);
+ }
+
+ 50% { transform: scale(0.9); }
+
+ 100% {
+ transform: scale(1);
+ background: var(--g-color-private-black-200);
}
+}
+
+:global(.is-idle) .gutter-handle {
+ animation: gutter-deactivate 0.4s forwards ease-in;
+}
+
+.container {
+ min-width: 400px;
+ container-type: size;
+ margin: 10px 0;
+ position: relative;
+ transition: min-width .2s ease;
+}
+
+.container-collapsed {
+ min-width: 0;
+}
diff --git a/lib/static/new-ui/components/SplitViewLayout.tsx b/lib/static/new-ui/components/SplitViewLayout.tsx
index 24da06db4..71faf8bb4 100644
--- a/lib/static/new-ui/components/SplitViewLayout.tsx
+++ b/lib/static/new-ui/components/SplitViewLayout.tsx
@@ -1,13 +1,59 @@
-import React from 'react';
+import classNames from 'classnames';
+import React, {ReactNode} from 'react';
import Split from 'react-split';
import styles from './SplitViewLayout.module.css';
+import {KeepDraggingToHideCard} from '@/static/new-ui/components/Card/KeepDraggingToHideCard';
interface SplitViewLayoutProps {
- children?: React.ReactNode;
+ sections: React.ReactNode[];
}
-export function SplitViewLayout(props: SplitViewLayoutProps): JSX.Element {
- return
- {props.children}
+export function SplitViewLayout(props: SplitViewLayoutProps): ReactNode {
+ const snapOffset = 200;
+ const [wasDragged, setWasDragged] = React.useState(false);
+ const [isDragging, setIsDragging] = React.useState(false);
+ const [isHiddenByIndex, setIsHiddenByIndex] = React.useState([]);
+
+ const onDragHandler = (sizes: number[]): void => {
+ setIsHiddenByIndex(sizes.map(size => size < 1));
+ };
+
+ const onDragStartHandler = (): void => {
+ setWasDragged(true);
+ setIsDragging(true);
+ };
+
+ const onDragEndHandler = (): void => {
+ setIsDragging(false);
+ };
+
+ const createGutter = (): HTMLDivElement => {
+ const handle = document.createElement('div');
+ handle.classList.add(styles.gutterHandle);
+
+ const gutter = document.createElement('div');
+ gutter.appendChild(handle);
+ gutter.classList.add(styles.gutter);
+
+ return gutter;
+ };
+
+ return
+ {props.sections.map((section, index) =>
+
+
+ {section}
+
)}
;
}
diff --git a/lib/static/new-ui/features/suites/components/SuitesPage/index.module.css b/lib/static/new-ui/features/suites/components/SuitesPage/index.module.css
index ff7fd0109..c05519eb9 100644
--- a/lib/static/new-ui/features/suites/components/SuitesPage/index.module.css
+++ b/lib/static/new-ui/features/suites/components/SuitesPage/index.module.css
@@ -19,25 +19,22 @@
background-color: #fff;
display: flex;
flex-direction: column;
- margin: 10px;
- border-radius: 10px;
- border: 20px solid white;
- border-top: 15px solid white;
+ padding: 0 20px 20px 20px;
+ overflow: hidden;
+ position: relative;
+ height: calc(100vh - 20px);
}
.card__title {
margin-bottom: 8px !important;
+ padding-top: 15px;
}
.tree-view-card {
- height: calc(100vh - 20px);
- margin-right: 2px;
gap: 8px;
}
.test-view-card {
- margin-left: 2px;
- max-height: calc(100vh - 20px);
gap: 12px;
overflow: scroll;
}
diff --git a/lib/static/new-ui/features/suites/components/SuitesPage/index.tsx b/lib/static/new-ui/features/suites/components/SuitesPage/index.tsx
index c59518a09..8e8544039 100644
--- a/lib/static/new-ui/features/suites/components/SuitesPage/index.tsx
+++ b/lib/static/new-ui/features/suites/components/SuitesPage/index.tsx
@@ -26,31 +26,27 @@ interface SuitesPageProps {
}
function SuitesPageInternal(props: SuitesPageProps): ReactNode {
- return
-
-
- Suites
-
-
-
-
-
-
-
-
-
-
-
-
-
props.actions.changeTestRetry({browserId, retryIndex})} />
-
-
-
- } id={'overview'}/>
-
-
-
- ;
+ return
+ Suites
+
+
+
+
+
+
+ ,
+
+
+
+
props.actions.changeTestRetry({browserId, retryIndex})} />
+
+
+
+ } id={'overview'}/>
+
+
+ ]} />;
}
export const SuitesPage = connect(
diff --git a/lib/static/styles.css b/lib/static/styles.css
index 75a6652c6..c39757817 100644
--- a/lib/static/styles.css
+++ b/lib/static/styles.css
@@ -608,8 +608,10 @@ a:active {
}
.tab-switcher {
- display: inline-block;
+ display: inline-flex;
margin-bottom: 5px;
+ gap: 2px;
+ flex-wrap: wrap;
}
.tab-switcher:before {