refactor: minor adjustments to actionstoolbar (#1281)

This commit is contained in:
Christian Veinfors
2023-05-29 10:04:56 +02:00
committed by GitHub
parent 3b4b6ece98
commit d053ee3811
14 changed files with 46 additions and 65 deletions

View File

@@ -18,21 +18,11 @@ const PREFIX = 'ActionsToolbar';
const classes = {
item: `${PREFIX}-item`,
itemSpacing: `${PREFIX}-itemSpacing`,
firstItemSpacing: `${PREFIX}-firstItemSpacing`,
lastItemSpacing: `${PREFIX}-lastItemSpacing`,
};
const StyledPopover = styled(Popover)(({ theme }) => ({
[`& .${classes.itemSpacing}`]: {
padding: theme.spacing(0, 0.5),
},
[`& .${classes.firstItemSpacing}`]: {
padding: theme.spacing(0, 0.5, 0, 0),
},
[`& .${classes.lastItemSpacing}`]: {
padding: theme.spacing(0, 0, 0, 0.5),
padding: theme.spacing(0, 0.25),
},
}));
@@ -47,37 +37,14 @@ const ActionToolbarElement = {
};
const ActionsGroup = React.forwardRef(
(
{ className, ariaExpanded = false, actions = [], first = false, last = false, addAnchor = false, isRtl = false },
ref
) =>
({ className, ariaExpanded = false, actions = [], addAnchor = false, isRtl = false }, ref) =>
actions.length > 0 ? (
<Grid item container gap={0} flexDirection={isRtl ? 'row-reverse' : 'row'} wrap="nowrap" className={className}>
{actions.map((e, ix) => {
let cls = [];
const isFirstItem = first && ix === 0;
const isLastItem = last && actions.length - 1 === ix;
if (isFirstItem && !isLastItem) {
cls = [classes.firstItemSpacing, classes.item];
}
if (isLastItem && !isFirstItem) {
cls = [...cls, classes.lastItemSpacing, classes.item];
}
if (!isFirstItem && !isLastItem && cls.length === 0) {
cls = [classes.itemSpacing, classes.item];
}
return (
<Grid item key={e.key} className={cls.join(' ').trim()}>
<Item
ariaExpanded={ariaExpanded}
key={e.key}
item={e}
ref={ix === 0 ? ref : null}
addAnchor={addAnchor}
/>
</Grid>
);
})}
{actions.map((e, ix) => (
<Grid item key={e.key} className={`${classes.itemSpacing} ${classes.item}`}>
<Item ariaExpanded={ariaExpanded} key={e.key} item={e} ref={ix === 0 ? ref : null} addAnchor={addAnchor} />
</Grid>
))}
</Grid>
) : null
);
@@ -119,7 +86,7 @@ function ActionsToolbar({
const [showMoreItems, setShowMoreItems] = useState(false);
const popoverAnchorOrigin = {
vertical: 7,
vertical: 12,
horizontal: (popover.anchorEl?.clientWidth ?? 0) - 7,
};
@@ -204,7 +171,7 @@ function ActionsToolbar({
data-testid="actions-toolbar"
sx={{ flexDirection: isRtl ? 'row-reverse' : 'row' }}
>
{showActions && <ActionsGroup actions={newActions} first last={!showMore && !selections.show} />}
{showActions && <ActionsGroup actions={newActions} />}
{showMore && (
<ActionsGroup
id="actions-toolbar-show-more"
@@ -212,8 +179,6 @@ function ActionsToolbar({
ref={moreRef}
ariaExpanded={showMoreItems}
actions={[moreItem]}
first={!showActions}
last={!selections.show}
addAnchor
/>
)}
@@ -223,13 +188,7 @@ function ActionsToolbar({
</Grid>
)}
{selections.show && (
<ActionsGroup
className="actions-toolbar-default-actions"
actions={defaultSelectionActions}
first={!showActions && !showMore}
last
isRtl={isRtl}
/>
<ActionsGroup className="actions-toolbar-default-actions" actions={defaultSelectionActions} isRtl={isRtl} />
)}
{showMoreItems && (
<More
@@ -261,7 +220,7 @@ function ActionsToolbar({
className: ActionToolbarElement.className,
style: {
pointerEvents: 'auto',
padding: theme.spacing(0.8),
padding: theme.spacing(0.5, 0.25),
},
}}
>

View File

@@ -19,7 +19,7 @@ import useAppSelections from '../../hooks/useAppSelections';
import showToolbarDetached from './interactions/listbox-show-toolbar-detached';
import getListboxActionProps from './interactions/listbox-get-action-props';
import createSelectionState from './hooks/selections/selectionState';
import { CELL_PADDING_LEFT, ICON_WIDTH, ICON_PADDING, BUTTON_ICON_WIDTH } from './constants';
import { CELL_PADDING_LEFT, ICON_WIDTH, ICON_PADDING, BUTTON_ICON_WIDTH, HEADER_PADDING_RIGHT } from './constants';
import useTempKeyboard from './components/useTempKeyboard';
import ListBoxError from './components/ListBoxError';
import useRect from '../../hooks/useRect';
@@ -223,13 +223,22 @@ function ListBoxInline({ options, layout }) {
const isDrillDown = layout?.qListObject?.qDimensionInfo?.qGrouping === 'H';
const showIcons = showSearchOrLockIcon || isDrillDown;
const iconsWidth = (showSearchOrLockIcon ? BUTTON_ICON_WIDTH : 0) + (isDrillDown ? ICON_WIDTH + ICON_PADDING : 0); // Drill-down icon needs padding right so there is space between the icon and the title
const isRtl = direction === 'rtl';
const headerPaddingLeft = CELL_PADDING_LEFT - (showSearchOrLockIcon ? ICON_PADDING : 0);
const headerPaddingRight = isRtl ? CELL_PADDING_LEFT - (showIcons ? ICON_PADDING : 0) : HEADER_PADDING_RIGHT;
useEffect(() => {
if (!titleRef.current || !containerRect) {
return;
}
const isDetached = showToolbarDetached({ containerRect, titleRef, iconsWidth });
const isDetached = showToolbarDetached({
containerRect,
titleRef,
iconsWidth,
headerPaddingLeft,
headerPaddingRight,
});
setIsToolbarDetached(isDetached);
}, [titleRef.current, containerRect]);
@@ -237,7 +246,6 @@ function ListBoxInline({ options, layout }) {
return null;
}
const isRtl = direction === 'rtl';
const listboxSelectionToolbarItems = createListboxSelectionToolbar({
layout,
model,
@@ -282,8 +290,6 @@ function ListBoxInline({ options, layout }) {
});
const shouldAutoFocus = searchVisible && search === 'toggle';
const headerPaddingLeft = CELL_PADDING_LEFT - (showSearchOrLockIcon ? ICON_PADDING : 0);
const headerPaddingRight = isRtl ? CELL_PADDING_LEFT - (showIcons ? ICON_PADDING : 0) : 0;
// Add a container padding for grid mode to harmonize with the grid item margins (should sum to 8px).
const isGridMode = layoutOptions?.dataLayout === 'grid';

View File

@@ -1,4 +1,5 @@
export const CELL_PADDING_LEFT = 9;
export const HEADER_PADDING_RIGHT = 4;
export const ICON_WIDTH = 12;
export const ICON_PADDING = 7;
export const BUTTON_ICON_WIDTH = ICON_WIDTH + (ICON_PADDING + 1) * 2; // 1 is border width

View File

@@ -1,23 +1,31 @@
import showToolbarDetached from '../listbox-show-toolbar-detached';
const iconsWidth = 28;
const headerPaddingLeft = 9;
const headerPaddingRight = 4;
describe('show listbox toolbar detached', () => {
it('should return true if there is not enough space for toolbar', () => {
const containerRect = { width: 100 };
const titleRef = { current: { clientWidth: 60, scrollWidth: 80, offsetWidth: 81 } };
expect(showToolbarDetached({ containerRect, titleRef, iconsWidth })).toStrictEqual(true);
const titleRef = { current: { clientWidth: 50, scrollWidth: 80, offsetWidth: 81 } };
expect(
showToolbarDetached({ containerRect, titleRef, iconsWidth, headerPaddingLeft, headerPaddingRight })
).toStrictEqual(true);
});
it('should return true if title is truncated', () => {
const containerRect = { width: 300 };
const titleRef = { current: { clientWidth: 60, scrollWidth: 200, offsetWidth: 199 } };
const titleRef = {
current: { clientWidth: 60, scrollWidth: 200, offsetWidth: 199, headerPaddingLeft, headerPaddingRight },
};
expect(showToolbarDetached({ containerRect, titleRef, iconsWidth })).toStrictEqual(true);
});
it('should return false if there is enough space for title and toolbar', () => {
const containerRect = { width: 300 };
const titleRef = { current: { clientWidth: 60, scrollWidth: 200, offsetWidth: 201 } };
const titleRef = {
current: { clientWidth: 60, scrollWidth: 200, offsetWidth: 201, headerPaddingLeft, headerPaddingRight },
};
expect(showToolbarDetached({ containerRect, titleRef, iconsWidth })).toStrictEqual(false);
});
});

View File

@@ -1,7 +1,14 @@
export default function showToolbarDetached({ containerRect, titleRef, iconsWidth }) {
export default function showToolbarDetached({
containerRect,
titleRef,
iconsWidth,
headerPaddingLeft,
headerPaddingRight,
}) {
const containerWidth = containerRect.width;
const padding = 16;
const contentWidth = (titleRef?.current?.clientWidth ?? 0) + iconsWidth + padding;
const preventTruncation = 2;
const padding = headerPaddingLeft + headerPaddingRight;
const contentWidth = (titleRef?.current?.clientWidth ?? 0) + iconsWidth + padding + preventTruncation;
const actionToolbarWidth = 128;
const notSufficientSpace = containerWidth < contentWidth + actionToolbarWidth;
const isTruncated = titleRef?.current?.scrollWidth > titleRef?.current?.offsetWidth;

View File

@@ -19,7 +19,7 @@ function init() {
});
nebbie.selections().then((s) => s.mount(document.querySelector('.toolbar')));
nebbie.field('Alpha').then((s) => s.mount(document.querySelector('.listbox')));
nebbie.field('Alpha').then((s) => s.mount(document.querySelector('.listbox'), { search: 'toggle' }));
document.querySelectorAll('.object').forEach((el) => {
const type = el.getAttribute('data-type');

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB