Skip to content

Commit

Permalink
Merge branch 'master' of github.com:qlik-oss/nebula.js into hide-sear…
Browse files Browse the repository at this point in the history
…ch-icon
  • Loading branch information
veinfors committed Mar 14, 2023
2 parents 44880f1 + fe78bac commit 43ba035
Show file tree
Hide file tree
Showing 19 changed files with 533 additions and 506 deletions.
36 changes: 15 additions & 21 deletions apis/nucleus/src/components/listbox/ListBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default function ListBox({
constraints,
layout,
selections,
selectionState,
direction,
checkboxes: checkboxOption,
height,
Expand Down Expand Up @@ -65,16 +66,23 @@ export default function ListBox({
postProcessPages,
listData,
});
const [pages, setPages] = useState([]);
const { setStoreValue } = useDataStore(model);
const loadMoreItems = useCallback(itemsLoader.loadMoreItems, [layout]);

const [overflowDisclaimer, setOverflowDisclaimer] = useState({ show: false, dismissed: false });
const showOverflowDisclaimer = (show) => setOverflowDisclaimer((state) => ({ ...state, show }));

useEffect(() => {
setPages(itemsLoader?.pages || []);
}, [itemsLoader?.pages]);
const [pages, setPages] = useState([]);

if (itemsLoader?.pages) {
selectionState.update({
setPages,
pages: itemsLoader?.pages,
isSingleSelect,
selectDisabled,
layout,
});
}

const isItemLoaded = useCallback(
(index) => {
Expand All @@ -89,18 +97,11 @@ export default function ListBox({
[layout, pages]
);

const {
instantPages = [],
interactionEvents,
select,
} = useSelectionsInteractions({
layout,
const { interactionEvents, select } = useSelectionsInteractions({
selectionState,
selections,
pages,
checkboxes,
selectDisabled,
doc: document,
isSingleSelect,
});

const { layoutOptions = {} } = layout || {};
Expand Down Expand Up @@ -143,13 +144,6 @@ export default function ListBox({
update.call(null, fetchData);
}

useEffect(() => {
if (!instantPages || isLoadingData) {
return;
}
setPages(instantPages);
}, [instantPages]);

useEffect(() => {
if (scrollState && !initScrollPosIsSet && loaderRef.current) {
loaderRef.current._listRef.scrollToItem(scrollState.initScrollPos);
Expand Down Expand Up @@ -198,7 +192,7 @@ export default function ListBox({
});
local.current.dataOffset = offset;
if (triggerRerender) {
setPages((currentPages) => [...currentPages]);
selectionState.triggerStateChanged();
}
scrollToIndex(scrollIndex);
};
Expand Down
60 changes: 42 additions & 18 deletions apis/nucleus/src/components/listbox/ListBoxInline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ListBoxSearch from './components/ListBoxSearch';
import { getListboxInlineKeyboardNavigation } from './interactions/listbox-keyboard-navigation';
import addListboxTheme from './assets/addListboxTheme';
import useAppSelections from '../../hooks/useAppSelections';
import createSelectionState from './hooks/selections/selectionState';
import { CELL_PADDING_LEFT, ICON_PADDING } from './constants';

const PREFIX = 'ListBoxInline';
Expand All @@ -23,22 +24,28 @@ const drillDownIconWidth = 24;
const classes = {
listBoxHeader: `${PREFIX}-listBoxHeader`,
screenReaderOnly: `${PREFIX}-screenReaderOnly`,
listboxWrapper: `${PREFIX}-listboxWrapper`,
};

const StyledGrid = styled(Grid)(({ theme }) => ({
backgroundColor: theme.listBox?.backgroundColor ?? theme.palette.background.default,
[`& .${classes.listBoxHeader}`]: {
alignSelf: 'center',
display: 'inline-flex',
width: `calc(100% - ${searchIconWidth}px)`,
},
[`& .${classes.screenReaderOnly}`]: {
position: 'absolute',
height: 0,
width: 0,
overflow: 'hidden',
},
}));
const StyledGrid = styled(Grid, { shouldForwardProp: (p) => !['containerPadding'].includes(p) })(
({ theme, containerPadding }) => ({
backgroundColor: theme.listBox?.backgroundColor ?? theme.palette.background.default,
[`& .${classes.listBoxHeader}`]: {
alignSelf: 'center',
display: 'inline-flex',
width: `calc(100% - ${searchIconWidth}px)`,
},
[`& .${classes.screenReaderOnly}`]: {
position: 'absolute',
height: 0,
width: 0,
overflow: 'hidden',
},
[`& .${classes.listboxWrapper}`]: {
padding: containerPadding,
},
})
);

const Title = styled(Typography)(({ theme }) => ({
color: theme.listBox?.title?.main?.color,
Expand Down Expand Up @@ -102,6 +109,7 @@ function ListBoxInline({ options, layout }) {
const updateKeyScroll = (newState) => setKeyScroll((current) => ({ ...current, ...newState }));
const [currentScrollIndex, setCurrentScrollIndex] = useState({ start: 0, stop: 0 });
const [appSelections] = useAppSelections(app);
const [selectionState] = useState(() => createSelectionState());

const { handleKeyDown, handleOnMouseEnter, handleOnMouseLeave } = getListboxInlineKeyboardNavigation({
setKeyboardActive,
Expand Down Expand Up @@ -176,13 +184,15 @@ function ListBoxInline({ options, layout }) {
layout,
model,
translator,
selectionState,
})
: [];

const showTitle = true;
const showSearchToggle = search === 'toggle' && showSearch;
const searchVisible = (search === true || showSearchToggle) && !selectDisabled();
const dense = layout.layoutOptions?.dense ?? false;
const { layoutOptions = {} } = layout;
const dense = layoutOptions.dense ?? false;
const searchHeight = dense ? 27 : 40;
const extraheight = dense ? 39 : 49;
const minHeight = 49 + (searchVisible ? searchHeight : 0) + extraheight;
Expand All @@ -202,14 +212,26 @@ function ListBoxInline({ options, layout }) {
const drillDownPaddingLeft = showSearchOrLockIcon ? 0 : ICON_PADDING;
const headerPaddingLeft = CELL_PADDING_LEFT - (showIcons ? ICON_PADDING : 0);

// Add a container padding for grid mode to harmonize with the grid item margins (should sum to 8px).
const isGridMode = layoutOptions?.dataLayout === 'grid';
let containerPadding;
if (isGridMode) {
containerPadding = layoutOptions.layoutOrder === 'row' ? '2px 4px' : '2px 6px 2px 4px';
}

return (
<StyledGrid
className="listbox-container"
container
tabIndex={keyboard.enabled && !keyboard.active ? 0 : -1}
direction="column"
gap={0}
style={{ height: '100%', minHeight: `${minHeight}px`, flexFlow: 'column nowrap' }}
containerPadding={containerPadding}
style={{
height: '100%',
minHeight: `${minHeight}px`,
flexFlow: 'column nowrap',
}}
onKeyDown={handleKeyDown}
onMouseEnter={handleOnMouseEnter}
onMouseLeave={handleOnMouseLeave}
Expand Down Expand Up @@ -251,7 +273,7 @@ function ListBoxInline({ options, layout }) {
)}
<Grid item className={classes.listBoxHeader}>
{showTitle && (
<Title variant="h6" noWrap>
<Title variant="h6" noWrap title={layout.title}>
{layout.title}
</Title>
)}
Expand Down Expand Up @@ -295,6 +317,7 @@ function ListBoxInline({ options, layout }) {
<div className={classes.screenReaderOnly}>{translator.get('Listbox.Search.ScreenReaderInstructions')}</div>
<ListBoxSearch
selections={selections}
selectionState={selectionState}
model={model}
dense={dense}
keyboard={keyboard}
Expand All @@ -306,7 +329,7 @@ function ListBoxInline({ options, layout }) {
searchEnabled={searchEnabled}
/>
</Grid>
<Grid item xs>
<Grid item xs className={classes.listboxWrapper}>
<div className={classes.screenReaderOnly}>{translator.get('Listbox.ScreenReaderInstructions')}</div>
<AutoSizer>
{({ height, width }) => (
Expand All @@ -315,6 +338,7 @@ function ListBoxInline({ options, layout }) {
constraints={constraints}
layout={layout}
selections={selections}
selectionState={selectionState}
direction={direction}
frequencyMode={frequencyMode}
rangeSelect={rangeSelect}
Expand Down
5 changes: 5 additions & 0 deletions apis/nucleus/src/components/listbox/ListBoxPopover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import InstanceContext from '../../contexts/InstanceContext';

import ListBoxSearch from './components/ListBoxSearch';
import useObjectSelections from '../../hooks/useObjectSelections';
import createSelectionState from './hooks/selections/selectionState';
import getHasSelections from './assets/has-selections';

export default function ListBoxPopover({
Expand Down Expand Up @@ -89,6 +90,7 @@ export default function ListBoxPopover({
const containerRef = useRef();
const [selections] = useObjectSelections(app, model, containerRef);
const [layout] = useLayout(model);
const [selectionState] = useState(() => createSelectionState());

useEffect(() => {
if (selections && open) {
Expand All @@ -114,6 +116,7 @@ export default function ListBoxPopover({
layout,
model,
translator,
selectionState,
});

const hasSelections = getHasSelections(layout);
Expand Down Expand Up @@ -173,13 +176,15 @@ export default function ListBoxPopover({
model={model}
listCount={listCount}
selections={selections}
selectionState={selectionState}
keyboard={{ enabled: false }}
autoFocus={autoFocus ?? true}
/>
<ListBox
model={model}
layout={layout}
selections={selections}
selectionState={selectionState}
direction="ltr"
onSetListCount={(c) => setListCount(c)}
/>
Expand Down
12 changes: 4 additions & 8 deletions apis/nucleus/src/components/listbox/__tests__/list-box.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('<Listbox />', () => {
let args;
let layout;
let selections;
let selectionState;
let renderer;
let render;
let pages;
Expand All @@ -55,7 +56,6 @@ describe('<Listbox />', () => {
};

useSelectionsInteractions = jest.fn().mockReturnValue({
instantPages: [],
interactionEvents: {
onMouseDown: () => {},
onMouseUp: () => {},
Expand Down Expand Up @@ -104,6 +104,7 @@ describe('<Listbox />', () => {
global.window = { setTimeout: setTimeoutStub };
selectDisabled = () => false;
selections = { key: 'selections' };
selectionState = { update: jest.fn() };

args = {
model: {
Expand All @@ -113,6 +114,7 @@ describe('<Listbox />', () => {
frequencyMode: 'N',
histogram: false,
selections,
selectionState,
postProcessPages: undefined,
calculatePagesHeight: false,
keyboard: undefined,
Expand Down Expand Up @@ -154,6 +156,7 @@ describe('<Listbox />', () => {
keyboard={mergedArgs.keyboard}
showGray={mergedArgs.showGray}
selections={mergedArgs.selections}
selectionState={mergedArgs.selectionState}
direction={mergedArgs.direction}
height={mergedArgs.height}
width={mergedArgs.width}
Expand Down Expand Up @@ -183,23 +186,18 @@ describe('<Listbox />', () => {
expect(rows).toHaveLength(1);
expect(columns).toHaveLength(0);
expect(useSelectionsInteractions.mock.lastCall[0]).toMatchObject({
layout,
selections,
pages: [],
doc: expect.any(Object),
});

expect(useSelectionsInteractions.mock.calls[1][0].selectDisabled instanceof Function).toBe(true);
expect(FixedSizeList.mock.calls.length).toBeGreaterThan(0);
});

test('should call useSelectionsInteractions', async () => {
await render();

expect(useSelectionsInteractions.mock.lastCall[0]).toMatchObject({
layout,
selections,
pages: [],
doc: expect.any(Object),
});
});
Expand Down Expand Up @@ -229,9 +227,7 @@ describe('<Listbox />', () => {
await render();

expect(useSelectionsInteractions.mock.lastCall[0]).toMatchObject({
layout,
selections,
pages: [],
doc: expect.any(Object),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ describe('get-list-sizes', () => {
const sizes = getListSizes(args);
expect(sizes).toEqual({
columnCount: 1,
columnWidth: 47.5,
columnWidth: 49.5,
count: 200,
itemPadding: 4,
itemSize: 29,
listCount: 100,
listHeight: 300,
frequencyWidth: 40,
maxCount: {
column: 706315,
column: 677777,
row: 577000,
},
overflowStyling: {
Expand Down Expand Up @@ -134,7 +134,7 @@ describe('get-list-sizes', () => {
});
});

it('A minimum item width should kick in if text is short and reverve extra space for frequency', () => {
it('A minimum item width should kick in if text is short and reserve extra space for frequency', () => {
args.layout.layoutOptions.dataLayout = 'grid';
args.layout.layoutOptions.layoutOrder = 'column';
args.textWidth = 10;
Expand Down Expand Up @@ -176,15 +176,15 @@ describe('get-list-sizes', () => {
const sizes = getListSizes(args);
expect(sizes).toEqual({
columnCount: 1,
columnWidth: 47.5,
columnWidth: 49.5,
count: 200,
itemPadding: 4,
itemSize: 29,
listCount: args.listCount,
listHeight: 300,
frequencyWidth: 40,
maxCount: {
column: 706315,
column: 677777,
row: 577000,
},
overflowStyling: {
Expand Down
Loading

0 comments on commit 43ba035

Please sign in to comment.