added auto focus offset
This commit is contained in:
parent
2378a32ddb
commit
16e83aedac
@ -7,16 +7,9 @@ const offset = 32;
|
||||
const wrapperPadding = DomHelpers.getViewport() <= tablet ? 16 : 20;
|
||||
|
||||
export const countAutoOffset = (data, submenuItemsRef) => {
|
||||
const refCurrent = submenuItemsRef.current;
|
||||
|
||||
const textWidths = data.map((d) => countTextWidth(d.name));
|
||||
const itemsAndGaps = countItemsAndGaps(textWidths);
|
||||
|
||||
const submenuWidth = refCurrent.offsetWidth;
|
||||
const marker = refCurrent.scrollLeft + submenuWidth - wrapperPadding;
|
||||
|
||||
const [itemOnMarker] = itemsAndGaps.filter(
|
||||
(obj) => obj.start < marker && marker < obj.end
|
||||
const [marker, itemsAndGaps, itemOnMarker] = countParams(
|
||||
data,
|
||||
submenuItemsRef
|
||||
);
|
||||
|
||||
if (itemOnMarker === undefined) return 0;
|
||||
@ -38,19 +31,54 @@ export const countAutoOffset = (data, submenuItemsRef) => {
|
||||
return 0;
|
||||
};
|
||||
|
||||
const countTextWidth = (text) => {
|
||||
export const countAutoFocus = (itemId, data, submenuItemsRef) => {
|
||||
const [marker, itemsAndGaps, itemOnMarker] = countParams(
|
||||
data,
|
||||
submenuItemsRef
|
||||
);
|
||||
|
||||
const [focusedItem] = itemsAndGaps.filter((obj) => obj.id === itemId);
|
||||
const submenuWidth = submenuItemsRef.current.offsetWidth;
|
||||
|
||||
if (itemOnMarker.id && focusedItem.id === itemOnMarker.id)
|
||||
return focusedItem.end - marker;
|
||||
if (
|
||||
focusedItem.start < marker - submenuWidth ||
|
||||
focusedItem.start - offset < marker - submenuWidth
|
||||
)
|
||||
return focusedItem.start - marker + submenuWidth - wrapperPadding - offset;
|
||||
return 0;
|
||||
};
|
||||
|
||||
const countParams = (data, submenuItemsRef) => {
|
||||
const refCurrent = submenuItemsRef.current;
|
||||
|
||||
const texts = data.map((d) => countText(d.name));
|
||||
const itemsAndGaps = countItemsAndGaps(texts);
|
||||
|
||||
const submenuWidth = refCurrent.offsetWidth;
|
||||
const marker = refCurrent.scrollLeft + submenuWidth - wrapperPadding;
|
||||
|
||||
const [itemOnMarker] = itemsAndGaps.filter(
|
||||
(obj) => obj.start < marker && marker < obj.end
|
||||
);
|
||||
|
||||
return [marker, itemsAndGaps, itemOnMarker];
|
||||
};
|
||||
|
||||
const countText = (text) => {
|
||||
const inputText = text;
|
||||
const font = "600 13px open sans";
|
||||
const canvas = document.createElement("canvas");
|
||||
const context = canvas.getContext("2d");
|
||||
context.font = font;
|
||||
return context.measureText(inputText).width;
|
||||
return { id: text, width: context.measureText(inputText).width };
|
||||
};
|
||||
|
||||
const countItemsAndGaps = (textWidths) => {
|
||||
const countItemsAndGaps = (texts) => {
|
||||
const result = [];
|
||||
|
||||
textWidths.forEach((textWidth) => {
|
||||
texts.forEach(({ id, width }) => {
|
||||
if (!result.length)
|
||||
result.push(
|
||||
{
|
||||
@ -60,10 +88,11 @@ const countItemsAndGaps = (textWidths) => {
|
||||
end: paddingGap + wrapperPadding,
|
||||
},
|
||||
{
|
||||
id: id,
|
||||
type: "item",
|
||||
length: textWidth,
|
||||
length: width,
|
||||
start: paddingGap,
|
||||
end: paddingGap + textWidth,
|
||||
end: paddingGap + width,
|
||||
}
|
||||
);
|
||||
else {
|
||||
@ -76,10 +105,11 @@ const countItemsAndGaps = (textWidths) => {
|
||||
end: lastItem.end + paddingGap * 2 + flexGap,
|
||||
},
|
||||
{
|
||||
id: id,
|
||||
type: "item",
|
||||
length: textWidth,
|
||||
length: width,
|
||||
start: lastItem.end + paddingGap * 2 + flexGap,
|
||||
end: lastItem.end + paddingGap * 2 + flexGap + textWidth,
|
||||
end: lastItem.end + paddingGap * 2 + flexGap + width,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import PropTypes from "prop-types";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Text from "../text";
|
||||
import { countAutoOffset } from "./autoOffset";
|
||||
|
||||
import Text from "../text";
|
||||
import { countAutoFocus, countAutoOffset } from "./autoOffset";
|
||||
import {
|
||||
StyledSubmenu,
|
||||
StyledSubmenuBottomLine,
|
||||
@ -20,17 +20,14 @@ const Submenu = ({ data, startSelect = 0, ...rest }) => {
|
||||
data[startSelect] || startSelect || null
|
||||
);
|
||||
|
||||
const submenuItemsRef = useRef();
|
||||
|
||||
const selectSubmenuItem = (e) => {
|
||||
const item = data.find((el) => el.id === e.currentTarget.id);
|
||||
if (item) setCurrentItem(item);
|
||||
};
|
||||
|
||||
const submenuItemsRef = useRef();
|
||||
|
||||
if (submenuItemsRef.current) {
|
||||
const offset = countAutoOffset(data, submenuItemsRef);
|
||||
const offset = countAutoFocus(item.name, data, submenuItemsRef);
|
||||
submenuItemsRef.current.scrollLeft += offset;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!submenuItemsRef.current) return;
|
||||
|
@ -15,11 +15,6 @@ export const StyledSubmenu = styled.div`
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
/* position: absolute;
|
||||
visibility: hidden;
|
||||
height: auto;
|
||||
width: auto;
|
||||
white-space: nowrap; */
|
||||
}
|
||||
`;
|
||||
|
||||
@ -43,9 +38,9 @@ export const StyledSubmenuItems = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 4px;
|
||||
padding: 20px;
|
||||
padding: 0 20px;
|
||||
@media ${tablet} {
|
||||
padding: 16px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
@ -59,8 +54,9 @@ export const StyledSubmenuItem = styled.div.attrs((props) => ({
|
||||
scroll-behavior: smooth;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex-direction: column;
|
||||
padding: 4px 14px;
|
||||
padding: 4px 14px 0;
|
||||
line-height: 20px;
|
||||
`;
|
||||
|
||||
@ -70,8 +66,9 @@ export const StyledSubmenuItemText = styled.div`
|
||||
`;
|
||||
|
||||
export const StyledSubmenuItemLabel = styled.div`
|
||||
positin: absolute;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
width: calc(100% + 28px);
|
||||
margin-left: -14px;
|
||||
height: 4px;
|
||||
bottom: 0px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
|
Loading…
Reference in New Issue
Block a user