Skip to content

Commit

Permalink
fix(components): update Tabs Menu to v5 syntax and tweak useVisibleRange
Browse files Browse the repository at this point in the history
Ticket: issue/Transversal-314
Reviewed-by: @MIGUELez11
Refs: #201
  • Loading branch information
fermarinsanchez authored Oct 29, 2024
1 parent 6e25a74 commit fc77712
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 79 deletions.
4 changes: 2 additions & 2 deletions packages/components/src/form/IconButton/IconButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const IconButton = forwardRef(
const variant = ICON_BUTTON_VARIANTS.includes(variantProp)
? variantProp
: ICON_BUTTON_DEFAULT_PROPS.variant;
const { classes } = IconButtonStyles({ color, size, variant });
const { classes, cx } = IconButtonStyles({ color, size, variant });

return (
<MantineActionIcon
Expand All @@ -44,7 +44,7 @@ const IconButton = forwardRef(
variant={variant}
radius={radius}
size={size}
className={classes.root}
className={cx(classes.root, className)}
ref={ref}
role={useAria ? 'button' : undefined}
>
Expand Down
88 changes: 28 additions & 60 deletions packages/components/src/navigation/Tabs/TabNavList/Dropdown.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, forwardRef } from 'react';
import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
import { isFunction } from 'lodash';
import { Menu, Box } from '@mantine/core';
Expand All @@ -7,63 +7,31 @@ import { IconButton } from '../../../form/IconButton';
import { DropdownStyles } from './Dropdown.styles';

const Dropdown = forwardRef(({ tabs, onTabClick }, ref) => {
// ········································································
// Dropdown
const [open, setOpen] = useState(false);
const [selectedKey, setSelectedKey] = useState(null);

const popupId = `more-popup`;
const selectedItemId = selectedKey !== null ? `${popupId}-${selectedKey}` : null;

// ········································································
// Effect
useEffect(() => {
// We use query element here to avoid React strict warning
const elem = document.getElementById(selectedItemId);
if (elem?.scrollIntoView) {
elem.scrollIntoView(false);
}
}, [selectedKey]);

useEffect(() => {
if (!open) {
setSelectedKey(null);
}
}, [open]);

// ········································································
// Render

const { classes, cx } = DropdownStyles({}, { name: 'Dropdown' });

return (
<Box className={cx(classes.root)} ref={ref}>
<Menu
control={<IconButton onClick={() => setOpen(true)} icon={<ChevronDownIcon />} />}
withArrow
closeOnScroll={false}
position="bottom"
placement="end"
opened={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
styles={() => ({
body: {
maxHeight: 300,
overflowY: 'auto',
},
})}
>
{tabs.map((tab) => (
<Menu.Item
key={tab.key}
onClick={(e) => {
if (isFunction(onTabClick)) onTabClick(tab.key, e);
}}
>
{tab.label}
</Menu.Item>
))}
<Menu shadow="md" width={200} position="bottom-end" offset={4}>
<Menu.Target>
<IconButton
className={cx(classes.buttonIcon)}
icon={<ChevronDownIcon className={classes.icon} />}
/>
</Menu.Target>

<Menu.Dropdown position="bottom-end" offset={4}>
{tabs.map((tab) => (
<Menu.Item
key={tab.key}
className={cx(classes.item)}
onClick={(e) => {
if (isFunction(onTabClick)) onTabClick(tab.key, e);
}}
>
{tab.label}
</Menu.Item>
))}
</Menu.Dropdown>
</Menu>
</Box>
);
Expand All @@ -72,13 +40,13 @@ const Dropdown = forwardRef(({ tabs, onTabClick }, ref) => {
Dropdown.displayName = 'Dropdown';

Dropdown.propTypes = {
id: PropTypes.string,
tabs: PropTypes.any,
rtl: PropTypes.bool,
tabBarGutter: PropTypes.number,
activeKey: PropTypes.string,
tabs: PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.string.isRequired,
label: PropTypes.node.isRequired,
}),
).isRequired,
onTabClick: PropTypes.func,
tabMoving: PropTypes.bool,
};

export { Dropdown };
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { createStyles } from '@mantine/styles';

export const DropdownStyles = createStyles((theme, {}, getRef) => {
return {
root: {
paddingLeft: theme.spacing['3'],
display: 'flex',
alignItems: 'center',
// paddingBottom: theme.spacing['2'],
const DropdownStyles = createStyles((theme, {}, getRef) => ({
root: {
paddingLeft: theme.spacing['3'],
display: 'flex',
alignItems: 'center',
zIndex: 1000,
// paddingBottom: theme.spacing['2'],
},
item: {
'&:hover': {
backgroundColor: theme.other.button.content.color.terciary.default,
},
};
});
},
buttonIcon: {
'&:hover': {
backgroundColor: theme.other.buttonIcon.background.color.ghost.hover,
'& > svg': {
color: theme.other.buttonIcon.background.color.secondary.down,
},
},
},
}));

export { DropdownStyles };
17 changes: 9 additions & 8 deletions packages/components/src/navigation/Tabs/hooks/useVisibleRange.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { useMemo } from 'react';

const DEFAULT_SIZE = { width: 0, height: 0, left: 0, top: 0, right: 0 };
const TOLERANCE = 5; // píxeles de tolerancia

export const useVisibleRange = (
tabOffsets, // Map<React.Key, { width: number, height: number, left: number, top: number }>
containerSize, // { width: number, height: number, left: number, top: number },
tabContentNodeSize, // { width: number, height: number },
addNodeSize, // { width: number, height: number },
{ tabs, rtl }
{ tabs, rtl },
) => {
// { tabs: Tab[] } & TabNavListProps
let unit = 'width'; // 'width' | 'height';
let position = rtl ? 'right' : 'left'; // 'left' | 'top' | 'right';
let transformSize = Math.abs(containerSize.left); // number;
const unit = 'width'; // 'width' | 'height';
const position = rtl ? 'right' : 'left'; // 'left' | 'top' | 'right';
const transformSize = Math.abs(containerSize.left); // number;

const basicSize = containerSize[unit];
const tabContentSize = tabContentNodeSize[unit];
Expand All @@ -29,7 +30,7 @@ export const useVisibleRange = (
}

const len = tabs.length;
let endIndex = len;
let endIndex = len - 1;
for (let i = 0; i < len; i += 1) {
const offset = tabOffsets.get(tabs[i].key) || DEFAULT_SIZE;
if (offset[position] + offset[unit] > transformSize + mergedBasicSize) {
Expand All @@ -39,10 +40,10 @@ export const useVisibleRange = (
}

let startIndex = 0;
for (let i = len - 1; i >= 0; i -= 1) {
for (let i = 0; i < len; i += 1) {
const offset = tabOffsets.get(tabs[i].key) || DEFAULT_SIZE;
if (offset[position] < transformSize) {
startIndex = i + 1;
if (offset[position] + offset[unit] >= transformSize) {
startIndex = i;
break;
}
}
Expand Down

0 comments on commit fc77712

Please sign in to comment.