Add blue focus on text inputs (#8343)

We removed the blue focus on phone/domain/array/email floating inputs
but we want to keep it in the app settings.

<img width="644" alt="Screenshot 2024-11-05 at 15 55 04"
src="https://github.com/user-attachments/assets/afcbe6b2-2d6b-4e0d-8397-4268d529127c">
<img width="606" alt="Screenshot 2024-11-05 at 15 55 23"
src="https://github.com/user-attachments/assets/004becf8-41e7-45d6-9ad9-9e487b8db8f3">
<img width="351" alt="Screenshot 2024-11-05 at 15 55 33"
src="https://github.com/user-attachments/assets/6a4c06e6-04d3-46bf-940b-9fd61ee91995">
<img width="330" alt="Screenshot 2024-11-05 at 15 55 41"
src="https://github.com/user-attachments/assets/e6fc8bbd-eca3-47bc-93f1-d6ff8d3d8a13">
<img width="588" alt="Screenshot 2024-11-05 at 15 56 07"
src="https://github.com/user-attachments/assets/0d0f5e80-3501-4346-94a1-6ea4b77ee7ba">
<img width="211" alt="Screenshot 2024-11-05 at 15 56 31"
src="https://github.com/user-attachments/assets/9cd85f4d-8052-4c6b-a694-84c691c6217d">
This commit is contained in:
Félix Malfait
2024-11-06 14:23:34 +01:00
committed by GitHub
parent 5a293b8d60
commit b627c55b9a
9 changed files with 58 additions and 36 deletions

View File

@@ -73,6 +73,15 @@ export const SignInUpForm = () => {
submitSSOEmail, submitSSOEmail,
} = useSignInUp(form); } = useSignInUp(form);
if (
signInUpStep === SignInUpStep.Init &&
!authProviders.google &&
!authProviders.microsoft &&
!authProviders.sso
) {
continueWithEmail();
}
const toggleSSOMode = () => { const toggleSSOMode = () => {
if (signInUpStep === SignInUpStep.SSOEmail) { if (signInUpStep === SignInUpStep.SSOEmail) {
continueWithEmail(); continueWithEmail();
@@ -155,6 +164,9 @@ export const SignInUpForm = () => {
Icon={() => <IconGoogle size={theme.icon.size.lg} />} Icon={() => <IconGoogle size={theme.icon.size.lg} />}
title="Continue with Google" title="Continue with Google"
onClick={signInWithGoogle} onClick={signInWithGoogle}
variant={
signInUpStep === SignInUpStep.Init ? undefined : 'secondary'
}
fullWidth fullWidth
/> />
<HorizontalSeparator visible={false} /> <HorizontalSeparator visible={false} />
@@ -167,6 +179,9 @@ export const SignInUpForm = () => {
Icon={() => <IconMicrosoft size={theme.icon.size.lg} />} Icon={() => <IconMicrosoft size={theme.icon.size.lg} />}
title="Continue with Microsoft" title="Continue with Microsoft"
onClick={signInWithMicrosoft} onClick={signInWithMicrosoft}
variant={
signInUpStep === SignInUpStep.Init ? undefined : 'secondary'
}
fullWidth fullWidth
/> />
<HorizontalSeparator visible={false} /> <HorizontalSeparator visible={false} />
@@ -176,6 +191,9 @@ export const SignInUpForm = () => {
<> <>
<MainButton <MainButton
Icon={() => <IconKey size={theme.icon.size.lg} />} Icon={() => <IconKey size={theme.icon.size.lg} />}
variant={
signInUpStep === SignInUpStep.Init ? undefined : 'secondary'
}
title={ title={
signInUpStep === SignInUpStep.SSOEmail signInUpStep === SignInUpStep.SSOEmail
? 'Continue with email' ? 'Continue with email'
@@ -282,9 +300,11 @@ export const SignInUpForm = () => {
</StyledFullWidthMotionDiv> </StyledFullWidthMotionDiv>
)} )}
<MainButton <MainButton
variant="secondary"
title={buttonTitle} title={buttonTitle}
type="submit" type="submit"
variant={
signInUpStep === SignInUpStep.Init ? 'secondary' : 'primary'
}
onClick={async () => { onClick={async () => {
if (signInUpStep === SignInUpStep.Init) { if (signInUpStep === SignInUpStep.Init) {
continueWithEmail(); continueWithEmail();
@@ -301,7 +321,7 @@ export const SignInUpForm = () => {
setShowErrors(true); setShowErrors(true);
form.handleSubmit(submitCredentials)(); form.handleSubmit(submitCredentials)();
}} }}
Icon={() => form.formState.isSubmitting && <Loader />} Icon={() => (form.formState.isSubmitting ? <Loader /> : null)}
disabled={isSubmitButtonDisabled} disabled={isSubmitButtonDisabled}
fullWidth fullWidth
/> />

View File

@@ -16,7 +16,7 @@ export const MultipleFiltersDropdownFilterOnFilterChangedEffect = ({
setDropdownWidth(280); setDropdownWidth(280);
break; break;
default: default:
setDropdownWidth(160); setDropdownWidth(200);
} }
}, [filterDefinitionUsedInDropdownType, setDropdownWidth]); }, [filterDefinitionUsedInDropdownType, setDropdownWidth]);

View File

@@ -10,7 +10,7 @@ import {
useRef, useRef,
useState, useState,
} from 'react'; } from 'react';
import { IconComponent, IconEye, IconEyeOff } from 'twenty-ui'; import { IconComponent, IconEye, IconEyeOff, RGBA } from 'twenty-ui';
import { useCombinedRefs } from '~/hooks/useCombinedRefs'; import { useCombinedRefs } from '~/hooks/useCombinedRefs';
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly'; import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
@@ -33,6 +33,7 @@ const StyledInputContainer = styled.div`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
width: 100%; width: 100%;
position: relative;
`; `;
const StyledInput = styled.input< const StyledInput = styled.input<
@@ -42,12 +43,7 @@ const StyledInput = styled.input<
border: 1px solid border: 1px solid
${({ theme, error }) => ${({ theme, error }) =>
error ? theme.border.color.danger : theme.border.color.medium}; error ? theme.border.color.danger : theme.border.color.medium};
border-bottom-left-radius: ${({ theme, LeftIcon }) => border-radius: ${({ theme }) => theme.border.radius.sm};
!LeftIcon && theme.border.radius.sm};
border-right: none;
border-left: ${({ LeftIcon }) => LeftIcon && 'none'};
border-top-left-radius: ${({ theme, LeftIcon }) =>
!LeftIcon && theme.border.radius.sm};
box-sizing: border-box; box-sizing: border-box;
color: ${({ theme }) => theme.font.color.primary}; color: ${({ theme }) => theme.font.color.primary};
display: flex; display: flex;
@@ -57,6 +53,8 @@ const StyledInput = styled.input<
height: 32px; height: 32px;
outline: none; outline: none;
padding: ${({ theme }) => theme.spacing(2)}; padding: ${({ theme }) => theme.spacing(2)};
padding-left: ${({ theme, LeftIcon }) =>
LeftIcon ? `calc(${theme.spacing(4)} + 16px)` : theme.spacing(2)};
width: 100%; width: 100%;
&::placeholder, &::placeholder,
@@ -69,6 +67,13 @@ const StyledInput = styled.input<
&:disabled { &:disabled {
color: ${({ theme }) => theme.font.color.tertiary}; color: ${({ theme }) => theme.font.color.tertiary};
} }
&:focus {
${({ theme }) => {
return `box-shadow: 0px 0px 0px 3px ${RGBA(theme.color.blue, 0.1)};
border-color: ${theme.color.blue};`;
}};
}
`; `;
const StyledErrorHelper = styled.div` const StyledErrorHelper = styled.div`
@@ -79,30 +84,27 @@ const StyledErrorHelper = styled.div`
const StyledLeftIconContainer = styled.div` const StyledLeftIconContainer = styled.div`
align-items: center; align-items: center;
background-color: ${({ theme }) => theme.background.transparent.lighter};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-bottom-left-radius: ${({ theme }) => theme.border.radius.sm};
border-right: none;
border-top-left-radius: ${({ theme }) => theme.border.radius.sm};
display: flex; display: flex;
justify-content: center; justify-content: center;
padding-left: ${({ theme }) => theme.spacing(2)}; padding-left: ${({ theme }) => theme.spacing(2)};
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
`; `;
const StyledTrailingIconContainer = styled.div< const StyledTrailingIconContainer = styled.div<
Pick<TextInputV2ComponentProps, 'error'> Pick<TextInputV2ComponentProps, 'error'>
>` >`
align-items: center; align-items: center;
background-color: ${({ theme }) => theme.background.transparent.lighter};
border: 1px solid
${({ theme, error }) =>
error ? theme.border.color.danger : theme.border.color.medium};
border-bottom-right-radius: ${({ theme }) => theme.border.radius.sm};
border-left: none;
border-top-right-radius: ${({ theme }) => theme.border.radius.sm};
display: flex; display: flex;
justify-content: center; justify-content: center;
padding-right: ${({ theme }) => theme.spacing(1)}; padding-right: ${({ theme }) => theme.spacing(1)};
position: absolute;
top: 0;
bottom: 0;
right: 0;
margin: auto 0;
`; `;
const StyledTrailingIcon = styled.div` const StyledTrailingIcon = styled.div`

View File

@@ -27,7 +27,7 @@ const StyledDropdownMenu = styled.div<{
flex-direction: column; flex-direction: column;
z-index: 30; z-index: 30;
width: ${({ width = 160 }) => width: ${({ width = 200 }) =>
typeof width === 'number' ? `${width}px` : width}; typeof width === 'number' ? `${width}px` : width};
`; `;

View File

@@ -1,6 +1,6 @@
import { act } from 'react-dom/test-utils';
import { expect } from '@storybook/test'; import { expect } from '@storybook/test';
import { renderHook } from '@testing-library/react'; import { renderHook } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { RecoilRoot } from 'recoil'; import { RecoilRoot } from 'recoil';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
@@ -57,7 +57,7 @@ describe('useDropdown', () => {
wrapper: Wrapper, wrapper: Wrapper,
}); });
expect(result.current.dropdownWidth).toBe(160); expect(result.current.dropdownWidth).toBe(200);
await act(async () => { await act(async () => {
result.current.setDropdownWidth(220); result.current.setDropdownWidth(220);

View File

@@ -4,5 +4,5 @@ export const dropdownWidthComponentState = createComponentState<
number | undefined number | undefined
>({ >({
key: 'dropdownWidthComponentState', key: 'dropdownWidthComponentState',
defaultValue: 160, defaultValue: 200,
}); });

View File

@@ -4,8 +4,8 @@ import { IconLayoutKanban, IconTable, IconX } from 'twenty-ui';
import { IconPicker } from '@/ui/input/components/IconPicker'; import { IconPicker } from '@/ui/input/components/IconPicker';
import { Select } from '@/ui/input/components/Select'; import { Select } from '@/ui/input/components/Select';
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
@@ -120,11 +120,11 @@ export const ViewPickerContentCreateMode = () => {
disableBlur disableBlur
onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)} onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)}
/> />
<DropdownMenuInput <TextInputV2
value={viewPickerInputName} value={viewPickerInputName}
onChange={(event) => { onChange={(value) => {
setViewPickerIsDirty(true); setViewPickerIsDirty(true);
setViewPickerInputName(event.target.value); setViewPickerInputName(value);
}} }}
autoFocus autoFocus
/> />

View File

@@ -2,8 +2,8 @@ import { Key } from 'ts-key-enum';
import { IconChevronLeft } from 'twenty-ui'; import { IconChevronLeft } from 'twenty-ui';
import { IconPicker } from '@/ui/input/components/IconPicker'; import { IconPicker } from '@/ui/input/components/IconPicker';
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
@@ -79,11 +79,11 @@ export const ViewPickerContentEditMode = () => {
disableBlur disableBlur
onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)} onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)}
/> />
<DropdownMenuInput <TextInputV2
value={viewPickerInputName} value={viewPickerInputName}
onChange={(event) => { onChange={(value) => {
setViewPickerIsDirty(true); setViewPickerIsDirty(true);
setViewPickerInputName(event.target.value); setViewPickerInputName(value);
}} }}
autoFocus autoFocus
/> />

View File

@@ -7,10 +7,10 @@ import { SignInUpForm } from '@/auth/sign-in-up/components/SignInUpForm';
import { SignInUpMode, useSignInUp } from '@/auth/sign-in-up/hooks/useSignInUp'; import { SignInUpMode, useSignInUp } from '@/auth/sign-in-up/hooks/useSignInUp';
import { useSignInUpForm } from '@/auth/sign-in-up/hooks/useSignInUpForm'; import { useSignInUpForm } from '@/auth/sign-in-up/hooks/useSignInUpForm';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { AnimatedEaseIn } from 'twenty-ui';
import { isDefined } from '~/utils/isDefined';
import { SignInUpStep } from '@/auth/states/signInUpStepState'; import { SignInUpStep } from '@/auth/states/signInUpStepState';
import { IconLockCustom } from '@ui/display/icon/components/IconLock'; import { IconLockCustom } from '@ui/display/icon/components/IconLock';
import { AnimatedEaseIn } from 'twenty-ui';
import { isDefined } from '~/utils/isDefined';
import { SSOWorkspaceSelection } from './SSOWorkspaceSelection'; import { SSOWorkspaceSelection } from './SSOWorkspaceSelection';
export const SignInUp = () => { export const SignInUp = () => {