fix(UI): spacings + UI fixes (#36010)

This commit is contained in:
Gabriel Torres Ruiz
2025-11-06 14:19:07 -04:00
committed by GitHub
parent f5f5913a29
commit c11be72ead
10 changed files with 201 additions and 140 deletions

View File

@@ -105,6 +105,15 @@ const StyledTable = styled(Table)<{
white-space: nowrap;
}
.ant-table-tbody > tr > td {
height: ${theme.sizeUnit * 12}px;
}
.ant-table-tbody > tr > td.ant-table-cell:has(.ant-avatar-group) {
padding-top: ${theme.sizeUnit}px;
padding-bottom: ${theme.sizeUnit}px;
}
.ant-table-placeholder .ant-table-cell {
border-bottom: 0;
}

View File

@@ -60,7 +60,7 @@ const ListViewStyles = styled.div`
& .controls {
display: flex;
flex-wrap: wrap;
column-gap: ${theme.sizeUnit * 6}px;
column-gap: ${theme.sizeUnit * 7}px;
row-gap: ${theme.sizeUnit * 4}px;
}
}

View File

@@ -70,7 +70,7 @@ const RisonParam: QueryParamConfig<string, any> = {
: rison.decode(dataStr),
};
export const SELECT_WIDTH = 175;
export const SELECT_WIDTH = 176;
export const RANGE_WIDTH = 300;
export const WIDER_DROPDOWN_WIDTH = '300px';

View File

@@ -167,7 +167,7 @@ const ControlHeader: FC<ControlHeaderProps> = ({
placement="top"
title={validationErrors?.join(' ')}
>
<Icons.InfoCircleOutlined iconColor={theme.colorErrorText} />
<Icons.ExclamationCircleOutlined iconColor={theme.colorError} />
</Tooltip>{' '}
</span>
)}

View File

@@ -627,7 +627,7 @@ export const ControlPanelsContainer = (props: ControlPanelsContainerProps) => {
id={`${kebabCase('validation-errors')}-tooltip`}
title={t('This section contains validation errors')}
>
<Icons.InfoCircleOutlined iconColor={theme.colorErrorText} />
<Icons.ExclamationCircleOutlined iconColor={theme.colorError} />
</Tooltip>
)}
</span>
@@ -752,9 +752,9 @@ export const ControlPanelsContainer = (props: ControlPanelsContainerProps) => {
placement="right"
title={props.errorMessage}
>
<Icons.InfoCircleOutlined
<Icons.ExclamationCircleOutlined
data-test="query-error-tooltip-trigger"
iconColor={theme.colorErrorText}
iconColor={theme.colorError}
iconSize="s"
/>
</Tooltip>
@@ -813,9 +813,9 @@ export const ControlPanelsContainer = (props: ControlPanelsContainerProps) => {
placement="right"
title={t('This section contains validation errors')}
>
<Icons.InfoCircleOutlined
<Icons.ExclamationCircleOutlined
data-test="matrixify-validation-error-tooltip-trigger"
iconColor={theme.colorErrorText}
iconColor={theme.colorError}
iconSize="s"
/>
</Tooltip>

View File

@@ -41,110 +41,163 @@ interface MenuProps {
}
const StyledHeader = styled.header`
${({ theme }) => `
background-color: ${theme.colorBgContainer};
border-bottom: 1px solid ${theme.colorBorderSecondary};
z-index: 10;
${({ theme }) => css`
background-color: ${theme.colorBgContainer};
border-bottom: 1px solid ${theme.colorBorderSecondary};
padding: 0 ${theme.sizeUnit * 4}px;
z-index: 10;
&:nth-last-of-type(2) nav {
margin-bottom: 2px;
}
.caret {
display: none;
}
& .ant-image{
display: contents;
height: 100%;
padding: ${theme.sizeUnit}px
${theme.sizeUnit * 2}px
${theme.sizeUnit}px
${theme.sizeUnit * 4}px;
}
.navbar-brand {
display: flex;
flex-direction: column;
justify-content: center;
/* must be exactly the height of the Antd navbar */
min-height: 50px;
padding: ${theme.sizeUnit}px
${theme.sizeUnit * 2}px
${theme.sizeUnit}px
${theme.sizeUnit * 4}px;
max-width: ${theme.sizeUnit * theme.brandIconMaxWidth}px;
img {
height: 100%;
object-fit: contain;
}
&:focus {
border-color: transparent;
}
&:focus-visible {
border-color: ${theme.colorPrimaryText};
}
}
.navbar-brand-text {
border-left: 1px solid ${theme.colorBorderSecondary};
border-right: 1px solid ${theme.colorBorderSecondary};
height: 100%;
color: ${theme.colorText};
padding-left: ${theme.sizeUnit * 4}px;
padding-right: ${theme.sizeUnit * 4}px;
margin-right: ${theme.sizeUnit * 6}px;
font-size: ${theme.fontSizeLG}px;
float: left;
display: flex;
flex-direction: column;
justify-content: center;
&:nth-last-of-type(2) nav {
margin-bottom: 2px;
}
span {
max-width: ${theme.sizeUnit * 58}px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 1127px) {
display: none;
}
}
@media (max-width: 767px) {
.navbar-brand {
float: none;
}
}
@media (max-width: 767px) {
.ant-menu-item {
padding: 0 ${theme.sizeUnit * 6}px 0
${theme.sizeUnit * 3}px !important;
}
.ant-menu > .ant-menu-item > span > a {
padding: 0px;
}
.main-nav .ant-menu-submenu-title > svg:nth-of-type(1) {
display: none;
}
}
.caret {
display: none;
}
`}
`;
const StyledBrandText = styled.div`
${({ theme }) => css`
border-left: 1px solid ${theme.colorBorderSecondary};
border-right: 1px solid ${theme.colorBorderSecondary};
height: 100%;
color: ${theme.colorText};
padding-left: ${theme.sizeUnit * 4}px;
padding-right: ${theme.sizeUnit * 4}px;
margin-right: ${theme.sizeUnit * 6}px;
font-size: ${theme.fontSizeLG}px;
float: left;
display: flex;
flex-direction: column;
justify-content: center;
span {
max-width: ${theme.sizeUnit * 58}px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 1127px) {
display: none;
}
`}
`;
const StyledMainNav = styled(MainNav)`
${({ theme }) => css`
.ant-menu-item .ant-menu-item-icon + span,
.ant-menu-submenu-title .ant-menu-item-icon + span,
.ant-menu-item .anticon + span,
.ant-menu-submenu-title .anticon + span {
margin-inline-start: 0;
}
@media (max-width: 767px) {
.ant-menu-item {
padding: 0 ${theme.sizeUnit * 6}px 0 ${theme.sizeUnit * 3}px !important;
}
.ant-menu > .ant-menu-item > span > a {
padding: 0;
}
&.main-nav .ant-menu-submenu-title > svg:nth-of-type(1) {
display: none;
}
}
`}
`;
const { SubMenu } = MainNav;
const StyledSubMenu = styled(SubMenu)`
${({ theme }) => css`
[data-icon="caret-down"] {
color: ${theme.colorIcon};
font-size: ${theme.fontSizeXS}px;
margin-left: ${theme.sizeUnit}px;
}
&.ant-menu-submenu {
padding: ${theme.sizeUnit * 2}px ${theme.sizeUnit * 4}px;
&.ant-menu-submenu.ant-menu-submenu-horizontal {
display: flex;
align-items: center;
height: 100%;
padding: 0;
.ant-menu-submenu-title {
display: flex;
gap: ${theme.sizeUnit * 2}px;
flex-direction: row-reverse;
align-items: center;
height: 100%; &.ant-menu-submenu-active {
.ant-menu-title-content {
color: ${theme.colorPrimary};
height: 100%;
padding: 0 ${theme.sizeUnit * 4}px;
}
&:hover,
&.ant-menu-submenu-active {
.ant-menu-title-content {
color: ${theme.colorPrimary};
}
}
&::after {
content: '';
position: absolute;
width: 98%;
height: 2px;
background-color: ${theme.colorPrimaryBorderHover};
bottom: ${theme.sizeUnit / 8}px;
left: 1%;
right: auto;
inset-inline-start: 1%;
inset-inline-end: auto;
transform: scale(0);
transition: 0.2s all ease-out;
}
&:hover::after,
&.ant-menu-submenu-open::after {
transform: scale(1);
}
}
&.ant-menu-submenu-selected.ant-menu-submenu-horizontal::after {
transform: scale(1);
}
}
`}
`;
const StyledBrandWrapper = styled.div<{ margin?: string }>`
${({ margin }) => css`
height: ${margin ? 'auto' : '100%'};
margin: ${margin ?? 0};
`}
`;
const StyledBrandLink = styled(Typography.Link)`
${({ theme }) => css`
align-items: center;
display: flex;
height: 100%;
justify-content: center;
&:focus {
border-color: transparent;
}
&:focus-visible {
border-color: ${theme.colorPrimaryText};
}
`}
`;
const StyledRow = styled(Row)`
height: 100%;
`;
const StyledCol = styled(Col)`
${({ theme }) => css`
display: flex;
gap: ${theme.sizeUnit * 4}px;
`}
`;
const { useBreakpoint } = Grid;
export function Menu({
@@ -179,6 +232,8 @@ export function Menu({
Dashboard = '/dashboard',
Chart = '/chart',
Datasets = '/tablemodelview',
SqlLab = '/sqllab',
SavedQueries = '/savedqueryview',
}
const defaultTabSelection: string[] = [];
@@ -196,6 +251,9 @@ export function Menu({
case path.startsWith(Paths.Datasets):
setActiveTabs(['Datasets']);
break;
case path.startsWith(Paths.SqlLab) || path.startsWith(Paths.SavedQueries):
setActiveTabs(['SQL']);
break;
default:
setActiveTabs(defaultTabSelection);
}
@@ -229,14 +287,11 @@ export function Menu({
}
return (
<StyledSubMenu
key={index}
key={label}
title={label}
popupOffset={[0, -8]}
icon={
showMenu === 'inline' ? (
<></>
) : (
<Icons.CaretDownOutlined iconSize="xs" />
)
showMenu === 'inline' ? <></> : <Icons.DownOutlined iconSize="xs" />
}
>
{childs?.map((child: MenuObjectChildProps | string, index1: number) => {
@@ -270,25 +325,17 @@ export function Menu({
const renderBrand = () => {
let link;
if (theme.brandLogoUrl) {
let style = { padding: '0px', margin: '0px' } as React.CSSProperties;
if (theme.brandLogoHeight) {
style = { ...style, height: theme.brandLogoHeight, minHeight: '0px' };
}
if (theme.brandLogoMargin) {
style = { ...style, margin: theme.brandLogoMargin };
}
link = (
<Typography.Link
href={theme.brandLogoHref}
className="navbar-brand"
style={style}
>
<Image
preview={false}
src={theme.brandLogoUrl}
alt={theme.brandLogoAlt || 'Apache Superset'}
/>
</Typography.Link>
<StyledBrandWrapper margin={theme.brandLogoMargin}>
<StyledBrandLink href={theme.brandLogoHref}>
<Image
preview={false}
src={theme.brandLogoUrl}
alt={theme.brandLogoAlt || 'Apache Superset'}
height={theme.brandLogoHeight}
/>
</StyledBrandLink>
</StyledBrandWrapper>
);
} else if (isFrontendRoute(window.location.pathname)) {
// ---------------------------------------------------------------------------------
@@ -315,8 +362,8 @@ export function Menu({
};
return (
<StyledHeader className="top" id="main-menu" role="navigation">
<Row>
<Col md={16} xs={24} style={{ display: 'flex' }}>
<StyledRow>
<StyledCol md={16} xs={24}>
<Tooltip
id="brand-tooltip"
placement="bottomLeft"
@@ -326,11 +373,11 @@ export function Menu({
{renderBrand()}
</Tooltip>
{brand.text && (
<div className="navbar-brand-text">
<StyledBrandText>
<span>{brand.text}</span>
</div>
</StyledBrandText>
)}
<MainNav
<StyledMainNav
mode={showMenu}
data-test="navbar-top"
className="main-nav"
@@ -356,8 +403,8 @@ export function Menu({
return renderSubMenu(props);
})}
</MainNav>
</Col>
</StyledMainNav>
</StyledCol>
<Col md={8} xs={24}>
<RightMenu
align={screens.md ? 'flex-end' : 'flex-start'}
@@ -367,7 +414,7 @@ export function Menu({
environmentTag={environmentTag}
/>
</Col>
</Row>
</StyledRow>
</StyledHeader>
);
}

View File

@@ -69,7 +69,6 @@ const StyledDiv = styled.div<{ align: string }>`
flex-direction: row;
justify-content: ${({ align }) => align};
align-items: center;
margin-right: ${({ theme }) => theme.sizeUnit}px;
`;
const StyledMenuItemWithIcon = styled.div`
@@ -565,7 +564,7 @@ const RightMenu = ({
key: 'new-dropdown',
label: <Icons.PlusOutlined data-test="new-dropdown-icon" />,
className: 'submenu-with-caret',
icon: <Icons.CaretDownOutlined iconSize="xs" />,
icon: <Icons.DownOutlined iconSize="xs" />,
children: buildNewDropdownItems(),
});
}
@@ -581,7 +580,7 @@ const RightMenu = ({
items.push({
key: 'settings',
label: t('Settings'),
icon: <Icons.CaretDownOutlined iconSize="xs" />,
icon: <Icons.DownOutlined iconSize="xs" />,
children: buildSettingsMenuItems(),
className: 'submenu-with-caret',
});
@@ -676,7 +675,7 @@ const RightMenu = ({
}
.submenu-with-caret {
padding: 0 ${theme.sizeUnit}px;
padding: 0;
.ant-menu-submenu-title {
display: flex;
gap: ${theme.sizeUnit * 2}px;
@@ -685,6 +684,12 @@ const RightMenu = ({
&.ant-menu-submenu::after {
inset-inline: ${theme.sizeUnit}px;
}
&.ant-menu-submenu:hover,
&.ant-menu-submenu-active {
.ant-menu-title-content {
color: ${theme.colorPrimary};
}
}
}
`}
selectable={false}

View File

@@ -40,7 +40,7 @@ const StyledHeader = styled.div<{ backgroundColor?: string }>`
align-items: center;
position: relative;
padding: ${({ theme }) => theme.sizeUnit * 2}px
${({ theme }) => theme.sizeUnit * 5}px;
${({ theme }) => theme.sizeUnit * 4}px;
margin-bottom: ${({ theme }) => theme.sizeUnit * 4}px;
.header {
font-weight: ${({ theme }) => theme.fontWeightStrong};
@@ -53,10 +53,10 @@ const StyledHeader = styled.div<{ backgroundColor?: string }>`
.nav-right {
display: flex;
align-items: center;
margin-right: ${({ theme }) => theme.sizeUnit * 3}px;
/* margin-right: ${({ theme }) => theme.sizeUnit * 3}px; */
float: right;
position: absolute;
right: 0;
right: ${({ theme }) => theme.sizeUnit * 4}px;
ul.ant-menu-root {
padding: 0px;
}

View File

@@ -134,7 +134,7 @@ export const useThemeMenuItems = ({
return {
key: 'theme-sub-menu',
label: selectedThemeModeIcon,
icon: <Icons.CaretDownOutlined iconSize="xs" />,
icon: <Icons.DownOutlined iconSize="xs" />,
className: 'submenu-with-caret',
children,
};

View File

@@ -752,7 +752,7 @@ THEME_DEFAULT: Theme = {
# Brand
"brandLogoAlt": "Apache Superset",
"brandLogoUrl": APP_ICON,
"brandLogoMargin": "18px",
"brandLogoMargin": "18px 0",
"brandLogoHref": "/",
"brandLogoHeight": "24px",
# Spinner