Я использую подсетку, а не гибкость, поскольку не могу установить жесткое ограничение для каждого столбца. Мне нужно, чтобы правый столбец адаптировался к его содержимому, а левый столбец рос как мог. Вот скриншот анимации, отстающей в середине свертывания:

Код:
Код: Выделить всё
let isOpen = false;
let state = {
items: [],
visibleRows: 3,
isMultiSelect: false,
};
// Initialize state
function initializeState() {
const rows = document.querySelectorAll('.table-row');
state.items = Array.from(rows).map((row, index) => ({
id: index,
selected: row.querySelector('input').checked,
transformMultiplier: 0,
element: row,
}));
calculateTransforms();
}
// Port of the calculateTransforms function from React component
function calculateTransforms() {
const selectedRows = state.items.reduce(
(count, item) => count + (item.selected ? 1 : 0),
0,
);
let gracePortion = Math.max(0, 3 - selectedRows);
let distance = 0;
const distances = [];
const firstPass = state.items.map((item, index) => {
let transformMultiplier = null;
if (item.selected) {
transformMultiplier = distance;
distances.push(distance);
} else if (gracePortion > 0) {
transformMultiplier = distance;
distances.push(distance);
gracePortion--;
} else if (state.items.length === index + 1) {
distance++;
transformMultiplier = distance;
distances.push(distance);
} else {
distance++;
}
return { ...item, transformMultiplier: transformMultiplier };
});
let distancePosition = 0;
const items = firstPass.map((item) => {
let transformMultiplier = item.transformMultiplier;
if (transformMultiplier === null) {
transformMultiplier = distances[distancePosition];
} else {
distancePosition++;
}
return { ...item, transformMultiplier: transformMultiplier };
});
state.items = items;
state.visibleRows = Math.max(3, selectedRows);
updateTransforms();
}
function updateTransforms() {
const table = document.getElementById('table');
const totalRows = isOpen ? state.items.length : state.visibleRows;
// Update CSS custom property for table height
table.style.setProperty('--number-of-rows', totalRows);
state.items.forEach((item, index) => {
const translateY = isOpen ? 0 : -item.transformMultiplier * 100;
item.element.style.transform = `translateY(${translateY}%)`;
item.element.style.zIndex = state.items.length - index;
});
}
function toggleRows() {
isOpen = !isOpen;
const button = document.querySelector('.footer-button');
const chevron = document.getElementById('chevron');
button.innerHTML = isOpen
? 'Show less '
: 'Show more ';
calculateTransforms();
}
// Handle radio button changes
function handleSelectionChange() {
const rows = document.querySelectorAll('.table-row');
rows.forEach((row, index) => {
const input = row.querySelector('input');
state.items[index].selected = input.checked;
});
calculateTransforms();
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', function () {
initializeState();
// Add event listeners to radio buttons
const inputs = document.querySelectorAll('input[type="radio"]');
inputs.forEach((input) => {
input.addEventListener('change', handleSelectionChange);
});
});Код: Выделить всё
:root {
--duration: 5000ms;
}
.table-container {
display: flex;
flex-direction: column;
width: 100%;
max-width: 600px;
margin: 20px auto;
}
.table {
--number-of-rows: 3;
position: relative;
display: grid;
grid-template-columns: auto max-content;
overflow: hidden;
height: calc(var(--number-of-rows) * 51px + 42px);
transition: height var(--duration) ease;
}
.table-header {
display: grid;
grid-template-columns: subgrid;
grid-column: span 2;
background-color: grey;
height: 40px;
align-items: center;
color: white;
font-weight: bold;
border: solid 1px black;
z-index: 9999;
}
.table-row {
display: grid;
grid-template-columns: subgrid;
grid-column: span 2;
height: 50px;
align-items: center;
border-inline: solid 1px red;
border-bottom: solid 1px red;
transition: transform var(--duration) ease;
}
.table-row:nth-child(even) {
background-color: #f8f8f8;
}
.table-row:nth-child(odd) {
background-color: #e8e8e8;
}
.table-row input[type="radio"] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
margin: 0;
}
.table-row:has(:checked) {
outline: 2px solid green;
outline-offset: -2px;
}
.footer-button {
width: 100%;
padding: 10px;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
text-align: center;
transition: background-color 0.2s ease;
}
.footer-button:hover {
background-color: #0056b3;
}
.item {
padding: 10px;
}
.chevron {
display: inline-block;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid white;
transition: transform 0.3s ease;
}
.chevron.open {
transform: rotate(180deg);
}Код: Выделить всё
Index
Test
1
Test
2
Test
3
Test
4
Test
5
Test
6
Test
7
Test
8
Test
9
Test
10
Test
11
Test
12
Test
Show more
Подробнее здесь: https://stackoverflow.com/questions/797 ... ut-of-sync
Мобильная версия