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

View File

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

View File

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