Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
fix(Tabs): highlight correct active tab on route changed
Browse files Browse the repository at this point in the history
  • Loading branch information
lukicenturi committed Dec 11, 2023
1 parent 30b2946 commit 6935c07
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/components/chips/Chip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('Chips/Chip', () => {
expect(wrapper.emitted()).toHaveProperty('click:close');
});

it("disabled chip can't close close", async () => {
it("disabled chip can't be closed", async () => {
const wrapper = createWrapper({
propsData: {
closeable: true,
Expand Down
109 changes: 59 additions & 50 deletions src/components/tabs/tabs/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ const updateValue = (newValue: string | number) => {
set(internalValue, newValue);
};
const route = useRoute();
const isPathMatch = (
path: string,
{
Expand All @@ -94,7 +96,6 @@ const isPathMatch = (
exact?: boolean;
},
) => {
const route = useRoute();
const currentRoute = route.fullPath;
if (exactPath) {
Expand All @@ -109,18 +110,59 @@ const isPathMatch = (
return currentRoute.startsWith(routeWithoutQueryParams);
};
onMounted(() => {
if (get(value) !== undefined) {
return;
}
const keepActiveTabVisible = () => {
nextTick(() => {
if (!get(showArrows)) {
return;
}
const elem = get(wrapper);
const barElem = get(bar);
if (elem) {
const activeTab = (elem.querySelector('.active-tab') ??
elem.querySelector('.active-tab-link')) as HTMLElement;
if (!activeTab || !barElem) {
return;
}
const childLeft = activeTab.offsetLeft - elem.offsetLeft;
const childTop = activeTab.offsetTop - elem.offsetTop;
const childWidth = activeTab.offsetWidth;
const childHeight = activeTab.offsetHeight;
const parentScrollLeft = barElem.scrollLeft;
const parentScrollTop = barElem.scrollTop;
const parentWidth = barElem.offsetWidth;
const parentHeight = barElem.offsetHeight;
const scrollLeft = Math.max(
Math.min(parentScrollLeft, childLeft),
childLeft + childWidth - parentWidth,
);
const scrollTop = Math.max(
Math.min(parentScrollTop, childTop),
childTop + childHeight - parentHeight,
);
barElem.scrollTo({
left: scrollLeft,
top: scrollTop,
behavior: 'smooth',
});
}
});
};
const applyNewValue = (onlyLink = false) => {
const enabledChildren = get(children).filter(
(child) => !(child.node.componentOptions?.propsData as TabProps).disabled,
);
if (enabledChildren.length > 0) {
let newValue: string | number = 0;
enabledChildren.forEach((child, index) => {
const props = child.node.componentOptions?.propsData as TabProps;
if (index === 0 && props.tabValue) {
if (!onlyLink && index === 0 && props.tabValue) {
newValue = props.tabValue;
}
if (props.link !== false && props.to && isPathMatch(props.to, props)) {
Expand All @@ -130,6 +172,17 @@ onMounted(() => {
updateValue(newValue);
}
keepActiveTabVisible();
};
onMounted(() => {
if (get(value) !== undefined) {
return;
}
applyNewValue();
});
watch(route, () => {
applyNewValue(true);
});
const css = useCssModule();
Expand Down Expand Up @@ -206,50 +259,6 @@ const onNextSliderClick = () => {
}
};
const keepActiveTabVisible = () => {
nextTick(() => {
if (!get(showArrows)) {
return;
}
const elem = get(wrapper);
const barElem = get(bar);
if (elem) {
const activeTab = (elem.querySelector('.active-tab') ??
elem.querySelector('.active-tab-link')) as HTMLElement;
if (!activeTab || !barElem) {
return;
}
const childLeft = activeTab.offsetLeft - elem.offsetLeft;
const childTop = activeTab.offsetTop - elem.offsetTop;
const childWidth = activeTab.offsetWidth;
const childHeight = activeTab.offsetHeight;
const parentScrollLeft = barElem.scrollLeft;
const parentScrollTop = barElem.scrollTop;
const parentWidth = barElem.offsetWidth;
const parentHeight = barElem.offsetHeight;
const scrollLeft = Math.max(
Math.min(parentScrollLeft, childLeft),
childLeft + childWidth - parentWidth,
);
const scrollTop = Math.max(
Math.min(parentScrollTop, childTop),
childTop + childHeight - parentHeight,
);
barElem.scrollTo({
left: scrollLeft,
top: scrollTop,
behavior: 'smooth',
});
}
});
};
useResizeObserver(bar, () => {
keepActiveTabVisible();
});
Expand Down
4 changes: 4 additions & 0 deletions tests/setup-files/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ vi.mock('vue', async () => {
),
};
});

vi.mock('vue-router/composables', () => ({
useRoute: vi.fn(),
}));

0 comments on commit 6935c07

Please sign in to comment.