forked from cerc-io/snowballtools-base
Merge pull request #138 from snowball-tools/ayungavis/T-4911-create-project-import-a-repository-section
[T-4911: feat] Re-styling and refactor create project import a repository section
This commit is contained in:
@@ -8,6 +8,8 @@ export const inputTheme = tv(
|
||||
'items-center',
|
||||
'rounded-lg',
|
||||
'relative',
|
||||
'gap-2',
|
||||
'w-full',
|
||||
'placeholder:text-elements-disabled',
|
||||
'disabled:cursor-not-allowed',
|
||||
'disabled:bg-controls-disabled',
|
||||
@@ -27,7 +29,7 @@ export const inputTheme = tv(
|
||||
'disabled:shadow-none',
|
||||
'disabled:border-none',
|
||||
],
|
||||
icon: ['text-elements-mid-em'],
|
||||
icon: ['text-elements-low-em'],
|
||||
iconContainer: [
|
||||
'absolute',
|
||||
'inset-y-0',
|
||||
|
||||
@@ -87,12 +87,12 @@ export const Input = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex flex-col gap-2 w-full">
|
||||
{renderLabels}
|
||||
<div className={containerCls({ class: className })}>
|
||||
{leftIcon && renderLeftIcon}
|
||||
<input
|
||||
className={cn(inputCls({ class: 'w-80' }), {
|
||||
className={cn(inputCls(), {
|
||||
'pl-10': leftIcon,
|
||||
})}
|
||||
{...props}
|
||||
|
||||
@@ -85,7 +85,7 @@ export const selectTheme = tv({
|
||||
size: {
|
||||
md: {
|
||||
container: ['min-h-11'],
|
||||
inputWrapper: ['min-h-11', 'text-sm', 'pl-4', 'pr-4', 'py-1'],
|
||||
inputWrapper: ['min-h-11', 'text-sm', 'pl-4', 'pr-4'],
|
||||
icon: ['h-[18px]', 'w-[18px]'],
|
||||
helperText: 'text-sm',
|
||||
helperIcon: ['h-5', 'w-5'],
|
||||
@@ -93,7 +93,7 @@ export const selectTheme = tv({
|
||||
},
|
||||
sm: {
|
||||
container: ['min-h-8'],
|
||||
inputWrapper: ['min-h-8', 'text-xs', 'pl-3', 'pr-3', 'py-0.5'],
|
||||
inputWrapper: ['min-h-8', 'text-xs', 'pl-3', 'pr-3'],
|
||||
icon: ['h-4', 'w-4'],
|
||||
helperText: 'text-xs',
|
||||
helperIcon: ['h-4', 'w-4'],
|
||||
|
||||
@@ -3,7 +3,6 @@ import React, {
|
||||
useState,
|
||||
ComponentPropsWithoutRef,
|
||||
useMemo,
|
||||
useCallback,
|
||||
MouseEvent,
|
||||
useRef,
|
||||
useEffect,
|
||||
@@ -135,7 +134,9 @@ export const Select = ({
|
||||
const theme = selectTheme({ size, error, variant, orientation });
|
||||
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const [selectedItem, setSelectedItem] = useState<SelectOption | null>(null);
|
||||
const [selectedItem, setSelectedItem] = useState<SelectOption | null>(
|
||||
(value as SelectOption) || null,
|
||||
);
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const [dropdownPosition, setDropdownPosition] = useState<'top' | 'bottom'>(
|
||||
'bottom',
|
||||
@@ -166,22 +167,6 @@ export const Select = ({
|
||||
}
|
||||
}, [dropdownOpen]); // Re-calculate whenever the dropdown is opened
|
||||
|
||||
useEffect(() => {
|
||||
// If multiple selection is enabled, ensure the internal state is an array
|
||||
if (multiple) {
|
||||
if (Array.isArray(value)) {
|
||||
// Directly use the provided array
|
||||
setSelectedItems(value);
|
||||
} else {
|
||||
// Reset or set to empty array if the value is not an array
|
||||
setSelectedItems([]);
|
||||
}
|
||||
} else {
|
||||
// For single selection, directly set the selected item
|
||||
setSelectedItem(value as SelectOption);
|
||||
}
|
||||
}, [value, multiple]);
|
||||
|
||||
const handleSelectedItemChange = (selectedItem: SelectOption | null) => {
|
||||
setSelectedItem(selectedItem);
|
||||
setInputValue(selectedItem ? selectedItem.label : '');
|
||||
@@ -194,9 +179,9 @@ export const Select = ({
|
||||
addSelectedItem,
|
||||
removeSelectedItem,
|
||||
selectedItems,
|
||||
setSelectedItems,
|
||||
reset,
|
||||
} = useMultipleSelection<SelectOption>({
|
||||
selectedItems: multiple ? (value as SelectOption[]) : [],
|
||||
onSelectedItemsChange: multiple
|
||||
? undefined
|
||||
: ({ selectedItems }) => {
|
||||
@@ -234,6 +219,7 @@ export const Select = ({
|
||||
openMenu,
|
||||
} = useCombobox({
|
||||
items: filteredItems,
|
||||
selectedItem: multiple ? null : (value as SelectOption) || null,
|
||||
// @ts-expect-error – there are two params but we don't need the second one
|
||||
isItemDisabled: (item) => item.disabled,
|
||||
onInputValueChange: ({ inputValue = '' }) => setInputValue(inputValue),
|
||||
@@ -265,16 +251,12 @@ export const Select = ({
|
||||
setInputValue('');
|
||||
}
|
||||
},
|
||||
selectedItem: multiple ? null : selectedItem,
|
||||
// TODO: Make the input value empty when the dropdown is open, has a value, it is not multiple, and searchable
|
||||
itemToString: (item) => (item && !multiple ? item.label : ''),
|
||||
});
|
||||
|
||||
const isSelected = useCallback(
|
||||
(item: SelectOption) =>
|
||||
multiple ? selectedItems.includes(item) : selectedItem === item,
|
||||
[selectedItems, selectedItem, multiple],
|
||||
);
|
||||
const isSelected = (item: SelectOption) =>
|
||||
multiple ? selectedItems.includes(item) : selectedItem === item;
|
||||
|
||||
const handleClear = (e: MouseEvent<SVGSVGElement, globalThis.MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
@@ -336,6 +318,7 @@ export const Select = ({
|
||||
const isMultipleHasValue = multiple && selectedItems.length > 0;
|
||||
const isMultipleHasValueButNotSearchable =
|
||||
multiple && !searchable && selectedItems.length > 0;
|
||||
|
||||
const displayPlaceholder = useMemo(() => {
|
||||
if (hideValues && isMultipleHasValue) {
|
||||
return `${selectedItems.length} selected`;
|
||||
@@ -391,6 +374,8 @@ export const Select = ({
|
||||
'w-6': isMultipleHasValueButNotSearchable && !hideValues,
|
||||
// Add margin to the X icon
|
||||
'ml-6': isMultipleHasValueButNotSearchable && clearable,
|
||||
// Add padding if there's a left icon
|
||||
'pl-7': leftIcon,
|
||||
},
|
||||
)}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user