Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions packages/react-core/src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ export class Tabs extends React.Component<TabsProps, TabsState> {
}
}

scrollTimeout: NodeJS.Timeout = null;

static defaultProps: PickOptional<TabsProps> = {
activeKey: 0,
onSelect: () => undefined as any,
Expand Down Expand Up @@ -179,28 +181,32 @@ export class Tabs extends React.Component<TabsProps, TabsState> {
}

handleScrollButtons = () => {
const container = this.tabList.current;
let disableLeftScrollButton = true;
let disableRightScrollButton = true;
let showScrollButtons = false;
// add debounce to the scroll event
clearTimeout(this.scrollTimeout);
this.scrollTimeout = setTimeout(() => {
const container = this.tabList.current;
let disableLeftScrollButton = true;
let disableRightScrollButton = true;
let showScrollButtons = false;

if (container && !this.props.isVertical) {
// get first element and check if it is in view
const overflowOnLeft = !isElementInView(container, container.firstChild as HTMLElement, false);
if (container && !this.props.isVertical) {
// get first element and check if it is in view
const overflowOnLeft = !isElementInView(container, container.firstChild as HTMLElement, false);

// get last element and check if it is in view
const overflowOnRight = !isElementInView(container, container.lastChild as HTMLElement, false);
// get last element and check if it is in view
const overflowOnRight = !isElementInView(container, container.lastChild as HTMLElement, false);

showScrollButtons = overflowOnLeft || overflowOnRight;
showScrollButtons = overflowOnLeft || overflowOnRight;

disableLeftScrollButton = !overflowOnLeft;
disableRightScrollButton = !overflowOnRight;
}
this.setState({
showScrollButtons,
disableLeftScrollButton,
disableRightScrollButton
});
disableLeftScrollButton = !overflowOnLeft;
disableRightScrollButton = !overflowOnRight;
}
this.setState({
showScrollButtons,
disableLeftScrollButton,
disableRightScrollButton
});
}, 100);
};

scrollLeft = () => {
Expand Down Expand Up @@ -258,6 +264,7 @@ export class Tabs extends React.Component<TabsProps, TabsState> {
window.removeEventListener('resize', this.handleScrollButtons, false);
}
}
clearTimeout(this.scrollTimeout);
}

componentDidUpdate(prevProps: TabsProps) {
Expand Down
14 changes: 10 additions & 4 deletions packages/react-core/src/helpers/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,30 @@ export function debounce(this: any, func: (...args: any[]) => any, wait: number)
* @param {HTMLElement} container The container to check if the element is in view of.
* @param {HTMLElement} element The element to check if it is view
* @param {boolean} partial true if partial view is allowed
* @param {boolean} strict true if strict mode is set, never consider the container width and element width
*
* @returns { boolean } True if the component is in View.
*/
export function isElementInView(container: HTMLElement, element: HTMLElement, partial: boolean) {
export function isElementInView(
container: HTMLElement,
element: HTMLElement,
partial: boolean,
strict: boolean = false
): boolean {
if (!container || !element) {
return false;
}
const containerBounds = container.getBoundingClientRect();
const elementBounds = element.getBoundingClientRect();
const containerBoundsLeft = Math.floor(containerBounds.left);
const containerBoundsLeft = Math.ceil(containerBounds.left);
const containerBoundsRight = Math.floor(containerBounds.right);
const elementBoundsLeft = Math.floor(elementBounds.left);
const elementBoundsLeft = Math.ceil(elementBounds.left);
const elementBoundsRight = Math.floor(elementBounds.right);

// Check if in view
const isTotallyInView = elementBoundsLeft >= containerBoundsLeft && elementBoundsRight <= containerBoundsRight;
const isPartiallyInView =
partial &&
(partial || (!strict && containerBounds.width < elementBounds.width)) &&
((elementBoundsLeft < containerBoundsLeft && elementBoundsRight > containerBoundsLeft) ||
(elementBoundsRight > containerBoundsRight && elementBoundsLeft < containerBoundsRight));

Expand Down