From 504fec46d2ab54073cef9728507052f8a79c21f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 25 Jan 2023 10:38:33 +0100 Subject: [PATCH] CommandPalette: Design tweaks and design fixes (#61971) * Command palette design tweaks start * Fix some item styling issues * Updated placeholder * Style fixes * Fix gradient border pos issue, and heading padding * Fix header top margin * Restore padding * Update * Change to md modal --- .../commandPalette/CommandPalette.tsx | 68 ++++++++----------- .../features/commandPalette/ResultItem.tsx | 29 ++++---- public/locales/en-US/grafana.json | 2 +- public/locales/pseudo-LOCALE/grafana.json | 2 +- 4 files changed, 46 insertions(+), 55 deletions(-) diff --git a/public/app/features/commandPalette/CommandPalette.tsx b/public/app/features/commandPalette/CommandPalette.tsx index 7ee00813631..3c3af74f770 100644 --- a/public/app/features/commandPalette/CommandPalette.tsx +++ b/public/app/features/commandPalette/CommandPalette.tsx @@ -57,10 +57,12 @@ export const CommandPalette = () => {
- +
+ +
@@ -92,22 +94,18 @@ const RenderResults = ({ dashboardResults }: RenderResultsProps) => { return ( { - // These items are rendered in a container, in a virtual list, so we cannot - // use :first/last-child selectors, so we must mimic them in JS - const isFirstItem = items[0] === item; - const isLastItem = items[items.length - 1] === item; + const isFirst = items[0] === item; const renderedItem = typeof item === 'string' ? ( -
-
{item}
-
+
{item}
) : ( ); - return isLastItem ?
{renderedItem}
: renderedItem; + return renderedItem; }} /> ); @@ -129,47 +127,39 @@ const getSearchStyles = (theme: GrafanaTheme2) => ({ }, }), animator: css({ - maxWidth: theme.breakpoints.values.sm, // supposed to be 600... + maxWidth: theme.breakpoints.values.md, width: '100%', - background: theme.colors.background.canvas, + background: theme.colors.background.primary, color: theme.colors.text.primary, - borderRadius: theme.shape.borderRadius(4), + borderRadius: theme.shape.borderRadius(2), + border: `1px solid ${theme.colors.border.weak}`, overflow: 'hidden', boxShadow: theme.shadows.z3, }), search: css({ - padding: theme.spacing(2, 3), + padding: theme.spacing(1.5, 2), fontSize: theme.typography.fontSize, width: '100%', boxSizing: 'border-box', outline: 'none', border: 'none', - background: theme.colors.background.canvas, - color: theme.colors.text.primary, - borderBottom: `1px solid ${theme.colors.border.medium}`, + background: theme.components.input.background, + color: theme.components.input.text, + borderBottom: `1px solid ${theme.colors.border.weak}`, }), - - // Virtual list measures margin incorrectly, so we need to split padding before/after border - // over and inner and outer element - sectionHeader: css({ - paddingTop: theme.spacing(2), - fontSize: theme.typography.h6.fontSize, - fontWeight: theme.typography.body.fontWeight, - color: theme.colors.text.secondary, - }), - sectionHeaderInner: css({ - padding: theme.spacing(1, 2), - borderTop: `1px solid ${theme.colors.border.medium}`, - }), - - // We don't need the header above the first section - sectionHeaderInnerFirst: css({ - borderTop: 'none', - paddingTop: 0, - }), - - // Last item gets extra padding so it's not clipped by the rounded corners on the container - lastItem: css({ + resultsContainer: css({ paddingBottom: theme.spacing(1), }), + sectionHeader: css({ + padding: theme.spacing(1.5, 2, 1, 2), + fontSize: theme.typography.bodySmall.fontSize, + fontWeight: theme.typography.fontWeightMedium, + color: theme.colors.text.primary, + borderTop: `1px solid ${theme.colors.border.weak}`, + marginTop: theme.spacing(1), + }), + sectionHeaderFirst: css({ + borderTop: 'none', + marginTop: 0, + }), }); diff --git a/public/app/features/commandPalette/ResultItem.tsx b/public/app/features/commandPalette/ResultItem.tsx index fc4858fa00e..464276f10e2 100644 --- a/public/app/features/commandPalette/ResultItem.tsx +++ b/public/app/features/commandPalette/ResultItem.tsx @@ -1,9 +1,9 @@ -import { css } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import { ActionId, ActionImpl } from 'kbar'; import React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { useTheme2 } from '@grafana/ui'; +import { useStyles2 } from '@grafana/ui'; export const ResultItem = React.forwardRef( ( @@ -31,8 +31,7 @@ export const ResultItem = React.forwardRef( return action.ancestors.slice(index + 1); }, [action.ancestors, currentRootActionId]); - const theme = useTheme2(); - const styles = getResultItemStyles(theme, active); + const styles = useStyles2(getResultItemStyles); let name = action.name; @@ -42,7 +41,7 @@ export const ResultItem = React.forwardRef( } return ( -
+
{action.icon}
@@ -63,31 +62,33 @@ export const ResultItem = React.forwardRef( ); } ); + ResultItem.displayName = 'ResultItem'; -const getResultItemStyles = (theme: GrafanaTheme2, isActive: boolean) => { - const textColor = isActive ? theme.colors.text.maxContrast : theme.colors.text.primary; - const rowBackgroundColor = isActive ? theme.colors.background.primary : 'transparent'; - const shortcutBackgroundColor = isActive ? theme.colors.background.secondary : theme.colors.background.primary; +const getResultItemStyles = (theme: GrafanaTheme2) => { return { row: css({ - color: textColor, padding: theme.spacing(1, 2), - background: rowBackgroundColor, display: 'flex', alightItems: 'center', justifyContent: 'space-between', cursor: 'pointer', position: 'relative', + borderRadius: theme.shape.borderRadius(2), + margin: theme.spacing(0, 1), + }), + activeRow: css({ + color: theme.colors.text.maxContrast, + background: theme.colors.emphasize(theme.colors.background.primary, 0.03), '&:before': { - display: isActive ? 'block' : 'none', + display: 'block', content: '" "', position: 'absolute', left: 0, top: 0, bottom: 0, width: theme.spacing(0.5), - borderRadius: theme.shape.borderRadius(1), + borderRadius: theme.shape.borderRadius(2), backgroundImage: theme.colors.gradients.brandVertical, }, }), @@ -103,7 +104,7 @@ const getResultItemStyles = (theme: GrafanaTheme2, isActive: boolean) => { }), shortcut: css({ padding: theme.spacing(0, 1), - background: shortcutBackgroundColor, + background: theme.colors.background.secondary, borderRadius: theme.shape.borderRadius(), fontSize: theme.typography.fontSize, }), diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index c2bb24742a0..1f9efec846a 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -13,7 +13,7 @@ "search": "Search" }, "search-box": { - "placeholder": "Search Grafana" + "placeholder": "Search or jump to..." }, "section": { "actions": "Actions", diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json index b480c15e316..266e11b36c8 100644 --- a/public/locales/pseudo-LOCALE/grafana.json +++ b/public/locales/pseudo-LOCALE/grafana.json @@ -13,7 +13,7 @@ "search": "Ŝęäřčĥ" }, "search-box": { - "placeholder": "Ŝęäřčĥ Ğřäƒäʼnä" + "placeholder": "Ŝęäřčĥ őř ĵūmp ŧő..." }, "section": { "actions": "Åčŧįőʼnş",