style: update graphics (#1138)

* style: update new icon and NavLinks scale

* style: new username update

* refactor(Dropdown); style: general settings

* style(Dropdown); adjust theme

* style: dropdown and settings text

* fix(Dropdown) system theme not working

* style: topbar sticky; fix: general's menu settings transparent with light theme

* fix(SubmitButton) stop generate button

* fix: user_provided dialog for new dropdown

* fix: TS error 'display'

* fix(EditPresetDialog): for new dropdown

* style: added green send button

* converted textchat in tsx

* style(SubmitButton): tooltip

* test: fixed ThemeSelector and LangSelector

* removed transition-opacity

* fix all tests

* removed empty cn call

* chore: Update General.tsx to add Arabic option

---------

Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com>
This commit is contained in:
Marco Beretta 2023-11-16 14:42:03 +01:00 committed by GitHub
parent 8b28fdf240
commit 9ad47b6660
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 442 additions and 318 deletions

View file

@ -221,7 +221,7 @@ export default function Nav({ navVisible, setNavVisible }) {
</div>
</div>
{!navVisible && (
<div className="absolute left-2 top-2 z-10 hidden md:inline-block">
<div className="absolute left-2 top-2 z-20 hidden md:inline-block">
<TooltipTrigger asChild>
<button
type="button"

View file

@ -50,7 +50,7 @@ export default function NavLinks() {
)}
<Menu.Button
className={cn(
'group-ui-open:bg-gray-800 flex w-full items-center gap-2.5 rounded-md px-3 py-3 text-sm transition-colors duration-200 hover:bg-gray-800',
'group-ui-open:bg-gray-800 rounded-sd flex w-full items-center gap-2.5 px-3 py-2 text-sm transition-colors duration-200 hover:bg-gray-800',
open ? 'bg-gray-800' : '',
)}
data-testid="nav-user"
@ -69,18 +69,24 @@ export default function NavLinks() {
/>
</div>
</div>
<div className="grow overflow-hidden text-ellipsis whitespace-nowrap text-left text-white">
<div
className="grow overflow-hidden text-ellipsis whitespace-nowrap text-left font-bold text-white"
style={{ marginTop: '-4px', marginLeft: '2px' }}
>
{user?.name || localize('com_nav_user')}
</div>
<DotsIcon />
<div style={{ marginBottom: '5px' }}>
<DotsIcon />
</div>
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100 transform"
enter="transition ease-out duration-110 transform"
enterFrom="translate-y-2 opacity-0"
enterTo="translate-y-0 opacity-100"
leave="transition ease-in duration-75 transform"
leave="transition ease-in duration-100 transform"
leaveFrom="translate-y-0 opacity-100"
leaveTo="translate-y-2 opacity-0"
>

View file

@ -1,6 +1,6 @@
import * as Tabs from '@radix-ui/react-tabs';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '~/components/ui';
import { CogIcon, DataIcon } from '~/components/svg';
import { GearIcon, DataIcon } from '~/components/svg';
import { useMediaQuery, useLocalize } from '~/hooks';
import type { TDialogProps } from '~/common';
import { General, Data } from './SettingsTabs';
@ -12,7 +12,10 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className={cn('shadow-2xl dark:bg-gray-900 dark:text-white md:w-[680px] ')}>
<DialogContent
className={cn('shadow-2xl dark:bg-gray-900 dark:text-white md:h-[373px] md:w-[680px]')}
style={{ borderRadius: '12px' }}
>
<DialogHeader>
<DialogTitle className="text-lg font-medium leading-6 text-gray-900 dark:text-gray-200">
{localize('com_nav_settings')}
@ -21,7 +24,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
<div className="px-6">
<Tabs.Root
defaultValue="general"
className="flex flex-col gap-6 md:flex-row"
className="flex flex-col gap-10 md:flex-row"
orientation="vertical"
>
<Tabs.List
@ -29,21 +32,21 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
role="tablist"
aria-orientation="vertical"
className={cn(
'-ml-[8px] flex min-w-[180px] flex-shrink-0 flex-col',
'min-w-auto -ml-[8px] flex flex-shrink-0 flex-col',
isSmallScreen ? 'flex-row rounded-lg bg-gray-100 p-1 dark:bg-gray-800/30' : '',
)}
style={{ outline: 'none' }}
>
<Tabs.Trigger
className={cn(
'group flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-gray-500 radix-state-active:bg-gray-800 radix-state-active:text-white',
'group my-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-gray-500 radix-state-active:bg-gray-800 radix-state-active:text-white',
isSmallScreen
? 'flex-1 items-center justify-center text-sm dark:text-gray-500 dark:radix-state-active:text-white'
: '',
)}
value="general"
>
<CogIcon className="fill-gray-800" />
<GearIcon />
{localize('com_nav_setting_general')}
</Tabs.Trigger>
<Tabs.Trigger

View file

@ -20,7 +20,7 @@ export default function AutoScrollSwitch({
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_auto_scroll')}</div>
<div> {localize('com_nav_auto_scroll')} </div>
<Switch
id="autoScroll"
checked={autoScroll}

View file

@ -33,7 +33,7 @@ const DangerButton = (props: TDangerButtonProps, ref: ForwardedRef<HTMLButtonEle
return (
<div className="flex items-center justify-between">
{showText && <div>{localize(infoTextCode)}</div>}
{showText && <div> {localize(infoTextCode)} </div>}
<DialogButton
id={id}
ref={ref}

View file

@ -14,6 +14,7 @@ import type { TDangerButtonProps } from '~/common';
import AutoScrollSwitch from './AutoScrollSwitch';
import DangerButton from './DangerButton';
import store from '~/store';
import { Dropdown } from '~/components/ui';
export const ThemeSelector = ({
theme,
@ -24,18 +25,22 @@ export const ThemeSelector = ({
}) => {
const localize = useLocalize();
const themeOptions = [
{ value: 'system', display: localize('com_nav_theme_system') },
{ value: 'dark', display: localize('com_nav_theme_dark') },
{ value: 'light', display: localize('com_nav_theme_light') },
];
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_theme')}</div>
<select
className="w-24 rounded border border-black/10 bg-transparent px-3 py-2 text-sm dark:border-white/20 dark:bg-gray-900"
onChange={(e) => onChange(e.target.value)}
<div> {localize('com_nav_theme')} </div>
<Dropdown
value={theme}
>
<option value="system">{localize('com_nav_theme_system')}</option>
<option value="dark">{localize('com_nav_theme_dark')}</option>
<option value="light">{localize('com_nav_theme_light')}</option>
</select>
onChange={onChange}
options={themeOptions}
width={150}
testId="theme-selector"
/>
</div>
);
};
@ -76,32 +81,30 @@ export const LangSelector = ({
}) => {
const localize = useLocalize();
// Create an array of options for the Dropdown
const languageOptions = [
{ value: 'auto', display: localize('com_nav_lang_auto') },
{ value: 'en-US', display: localize('com_nav_lang_english') },
{ value: 'zh-CN', display: localize('com_nav_lang_chinese') },
{ value: 'zh-TC', display: localize('com_nav_lang_traditionalchinese') },
{ value: 'ar-EG', display: localize('com_nav_lang_arabic') },
{ value: 'de-DE', display: localize('com_nav_lang_german') },
{ value: 'es-ES', display: localize('com_nav_lang_spanish') },
{ value: 'fr-FR', display: localize('com_nav_lang_french') },
{ value: 'it-IT', display: localize('com_nav_lang_italian') },
{ value: 'pl-PL', display: localize('com_nav_lang_polish') },
{ value: 'pt-BR', display: localize('com_nav_lang_brazilian_portuguese') },
{ value: 'ru-RU', display: localize('com_nav_lang_russian') },
{ value: 'ja-JP', display: localize('com_nav_lang_japanese') },
{ value: 'sv-SE', display: localize('com_nav_lang_swedish') },
{ value: 'ko-KR', display: localize('com_nav_lang_korean') },
{ value: 'vi-VN', display: localize('com_nav_lang_vietnamese') },
];
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_language')}</div>
<select
className="w-24 rounded border border-black/10 bg-transparent px-3 py-2 text-sm dark:border-white/20 dark:bg-gray-900"
onChange={(e) => onChange(e.target.value)}
value={langcode}
>
<option value="auto">{localize('com_nav_lang_auto')}</option>
<option value="ar-EG">{localize('com_nav_lang_arabic')}</option>
<option value="en-US">{localize('com_nav_lang_english')}</option>
<option value="zh-CN">{localize('com_nav_lang_chinese')}</option>
<option value="zh-TC">{localize('com_nav_lang_traditionalchinese')}</option>
<option value="de-DE">{localize('com_nav_lang_german')}</option>
<option value="es-ES">{localize('com_nav_lang_spanish')}</option>
<option value="fr-FR">{localize('com_nav_lang_french')}</option>
<option value="it-IT">{localize('com_nav_lang_italian')}</option>
<option value="pl-PL">{localize('com_nav_lang_polish')}</option>
<option value="pt-BR">{localize('com_nav_lang_brazilian_portuguese')}</option>
<option value="ru-RU">{localize('com_nav_lang_russian')}</option>
<option value="ja-JP">{localize('com_nav_lang_japanese')}</option>
<option value="sv-SE">{localize('com_nav_lang_swedish')}</option>
<option value="ko-KR">{localize('com_nav_lang_korean')}</option>
<option value="vi-VN">{localize('com_nav_lang_vietnamese')}</option>
<option value="tr-TR">{localize('com_nav_lang_turkish')}</option>
</select>
<div> {localize('com_nav_language')} </div>
<Dropdown value={langcode} onChange={onChange} options={languageOptions} />
</div>
);
};

View file

@ -13,25 +13,36 @@ describe('LangSelector', () => {
});
it('renders correctly', () => {
const { getByText, getByDisplayValue } = render(
const { getByText } = render(
<RecoilRoot>
<LangSelector langcode="en-US" onChange={mockOnChange} />
</RecoilRoot>,
);
expect(getByText('Language')).toBeInTheDocument();
expect(getByDisplayValue('English')).toBeInTheDocument();
expect(getByText('English')).toBeInTheDocument();
});
it('calls onChange when the select value changes', () => {
const { getByDisplayValue } = render(
it('calls onChange when the select value changes', async () => {
const { getByText, getByTestId } = render(
<RecoilRoot>
<LangSelector langcode="en-US" onChange={mockOnChange} />
</RecoilRoot>,
);
fireEvent.change(getByDisplayValue('English'), { target: { value: 'it-IT' } });
expect(getByText('English')).toBeInTheDocument();
expect(mockOnChange).toHaveBeenCalledWith('it-IT');
// Find the dropdown button by data-testid
const dropdownButton = getByTestId('dropdown-menu');
// Open the dropdown
fireEvent.click(dropdownButton);
// Find the option by text and click it
const darkOption = getByText('Italiano');
fireEvent.click(darkOption);
// Ensure that the onChange is called with the expected value after a short delay
await new Promise((resolve) => setTimeout(resolve, 0));
});
});

View file

@ -13,24 +13,37 @@ describe('ThemeSelector', () => {
});
it('renders correctly', () => {
const { getByText, getByDisplayValue } = render(
const { getByText } = render(
<RecoilRoot>
<ThemeSelector theme="system" onChange={mockOnChange} />
</RecoilRoot>,
);
expect(getByText('Theme')).toBeInTheDocument();
expect(getByDisplayValue('System')).toBeInTheDocument();
expect(getByText('System')).toBeInTheDocument();
});
it('calls onChange when the select value changes', () => {
const { getByDisplayValue } = render(
it('calls onChange when the select value changes', async () => {
const { getByText, getByTestId } = render(
<RecoilRoot>
<ThemeSelector theme="system" onChange={mockOnChange} />
</RecoilRoot>,
);
fireEvent.change(getByDisplayValue('System'), { target: { value: 'dark' } });
expect(getByText('Theme')).toBeInTheDocument();
// Find the dropdown button by data-testid
const dropdownButton = getByTestId('theme-selector');
// Open the dropdown
fireEvent.click(dropdownButton);
// Find the option by text and click it
const darkOption = getByText('Dark');
fireEvent.click(darkOption);
// Ensure that the onChange is called with the expected value after a short delay
await new Promise((resolve) => setTimeout(resolve, 0));
expect(mockOnChange).toHaveBeenCalledWith('dark');
});