This is an automated email from the ASF dual-hosted git repository.

kgabryje pushed a commit to branch what-if
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 5d6a697e324dd8142dac06d3e88c0ceef09d5c70
Author: Kamil Gabryjelski <[email protected]>
AuthorDate: Tue Dec 16 23:12:10 2025 +0100

    fun border
---
 .../gridComponents/ChartHolder/ChartHolder.tsx     |   5 +-
 .../src/dashboard/util/useWhatIfHighlightStyles.ts | 143 +++++++++++++++++++++
 2 files changed, 147 insertions(+), 1 deletion(-)

diff --git 
a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder/ChartHolder.tsx
 
b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder/ChartHolder.tsx
index 7d68c8ceae..1f1014b67d 100644
--- 
a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder/ChartHolder.tsx
+++ 
b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder/ChartHolder.tsx
@@ -31,6 +31,7 @@ import HoverMenu from 
'src/dashboard/components/menu/HoverMenu';
 import ResizableContainer from 
'src/dashboard/components/resizable/ResizableContainer';
 import getChartAndLabelComponentIdFromPath from 
'src/dashboard/util/getChartAndLabelComponentIdFromPath';
 import useFilterFocusHighlightStyles from 
'src/dashboard/util/useFilterFocusHighlightStyles';
+import useWhatIfHighlightStyles from 
'src/dashboard/util/useWhatIfHighlightStyles';
 import { COLUMN_TYPE, ROW_TYPE } from 'src/dashboard/util/componentTypes';
 import {
   GRID_BASE_UNIT,
@@ -107,6 +108,7 @@ const ChartHolder = ({
   const isFullSize = fullSizeChartId === chartId;
 
   const focusHighlightStyles = useFilterFocusHighlightStyles(chartId);
+  const whatIfHighlightStyles = useWhatIfHighlightStyles(chartId);
   const directPathToChild = useSelector(
     (state: RootState) => state.dashboardState.directPathToChild,
   );
@@ -260,7 +262,7 @@ const ChartHolder = ({
           ref={dragSourceRef}
           data-test="dashboard-component-chart-holder"
           style={focusHighlightStyles}
-          css={isFullSize ? fullSizeStyle : undefined}
+          css={[isFullSize && fullSizeStyle, whatIfHighlightStyles]}
           className={cx(
             'dashboard-component',
             'dashboard-component-chart-holder',
@@ -325,6 +327,7 @@ const ChartHolder = ({
       onResizeStop,
       editMode,
       focusHighlightStyles,
+      whatIfHighlightStyles,
       isFullSize,
       fullSizeStyle,
       chartId,
diff --git a/superset-frontend/src/dashboard/util/useWhatIfHighlightStyles.ts 
b/superset-frontend/src/dashboard/util/useWhatIfHighlightStyles.ts
new file mode 100644
index 0000000000..1db666a7f8
--- /dev/null
+++ b/superset-frontend/src/dashboard/util/useWhatIfHighlightStyles.ts
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { useMemo } from 'react';
+import { useSelector } from 'react-redux';
+import { css, keyframes } from '@emotion/react';
+import { RootState, WhatIfModification } from 'src/dashboard/types';
+import { extractColumnsFromSlice } from './whatIf';
+
+const EMPTY_STYLES = undefined;
+
+/* eslint-disable theme-colors/no-literal-colors */
+const rainbowSlide = keyframes`
+  0% {
+    background-position: 0% 50%;
+  }
+  100% {
+    background-position: 300% 50%;
+  }
+`;
+
+const pulse = keyframes`
+  0%, 100% {
+    opacity: 0.7;
+    filter: blur(0px);
+  }
+  50% {
+    opacity: 1;
+    filter: blur(2px);
+  }
+`;
+
+const whatIfHighlightStyles = css`
+  position: relative;
+
+  &::before {
+    content: '';
+    position: absolute;
+    inset: -2px;
+    border-radius: 10px;
+    padding: 4px;
+    background: linear-gradient(
+      90deg,
+      #ff0000,
+      #ff8000,
+      #ffff00,
+      #80ff00,
+      #00ff00,
+      #00ff80,
+      #00ffff,
+      #0080ff,
+      #0000ff,
+      #8000ff,
+      #ff00ff,
+      #ff0080,
+      #ff0000,
+      #ff8000,
+      #ffff00,
+      #80ff00,
+      #00ff00,
+      #00ff80,
+      #00ffff,
+      #0080ff,
+      #0000ff,
+      #8000ff,
+      #ff00ff,
+      #ff0080,
+      #ff0000
+    );
+    background-size: 300% 100%;
+    animation:
+      ${rainbowSlide} 20s linear infinite,
+      ${pulse} 3s ease-in-out infinite;
+    -webkit-mask:
+      linear-gradient(#fff 0 0) content-box,
+      linear-gradient(#fff 0 0);
+    -webkit-mask-composite: xor;
+    mask-composite: exclude;
+    pointer-events: none;
+  }
+`;
+/* eslint-enable theme-colors/no-literal-colors */
+
+/**
+ * Hook that returns animated rainbow border styles for charts
+ * that are affected by what-if transformations.
+ */
+const useWhatIfHighlightStyles = (chartId: number) => {
+  const whatIfModifications = useSelector(
+    (state: RootState) => state.dashboardState.whatIfModifications,
+  );
+
+  const slice = useSelector(
+    (state: RootState) => state.sliceEntities?.slices?.[chartId],
+  );
+
+  const isAffected = useMemo(() => {
+    if (!whatIfModifications || whatIfModifications.length === 0) {
+      return false;
+    }
+
+    if (!slice) {
+      return false;
+    }
+
+    const chartColumns = extractColumnsFromSlice(slice);
+    const modifiedColumns = new Set(
+      whatIfModifications.map((mod: WhatIfModification) => mod.column),
+    );
+
+    // Check if any of the chart's columns are being modified
+    for (const column of chartColumns) {
+      if (modifiedColumns.has(column)) {
+        return true;
+      }
+    }
+
+    return false;
+  }, [whatIfModifications, slice]);
+
+  if (!isAffected) {
+    return EMPTY_STYLES;
+  }
+
+  return whatIfHighlightStyles;
+};
+
+export default useWhatIfHighlightStyles;

Reply via email to