Files
PriceUpdaterAppv2/src/tui/utils/responsiveLayout.js

173 lines
3.6 KiB
JavaScript

/**
* Responsive Layout Utilities
* Helper functions for adapting layouts to different terminal sizes
* Requirements: 10.2, 10.3, 10.4
*/
/**
* Calculate responsive dimensions for components
*/
const getResponsiveDimensions = (layoutConfig, componentType) => {
const { isSmall, isMedium, isLarge, maxContentWidth, maxContentHeight } =
layoutConfig;
const dimensions = {
menu: {
width: isSmall
? maxContentWidth
: isMedium
? Math.floor(maxContentWidth * 0.7)
: Math.floor(maxContentWidth * 0.6),
height: isSmall
? Math.floor(maxContentHeight * 0.8)
: maxContentHeight - 2,
},
form: {
width: isSmall ? maxContentWidth : Math.min(60, maxContentWidth),
height: maxContentHeight - 4,
},
progress: {
width: isSmall ? maxContentWidth - 4 : Math.min(50, maxContentWidth - 10),
height: isSmall ? 8 : 10,
},
logs: {
width: maxContentWidth,
height: maxContentHeight - 6,
},
sidebar: {
width: isLarge ? 30 : isMedium ? 25 : 0,
height: maxContentHeight,
},
};
return (
dimensions[componentType] || {
width: maxContentWidth,
height: maxContentHeight,
}
);
};
/**
* Get responsive column layout
*/
const getColumnLayout = (layoutConfig, itemCount) => {
const { columnsCount, maxContentWidth } = layoutConfig;
if (itemCount <= columnsCount) {
return {
columns: itemCount,
itemWidth: Math.floor(maxContentWidth / itemCount) - 2,
};
}
return {
columns: columnsCount,
itemWidth: Math.floor(maxContentWidth / columnsCount) - 2,
rows: Math.ceil(itemCount / columnsCount),
};
};
/**
* Calculate scrollable area dimensions
*/
const getScrollableDimensions = (layoutConfig, totalItems, itemHeight = 1) => {
const { maxContentHeight } = layoutConfig;
const availableHeight = maxContentHeight - 4; // Leave space for headers/footers
const visibleItems = Math.floor(availableHeight / itemHeight);
const needsScrolling = totalItems > visibleItems;
return {
visibleItems,
totalItems,
needsScrolling,
scrollHeight: availableHeight,
itemHeight,
};
};
/**
* Get responsive text truncation length
*/
const getTextTruncationLength = (layoutConfig, containerWidth) => {
const { isSmall, isMedium } = layoutConfig;
if (isSmall) {
return Math.max(20, containerWidth - 10);
} else if (isMedium) {
return Math.max(40, containerWidth - 8);
}
return Math.max(60, containerWidth - 6);
};
/**
* Get responsive padding and margins
*/
const getResponsiveSpacing = (layoutConfig) => {
const { isSmall, isMedium } = layoutConfig;
return {
padding: isSmall ? 1 : 2,
margin: isSmall ? 0 : 1,
gap: isSmall ? 0 : 1,
};
};
/**
* Check if component should be hidden on small screens
*/
const shouldHideOnSmallScreen = (layoutConfig, componentType) => {
const { isSmall } = layoutConfig;
const hideOnSmall = ["sidebar", "secondary-info", "decorative-elements"];
return isSmall && hideOnSmall.includes(componentType);
};
/**
* Get adaptive font styling for different screen sizes
*/
const getAdaptiveFontStyle = (layoutConfig, textType = "normal") => {
const { isSmall } = layoutConfig;
const styles = {
title: {
bold: true,
color: isSmall ? "white" : "blue",
},
subtitle: {
bold: !isSmall,
color: "gray",
},
normal: {
color: "white",
},
emphasis: {
bold: true,
color: "yellow",
},
error: {
bold: true,
color: "red",
},
success: {
bold: true,
color: "green",
},
};
return styles[textType] || styles.normal;
};
module.exports = {
getResponsiveDimensions,
getColumnLayout,
getScrollableDimensions,
getTextTruncationLength,
getResponsiveSpacing,
shouldHideOnSmallScreen,
getAdaptiveFontStyle,
};