From a6eed6e7dc2353f165e64c7b54d09f496709fcf6 Mon Sep 17 00:00:00 2001 From: Caroline Horn <549577+cchaos@users.noreply.github.com> Date: Thu, 24 Sep 2020 11:25:41 -0400 Subject: [PATCH] [Lens] Add a better drag/drop illustration (#78245) (#78425) Fixes #76021 --- .../lens/public/assets/drop_illustration.tsx | 48 +++++++++ .../_workspace_panel_wrapper.scss | 89 ++++++++++++++- .../workspace_panel/workspace_panel.tsx | 102 +++++++++--------- .../indexpattern_datasource/field_item.tsx | 1 - .../lens/public/visualization_container.scss | 3 +- 5 files changed, 190 insertions(+), 53 deletions(-) create mode 100644 x-pack/plugins/lens/public/assets/drop_illustration.tsx diff --git a/x-pack/plugins/lens/public/assets/drop_illustration.tsx b/x-pack/plugins/lens/public/assets/drop_illustration.tsx new file mode 100644 index 0000000000000..1076f4875d60c --- /dev/null +++ b/x-pack/plugins/lens/public/assets/drop_illustration.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as React from 'react'; +import { EuiIconProps } from '@elastic/eui'; + +export const DropIllustration = ({ title, titleId, ...props }: Omit) => ( + + {title ? {title} : null} + + + + + + + + +); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_workspace_panel_wrapper.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_workspace_panel_wrapper.scss index a4d8288d5e600..7f7385f029ed4 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_workspace_panel_wrapper.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_workspace_panel_wrapper.scss @@ -6,6 +6,7 @@ margin-bottom: $euiSize; display: flex; flex-direction: column; + position: relative; // For positioning the dnd overlay .lnsWorkspacePanelWrapper__pageContentHeader { @include euiTitle('xs'); @@ -24,8 +25,7 @@ display: flex; align-items: stretch; justify-content: stretch; - overflow: auto; - position: relative; + overflow: hidden; > * { flex: 1 1 100%; @@ -37,6 +37,91 @@ } } +.lnsWorkspacePanel__dragDrop { + // Disable the coloring of the DnD for this element as we'll + // Color the whole panel instead + background-color: transparent !important; // sass-lint:disable-line no-important +} + +.lnsExpressionRenderer { + .lnsDragDrop-isDropTarget & { + transition: filter $euiAnimSpeedNormal ease-in-out, opacity $euiAnimSpeedNormal ease-in-out; + filter: blur($euiSizeXS); + opacity: .25; + } +} + +.lnsWorkspacePanel__emptyContent { + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + display: flex; + justify-content: center; + align-items: center; + transition: background-color $euiAnimSpeedNormal ease-in-out; + + .lnsDragDrop-isDropTarget & { + background-color: transparentize($euiColorSecondary, .9); + + p { + transition: filter $euiAnimSpeedNormal ease-in-out; + filter: blur(5px); + } + } + + .lnsDragDrop-isActiveDropTarget & { + background-color: transparentize($euiColorSecondary, .75); + + .lnsDropIllustration__hand { + animation: pulseArrowContinuous 1.5s ease-in-out 0s infinite normal forwards; + } + } + + &.lnsWorkspacePanel__emptyContent-onTop p { + display: none; + } +} + .lnsWorkspacePanelWrapper__toolbar { margin-bottom: 0; } + +.lnsDropIllustration__adjustFill { + fill: $euiColorFullShade; +} + +.lnsWorkspacePanel__dropIllustration { + overflow: visible; // Shows arrow animation when it gets out of bounds + margin-top: $euiSizeL; + margin-bottom: $euiSizeXXL; + // Drop shadow values is a dupe of @euiBottomShadowMedium but used as a filter + // Hard-coded px values OK (@cchaos) + // sass-lint:disable-block indentation + filter: + drop-shadow(0 6px 12px transparentize($euiShadowColor, .8)) + drop-shadow(0 4px 4px transparentize($euiShadowColor, .8)) + drop-shadow(0 2px 2px transparentize($euiShadowColor, .8)); +} + +.lnsDropIllustration__hand { + animation: pulseArrow 5s ease-in-out 0s infinite normal forwards; +} + +@keyframes pulseArrow { + 0% { transform: translateY(0%); } + 65% { transform: translateY(0%); } + 72% { transform: translateY(10%); } + 79% { transform: translateY(7%); } + 86% { transform: translateY(10%); } + 95% { transform: translateY(0); } +} + +@keyframes pulseArrowContinuous { + 0% { transform: translateY(10%); } + 25% { transform: translateY(15%); } + 50% { transform: translateY(10%); } + 75% { transform: translateY(15%); } + 100% { transform: translateY(10%); } +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index 06cd858eda210..e56e55fdd5d6c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -5,17 +5,10 @@ */ import React, { useState, useEffect, useMemo, useContext, useCallback } from 'react'; +import classNames from 'classnames'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiImage, - EuiText, - EuiButtonEmpty, - EuiLink, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiButtonEmpty, EuiLink } from '@elastic/eui'; import { CoreStart, CoreSetup } from 'kibana/public'; import { ExecutionContextSearch } from 'src/plugins/expressions'; import { @@ -39,6 +32,7 @@ import { UiActionsStart } from '../../../../../../../src/plugins/ui_actions/publ import { VIS_EVENT_TO_TRIGGER } from '../../../../../../../src/plugins/visualizations/public'; import { DataPublicPluginStart } from '../../../../../../../src/plugins/data/public'; import { WorkspacePanelWrapper } from './workspace_panel_wrapper'; +import { DropIllustration } from '../../../assets/drop_illustration'; export interface WorkspacePanelProps { activeVisualizationId: string | null; @@ -78,11 +72,6 @@ export function InnerWorkspacePanel({ ExpressionRenderer: ExpressionRendererComponent, title, }: WorkspacePanelProps) { - const IS_DARK_THEME = core.uiSettings.get('theme:darkMode'); - const emptyStateGraphicURL = IS_DARK_THEME - ? '/plugins/lens/assets/lens_app_graphic_dark_2x.png' - : '/plugins/lens/assets/lens_app_graphic_light_2x.png'; - const dragDropContext = useContext(DragContext); const suggestionForDraggedField = useMemo( @@ -210,41 +199,54 @@ export function InnerWorkspacePanel({ function renderEmptyWorkspace() { return ( -
- -

- -

- -

- -

-

- - - - - -

-
-
+ +

+ + {expression === null ? ( + + ) : ( + + )} + +

+ + {expression === null && ( + <> +

+ +

+

+ + + + + +

+ + )} +
); } @@ -330,12 +332,14 @@ export function InnerWorkspacePanel({ visualizationMap={visualizationMap} > {renderVisualization()} + {Boolean(suggestionForDraggedField) && expression !== null && renderEmptyWorkspace()} ); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx index 1eeb64127310f..f141d3f8ecb9e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -196,7 +196,6 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { return ( ('.application') || undefined} diff --git a/x-pack/plugins/lens/public/visualization_container.scss b/x-pack/plugins/lens/public/visualization_container.scss index e5c359112fe4b..59ddbf4bf6478 100644 --- a/x-pack/plugins/lens/public/visualization_container.scss +++ b/x-pack/plugins/lens/public/visualization_container.scss @@ -1,3 +1,4 @@ .lnsVisualizationContainer { + @include euiScrollBar; overflow: auto; -} \ No newline at end of file +}