Fixed dropdown blur and unified components (#9062)

- Removed disableBlur property from dropdown because it is no longer
needed since there's only one OverlayContainer component so there can be
only one blur at a time.
- Removed blur CSS properties from every component that used it because
one standalone OverlayContainer is able to handle all cases if placed
properly.
- Also removed disableBackgroundBlur property from SingleRecordSelect
- Removed FieldInputOverlay and FieldTextAreaOverlay components that
were a first attempt to create something like an OverlayContainer
- Used new unified OverlayContainer in RecordInlineCell and
RecordTableCell
- Fixed ScrollWrapper so that it works well both for dropdown with non
overflowing content and dropdown with overflowing content.
- Removed export default value on SearchVariablesDropdown as it is not
used in this codebase
- Refactored SearchVariablesDropdown function as component anti-pattern
- Refactored SearchVariablesDropdownFieldItems UI problems with
separator and missing ScrollWrapper behavior
- Refactored SearchVariablesDropdownObjectItems with UI problems with
separator and missing ScrollWrapper behavior
- Fixed blur bug on Firefox due to wrong placement of the element that
had the CSS property. Blur works on Firefox it it's on the container
that has the highest level in the tree.
- Fixed bug in ActivityTargetInlineCell by removing an unnecessary
container component StyledSelectContainer
- Unified problems of field height with a new common component
FieldInputContainer, instead of putting width and height at the wrong
abstraction level, width and height are a field's concern not a
dropdown, overlay or low-level input concern.
- Fixed block editor dropdown with new OverlayContainer
- Aligning field dropdown with their anchor on inline and table cells,
there are still many small pixel misalignments that give a low quality
impression.
- Fixed FormDateFieldInput that was missing OverlayContainer
This commit is contained in:
Lucas Bordeau
2024-12-17 15:28:26 +01:00
committed by GitHub
parent 4aabe9e224
commit 860dec3428
66 changed files with 427 additions and 602 deletions

View File

@ -15,11 +15,6 @@ import { useRecoilValue } from 'recoil';
import { isDefined, MOBILE_VIEWPORT } from 'twenty-ui';
const StyledAddressContainer = styled.div`
background: ${({ theme }) => theme.background.secondary};
border: 1px solid ${({ theme }) => theme.border.color.light};
border-radius: ${({ theme }) => theme.border.radius.md};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
padding: 4px 8px;
width: 344px;
@ -27,11 +22,6 @@ const StyledAddressContainer = styled.div`
margin-bottom: 6px;
}
input {
background-color: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
}
@media (max-width: ${MOBILE_VIEWPORT}px) {
width: auto;
min-width: 100px;

View File

@ -21,10 +21,6 @@ export const StyledIMaskInput = styled(IMaskInput)<StyledInputProps>`
const StyledContainer = styled.div`
align-items: center;
border: none;
border-radius: ${({ theme }) => theme.border.radius.sm};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
display: flex;
justify-content: center;
`;

View File

@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { useRef, useState } from 'react';
import { Nullable } from 'twenty-ui';
import {
@ -9,15 +9,6 @@ import {
} from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useRef, useState } from 'react';
export const StyledCalendarContainer = styled.div`
background: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
border: 1px solid ${({ theme }) => theme.border.color.light};
border-radius: ${({ theme }) => theme.border.radius.md};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
`;
export type DateInputProps = {
value: Nullable<Date>;
@ -89,19 +80,17 @@ export const DateInput = ({
return (
<div ref={wrapperRef}>
<StyledCalendarContainer>
<InternalDatePicker
date={internalValue ?? new Date()}
onChange={handleChange}
onMouseSelect={handleMouseSelect}
clearable={clearable ? clearable : false}
isDateTimeInput={isDateTimeInput}
onEnter={onEnter}
onEscape={onEscape}
onClear={handleClear}
hideHeaderInput={hideHeaderInput}
/>
</StyledCalendarContainer>
<InternalDatePicker
date={internalValue ?? new Date()}
onChange={handleChange}
onMouseSelect={handleMouseSelect}
clearable={clearable ? clearable : false}
isDateTimeInput={isDateTimeInput}
onEnter={onEnter}
onEscape={onEscape}
onClear={handleClear}
hideHeaderInput={hideHeaderInput}
/>
</div>
);
};

View File

@ -12,22 +12,18 @@ import { FieldDoubleText } from '@/object-record/record-field/types/FieldDoubleT
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { isDefined } from '~/utils/isDefined';
import { FieldInputContainer } from '@/ui/field/input/components/FieldInputContainer';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { splitFullName } from '~/utils/format/spiltFullName';
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
import { StyledTextInput } from './TextInput';
const StyledContainer = styled.div`
align-items: center;
display: flex;
justify-content: space-between;
input {
width: 100%;
}
& > input:last-child {
border-left: 1px solid ${({ theme }) => theme.border.color.medium};
border-left: 1px solid ${({ theme }) => theme.border.color.strong};
padding-left: ${({ theme }) => theme.spacing(2)};
}
`;
@ -186,39 +182,41 @@ export const DoubleTextInput = ({
};
return (
<StyledContainer ref={containerRef}>
<StyledTextInput
autoComplete="off"
autoFocus
onFocus={() => setFocusPosition('left')}
ref={firstValueInputRef}
placeholder={firstValuePlaceholder}
value={firstInternalValue}
onChange={(event: ChangeEvent<HTMLInputElement>) => {
handleChange(
turnIntoEmptyStringIfWhitespacesOnly(event.target.value),
secondInternalValue,
);
}}
onPaste={(event: ClipboardEvent<HTMLInputElement>) =>
handleOnPaste(event)
}
onClick={handleClickToPreventParentClickEvents}
/>
<StyledTextInput
autoComplete="off"
onFocus={() => setFocusPosition('right')}
ref={secondValueInputRef}
placeholder={secondValuePlaceholder}
value={secondInternalValue}
onChange={(event: ChangeEvent<HTMLInputElement>) => {
handleChange(
firstInternalValue,
turnIntoEmptyStringIfWhitespacesOnly(event.target.value),
);
}}
onClick={handleClickToPreventParentClickEvents}
/>
</StyledContainer>
<FieldInputContainer>
<StyledContainer ref={containerRef}>
<StyledTextInput
autoComplete="off"
autoFocus
onFocus={() => setFocusPosition('left')}
ref={firstValueInputRef}
placeholder={firstValuePlaceholder}
value={firstInternalValue}
onChange={(event: ChangeEvent<HTMLInputElement>) => {
handleChange(
turnIntoEmptyStringIfWhitespacesOnly(event.target.value),
secondInternalValue,
);
}}
onPaste={(event: ClipboardEvent<HTMLInputElement>) =>
handleOnPaste(event)
}
onClick={handleClickToPreventParentClickEvents}
/>
<StyledTextInput
autoComplete="off"
onFocus={() => setFocusPosition('right')}
ref={secondValueInputRef}
placeholder={secondValuePlaceholder}
value={secondInternalValue}
onChange={(event: ChangeEvent<HTMLInputElement>) => {
handleChange(
firstInternalValue,
turnIntoEmptyStringIfWhitespacesOnly(event.target.value),
);
}}
onClick={handleClickToPreventParentClickEvents}
/>
</StyledContainer>
</FieldInputContainer>
);
};

View File

@ -0,0 +1,10 @@
import styled from '@emotion/styled';
// eslint-disable-next-line @nx/workspace-styled-components-prefixed-with-styled
export const FieldInputContainer = styled.div`
align-items: center;
display: flex;
min-height: 32px;
min-width: 200px;
width: 100%;
`;

View File

@ -1,16 +0,0 @@
import styled from '@emotion/styled';
import { OVERLAY_BACKGROUND } from 'twenty-ui';
const StyledFieldInputOverlay = styled.div`
align-items: center;
border: ${({ theme }) => `1px solid ${theme.border.color.light}`};
border-radius: ${({ theme }) => theme.border.radius.sm};
display: flex;
height: 32px;
justify-content: space-between;
margin: -1px;
width: 100%;
${OVERLAY_BACKGROUND}
`;
export const FieldInputOverlay = StyledFieldInputOverlay;

View File

@ -1,16 +0,0 @@
import styled from '@emotion/styled';
import { OVERLAY_BACKGROUND } from 'twenty-ui';
const StyledFieldTextAreaOverlay = styled.div`
align-items: center;
border-radius: ${({ theme }) => theme.border.radius.sm};
display: flex;
margin: -1px;
max-height: 420px;
position: absolute;
top: 0;
width: 100%;
${OVERLAY_BACKGROUND}
`;
export const FieldTextAreaOverlay = StyledFieldTextAreaOverlay;

View File

@ -33,33 +33,14 @@ const StyledTextArea = styled(TextareaAutosize)`
resize: none;
max-height: 400px;
width: calc(100% - ${({ theme }) => theme.spacing(7)});
background: transparent;
line-height: 18px;
`;
const StyledTextAreaContainer = styled.div`
background: ${({ theme }) => theme.background.primary};
border: ${({ theme }) => `1px solid ${theme.border.color.medium}`};
position: relative;
width: 100%;
padding-top: ${({ theme }) => theme.spacing(2)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
border-radius: ${({ theme }) => theme.border.radius.sm};
@supports (
(backdrop-filter: blur(20px)) or (-webkit-backdrop-filter: blur(20px))
) {
background: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
-webkit-backdrop-filter: ${({ theme }) => theme.blur.medium};
}
`;
const StyledLightIconButtonContainer = styled.div`
background: transparent;
position: absolute;
top: 18px;
top: 16px;
transform: translateY(-50%);
right: 0;
`;
@ -114,7 +95,7 @@ export const TextAreaInput = ({
});
return (
<StyledTextAreaContainer>
<>
<StyledTextArea
placeholder={placeholder}
disabled={disabled}
@ -130,6 +111,6 @@ export const TextAreaInput = ({
<LightCopyIconButton copyText={internalText} />
</StyledLightIconButtonContainer>
)}
</StyledTextAreaContainer>
</>
);
};