Dates beyond 2030 and autoscroll in select (#12998)

We got several requests to be able to set dates beyond 2030 which seems
reasonable from a business standpoint! The problem was that then it
required scrolling to get to the current date so a bad UX for most
cases. I forced re-selecting the item to trigger auto scroll
This commit is contained in:
Félix Malfait
2025-07-02 17:21:13 +02:00
committed by GitHub
parent e8a2d71844
commit 9f0b8809cb
4 changed files with 16 additions and 4 deletions

View File

@ -1,5 +1,6 @@
import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect'; import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect';
import { Select, SelectValue } from '@/ui/input/components/Select'; import { Select } from '@/ui/input/components/Select';
import { SelectValue } from '@/ui/input/components/internal/select/types';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { useState } from 'react'; import { useState } from 'react';

View File

@ -7,6 +7,7 @@ import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/Dropdow
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; 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 { SelectValue } from '@/ui/input/components/internal/select/types';
import { SelectControl } from '@/ui/input/components/SelectControl'; import { SelectControl } from '@/ui/input/components/SelectControl';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope'; import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
@ -14,6 +15,7 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset'; import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList'; import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem'; import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState'; import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils'; import { isDefined } from 'twenty-shared/utils';
@ -29,8 +31,6 @@ type CallToActionButton = {
Icon?: IconComponent; Icon?: IconComponent;
}; };
export type SelectValue = string | number | boolean | null;
export type SelectProps<Value extends SelectValue> = { export type SelectProps<Value extends SelectValue> = {
className?: string; className?: string;
disabled?: boolean; disabled?: boolean;
@ -99,6 +99,7 @@ export const Select = <Value extends SelectValue>({
options.find(({ value: key }) => key === value) || options.find(({ value: key }) => key === value) ||
emptyOption || emptyOption ||
options[0]; options[0];
const filteredOptions = useMemo( const filteredOptions = useMemo(
() => () =>
searchInputValue searchInputValue
@ -129,6 +130,14 @@ export const Select = <Value extends SelectValue>({
dropdownId, dropdownId,
); );
const { setSelectedItemId } = useSelectableList(dropdownId);
const handleDropdownOpen = () => {
if (selectedOption && !searchInputValue) {
setSelectedItemId(selectedOption.label);
}
};
return ( return (
<StyledContainer <StyledContainer
className={className} className={className}
@ -150,6 +159,7 @@ export const Select = <Value extends SelectValue>({
dropdownId={dropdownId} dropdownId={dropdownId}
dropdownPlacement="bottom-start" dropdownPlacement="bottom-start"
dropdownOffset={dropdownOffset} dropdownOffset={dropdownOffset}
onOpen={handleDropdownOpen}
clickableComponent={ clickableComponent={
<SelectControl <SelectControl
selectedOption={selectedOption} selectedOption={selectedOption}

View File

@ -26,7 +26,7 @@ const StyledCustomDatePickerHeader = styled.div`
const years = Array.from( const years = Array.from(
{ length: 200 }, { length: 200 },
(_, i) => new Date().getFullYear() + 5 - i, (_, i) => new Date().getFullYear() + 50 - i,
).map((year) => ({ label: year.toString(), value: year })); ).map((year) => ({ label: year.toString(), value: year }));
type AbsoluteDatePickerHeaderProps = { type AbsoluteDatePickerHeaderProps = {

View File

@ -0,0 +1 @@
export type SelectValue = string | number | boolean | null;