mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
chore: Adjust language picker theme to match other menus (#14644)
This commit is contained in:
parent
1b47902e47
commit
4e6169e0f9
@ -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();
|
||||||
});
|
});
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
});
|
});
|
||||||
|
@ -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" />
|
||||||
|
Loading…
Reference in New Issue
Block a user