mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-13 03:13:47 +00:00
refactor: improve sheet import UX
This commit is contained in:
committed by
Carlos Valente
parent
42dcf35f45
commit
f53cb687bf
@@ -1,5 +1,5 @@
|
||||
import { Autocomplete as BaseAutocomplete } from '@base-ui/react/autocomplete';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { ReactNode, Ref } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { cx } from '../../utils/styleUtils';
|
||||
@@ -15,6 +15,7 @@ export interface AutocompleteInputProps extends Omit<InputProps, 'value' | 'defa
|
||||
onValueChange: (value: string) => void;
|
||||
emptyLabel?: string;
|
||||
trailingElement?: (option: string) => ReactNode;
|
||||
inputRef?: Ref<HTMLInputElement>;
|
||||
}
|
||||
|
||||
export default function AutocompleteInput({
|
||||
@@ -23,6 +24,7 @@ export default function AutocompleteInput({
|
||||
emptyLabel,
|
||||
fluid,
|
||||
height = 'medium',
|
||||
inputRef,
|
||||
onValueChange,
|
||||
options,
|
||||
trailingElement,
|
||||
@@ -30,16 +32,31 @@ export default function AutocompleteInput({
|
||||
variant = 'subtle',
|
||||
...inputProps
|
||||
}: AutocompleteInputProps) {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const internalInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const handleInputRef = (node: HTMLInputElement | null) => {
|
||||
internalInputRef.current = node;
|
||||
|
||||
if (!inputRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof inputRef === 'function') {
|
||||
inputRef(node);
|
||||
return;
|
||||
}
|
||||
|
||||
inputRef.current = node;
|
||||
};
|
||||
|
||||
// close the popover when the parent scrollable container scrolls or the window resizes
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scrollTarget = getScrollParent(inputRef.current);
|
||||
const scrollTarget = getScrollParent(internalInputRef.current);
|
||||
const handleScroll = () => setOpen(false);
|
||||
|
||||
scrollTarget.addEventListener('scroll', handleScroll, { passive: true });
|
||||
@@ -63,7 +80,7 @@ export default function AutocompleteInput({
|
||||
onValueChange={onValueChange}
|
||||
>
|
||||
<BaseAutocomplete.Input
|
||||
ref={inputRef}
|
||||
ref={handleInputRef}
|
||||
className={cx([
|
||||
inputStyles.input,
|
||||
inputStyles[variant],
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
.title {
|
||||
color: $ui-white;
|
||||
font-size: 1.125rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
padding-block: 1rem;
|
||||
|
||||
display: flex;
|
||||
@@ -49,6 +47,11 @@
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.titleText {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -38,9 +38,9 @@ export default function Modal({
|
||||
>
|
||||
<BaseDialog.Portal>
|
||||
{showBackdrop && <BaseDialog.Backdrop className={style.backdrop} />}
|
||||
<BaseDialog.Popup className={cx([style.modal, size === 'wide' && style.wide])}>
|
||||
<BaseDialog.Popup aria-label={title} className={cx([style.modal, size === 'wide' && style.wide])}>
|
||||
<div className={style.title}>
|
||||
{title}
|
||||
{title ? <BaseDialog.Title className={style.titleText}>{title}</BaseDialog.Title> : <div />}
|
||||
{showCloseButton && (
|
||||
<IconButton variant='subtle-white' onClick={onClose}>
|
||||
<IoClose />
|
||||
|
||||
Reference in New Issue
Block a user