Skip to content

Commit

Permalink
feat: forward and back buttons for organize column search (#1620)
Browse files Browse the repository at this point in the history
Closes #1529
  • Loading branch information
ethanalvizo authored Nov 14, 2023
1 parent 93eebff commit 75cf184
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 13 deletions.
27 changes: 27 additions & 0 deletions packages/components/src/SearchInput.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,31 @@
border-radius: 1rem;
background-color: rgba($white, 0.25);
}

.search-change-selection {
position: absolute;
right: $spacer-1;
top: 15%;
bottom: 15%;
height: 70%;
}

.search-change-button {
background: none;
border: none;
padding: 1px 2px;
}

.search-change-text {
background-color: rgba($white, 0.2);
border-radius: 10px;
padding: 1px 5px;
}

.match_count {
background-color: rgba($white, 0.2);
border-radius: 10px;
padding: 1px 5px;
margin: 0 5px;
}
}
88 changes: 81 additions & 7 deletions packages/components/src/SearchInput.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React, { PureComponent } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { vsSearch } from '@deephaven/icons';
import { vsArrowLeft, vsArrowRight, vsSearch } from '@deephaven/icons';
import classNames from 'classnames';
import Button from './Button';
import './SearchInput.scss';

interface QueryParams {
queriedColumnIndex: number | undefined;
changeQueriedColumnIndex: (direction: 'forward' | 'back') => void;
}
interface SearchInputProps {
value: string;
placeholder: string;
Expand All @@ -15,6 +20,7 @@ interface SearchInputProps {
matchCount: number;
id: string;
'data-testid'?: string;
queryParams?: QueryParams;
}

class SearchInput extends PureComponent<SearchInputProps> {
Expand All @@ -27,19 +33,40 @@ class SearchInput extends PureComponent<SearchInputProps> {
},
id: '',
'data-testid': undefined,
queryParams: undefined,
};

constructor(props: SearchInputProps) {
super(props);
this.inputField = React.createRef();
this.searchChangeSelection = React.createRef();
}

inputField: React.RefObject<HTMLInputElement>;
componentDidMount(): void {
this.setInputPaddingRight();
}

componentDidUpdate(): void {
this.setInputPaddingRight();
}

focus(): void {
this.inputField.current?.focus();
}

inputField: React.RefObject<HTMLInputElement>;

searchChangeSelection: React.RefObject<HTMLDivElement>;

setInputPaddingRight(): void {
const inputField = this.inputField.current;
const searchChangeSelection = this.searchChangeSelection.current;
if (inputField && searchChangeSelection) {
const paddingRight = searchChangeSelection.getBoundingClientRect().width;
inputField.style.paddingRight = `${paddingRight}px`;
}
}

render(): JSX.Element {
const {
value,
Expand All @@ -52,7 +79,47 @@ class SearchInput extends PureComponent<SearchInputProps> {
id,
onKeyDown,
'data-testid': dataTestId,
queryParams,
} = this.props;

let matchCountSection;

if (queryParams && matchCount > 1) {
matchCountSection = (
<>
<Button
kind="ghost"
className="search-change-button"
type="button"
onClick={() => {
queryParams.changeQueriedColumnIndex('back');
}}
icon={vsArrowLeft}
tooltip="Next match"
/>
<span className="search-change-text">
{queryParams.queriedColumnIndex !== undefined &&
`${queryParams.queriedColumnIndex + 1} of `}
{matchCount}
</span>
<Button
kind="ghost"
className="search-change-button"
type="button"
onClick={() => {
queryParams.changeQueriedColumnIndex('forward');
}}
icon={vsArrowRight}
tooltip="Next match"
/>
</>
);
} else {
matchCountSection = matchCount > 0 && (
<span className="match_count">{matchCount}</span>
);
}

return (
<div className={classNames('search-group', className)}>
<input
Expand All @@ -68,12 +135,19 @@ class SearchInput extends PureComponent<SearchInputProps> {
id={id}
data-testid={dataTestId}
/>
{matchCount != null && (
<span className="search-match">{matchCount}</span>

{matchCount != null ? (
<div
className="search-change-selection"
ref={this.searchChangeSelection}
>
{matchCountSection}
</div>
) : (
<span className="search-icon">
<FontAwesomeIcon icon={vsSearch} />
</span>
)}
<span className="search-icon">
<FontAwesomeIcon icon={vsSearch} />
</span>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1184,3 +1184,31 @@ test('On drag start/end', () => {
expect(mockGroupHandler).toBeCalledWith([]);
expect(mockMoveHandler).toBeCalledWith([{ from: 0, to: 1 }]);
});

test('changeSelectedColumn moves queried column index and loops', () => {
const builder = React.createRef<VisibilityOrderingBuilder>();
render(<Builder builderRef={builder} />);

builder.current?.searchColumns('TestColumn');
expect(builder.current?.state.selectedColumns.size).toEqual(10);

builder.current?.changeSelectedColumn('forward');
expect(builder.current?.state.queriedColumnIndex).toEqual(9);

builder.current?.changeSelectedColumn('forward');
expect(builder.current?.state.queriedColumnIndex).toEqual(0);
});

test('adjustQueriedIndex sets queriedColumnRange to prevIndex = 9 and nextIndex = 0', () => {
const builder = React.createRef<VisibilityOrderingBuilder>();
render(<Builder builderRef={builder} />);

builder.current?.searchColumns('TestColumn');

builder.current?.adjustQueriedIndex('Test');

expect(builder.current?.state.queriedColumnRange).toEqual({
prevIndex: 9,
nextIndex: 0,
});
});
Loading

0 comments on commit 75cf184

Please sign in to comment.