chore: Adjust language picker theme to match other menus (#14644)

This commit is contained in:
Michael S. Molina 2021-05-17 14:24:30 -03:00 committed by GitHub
parent 1b47902e47
commit 4e6169e0f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 76 deletions

View File

@ -19,6 +19,7 @@
import React from 'react';
import { render, screen } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import { MainNav as Menu } from 'src/common/components';
import LanguagePicker from './LanguagePicker';
const mockedProps = {
@ -38,18 +39,30 @@ const mockedProps = {
};
test('should render', () => {
const { container } = render(<LanguagePicker {...mockedProps} />);
const { container } = render(
<Menu>
<LanguagePicker {...mockedProps} />
</Menu>,
);
expect(container).toBeInTheDocument();
});
test('should render the combobox', () => {
render(<LanguagePicker {...mockedProps} />);
expect(screen.getByRole('combobox')).toBeInTheDocument();
test('should render the language picker', () => {
render(
<Menu>
<LanguagePicker {...mockedProps} />
</Menu>,
);
expect(screen.getByLabelText('Languages')).toBeInTheDocument();
});
test('should render the items', async () => {
render(<LanguagePicker {...mockedProps} />);
userEvent.click(screen.getByRole('combobox'));
render(
<Menu>
<LanguagePicker {...mockedProps} />
</Menu>,
);
userEvent.hover(screen.getByRole('button'));
expect(await screen.findByText('English')).toBeInTheDocument();
expect(await screen.findByText('Italian')).toBeInTheDocument();
});

View File

@ -16,10 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { useState } from 'react';
import { Select } from 'src/common/components';
import { styled, useTheme } from '@superset-ui/core';
import Icons from 'src/components/Icons';
import React from 'react';
import { MainNav as Menu } from 'src/common/components';
import { styled } from '@superset-ui/core';
import Icon from 'src/components/Icon';
const { SubMenu } = Menu;
export interface Languages {
[key: string]: {
@ -34,81 +36,50 @@ interface LanguagePickerProps {
languages: Languages;
}
const dropdownWidth = 150;
const StyledLabel = styled.div`
display: flex;
align-items: center;
& i {
margin-right: ${({ theme }) => theme.gridUnit}px;
margin-right: ${({ theme }) => theme.gridUnit * 2}px;
}
& span {
& a {
display: block;
width: ${dropdownWidth}px;
width: 150px;
word-wrap: break-word;
white-space: normal;
text-decoration: none;
}
`;
const StyledFlag = styled.div`
const StyledFlag = styled.i`
margin-top: 2px;
`;
const StyledIcon = styled(Icons.TriangleDown)`
${({ theme }) => `
margin-top: -${theme.gridUnit}px;
margin-left: -${theme.gridUnit * 2}px;
`}
`;
export default function LanguagePicker({
locale,
languages,
}: LanguagePickerProps) {
const theme = useTheme();
const [open, setOpen] = useState(false);
const options = Object.keys(languages).map(langKey => ({
label: (
<StyledLabel className="f16">
<i className={`flag ${languages[langKey].flag}`} />{' '}
<span>{languages[langKey].name}</span>
</StyledLabel>
),
value: langKey,
flag: (
<StyledFlag className="f16">
<i className={`flag ${languages[langKey].flag}`} />
</StyledFlag>
),
}));
export default function LanguagePicker(props: LanguagePickerProps) {
const { locale, languages, ...rest } = props;
return (
<Select
defaultValue={locale}
open={open}
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
onDropdownVisibleChange={open => setOpen(open)}
bordered={false}
options={options}
suffixIcon={
<StyledIcon
iconColor={theme.colors.grayscale.base}
className="ant-select-suffix"
/>
<SubMenu
aria-label="Languages"
title={
<div className="f16">
<StyledFlag className={`flag ${languages[locale].flag}`} />
</div>
}
listHeight={400}
dropdownAlign={{
offset: [-dropdownWidth, 0],
}}
optionLabelProp="flag"
dropdownMatchSelectWidth={false}
onChange={(value: string) => {
window.location.href = languages[value].url;
}}
/>
icon={<Icon name="triangle-down" />}
{...rest}
>
{Object.keys(languages).map(langKey => (
<Menu.Item
key={langKey}
style={{ whiteSpace: 'normal', height: 'auto' }}
>
<StyledLabel className="f16">
<i className={`flag ${languages[langKey].flag}`} />
<a href={languages[langKey].url}>{languages[langKey].name}</a>
</StyledLabel>
</Menu.Item>
))}
</SubMenu>
);
}

View File

@ -332,5 +332,5 @@ test('should render the Login link when user is anonymous', () => {
test('should render the Language Picker', () => {
render(<Menu {...mockedProps} />);
expect(screen.getByRole('combobox')).toBeInTheDocument();
expect(screen.getByLabelText('Languages')).toBeInTheDocument();
});

View File

@ -153,6 +153,12 @@ const RightMenu = ({
</Menu.ItemGroup>,
]}
</SubMenu>
{navbarRight.show_language_picker && (
<LanguagePicker
locale={navbarRight.locale}
languages={navbarRight.languages}
/>
)}
</Menu>
{navbarRight.documentation_url && (
<a
@ -175,12 +181,6 @@ const RightMenu = ({
<i className="fa fa-bug" />
</a>
)}
{navbarRight.show_language_picker && (
<LanguagePicker
locale={navbarRight.locale}
languages={navbarRight.languages}
/>
)}
{navbarRight.user_is_anonymous && (
<a href={navbarRight.user_login_url}>
<i className="fa fa-fw fa-sign-in" />