Skip to content

Commit

Permalink
feat: search & selectAll shortcuts (#1159)
Browse files Browse the repository at this point in the history
  • Loading branch information
T-Wizard committed Mar 20, 2023
1 parent 72af025 commit 6273681
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 12 deletions.
7 changes: 7 additions & 0 deletions apis/nucleus/src/components/listbox/ListBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default function ListBox({
selectDisabled = () => false,
keyScroll = { state: {}, reset: () => {} },
currentScrollIndex = { set: () => {} },
onCtrlF,
}) {
const [initScrollPosIsSet, setInitScrollPosIsSet] = useState(false);
const isSingleSelect = !!(layout && layout.qListObject.qDimensionInfo.qIsOneAndOnlyOne);
Expand Down Expand Up @@ -233,6 +234,10 @@ export default function ListBox({
setLast: (last) => setFocusListItem((prevState) => ({ ...prevState, last })),
});

const selectAll = () => {
selectionState.clearItemStates(false);
model.selectListObjectAll('/qListObjectDef');
};
const frequencyMax = useFrequencyMax(app, layout);

const { List, Grid } = getListBoxComponents({
Expand All @@ -247,6 +252,8 @@ export default function ListBox({
showGray,
interactionEvents,
select,
selectAll,
onCtrlF,
textAlign,
isVertical,
pages,
Expand Down
12 changes: 11 additions & 1 deletion apis/nucleus/src/components/listbox/ListBoxInline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,15 @@ function ListBoxInline({ options, layout }) {
setShowSearch(newValue);
};

const onCtrlF = () => {
if (search === 'toggle') {
onShowSearch();
} else {
const input = searchContainer.current.querySelector('input');
input?.focus();
}
};

const getActionToolbarProps = (isPopover) =>
getListboxActionProps({
isPopover,
Expand Down Expand Up @@ -345,10 +354,10 @@ function ListBoxInline({ options, layout }) {
visible={searchVisible}
search={search}
autoFocus={shouldAutoFocus}
searchContainerRef={searchContainerRef}
wildCardSearch={wildCardSearch}
searchEnabled={searchEnabled}
direction={direction}
hide={showSearchIcon && onShowSearch}
/>
</Grid>
<Grid item xs className={classes.listboxWrapper}>
Expand Down Expand Up @@ -384,6 +393,7 @@ function ListBoxInline({ options, layout }) {
state: currentScrollIndex,
set: setCurrentScrollIndex,
}}
onCtrlF={onCtrlF}
/>
)}
</AutoSizer>
Expand Down
27 changes: 18 additions & 9 deletions apis/nucleus/src/components/listbox/ListBoxPopover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default function ListBoxPopover({
const open = show && Boolean(alignTo.current);
const [listCount, setListCount] = useState(0);
const theme = useTheme();
const searchContainerRef = useRef();
const [model] = useSessionModel(
{
qInfo: {
Expand Down Expand Up @@ -119,6 +120,11 @@ export default function ListBoxPopover({
selectionState,
});

const onCtrlF = () => {
const input = searchContainerRef.current.querySelector('input');
input?.focus();
};

const hasSelections = getHasSelections(layout);

return (
Expand Down Expand Up @@ -171,15 +177,17 @@ export default function ListBoxPopover({
</Grid>
<Grid item xs>
<div ref={moreAlignTo} />
<ListBoxSearch
visible
model={model}
listCount={listCount}
selections={selections}
selectionState={selectionState}
keyboard={{ enabled: false }}
autoFocus={autoFocus ?? true}
/>
<Grid item ref={searchContainerRef}>
<ListBoxSearch
visible
model={model}
listCount={listCount}
selections={selections}
selectionState={selectionState}
keyboard={{ enabled: false }}
autoFocus={autoFocus ?? true}
/>
</Grid>
<ListBox
model={model}
app={app}
Expand All @@ -188,6 +196,7 @@ export default function ListBoxPopover({
selectionState={selectionState}
direction="ltr"
onSetListCount={(c) => setListCount(c)}
onCtrlF={onCtrlF}
/>
</Grid>
</Grid>
Expand Down
11 changes: 11 additions & 0 deletions apis/nucleus/src/components/listbox/components/ListBoxSearch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default function ListBoxSearch({
wildCardSearch = false,
searchEnabled,
direction,
hide,
}) {
const { translator } = useContext(InstanceContext);
const [value, setValue] = useState('');
Expand Down Expand Up @@ -123,6 +124,16 @@ export default function ListBoxSearch({
e.preventDefault();
e.stopPropagation();
break;
case 'f':
case 'F':
if (e.ctrlKey || e.metaKey) {
if (hide) {
hide();
}
e.preventDefault();
e.stopPropagation();
}
break;
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ exports[`grid-list-components should create a Grid component 1`] = `
"actions": {
"cancel": [Function],
"confirm": [Function],
"onCtrlF": undefined,
"select": [MockFunction],
"selectAll": undefined,
"setScrollPosition": undefined,
},
"checkboxes": false,
Expand Down Expand Up @@ -68,7 +70,9 @@ exports[`grid-list-components should create a List component 1`] = `
"actions": {
"cancel": [Function],
"confirm": [Function],
"onCtrlF": undefined,
"select": [MockFunction],
"selectAll": undefined,
"setScrollPosition": undefined,
},
"checkboxes": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default function getListBoxComponents({
histogram,
isSingleSelect,
select,
selectAll,
onCtrlF,
textAlign,
selections,
keyboard,
Expand Down Expand Up @@ -72,6 +74,8 @@ export default function getListBoxComponents({
confirm: () => selections?.confirm.call(selections),
cancel: () => selections?.cancel.call(selections),
setScrollPosition,
selectAll,
onCtrlF,
},
frequencyMax,
histogram,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import KEYS from '../../../keys';

export function getFieldKeyboardNavigation({ select, confirm, cancel, setScrollPosition, focusListItems }) {
export function getFieldKeyboardNavigation({
select,
selectAll,
onCtrlF,
confirm,
cancel,
setScrollPosition,
focusListItems,
}) {
const getElement = (elm, next = false) => {
const parentElm = elm && elm.parentElement[next ? 'nextElementSibling' : 'previousElementSibling'];
return parentElm && parentElm.querySelector('[role]');
Expand All @@ -13,7 +21,7 @@ export function getFieldKeyboardNavigation({ select, confirm, cancel, setScrollP

const handleKeyDown = (event) => {
let elementToFocus;
const { keyCode, shiftKey = false, ctrlKey = false } = event.nativeEvent;
const { keyCode, shiftKey = false, ctrlKey = false, metaKey = false } = event.nativeEvent;
switch (keyCode) {
case KEYS.SHIFT:
// This is to ensure we include the first value when starting a range selection.
Expand Down Expand Up @@ -66,6 +74,18 @@ export function getFieldKeyboardNavigation({ select, confirm, cancel, setScrollP
}
setScrollPosition?.('end');
break;
case KEYS.A:
if (ctrlKey || metaKey) {
selectAll();
break;
}
return;
case KEYS.F:
if (ctrlKey || metaKey) {
onCtrlF();
break;
}
return;
default:
return; // don't stop propagation since we want to outsource keydown to other handlers.
}
Expand Down

0 comments on commit 6273681

Please sign in to comment.