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

@ -1,4 +1,3 @@
import styled from '@emotion/styled';
import { isNull } from '@sniptt/guards'; import { isNull } from '@sniptt/guards';
import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil'; import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
@ -32,12 +31,6 @@ import { MultiRecordSelect } from '@/object-record/relation-picker/components/Mu
import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext'; import { RecordPickerComponentInstanceContext } from '@/object-record/relation-picker/states/contexts/RecordPickerComponentInstanceContext';
import { prefillRecord } from '@/object-record/utils/prefillRecord'; import { prefillRecord } from '@/object-record/utils/prefillRecord';
const StyledSelectContainer = styled.div`
position: absolute;
left: 0;
top: 0;
`;
type ActivityTargetInlineCellEditModeProps = { type ActivityTargetInlineCellEditModeProps = {
activity: Task | Note; activity: Task | Note;
activityTargetWithTargetRecords: ActivityTargetWithTargetRecord[]; activityTargetWithTargetRecords: ActivityTargetWithTargetRecord[];
@ -282,7 +275,7 @@ export const ActivityTargetInlineCellEditMode = ({
); );
return ( return (
<StyledSelectContainer> <>
<RecordPickerComponentInstanceContext.Provider <RecordPickerComponentInstanceContext.Provider
value={{ instanceId: recordPickerInstanceId }} value={{ instanceId: recordPickerInstanceId }}
> >
@ -295,6 +288,6 @@ export const ActivityTargetInlineCellEditMode = ({
<ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect /> <ActivityTargetInlineCellEditModeMultiRecordsSearchFilterEffect />
<MultiRecordSelect onSubmit={handleSubmit} onChange={handleChange} /> <MultiRecordSelect onSubmit={handleSubmit} onChange={handleChange} />
</RecordPickerComponentInstanceContext.Provider> </RecordPickerComponentInstanceContext.Provider>
</StyledSelectContainer> </>
); );
}; };

View File

@ -137,7 +137,6 @@ export const AdvancedFilterAddFilterRuleSelect = ({
return ( return (
<Dropdown <Dropdown
disableBlur
dropdownId={dropdownId} dropdownId={dropdownId}
clickableComponent={ clickableComponent={
<LightButton Icon={IconPlus} title="Add filter rule" /> <LightButton Icon={IconPlus} title="Add filter rule" />

View File

@ -22,7 +22,6 @@ export const AdvancedFilterLogicalOperatorDropdown = ({
return ( return (
<Select <Select
disableBlur
fullWidth fullWidth
dropdownId={`advanced-filter-logical-operator-${viewFilterGroup.id}`} dropdownId={`advanced-filter-logical-operator-${viewFilterGroup.id}`}
value={viewFilterGroup.logicalOperator} value={viewFilterGroup.logicalOperator}

View File

@ -68,7 +68,6 @@ export const AdvancedFilterRuleOptionsDropdown = ({
return ( return (
<Dropdown <Dropdown
disableBlur
dropdownId={dropdownId} dropdownId={dropdownId}
clickableComponent={ clickableComponent={
<AdvancedFilterRuleOptionsDropdownButton dropdownId={dropdownId} /> <AdvancedFilterRuleOptionsDropdownButton dropdownId={dropdownId} />

View File

@ -41,7 +41,6 @@ export const AdvancedFilterViewFilterFieldSelect = ({
return ( return (
<StyledContainer> <StyledContainer>
<Dropdown <Dropdown
disableBlur
dropdownId={advancedFilterDropdownId} dropdownId={advancedFilterDropdownId}
clickableComponent={ clickableComponent={
<SelectControl <SelectControl

View File

@ -76,7 +76,6 @@ export const AdvancedFilterViewFilterOperandSelect = ({
return ( return (
<StyledContainer> <StyledContainer>
<Dropdown <Dropdown
disableBlur
dropdownId={dropdownId} dropdownId={dropdownId}
clickableComponent={ clickableComponent={
<SelectControl <SelectControl

View File

@ -39,7 +39,6 @@ export const AdvancedFilterViewFilterValueInput = ({
return ( return (
<Dropdown <Dropdown
disableBlur
dropdownId={dropdownId} dropdownId={dropdownId}
clickableComponent={ clickableComponent={
<SelectControl <SelectControl

View File

@ -98,7 +98,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
{/** TODO: Should be removed when view settings contains more options */} {/** TODO: Should be removed when view settings contains more options */}
{viewType === ViewType.Kanban && ( {viewType === ViewType.Kanban && (
<> <>
<DropdownMenuItemsContainer> <DropdownMenuItemsContainer withoutScrollWrapper>
<MenuItem <MenuItem
onClick={() => onContentChange('viewSettings')} onClick={() => onContentChange('viewSettings')}
LeftIcon={IconLayout} LeftIcon={IconLayout}
@ -109,7 +109,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
<DropdownMenuSeparator /> <DropdownMenuSeparator />
</> </>
)} )}
<DropdownMenuItemsContainer> <DropdownMenuItemsContainer withoutScrollWrapper>
<MenuItem <MenuItem
onClick={() => onContentChange('fields')} onClick={() => onContentChange('fields')}
LeftIcon={IconTag} LeftIcon={IconTag}

View File

@ -81,11 +81,8 @@ const StyledBoardCard = styled.div<{ selected: boolean }>`
`; `;
const StyledTextInput = styled(TextInput)` const StyledTextInput = styled(TextInput)`
backdrop-filter: blur(12px) saturate(200%) contrast(50%) brightness(130%);
background: ${({ theme }) => theme.background.primary};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
width: ${({ theme }) => theme.spacing(53)};
border-radius: ${({ theme }) => theme.border.radius.sm}; border-radius: ${({ theme }) => theme.border.radius.sm};
width: ${({ theme }) => theme.spacing(53)};
`; `;
const StyledBoardCardWrapper = styled.div` const StyledBoardCardWrapper = styled.div`

View File

@ -6,6 +6,7 @@ import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { MenuItem } from 'twenty-ui'; import { MenuItem } from 'twenty-ui';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
const StyledMenuContainer = styled.div` const StyledMenuContainer = styled.div`
position: absolute; position: absolute;
@ -20,6 +21,7 @@ type RecordBoardColumnDropdownMenuProps = {
stageId: string; stageId: string;
}; };
// TODO: unify and use Dropdown component
export const RecordBoardColumnDropdownMenu = ({ export const RecordBoardColumnDropdownMenu = ({
onClose, onClose,
}: RecordBoardColumnDropdownMenuProps) => { }: RecordBoardColumnDropdownMenuProps) => {
@ -39,21 +41,23 @@ export const RecordBoardColumnDropdownMenu = ({
return ( return (
<StyledMenuContainer ref={boardColumnMenuRef}> <StyledMenuContainer ref={boardColumnMenuRef}>
<DropdownMenu data-select-disable> <OverlayContainer>
<DropdownMenuItemsContainer> <DropdownMenu data-select-disable>
{recordGroupActions.map((action) => ( <DropdownMenuItemsContainer>
<MenuItem {recordGroupActions.map((action) => (
key={action.id} <MenuItem
onClick={() => { key={action.id}
action.callback(); onClick={() => {
closeMenu(); action.callback();
}} closeMenu();
LeftIcon={action.icon} }}
text={action.label} LeftIcon={action.icon}
/> text={action.label}
))} />
</DropdownMenuItemsContainer> ))}
</DropdownMenu> </DropdownMenuItemsContainer>
</DropdownMenu>
</OverlayContainer>
</StyledMenuContainer> </StyledMenuContainer>
); );
}; };

View File

@ -1,23 +1,10 @@
import styled from '@emotion/styled';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard'; import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
import { recordBoardNewRecordByColumnIdSelector } from '@/object-record/record-board/states/selectors/recordBoardNewRecordByColumnIdSelector'; import { recordBoardNewRecordByColumnIdSelector } from '@/object-record/record-board/states/selectors/recordBoardNewRecordByColumnIdSelector';
import { SingleRecordSelect } from '@/object-record/relation-picker/components/SingleRecordSelect'; import { SingleRecordSelect } from '@/object-record/relation-picker/components/SingleRecordSelect';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
const StyledCompanyPickerContainer = styled.div`
align-items: center;
align-self: baseline;
background-color: ${({ theme }) => theme.background.primary};
border: none;
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.font.color.tertiary};
cursor: pointer;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
`;
export const RecordBoardColumnNewOpportunity = ({ export const RecordBoardColumnNewOpportunity = ({
columnId, columnId,
position, position,
@ -36,9 +23,8 @@ export const RecordBoardColumnNewOpportunity = ({
return ( return (
<> <>
{newRecord.isCreating && newRecord.position === position && ( {newRecord.isCreating && newRecord.position === position && (
<StyledCompanyPickerContainer> <OverlayContainer>
<SingleRecordSelect <SingleRecordSelect
disableBackgroundBlur
onCancel={() => handleCreateSuccess(position, columnId, false)} onCancel={() => handleCreateSuccess(position, columnId, false)}
onRecordSelected={(company) => onRecordSelected={(company) =>
company ? handleEntitySelect(position, company) : null company ? handleEntitySelect(position, company) : null
@ -47,7 +33,7 @@ export const RecordBoardColumnNewOpportunity = ({
recordPickerInstanceId="relation-picker" recordPickerInstanceId="relation-picker"
selectedRecordIds={[]} selectedRecordIds={[]}
/> />
</StyledCompanyPickerContainer> </OverlayContainer>
)} )}
</> </>
); );

View File

@ -3,7 +3,6 @@ import { FormFieldInputInputContainer } from '@/object-record/record-field/form-
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer'; import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
import { VariableChip } from '@/object-record/record-field/form-types/components/VariableChip'; import { VariableChip } from '@/object-record/record-field/form-types/components/VariableChip';
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
import { StyledCalendarContainer } from '@/ui/field/input/components/DateInput';
import { InputLabel } from '@/ui/input/components/InputLabel'; import { InputLabel } from '@/ui/input/components/InputLabel';
import { import {
InternalDatePicker, InternalDatePicker,
@ -16,6 +15,7 @@ import { MIN_DATE } from '@/ui/input/components/internal/date/constants/MinDate'
import { parseDateToString } from '@/ui/input/components/internal/date/utils/parseDateToString'; import { parseDateToString } from '@/ui/input/components/internal/date/utils/parseDateToString';
import { parseStringToDate } from '@/ui/input/components/internal/date/utils/parseStringToDate'; import { parseStringToDate } from '@/ui/input/components/internal/date/utils/parseStringToDate';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { UserContext } from '@/users/contexts/UserContext'; import { UserContext } from '@/users/contexts/UserContext';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString'; import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
@ -338,7 +338,7 @@ export const FormDateFieldInput = ({
{draftValue.mode === 'edit' ? ( {draftValue.mode === 'edit' ? (
<StyledDateInputContainer> <StyledDateInputContainer>
<StyledDateInputAbsoluteContainer> <StyledDateInputAbsoluteContainer>
<StyledCalendarContainer> <OverlayContainer>
<InternalDatePicker <InternalDatePicker
date={pickerDate ?? new Date()} date={pickerDate ?? new Date()}
isDateTimeInput={false} isDateTimeInput={false}
@ -349,7 +349,7 @@ export const FormDateFieldInput = ({
onClear={handlePickerClear} onClear={handlePickerClear}
hideHeaderInput hideHeaderInput
/> />
</StyledCalendarContainer> </OverlayContainer>
</StyledDateInputAbsoluteContainer> </StyledDateInputAbsoluteContainer>
</StyledDateInputContainer> </StyledDateInputContainer>
) : null} ) : null}

View File

@ -9,6 +9,7 @@ import { SelectOption } from '@/spreadsheet-import/types';
import { SelectDisplay } from '@/ui/field/display/components/SelectDisplay'; import { SelectDisplay } from '@/ui/field/display/components/SelectDisplay';
import { SelectInput } from '@/ui/field/input/components/SelectInput'; import { SelectInput } from '@/ui/field/input/components/SelectInput';
import { InputLabel } from '@/ui/input/components/InputLabel'; import { InputLabel } from '@/ui/input/components/InputLabel';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList'; import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
@ -238,19 +239,21 @@ export const FormSelectFieldInput = ({
<StyledSelectInputContainer> <StyledSelectInputContainer>
{draftValue.type === 'static' && {draftValue.type === 'static' &&
draftValue.editingMode === 'edit' && ( draftValue.editingMode === 'edit' && (
<SelectInput <OverlayContainer>
selectableListId={SINGLE_RECORD_SELECT_BASE_LIST} <SelectInput
selectableItemIdArray={optionIds} selectableListId={SINGLE_RECORD_SELECT_BASE_LIST}
hotkeyScope={hotkeyScope} selectableItemIdArray={optionIds}
onEnter={handleSelectEnter} hotkeyScope={hotkeyScope}
onOptionSelected={handleSubmit} onEnter={handleSelectEnter}
options={options} onOptionSelected={handleSubmit}
onCancel={onCancel} options={options}
defaultOption={selectedOption} onCancel={onCancel}
onFilterChange={setFilteredOptions} defaultOption={selectedOption}
onClear={handleClearField} onFilterChange={setFilteredOptions}
clearLabel={clearLabel} onClear={handleClearField}
/> clearLabel={clearLabel}
/>
</OverlayContainer>
)} )}
</StyledSelectInputContainer> </StyledSelectInputContainer>

View File

@ -4,7 +4,6 @@ import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata'; import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata';
import { CurrencyInput } from '@/ui/field/input/components/CurrencyInput'; import { CurrencyInput } from '@/ui/field/input/components/CurrencyInput';
import { FieldInputOverlay } from '../../../../../ui/field/input/components/FieldInputOverlay';
import { useCurrencyField } from '../../hooks/useCurrencyField'; import { useCurrencyField } from '../../hooks/useCurrencyField';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
@ -118,21 +117,19 @@ export const CurrencyFieldInput = ({
}; };
return ( return (
<FieldInputOverlay> <CurrencyInput
<CurrencyInput value={draftValue?.amount?.toString() ?? ''}
value={draftValue?.amount?.toString() ?? ''} currencyCode={currencyCode}
currencyCode={currencyCode} autoFocus
autoFocus placeholder="Currency"
placeholder="Currency" onClickOutside={handleClickOutside}
onClickOutside={handleClickOutside} onEnter={handleEnter}
onEnter={handleEnter} onEscape={handleEscape}
onEscape={handleEscape} onShiftTab={handleShiftTab}
onShiftTab={handleShiftTab} onTab={handleTab}
onTab={handleTab} onChange={handleChange}
onChange={handleChange} onSelect={handleSelect}
onSelect={handleSelect} hotkeyScope={hotkeyScope}
hotkeyScope={hotkeyScope} />
/>
</FieldInputOverlay>
); );
}; };

View File

@ -1,7 +1,6 @@
import { useFullNameField } from '@/object-record/record-field/meta-types/hooks/useFullNameField'; import { useFullNameField } from '@/object-record/record-field/meta-types/hooks/useFullNameField';
import { FieldDoubleText } from '@/object-record/record-field/types/FieldDoubleText'; import { FieldDoubleText } from '@/object-record/record-field/types/FieldDoubleText';
import { DoubleTextInput } from '@/ui/field/input/components/DoubleTextInput'; import { DoubleTextInput } from '@/ui/field/input/components/DoubleTextInput';
import { FieldInputOverlay } from '@/ui/field/input/components/FieldInputOverlay';
import { FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/FirstNamePlaceholder'; import { FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/FirstNamePlaceholder';
import { LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/LastNamePlaceholder'; import { LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/LastNamePlaceholder';
@ -79,25 +78,23 @@ export const FullNameFieldInput = ({
}; };
return ( return (
<FieldInputOverlay> <DoubleTextInput
<DoubleTextInput firstValue={draftValue?.firstName ?? ''}
firstValue={draftValue?.firstName ?? ''} secondValue={draftValue?.lastName ?? ''}
secondValue={draftValue?.lastName ?? ''} firstValuePlaceholder={
firstValuePlaceholder={ FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS
FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS }
} secondValuePlaceholder={
secondValuePlaceholder={ LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS
LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS }
} onClickOutside={handleClickOutside}
onClickOutside={handleClickOutside} onEnter={handleEnter}
onEnter={handleEnter} onEscape={handleEscape}
onEscape={handleEscape} onShiftTab={handleShiftTab}
onShiftTab={handleShiftTab} onTab={handleTab}
onTab={handleTab} onPaste={handlePaste}
onPaste={handlePaste} hotkeyScope={hotkeyScope}
hotkeyScope={hotkeyScope} onChange={handleChange}
onChange={handleChange} />
/>
</FieldInputOverlay>
); );
}; };

View File

@ -1,4 +1,3 @@
import styled from '@emotion/styled';
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
import { IconCheck, IconPlus, LightIconButton, MenuItem } from 'twenty-ui'; import { IconCheck, IconPlus, LightIconButton, MenuItem } from 'twenty-ui';
@ -18,11 +17,6 @@ import { moveArrayItem } from '~/utils/array/moveArrayItem';
import { toSpliced } from '~/utils/array/toSpliced'; import { toSpliced } from '~/utils/array/toSpliced';
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly'; import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
const StyledDropdownMenu = styled(DropdownMenu)`
margin: -1px;
position: relative;
`;
type MultiItemFieldInputProps<T> = { type MultiItemFieldInputProps<T> = {
items: T[]; items: T[];
onPersist: (updatedItems: T[]) => void; onPersist: (updatedItems: T[]) => void;
@ -164,7 +158,7 @@ export const MultiItemFieldInput = <T,>({
}; };
return ( return (
<StyledDropdownMenu ref={containerRef} width={200}> <DropdownMenu ref={containerRef} width={200}>
{!!items.length && ( {!!items.length && (
<> <>
<DropdownMenuItemsContainer> <DropdownMenuItemsContainer>
@ -222,6 +216,6 @@ export const MultiItemFieldInput = <T,>({
/> />
</DropdownMenuItemsContainer> </DropdownMenuItemsContainer>
)} )}
</StyledDropdownMenu> </DropdownMenu>
); );
}; };

View File

@ -1,8 +1,8 @@
import { TextInput } from '@/ui/field/input/components/TextInput'; import { TextInput } from '@/ui/field/input/components/TextInput';
import { FieldInputOverlay } from '../../../../../ui/field/input/components/FieldInputOverlay';
import { useNumberField } from '../../hooks/useNumberField';
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput'; import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
import { FieldInputContainer } from '@/ui/field/input/components/FieldInputContainer';
import { useNumberField } from '../../hooks/useNumberField';
export type FieldInputEvent = (persist: () => void) => void; export type FieldInputEvent = (persist: () => void) => void;
@ -57,7 +57,7 @@ export const NumberFieldInput = ({
}; };
return ( return (
<FieldInputOverlay> <FieldInputContainer>
<TextInput <TextInput
placeholder={fieldDefinition.metadata.placeHolder} placeholder={fieldDefinition.metadata.placeHolder}
autoFocus autoFocus
@ -70,6 +70,6 @@ export const NumberFieldInput = ({
hotkeyScope={hotkeyScope} hotkeyScope={hotkeyScope}
onChange={handleChange} onChange={handleChange}
/> />
</FieldInputOverlay> </FieldInputContainer>
); );
}; };

View File

@ -18,7 +18,6 @@ export const DEFAULT_PHONE_COUNTRY_CODE = '1';
const StyledCustomPhoneInput = styled(ReactPhoneNumberInput)` const StyledCustomPhoneInput = styled(ReactPhoneNumberInput)`
font-family: ${({ theme }) => theme.font.family}; font-family: ${({ theme }) => theme.font.family};
height: 32px;
${TEXT_INPUT_STYLE} ${TEXT_INPUT_STYLE}
padding: 0; padding: 0;

View File

@ -1,4 +1,3 @@
import { FieldTextAreaOverlay } from '@/ui/field/input/components/FieldTextAreaOverlay';
import { TextAreaInput } from '@/ui/field/input/components/TextAreaInput'; import { TextAreaInput } from '@/ui/field/input/components/TextAreaInput';
import { useJsonField } from '../../hooks/useJsonField'; import { useJsonField } from '../../hooks/useJsonField';
@ -59,20 +58,18 @@ export const RawJsonFieldInput = ({
}; };
return ( return (
<FieldTextAreaOverlay> <TextAreaInput
<TextAreaInput placeholder={fieldDefinition.metadata.placeHolder}
placeholder={fieldDefinition.metadata.placeHolder} autoFocus
autoFocus value={draftValue ?? ''}
value={draftValue ?? ''} onClickOutside={handleClickOutside}
onClickOutside={handleClickOutside} onEnter={handleEnter}
onEnter={handleEnter} onEscape={handleEscape}
onEscape={handleEscape} onShiftTab={handleShiftTab}
onShiftTab={handleShiftTab} onTab={handleTab}
onTab={handleTab} hotkeyScope={hotkeyScope}
hotkeyScope={hotkeyScope} onChange={handleChange}
onChange={handleChange} maxRows={25}
maxRows={25} />
/>
</FieldTextAreaOverlay>
); );
}; };

View File

@ -1,5 +1,3 @@
import styled from '@emotion/styled';
import { RelationPicker } from '@/object-record/relation-picker/components/RelationPicker'; import { RelationPicker } from '@/object-record/relation-picker/components/RelationPicker';
import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect'; import { RecordForSelect } from '@/object-record/relation-picker/types/RecordForSelect';
@ -8,12 +6,6 @@ import { useRelationField } from '../../hooks/useRelationField';
import { FieldInputEvent } from './DateTimeFieldInput'; import { FieldInputEvent } from './DateTimeFieldInput';
const StyledRelationPickerContainer = styled.div`
left: -1px;
position: absolute;
top: -1px;
`;
export type RelationToOneFieldInputProps = { export type RelationToOneFieldInputProps = {
onSubmit?: FieldInputEvent; onSubmit?: FieldInputEvent;
onCancel?: () => void; onCancel?: () => void;
@ -33,14 +25,12 @@ export const RelationToOneFieldInput = ({
}; };
return ( return (
<StyledRelationPickerContainer> <RelationPicker
<RelationPicker fieldDefinition={fieldDefinition}
fieldDefinition={fieldDefinition} selectedRecordId={fieldValue?.id}
selectedRecordId={fieldValue?.id} onSubmit={handleSubmit}
onSubmit={handleSubmit} onCancel={onCancel}
onCancel={onCancel} initialSearchFilter={initialSearchValue}
initialSearchFilter={initialSearchValue} />
/>
</StyledRelationPickerContainer>
); );
}; };

View File

@ -1,9 +1,9 @@
import { FieldTextAreaOverlay } from '@/ui/field/input/components/FieldTextAreaOverlay';
import { TextAreaInput } from '@/ui/field/input/components/TextAreaInput'; import { TextAreaInput } from '@/ui/field/input/components/TextAreaInput';
import { usePersistField } from '../../../hooks/usePersistField'; import { usePersistField } from '../../../hooks/usePersistField';
import { useTextField } from '../../hooks/useTextField'; import { useTextField } from '../../hooks/useTextField';
import { FieldInputContainer } from '@/ui/field/input/components/FieldInputContainer';
import { turnIntoUndefinedIfWhitespacesOnly } from '~/utils/string/turnIntoUndefinedIfWhitespacesOnly'; import { turnIntoUndefinedIfWhitespacesOnly } from '~/utils/string/turnIntoUndefinedIfWhitespacesOnly';
import { import {
FieldInputClickOutsideEvent, FieldInputClickOutsideEvent,
@ -57,7 +57,7 @@ export const TextFieldInput = ({
}; };
return ( return (
<FieldTextAreaOverlay> <FieldInputContainer>
<TextAreaInput <TextAreaInput
placeholder={fieldDefinition.metadata.placeHolder} placeholder={fieldDefinition.metadata.placeHolder}
autoFocus autoFocus
@ -70,6 +70,6 @@ export const TextFieldInput = ({
hotkeyScope={hotkeyScope} hotkeyScope={hotkeyScope}
onChange={handleChange} onChange={handleChange}
/> />
</FieldTextAreaOverlay> </FieldInputContainer>
); );
}; };

View File

@ -9,6 +9,7 @@ const StyledInlineCellButtonContainer = styled.div`
align-items: center; align-items: center;
display: flex; display: flex;
`; `;
export const RecordInlineCellButton = ({ Icon }: { Icon: IconComponent }) => { export const RecordInlineCellButton = ({ Icon }: { Icon: IconComponent }) => {
return ( return (
<AnimatedContainer> <AnimatedContainer>

View File

@ -1,4 +1,5 @@
import { RecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext'; import { RecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react'; import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react';
import { useContext } from 'react'; import { useContext } from 'react';
@ -11,24 +12,14 @@ const StyledInlineCellEditModeContainer = styled.div`
width: 100%; width: 100%;
position: absolute; position: absolute;
height: 24px; height: 24px;
`;
const StyledInlineCellInput = styled.div` background: transparent;
align-items: center;
display: flex;
min-height: 32px;
width: 240px;
z-index: 30;
`; `;
type RecordInlineCellEditModeProps = { type RecordInlineCellEditModeProps = {
children: React.ReactNode; children: React.ReactNode;
}; };
// TODO: Refactor this to avoid setting absolute px values.
export const RecordInlineCellEditMode = ({ export const RecordInlineCellEditMode = ({
children, children,
}: RecordInlineCellEditModeProps) => { }: RecordInlineCellEditModeProps) => {
@ -46,7 +37,7 @@ export const RecordInlineCellEditMode = ({
} }
: { : {
mainAxis: -29, mainAxis: -29,
crossAxis: -4, crossAxis: -5,
}, },
), ),
], ],
@ -59,9 +50,9 @@ export const RecordInlineCellEditMode = ({
data-testid="inline-cell-edit-mode-container" data-testid="inline-cell-edit-mode-container"
> >
{createPortal( {createPortal(
<StyledInlineCellInput ref={refs.setFloating} style={floatingStyles}> <OverlayContainer ref={refs.setFloating} style={floatingStyles}>
{children} {children}
</StyledInlineCellInput>, </OverlayContainer>,
document.body, document.body,
)} )}
</StyledInlineCellEditModeContainer> </StyledInlineCellEditModeContainer>

View File

@ -11,6 +11,7 @@ const StyledClickableContainer = styled.div<{
readonly?: boolean; readonly?: boolean;
isCentered?: boolean; isCentered?: boolean;
}>` }>`
align-items: center;
display: flex; display: flex;
gap: ${({ theme }) => theme.spacing(1)}; gap: ${({ theme }) => theme.spacing(1)};
width: 100%; width: 100%;

View File

@ -1,3 +1,4 @@
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react'; import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react';
import { ReactElement } from 'react'; import { ReactElement } from 'react';
@ -12,16 +13,6 @@ const StyledEditableCellEditModeContainer = styled.div<RecordTableCellEditModePr
height: 100%; height: 100%;
`; `;
const StyledTableCellInput = styled.div`
align-items: center;
display: flex;
min-height: 32px;
min-width: 200px;
z-index: 10;
`;
export type RecordTableCellEditModeProps = { export type RecordTableCellEditModeProps = {
children: ReactElement; children: ReactElement;
transparent?: boolean; transparent?: boolean;
@ -37,8 +28,8 @@ export const RecordTableCellEditMode = ({
middleware: [ middleware: [
flip(), flip(),
offset({ offset({
mainAxis: -31, mainAxis: -33,
crossAxis: -2, crossAxis: -3,
}), }),
], ],
whileElementsMounted: autoUpdate, whileElementsMounted: autoUpdate,
@ -49,9 +40,9 @@ export const RecordTableCellEditMode = ({
ref={refs.setReference} ref={refs.setReference}
data-testid="editable-cell-edit-mode-container" data-testid="editable-cell-edit-mode-container"
> >
<StyledTableCellInput ref={refs.setFloating} style={floatingStyles}> <OverlayContainer ref={refs.setFloating} style={floatingStyles}>
{children} {children}
</StyledTableCellInput> </OverlayContainer>
</StyledEditableCellEditModeContainer> </StyledEditableCellEditModeContainer>
); );
}; };

View File

@ -96,6 +96,7 @@ export const MultiRecordSelect = ({
[setSearchFilter], [setSearchFilter],
); );
// TODO: refactor this in a separate component
const results = ( const results = (
<DropdownMenuItemsContainer hasMaxHeight> <DropdownMenuItemsContainer hasMaxHeight>
<SelectableList <SelectableList
@ -139,7 +140,7 @@ export const MultiRecordSelect = ({
onSubmit?.(); onSubmit?.();
}} }}
/> />
<DropdownMenu ref={containerRef} data-select-disable> <DropdownMenu ref={containerRef} data-select-disable width={200}>
{dropdownPlacement?.includes('end') && ( {dropdownPlacement?.includes('end') && (
<> <>
{isDefined(onCreate) && ( {isDefined(onCreate) && (

View File

@ -9,12 +9,10 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
export type SingleRecordSelectProps = { export type SingleRecordSelectProps = {
disableBackgroundBlur?: boolean;
width?: number; width?: number;
} & SingleRecordSelectMenuItemsWithSearchProps; } & SingleRecordSelectMenuItemsWithSearchProps;
export const SingleRecordSelect = ({ export const SingleRecordSelect = ({
disableBackgroundBlur = false,
EmptyIcon, EmptyIcon,
emptyLabel, emptyLabel,
excludedRecordIds, excludedRecordIds,
@ -45,12 +43,7 @@ export const SingleRecordSelect = ({
}); });
return ( return (
<DropdownMenu <DropdownMenu ref={containerRef} width={width} data-select-disable>
disableBlur={disableBackgroundBlur}
ref={containerRef}
width={width}
data-select-disable
>
<SingleRecordSelectMenuItemsWithSearch <SingleRecordSelectMenuItemsWithSearch
{...{ {...{
EmptyIcon, EmptyIcon,

View File

@ -1,7 +1,6 @@
import { EnvironmentVariable } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTabEnvironmentVariablesSection'; import { EnvironmentVariable } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTabEnvironmentVariablesSection';
import { TextInputV2 } from '@/ui/input/components/TextInputV2'; import { TextInputV2 } from '@/ui/input/components/TextInputV2';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { TableCell } from '@/ui/layout/table/components/TableCell'; import { TableCell } from '@/ui/layout/table/components/TableCell';
@ -101,7 +100,6 @@ export const SettingsServerlessFunctionTabEnvironmentVariableTableRow = ({
</TableCell> </TableCell>
<TableCell> <TableCell>
<Dropdown <Dropdown
dropdownMenuWidth="100px"
dropdownId={dropDownId} dropdownId={dropDownId}
clickableComponent={ clickableComponent={
<LightIconButton <LightIconButton
@ -111,26 +109,24 @@ export const SettingsServerlessFunctionTabEnvironmentVariableTableRow = ({
/> />
} }
dropdownComponents={ dropdownComponents={
<DropdownMenu disableBlur disableBorder width="auto"> <DropdownMenuItemsContainer>
<DropdownMenuItemsContainer> <MenuItem
<MenuItem text={'Edit'}
text={'Edit'} LeftIcon={IconPencil}
LeftIcon={IconPencil} onClick={() => {
onClick={() => { setEditMode(true);
setEditMode(true); closeDropdown();
closeDropdown(); }}
}} />
/> <MenuItem
<MenuItem text={'Delete'}
text={'Delete'} LeftIcon={IconTrash}
LeftIcon={IconTrash} onClick={() => {
onClick={() => { onDelete();
onDelete(); closeDropdown();
closeDropdown(); }}
}} />
/> </DropdownMenuItemsContainer>
</DropdownMenuItemsContainer>
</DropdownMenu>
} }
dropdownHotkeyScope={{ dropdownHotkeyScope={{
scope: dropDownId, scope: dropDownId,

View File

@ -15,11 +15,6 @@ import { useRecoilValue } from 'recoil';
import { isDefined, MOBILE_VIEWPORT } from 'twenty-ui'; import { isDefined, MOBILE_VIEWPORT } from 'twenty-ui';
const StyledAddressContainer = styled.div` 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; padding: 4px 8px;
width: 344px; width: 344px;
@ -27,11 +22,6 @@ const StyledAddressContainer = styled.div`
margin-bottom: 6px; margin-bottom: 6px;
} }
input {
background-color: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
}
@media (max-width: ${MOBILE_VIEWPORT}px) { @media (max-width: ${MOBILE_VIEWPORT}px) {
width: auto; width: auto;
min-width: 100px; min-width: 100px;

View File

@ -21,10 +21,6 @@ export const StyledIMaskInput = styled(IMaskInput)<StyledInputProps>`
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center; align-items: center;
border: none;
border-radius: ${({ theme }) => theme.border.radius.sm};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
display: flex; display: flex;
justify-content: center; 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 { Nullable } from 'twenty-ui';
import { import {
@ -9,15 +9,6 @@ import {
} from '@/ui/input/components/internal/date/components/InternalDatePicker'; } from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; 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 = { export type DateInputProps = {
value: Nullable<Date>; value: Nullable<Date>;
@ -89,19 +80,17 @@ export const DateInput = ({
return ( return (
<div ref={wrapperRef}> <div ref={wrapperRef}>
<StyledCalendarContainer> <InternalDatePicker
<InternalDatePicker date={internalValue ?? new Date()}
date={internalValue ?? new Date()} onChange={handleChange}
onChange={handleChange} onMouseSelect={handleMouseSelect}
onMouseSelect={handleMouseSelect} clearable={clearable ? clearable : false}
clearable={clearable ? clearable : false} isDateTimeInput={isDateTimeInput}
isDateTimeInput={isDateTimeInput} onEnter={onEnter}
onEnter={onEnter} onEscape={onEscape}
onEscape={onEscape} onClear={handleClear}
onClear={handleClear} hideHeaderInput={hideHeaderInput}
hideHeaderInput={hideHeaderInput} />
/>
</StyledCalendarContainer>
</div> </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 { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
import { FieldInputContainer } from '@/ui/field/input/components/FieldInputContainer';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { splitFullName } from '~/utils/format/spiltFullName'; import { splitFullName } from '~/utils/format/spiltFullName';
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly'; import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
import { StyledTextInput } from './TextInput'; import { StyledTextInput } from './TextInput';
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
input {
width: 100%;
}
& > input:last-child { & > 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)}; padding-left: ${({ theme }) => theme.spacing(2)};
} }
`; `;
@ -186,39 +182,41 @@ export const DoubleTextInput = ({
}; };
return ( return (
<StyledContainer ref={containerRef}> <FieldInputContainer>
<StyledTextInput <StyledContainer ref={containerRef}>
autoComplete="off" <StyledTextInput
autoFocus autoComplete="off"
onFocus={() => setFocusPosition('left')} autoFocus
ref={firstValueInputRef} onFocus={() => setFocusPosition('left')}
placeholder={firstValuePlaceholder} ref={firstValueInputRef}
value={firstInternalValue} placeholder={firstValuePlaceholder}
onChange={(event: ChangeEvent<HTMLInputElement>) => { value={firstInternalValue}
handleChange( onChange={(event: ChangeEvent<HTMLInputElement>) => {
turnIntoEmptyStringIfWhitespacesOnly(event.target.value), handleChange(
secondInternalValue, turnIntoEmptyStringIfWhitespacesOnly(event.target.value),
); secondInternalValue,
}} );
onPaste={(event: ClipboardEvent<HTMLInputElement>) => }}
handleOnPaste(event) onPaste={(event: ClipboardEvent<HTMLInputElement>) =>
} handleOnPaste(event)
onClick={handleClickToPreventParentClickEvents} }
/> onClick={handleClickToPreventParentClickEvents}
<StyledTextInput />
autoComplete="off" <StyledTextInput
onFocus={() => setFocusPosition('right')} autoComplete="off"
ref={secondValueInputRef} onFocus={() => setFocusPosition('right')}
placeholder={secondValuePlaceholder} ref={secondValueInputRef}
value={secondInternalValue} placeholder={secondValuePlaceholder}
onChange={(event: ChangeEvent<HTMLInputElement>) => { value={secondInternalValue}
handleChange( onChange={(event: ChangeEvent<HTMLInputElement>) => {
firstInternalValue, handleChange(
turnIntoEmptyStringIfWhitespacesOnly(event.target.value), firstInternalValue,
); turnIntoEmptyStringIfWhitespacesOnly(event.target.value),
}} );
onClick={handleClickToPreventParentClickEvents} }}
/> onClick={handleClickToPreventParentClickEvents}
</StyledContainer> />
</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; resize: none;
max-height: 400px; max-height: 400px;
width: calc(100% - ${({ theme }) => theme.spacing(7)}); width: calc(100% - ${({ theme }) => theme.spacing(7)});
background: transparent;
line-height: 18px; 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` const StyledLightIconButtonContainer = styled.div`
background: transparent; background: transparent;
position: absolute; position: absolute;
top: 18px; top: 16px;
transform: translateY(-50%); transform: translateY(-50%);
right: 0; right: 0;
`; `;
@ -114,7 +95,7 @@ export const TextAreaInput = ({
}); });
return ( return (
<StyledTextAreaContainer> <>
<StyledTextArea <StyledTextArea
placeholder={placeholder} placeholder={placeholder}
disabled={disabled} disabled={disabled}
@ -130,6 +111,6 @@ export const TextAreaInput = ({
<LightCopyIconButton copyText={internalText} /> <LightCopyIconButton copyText={internalText} />
</StyledLightIconButtonContainer> </StyledLightIconButtonContainer>
)} )}
</StyledTextAreaContainer> </>
); );
}; };

View File

@ -3,11 +3,11 @@ import { useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { import {
IconApps, IconApps,
IconComponent,
useIcons,
IconButton, IconButton,
IconButtonVariant, IconButtonVariant,
IconComponent,
LightIconButton, LightIconButton,
useIcons,
} from 'twenty-ui'; } from 'twenty-ui';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
@ -33,7 +33,6 @@ export type IconPickerProps = {
onOpen?: () => void; onOpen?: () => void;
variant?: IconButtonVariant; variant?: IconButtonVariant;
className?: string; className?: string;
disableBlur?: boolean;
}; };
const StyledMenuIconItemsContainer = styled.div` const StyledMenuIconItemsContainer = styled.div`
@ -90,7 +89,6 @@ export const IconPicker = ({
onClose, onClose,
onOpen, onOpen,
variant = 'secondary', variant = 'secondary',
disableBlur = false,
className, className,
}: IconPickerProps) => { }: IconPickerProps) => {
const [searchString, setSearchString] = useState(''); const [searchString, setSearchString] = useState('');
@ -172,7 +170,6 @@ export const IconPicker = ({
/> />
} }
dropdownMenuWidth={176} dropdownMenuWidth={176}
disableBlur={disableBlur}
dropdownComponents={ dropdownComponents={
<SelectableList <SelectableList
selectableListId="icon-list" selectableListId="icon-list"

View File

@ -32,7 +32,6 @@ export type SelectProps<Value extends SelectValue> = {
className?: string; className?: string;
disabled?: boolean; disabled?: boolean;
selectSizeVariant?: SelectSizeVariant; selectSizeVariant?: SelectSizeVariant;
disableBlur?: boolean;
dropdownId: string; dropdownId: string;
dropdownWidth?: `${string}px` | 'auto' | number; dropdownWidth?: `${string}px` | 'auto' | number;
dropdownWidthAuto?: boolean; dropdownWidthAuto?: boolean;
@ -63,7 +62,6 @@ export const Select = <Value extends SelectValue>({
className, className,
disabled: disabledFromProps, disabled: disabledFromProps,
selectSizeVariant, selectSizeVariant,
disableBlur = false,
dropdownId, dropdownId,
dropdownWidth = 176, dropdownWidth = 176,
dropdownWidthAuto = false, dropdownWidthAuto = false,
@ -135,7 +133,6 @@ export const Select = <Value extends SelectValue>({
selectSizeVariant={selectSizeVariant} selectSizeVariant={selectSizeVariant}
/> />
} }
disableBlur={disableBlur}
dropdownComponents={ dropdownComponents={
<> <>
{!!withSearchInput && ( {!!withSearchInput && (

View File

@ -32,7 +32,7 @@ export const CurrencyPickerDropdownSelect = ({
); );
return ( return (
<DropdownMenu disableBlur> <DropdownMenu>
<DropdownMenuSearchInput <DropdownMenuSearchInput
value={searchFilter} value={searchFilter}
onChange={(event) => setSearchFilter(event.target.value)} onChange={(event) => setSearchFilter(event.target.value)}

View File

@ -81,7 +81,6 @@ export const AbsoluteDatePickerHeader = ({
<Select <Select
dropdownId={MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID} dropdownId={MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID}
options={getMonthSelectOptions()} options={getMonthSelectOptions()}
disableBlur
onChange={onChangeMonth} onChange={onChangeMonth}
value={endOfDayInLocalTimezone.getMonth()} value={endOfDayInLocalTimezone.getMonth()}
fullWidth fullWidth
@ -91,7 +90,6 @@ export const AbsoluteDatePickerHeader = ({
onChange={onChangeYear} onChange={onChangeYear}
value={endOfDayInLocalTimezone.getFullYear()} value={endOfDayInLocalTimezone.getFullYear()}
options={years} options={years}
disableBlur
fullWidth fullWidth
/> />
<LightIconButton <LightIconButton

View File

@ -16,8 +16,6 @@ import { isDefined } from 'twenty-ui';
const StyledInputContainer = styled.div` const StyledInputContainer = styled.div`
align-items: center; align-items: center;
background-color: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
border-top-left-radius: ${({ theme }) => theme.border.radius.md}; border-top-left-radius: ${({ theme }) => theme.border.radius.md};
border-top-right-radius: ${({ theme }) => theme.border.radius.md}; border-top-right-radius: ${({ theme }) => theme.border.radius.md};

View File

@ -5,7 +5,6 @@ import { Key } from 'ts-key-enum';
import { import {
IconCalendarX, IconCalendarX,
MenuItemLeftContent, MenuItemLeftContent,
OVERLAY_BACKGROUND,
StyledHoverableMenuItemBase, StyledHoverableMenuItemBase,
} from 'twenty-ui'; } from 'twenty-ui';
@ -122,8 +121,6 @@ const StyledContainer = styled.div<{ calendarDisabled?: boolean }>`
& .react-datepicker__month-dropdown, & .react-datepicker__month-dropdown,
& .react-datepicker__year-dropdown { & .react-datepicker__year-dropdown {
border: ${({ theme }) => theme.border.color.light};
${OVERLAY_BACKGROUND}
overflow-y: scroll; overflow-y: scroll;
top: ${({ theme }) => theme.spacing(2)}; top: ${({ theme }) => theme.spacing(2)};
} }

View File

@ -57,7 +57,6 @@ export const RelativeDatePickerHeader = (
return ( return (
<StyledContainer> <StyledContainer>
<Select <Select
disableBlur
dropdownId="direction-select" dropdownId="direction-select"
value={direction} value={direction}
onChange={(newDirection) => { onChange={(newDirection) => {
@ -95,7 +94,6 @@ export const RelativeDatePickerHeader = (
disabled={direction === 'THIS'} disabled={direction === 'THIS'}
/> />
<Select <Select
disableBlur
dropdownId="unit-select" dropdownId="unit-select"
value={unit} value={unit}
onChange={(newUnit) => { onChange={(newUnit) => {

View File

@ -2,7 +2,6 @@ import styled from '@emotion/styled';
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
import { Country } from '@/ui/input/components/internal/types/Country'; import { Country } from '@/ui/input/components/internal/types/Country';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
@ -47,7 +46,7 @@ export const PhoneCountryPickerDropdownSelect = ({
); );
return ( return (
<DropdownMenu width="auto" disableBlur> <>
<DropdownMenuSearchInput <DropdownMenuSearchInput
value={searchFilter} value={searchFilter}
onChange={(event) => setSearchFilter(event.currentTarget.value)} onChange={(event) => setSearchFilter(event.currentTarget.value)}
@ -91,6 +90,6 @@ export const PhoneCountryPickerDropdownSelect = ({
</> </>
)} )}
</DropdownMenuItemsContainer> </DropdownMenuItemsContainer>
</DropdownMenu> </>
); );
}; };

View File

@ -53,7 +53,7 @@ const StyledEditor = styled.div`
} }
& .bn-drag-handle-menu { & .bn-drag-handle-menu {
background: ${({ theme }) => theme.background.transparent.secondary}; background: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: blur(12px) saturate(200%) contrast(50%) brightness(130%); backdrop-filter: ${({ theme }) => theme.blur.medium};
box-shadow: box-shadow:
0px 2px 4px rgba(0, 0, 0, 0.04), 0px 2px 4px rgba(0, 0, 0, 0.04),
2px 4px 16px rgba(0, 0, 0, 0.12); 2px 4px 16px rgba(0, 0, 0, 0.12);
@ -64,6 +64,19 @@ const StyledEditor = styled.div`
border: 1px solid ${({ theme }) => theme.border.color.medium}; border: 1px solid ${({ theme }) => theme.border.color.medium};
left: 26px; left: 26px;
} }
& .bn-container .bn-suggestion-menu-item:hover {
background-color: blue;
}
& .bn-suggestion-menu {
padding: 4px;
border-radius: 8px;
border: 1px solid ${({ theme }) => theme.border.color.medium};
background: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
}
& .mantine-Menu-item { & .mantine-Menu-item {
background-color: transparent; background-color: transparent;
min-width: 152px; min-width: 152px;

View File

@ -4,6 +4,9 @@ import { IconComponent, MenuItemSuggestion } from 'twenty-ui';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import { useFloating } from '@floating-ui/react';
import { createPortal } from 'react-dom';
export type SuggestionItem = { export type SuggestionItem = {
title: string; title: string;
@ -14,28 +17,43 @@ export type SuggestionItem = {
type CustomSlashMenuProps = SuggestionMenuProps<SuggestionItem>; type CustomSlashMenuProps = SuggestionMenuProps<SuggestionItem>;
const StyledSlashMenu = styled.div` const StyledContainer = styled.div`
* { height: 1px;
box-sizing: content-box; width: 1px;
} `;
const StyledInnerContainer = styled.div`
height: 250px;
width: 100%;
`; `;
export const CustomSlashMenu = (props: CustomSlashMenuProps) => { export const CustomSlashMenu = (props: CustomSlashMenuProps) => {
const { refs, floatingStyles } = useFloating({
placement: 'bottom-start',
});
return ( return (
<StyledSlashMenu> <StyledContainer ref={refs.setReference}>
<DropdownMenu style={{ zIndex: 2001 }}> {createPortal(
<DropdownMenuItemsContainer> <OverlayContainer ref={refs.setFloating} style={floatingStyles}>
{props.items.map((item, index) => ( <StyledInnerContainer>
<MenuItemSuggestion <DropdownMenu style={{ zIndex: 2001 }}>
key={item.title} <DropdownMenuItemsContainer>
onClick={() => item.onItemClick()} {props.items.map((item, index) => (
text={item.title} <MenuItemSuggestion
LeftIcon={item.Icon} key={item.title}
selected={props.selectedIndex === index} onClick={() => item.onItemClick()}
/> text={item.title}
))} LeftIcon={item.Icon}
</DropdownMenuItemsContainer> selected={props.selectedIndex === index}
</DropdownMenu> />
</StyledSlashMenu> ))}
</DropdownMenuItemsContainer>
</DropdownMenu>
</StyledInnerContainer>
</OverlayContainer>,
document.body,
)}
</StyledContainer>
); );
}; };

View File

@ -37,7 +37,6 @@ type DropdownProps = {
dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number; dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number;
dropdownOffset?: { x?: number; y?: number }; dropdownOffset?: { x?: number; y?: number };
dropdownStrategy?: 'fixed' | 'absolute'; dropdownStrategy?: 'fixed' | 'absolute';
disableBlur?: boolean;
onClickOutside?: () => void; onClickOutside?: () => void;
onClose?: () => void; onClose?: () => void;
onOpen?: () => void; onOpen?: () => void;
@ -55,7 +54,6 @@ export const Dropdown = ({
dropdownPlacement = 'bottom-end', dropdownPlacement = 'bottom-end',
dropdownStrategy = 'absolute', dropdownStrategy = 'absolute',
dropdownOffset = { x: 0, y: 0 }, dropdownOffset = { x: 0, y: 0 },
disableBlur = false,
onClickOutside, onClickOutside,
onClose, onClose,
onOpen, onOpen,
@ -123,7 +121,6 @@ export const Dropdown = ({
<DropdownContent <DropdownContent
className={className} className={className}
floatingStyles={floatingStyles} floatingStyles={floatingStyles}
disableBlur={disableBlur}
dropdownMenuWidth={dropdownMenuWidth} dropdownMenuWidth={dropdownMenuWidth}
dropdownComponents={dropdownComponents} dropdownComponents={dropdownComponents}
dropdownId={dropdownId} dropdownId={dropdownId}

View File

@ -3,12 +3,14 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useInternalHotkeyScopeManagement } from '@/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement'; import { useInternalHotkeyScopeManagement } from '@/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement';
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState'; import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
import { dropdownMaxHeightComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownMaxHeightComponentStateV2'; import { dropdownMaxHeightComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownMaxHeightComponentStateV2';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect'; import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
import { import {
FloatingPortal, FloatingPortal,
Placement, Placement,
@ -19,6 +21,11 @@ import { Keys } from 'react-hotkeys-hook';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
export const StyledDropdownContentContainer = styled.div`
display: flex;
z-index: 30;
`;
export type DropdownContentProps = { export type DropdownContentProps = {
className?: string; className?: string;
dropdownId: string; dropdownId: string;
@ -32,7 +39,6 @@ export type DropdownContentProps = {
scope: string; scope: string;
}; };
onHotkeyTriggered?: () => void; onHotkeyTriggered?: () => void;
disableBlur?: boolean;
dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number; dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number;
dropdownComponents: React.ReactNode; dropdownComponents: React.ReactNode;
parentDropdownId?: string; parentDropdownId?: string;
@ -49,7 +55,6 @@ export const DropdownContent = ({
floatingStyles, floatingStyles,
hotkey, hotkey,
onHotkeyTriggered, onHotkeyTriggered,
disableBlur,
dropdownMenuWidth, dropdownMenuWidth,
dropdownComponents, dropdownComponents,
avoidPortal, avoidPortal,
@ -59,7 +64,7 @@ export const DropdownContent = ({
const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState); const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState);
const [dropdownMaxHeight] = useRecoilComponentStateV2( const dropdownMaxHeight = useRecoilComponentValueV2(
dropdownMaxHeightComponentStateV2, dropdownMaxHeightComponentStateV2,
dropdownId, dropdownId,
); );
@ -114,28 +119,36 @@ export const DropdownContent = ({
<HotkeyEffect hotkey={hotkey} onHotkeyTriggered={onHotkeyTriggered} /> <HotkeyEffect hotkey={hotkey} onHotkeyTriggered={onHotkeyTriggered} />
)} )}
{avoidPortal ? ( {avoidPortal ? (
<DropdownMenu <StyledDropdownContentContainer
className={className}
disableBlur={disableBlur}
width={dropdownMenuWidth ?? dropdownWidth}
data-select-disable
ref={floatingUiRefs.setFloating} ref={floatingUiRefs.setFloating}
style={dropdownMenuStyles} style={dropdownMenuStyles}
> >
{dropdownComponents} <OverlayContainer>
</DropdownMenu> <DropdownMenu
className={className}
width={dropdownMenuWidth ?? dropdownWidth}
data-select-disable
>
{dropdownComponents}
</DropdownMenu>
</OverlayContainer>
</StyledDropdownContentContainer>
) : ( ) : (
<FloatingPortal> <FloatingPortal>
<DropdownMenu <StyledDropdownContentContainer
className={className}
disableBlur={disableBlur}
width={dropdownMenuWidth ?? dropdownWidth}
data-select-disable
ref={floatingUiRefs.setFloating} ref={floatingUiRefs.setFloating}
style={dropdownMenuStyles} style={dropdownMenuStyles}
> >
{dropdownComponents} <OverlayContainer>
</DropdownMenu> <DropdownMenu
className={className}
width={dropdownMenuWidth ?? dropdownWidth}
data-select-disable
>
{dropdownComponents}
</DropdownMenu>
</OverlayContainer>
</StyledDropdownContentContainer>
</FloatingPortal> </FloatingPortal>
)} )}
</> </>

View File

@ -1,29 +1,12 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
const StyledDropdownMenu = styled.div<{ const StyledDropdownMenu = styled.div<{
disableBlur?: boolean;
disableBorder?: boolean;
width?: `${string}px` | `${number}%` | 'auto' | number; width?: `${string}px` | `${number}%` | 'auto' | number;
}>` }>`
backdrop-filter: ${({ theme, disableBlur }) =>
disableBlur ? 'none' : theme.blur.medium};
color: ${({ theme }) => theme.font.color.secondary};
background: ${({ theme, disableBlur }) =>
disableBlur
? theme.background.primary
: theme.background.transparent.primary};
border: ${({ disableBorder, theme }) =>
disableBorder ? 'none' : `1px solid ${theme.border.color.medium}`};
border-radius: ${({ theme }) => theme.border.radius.md};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
display: flex; display: flex;
flex-direction: column; flex-direction: column;
z-index: 30; height: 100%;
width: ${({ width = 200 }) => width: ${({ width = 200 }) =>
typeof width === 'number' ? `${width}px` : width}; typeof width === 'number' ? `${width}px` : width};
`; `;

View File

@ -13,11 +13,6 @@ const StyledInput = styled.input<{
}>` }>`
${TEXT_INPUT_STYLE} ${TEXT_INPUT_STYLE}
border: 1px solid ${({ theme, hasError }) =>
hasError ? theme.border.color.danger : theme.border.color.medium};
background-color: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
box-sizing: border-box; box-sizing: border-box;
font-weight: ${({ theme }) => theme.font.weight.medium}; font-weight: ${({ theme }) => theme.font.weight.medium};
height: 32px; height: 32px;

View File

@ -6,12 +6,9 @@ import { TEXT_INPUT_STYLE } from 'twenty-ui';
const StyledDropdownMenuSearchInputContainer = styled.div` const StyledDropdownMenuSearchInputContainer = styled.div`
align-items: center; align-items: center;
--vertical-padding: ${({ theme }) => theme.spacing(2)}; --vertical-padding: ${({ theme }) => theme.spacing(2)};
border-radius: ${({ theme }) => theme.border.radius.sm};
display: flex; display: flex;
background: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
flex-direction: row; flex-direction: row;
height: calc(36px - 2 * var(--vertical-padding)); min-height: calc(36px - 2 * var(--vertical-padding));
padding: var(--vertical-padding) 0; padding: var(--vertical-padding) 0;
width: 100%; width: 100%;

View File

@ -3,8 +3,10 @@ import styled from '@emotion/styled';
import { FloatingPortal, offset, shift, useFloating } from '@floating-ui/react'; import { FloatingPortal, offset, shift, useFloating } from '@floating-ui/react';
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { StyledDropdownContentContainer } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
type ExpandedListDropdownProps = { type ExpandedListDropdownProps = {
anchorElement?: HTMLElement; anchorElement?: HTMLElement;
@ -16,11 +18,6 @@ type ExpandedListDropdownProps = {
const StyledExpandedListContainer = styled.div<{ const StyledExpandedListContainer = styled.div<{
withBorder?: boolean; withBorder?: boolean;
}>` }>`
backdrop-filter: ${({ theme }) => theme.blur.strong};
background-color: ${({ theme }) => theme.background.secondary};
border-radius: ${({ theme }) => theme.border.radius.sm};
box-shadow: ${({ theme }) =>
`0px 2px 4px ${theme.boxShadow.light}, 2px 4px 16px ${theme.boxShadow.strong}`};
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: ${({ theme }) => theme.spacing(1)}; gap: ${({ theme }) => theme.spacing(1)};
@ -33,6 +30,7 @@ const StyledExpandedListContainer = styled.div<{
`}; `};
`; `;
// TODO: unify this and use Dropdown component instead
export const ExpandedListDropdown = ({ export const ExpandedListDropdown = ({
anchorElement, anchorElement,
children, children,
@ -55,19 +53,24 @@ export const ExpandedListDropdown = ({
return ( return (
<FloatingPortal> <FloatingPortal>
<DropdownMenu <StyledDropdownContentContainer
ref={refs.setFloating} ref={refs.setFloating}
style={floatingStyles} style={floatingStyles}
width={
anchorElement
? Math.max(220, anchorElement.getBoundingClientRect().width)
: undefined
}
> >
<StyledExpandedListContainer withBorder={withBorder}> <OverlayContainer>
{children} <DropdownMenu
</StyledExpandedListContainer> width={
</DropdownMenu> anchorElement
? Math.max(220, anchorElement.getBoundingClientRect().width)
: undefined
}
>
<StyledExpandedListContainer withBorder={withBorder}>
{children}
</StyledExpandedListContainer>
</DropdownMenu>
</OverlayContainer>
</StyledDropdownContentContainer>
</FloatingPortal> </FloatingPortal>
); );
}; };

View File

@ -0,0 +1,20 @@
import styled from '@emotion/styled';
// eslint-disable-next-line @nx/workspace-styled-components-prefixed-with-styled
export const OverlayContainer = styled.div`
align-items: center;
display: flex;
backdrop-filter: ${({ theme }) => theme.blur.medium};
width: fit-content;
border-radius: ${({ theme }) => theme.border.radius.md};
background: ${({ theme }) => theme.background.transparent.primary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
overflow: hidden;
z-index: 30;
`;

View File

@ -93,7 +93,6 @@ export const MenuItemWithOptionDropdown = ({
dropdownComponents={dropdownContent} dropdownComponents={dropdownContent}
dropdownId={dropdownId} dropdownId={dropdownId}
dropdownHotkeyScope={{ scope: SelectHotkeyScope.Select }} dropdownHotkeyScope={{ scope: SelectHotkeyScope.Select }}
disableBlur
/> />
</div> </div>
{hasSubMenu && ( {hasSubMenu && (

View File

@ -17,7 +17,7 @@ import 'overlayscrollbars/overlayscrollbars.css';
const StyledScrollWrapper = styled.div<{ scrollHide?: boolean }>` const StyledScrollWrapper = styled.div<{ scrollHide?: boolean }>`
display: flex; display: flex;
height: 100%; height: fit-content;
width: 100%; width: 100%;
.os-scrollbar-handle { .os-scrollbar-handle {

View File

@ -128,7 +128,6 @@ export const ViewPickerContentCreateMode = () => {
<IconPicker <IconPicker
onChange={onIconChange} onChange={onIconChange}
selectedIconKey={selectedIcon} selectedIconKey={selectedIcon}
disableBlur
onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)} onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)}
/> />
<TextInputV2 <TextInputV2
@ -142,7 +141,6 @@ export const ViewPickerContentCreateMode = () => {
</ViewPickerIconAndNameContainer> </ViewPickerIconAndNameContainer>
<ViewPickerSelectContainer> <ViewPickerSelectContainer>
<Select <Select
disableBlur
label="View type" label="View type"
fullWidth fullWidth
value={viewPickerType} value={viewPickerType}
@ -165,7 +163,6 @@ export const ViewPickerContentCreateMode = () => {
<> <>
<ViewPickerSelectContainer> <ViewPickerSelectContainer>
<Select <Select
disableBlur
label="Stages" label="Stages"
fullWidth fullWidth
value={viewPickerKanbanFieldMetadataId} value={viewPickerKanbanFieldMetadataId}

View File

@ -76,7 +76,6 @@ export const ViewPickerContentEditMode = () => {
<IconPicker <IconPicker
onChange={onIconChange} onChange={onIconChange}
selectedIconKey={viewPickerSelectedIcon} selectedIconKey={viewPickerSelectedIcon}
disableBlur
onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)} onClose={() => setHotkeyScope(ViewsHotkeyScope.ListDropdown)}
/> />
<TextInputV2 <TextInputV2

View File

@ -17,7 +17,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { WorkflowSingleRecordFieldChip } from '@/workflow/components/WorkflowSingleRecordFieldChip'; import { WorkflowSingleRecordFieldChip } from '@/workflow/components/WorkflowSingleRecordFieldChip';
import SearchVariablesDropdown from '@/workflow/search-variables/components/SearchVariablesDropdown'; import { SearchVariablesDropdown } from '@/workflow/search-variables/components/SearchVariablesDropdown';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString'; import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';

View File

@ -1,5 +1,5 @@
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
import SearchVariablesDropdown from '@/workflow/search-variables/components/SearchVariablesDropdown'; import { SearchVariablesDropdown } from '@/workflow/search-variables/components/SearchVariablesDropdown';
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';

View File

@ -1,5 +1,4 @@
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer'; import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SearchVariablesDropdownFieldItems } from '@/workflow/search-variables/components/SearchVariablesDropdownFieldItems'; import { SearchVariablesDropdownFieldItems } from '@/workflow/search-variables/components/SearchVariablesDropdownFieldItems';
@ -20,6 +19,7 @@ const StyledDropdownVariableButtonContainer = styled(
transparentBackground transparentBackground
? 'transparent' ? 'transparent'
: theme.background.transparent.lighter}; : theme.background.transparent.lighter};
color: ${({ theme }) => theme.font.color.tertiary}; color: ${({ theme }) => theme.font.color.tertiary};
padding: ${({ theme }) => theme.spacing(2)}; padding: ${({ theme }) => theme.spacing(2)};
:hover { :hover {
@ -27,12 +27,7 @@ const StyledDropdownVariableButtonContainer = styled(
} }
`; `;
const StyledDropdownComponentsContainer = styled(DropdownMenuItemsContainer)` export const SearchVariablesDropdown = ({
display: flex;
flex-direction: column;
`;
const SearchVariablesDropdown = ({
inputId, inputId,
onVariableSelect, onVariableSelect,
disabled, disabled,
@ -76,36 +71,6 @@ const SearchVariablesDropdown = ({
setSelectedStep(undefined); setSelectedStep(undefined);
}; };
const renderSearchVariablesDropdownComponents = () => {
if (!isDefined(selectedStep)) {
return (
<SearchVariablesDropdownWorkflowStepItems
dropdownId={dropdownId}
steps={availableVariablesInWorkflowStep}
onSelect={handleStepSelect}
/>
);
}
if (isDefined(objectNameSingularToSelect)) {
return (
<SearchVariablesDropdownObjectItems
step={selectedStep}
onSelect={handleSubItemSelect}
onBack={handleBack}
/>
);
}
return (
<SearchVariablesDropdownFieldItems
step={selectedStep}
onSelect={handleSubItemSelect}
onBack={handleBack}
/>
);
};
if (disabled === true) { if (disabled === true) {
return ( return (
<StyledDropdownVariableButtonContainer <StyledDropdownVariableButtonContainer
@ -138,14 +103,28 @@ const SearchVariablesDropdown = ({
</StyledDropdownVariableButtonContainer> </StyledDropdownVariableButtonContainer>
} }
dropdownComponents={ dropdownComponents={
<StyledDropdownComponentsContainer> !isDefined(selectedStep) ? (
{renderSearchVariablesDropdownComponents()} <SearchVariablesDropdownWorkflowStepItems
</StyledDropdownComponentsContainer> dropdownId={dropdownId}
steps={availableVariablesInWorkflowStep}
onSelect={handleStepSelect}
/>
) : isDefined(objectNameSingularToSelect) ? (
<SearchVariablesDropdownObjectItems
step={selectedStep}
onSelect={handleSubItemSelect}
onBack={handleBack}
/>
) : (
<SearchVariablesDropdownFieldItems
step={selectedStep}
onSelect={handleSubItemSelect}
onBack={handleBack}
/>
)
} }
dropdownPlacement="bottom-end" dropdownPlacement="bottom-end"
dropdownOffset={{ x: 0, y: 4 }} dropdownOffset={{ x: 2, y: 4 }}
/> />
); );
}; };
export default SearchVariablesDropdown;

View File

@ -1,5 +1,7 @@
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { import {
BaseOutputSchema, BaseOutputSchema,
LinkOutputSchema, LinkOutputSchema,
@ -8,11 +10,9 @@ import {
} from '@/workflow/search-variables/types/StepOutputSchema'; } from '@/workflow/search-variables/types/StepOutputSchema';
import { isBaseOutputSchema } from '@/workflow/search-variables/utils/isBaseOutputSchema'; import { isBaseOutputSchema } from '@/workflow/search-variables/utils/isBaseOutputSchema';
import { isRecordOutputSchema } from '@/workflow/search-variables/utils/isRecordOutputSchema'; import { isRecordOutputSchema } from '@/workflow/search-variables/utils/isRecordOutputSchema';
import { useTheme } from '@emotion/react';
import { useState } from 'react'; import { useState } from 'react';
import { import {
HorizontalSeparator,
IconChevronLeft, IconChevronLeft,
isDefined, isDefined,
MenuItemSelect, MenuItemSelect,
@ -37,7 +37,6 @@ export const SearchVariablesDropdownFieldItems = ({
onSelect, onSelect,
onBack, onBack,
}: SearchVariablesDropdownFieldItemsProps) => { }: SearchVariablesDropdownFieldItemsProps) => {
const theme = useTheme();
const [currentPath, setCurrentPath] = useState<string[]>([]); const [currentPath, setCurrentPath] = useState<string[]>([]);
const [searchInputValue, setSearchInputValue] = useState(''); const [searchInputValue, setSearchInputValue] = useState('');
const { getIcon } = useIcons(); const { getIcon } = useIcons();
@ -139,30 +138,25 @@ export const SearchVariablesDropdownFieldItems = ({
> >
<OverflowingTextWithTooltip text={headerLabel} /> <OverflowingTextWithTooltip text={headerLabel} />
</DropdownMenuHeader> </DropdownMenuHeader>
<HorizontalSeparator
color={theme.background.transparent.primary}
noMargin
/>
<DropdownMenuSearchInput <DropdownMenuSearchInput
autoFocus autoFocus
value={searchInputValue} value={searchInputValue}
onChange={(event) => setSearchInputValue(event.target.value)} onChange={(event) => setSearchInputValue(event.target.value)}
/> />
<HorizontalSeparator <DropdownMenuSeparator />
color={theme.background.transparent.primary} <DropdownMenuItemsContainer>
noMargin {filteredOptions.map(([key, value]) => (
/> <MenuItemSelect
{filteredOptions.map(([key, value]) => ( key={key}
<MenuItemSelect selected={false}
key={key} hovered={false}
selected={false} onClick={() => handleSelectField(key)}
hovered={false} text={value.label || key}
onClick={() => handleSelectField(key)} hasSubMenu={!value.isLeaf}
text={value.label || key} LeftIcon={value.icon ? getIcon(value.icon) : undefined}
hasSubMenu={!value.isLeaf} />
LeftIcon={value.icon ? getIcon(value.icon) : undefined} ))}
/> </DropdownMenuItemsContainer>
))}
</> </>
); );
}; };

View File

@ -1,16 +1,16 @@
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { import {
OutputSchema, OutputSchema,
StepOutputSchema, StepOutputSchema,
} from '@/workflow/search-variables/types/StepOutputSchema'; } from '@/workflow/search-variables/types/StepOutputSchema';
import { isBaseOutputSchema } from '@/workflow/search-variables/utils/isBaseOutputSchema'; import { isBaseOutputSchema } from '@/workflow/search-variables/utils/isBaseOutputSchema';
import { isRecordOutputSchema } from '@/workflow/search-variables/utils/isRecordOutputSchema'; import { isRecordOutputSchema } from '@/workflow/search-variables/utils/isRecordOutputSchema';
import { useTheme } from '@emotion/react';
import { useState } from 'react'; import { useState } from 'react';
import { import {
HorizontalSeparator,
IconChevronLeft, IconChevronLeft,
MenuItemSelect, MenuItemSelect,
OverflowingTextWithTooltip, OverflowingTextWithTooltip,
@ -28,7 +28,6 @@ export const SearchVariablesDropdownObjectItems = ({
onSelect, onSelect,
onBack, onBack,
}: SearchVariablesDropdownObjectItemsProps) => { }: SearchVariablesDropdownObjectItemsProps) => {
const theme = useTheme();
const [currentPath, setCurrentPath] = useState<string[]>([]); const [currentPath, setCurrentPath] = useState<string[]>([]);
const [searchInputValue, setSearchInputValue] = useState(''); const [searchInputValue, setSearchInputValue] = useState('');
const { getIcon } = useIcons(); const { getIcon } = useIcons();
@ -119,44 +118,39 @@ export const SearchVariablesDropdownObjectItems = ({
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={goBack}> <DropdownMenuHeader StartIcon={IconChevronLeft} onClick={goBack}>
<OverflowingTextWithTooltip text={headerLabel} /> <OverflowingTextWithTooltip text={headerLabel} />
</DropdownMenuHeader> </DropdownMenuHeader>
<HorizontalSeparator
color={theme.background.transparent.primary}
noMargin
/>
<DropdownMenuSearchInput <DropdownMenuSearchInput
autoFocus autoFocus
value={searchInputValue} value={searchInputValue}
onChange={(event) => setSearchInputValue(event.target.value)} onChange={(event) => setSearchInputValue(event.target.value)}
/> />
<HorizontalSeparator <DropdownMenuSeparator />
color={theme.background.transparent.primary} <DropdownMenuItemsContainer>
noMargin {shouldDisplaySubStepObject && displayedSubStepObject?.label && (
/> <MenuItemSelect
{shouldDisplaySubStepObject && displayedSubStepObject?.label && ( selected={false}
<MenuItemSelect hovered={false}
selected={false} onClick={handleSelectObject}
hovered={false} text={displayedSubStepObject.label}
onClick={handleSelectObject} hasSubMenu={false}
text={displayedSubStepObject.label} LeftIcon={
hasSubMenu={false} displayedSubStepObject.icon
LeftIcon={ ? getIcon(displayedSubStepObject.icon)
displayedSubStepObject.icon : undefined
? getIcon(displayedSubStepObject.icon) }
: undefined />
} )}
/> {filteredOptions.map(([key, value]) => (
)} <MenuItemSelect
{filteredOptions.map(([key, value]) => ( key={key}
<MenuItemSelect selected={false}
key={key} hovered={false}
selected={false} onClick={() => handleSelectField(key)}
hovered={false} text={value.label || key}
onClick={() => handleSelectField(key)} hasSubMenu={!value.isLeaf}
text={value.label || key} LeftIcon={value.icon ? getIcon(value.icon) : undefined}
hasSubMenu={!value.isLeaf} />
LeftIcon={value.icon ? getIcon(value.icon) : undefined} ))}
/> </DropdownMenuItemsContainer>
))}
</> </>
); );
}; };

View File

@ -1,11 +1,11 @@
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { StepOutputSchema } from '@/workflow/search-variables/types/StepOutputSchema'; import { StepOutputSchema } from '@/workflow/search-variables/types/StepOutputSchema';
import { useTheme } from '@emotion/react';
import { useState } from 'react'; import { useState } from 'react';
import { import {
HorizontalSeparator,
IconX, IconX,
MenuItem, MenuItem,
MenuItemSelect, MenuItemSelect,
@ -24,7 +24,6 @@ export const SearchVariablesDropdownWorkflowStepItems = ({
steps, steps,
onSelect, onSelect,
}: SearchVariablesDropdownWorkflowStepItemsProps) => { }: SearchVariablesDropdownWorkflowStepItemsProps) => {
const theme = useTheme();
const { getIcon } = useIcons(); const { getIcon } = useIcons();
const [searchInputValue, setSearchInputValue] = useState(''); const [searchInputValue, setSearchInputValue] = useState('');
@ -41,40 +40,35 @@ export const SearchVariablesDropdownWorkflowStepItems = ({
<DropdownMenuHeader StartIcon={IconX} onClick={closeDropdown}> <DropdownMenuHeader StartIcon={IconX} onClick={closeDropdown}>
<OverflowingTextWithTooltip text={'Select Step'} /> <OverflowingTextWithTooltip text={'Select Step'} />
</DropdownMenuHeader> </DropdownMenuHeader>
<HorizontalSeparator
color={theme.background.transparent.primary}
noMargin
/>
<DropdownMenuSearchInput <DropdownMenuSearchInput
autoFocus autoFocus
value={searchInputValue} value={searchInputValue}
onChange={(event) => setSearchInputValue(event.target.value)} onChange={(event) => setSearchInputValue(event.target.value)}
/> />
<HorizontalSeparator <DropdownMenuSeparator />
color={theme.background.transparent.primary} <DropdownMenuItemsContainer>
noMargin {availableSteps.length > 0 ? (
/> availableSteps.map((item, _index) => (
{availableSteps.length > 0 ? ( <MenuItemSelect
availableSteps.map((item, _index) => ( key={`step-${item.id}`}
<MenuItemSelect selected={false}
key={`step-${item.id}`} hovered={false}
selected={false} onClick={() => onSelect(item.id)}
hovered={false} text={item.name}
onClick={() => onSelect(item.id)} LeftIcon={item.icon ? getIcon(item.icon) : undefined}
text={item.name} hasSubMenu
LeftIcon={item.icon ? getIcon(item.icon) : undefined} />
hasSubMenu ))
) : (
<MenuItem
key="no-steps"
onClick={() => {}}
text="No variables available"
LeftIcon={undefined}
hasSubMenu={false}
/> />
)) )}
) : ( </DropdownMenuItemsContainer>
<MenuItem
key="no-steps"
onClick={() => {}}
text="No variables available"
LeftIcon={undefined}
hasSubMenu={false}
/>
)}
</> </>
); );
}; };

View File

@ -19,7 +19,6 @@ export const DateTimeSettingsTimeZoneSelect = ({
return ( return (
<Select <Select
disableBlur
dropdownId="settings-accounts-calendar-time-zone" dropdownId="settings-accounts-calendar-time-zone"
label="Time zone" label="Time zone"
dropdownWidthAuto dropdownWidthAuto

View File

@ -1,9 +0,0 @@
import { css } from '@emotion/react';
import { ThemeType } from '..';
export const OVERLAY_BACKGROUND = (props: { theme: ThemeType }) => css`
backdrop-filter: ${props.theme.blur.medium};
background: ${props.theme.background.transparent.secondary};
box-shadow: ${props.theme.boxShadow.strong};
`;

View File

@ -25,7 +25,6 @@ export * from './constants/MainColorNames';
export * from './constants/MainColors'; export * from './constants/MainColors';
export * from './constants/MobileViewport'; export * from './constants/MobileViewport';
export * from './constants/Modal'; export * from './constants/Modal';
export * from './constants/OverlayBackground';
export * from './constants/Rgba'; export * from './constants/Rgba';
export * from './constants/SecondaryColors'; export * from './constants/SecondaryColors';
export * from './constants/SnackBarCommon'; export * from './constants/SnackBarCommon';