Add configurable amount of rows per amount of columns to showFirstRow

This commit is contained in:
Kuba Orlik 2024-07-28 17:26:37 +02:00
parent b8b5d6c449
commit 7df06edc9f
3 changed files with 86 additions and 20 deletions

View File

@ -10,10 +10,14 @@
transition: row-gap 200ms, overflow 200ms; transition: row-gap 200ms, overflow 200ms;
overflow: hidden; overflow: hidden;
input:not(:checked) + & { .show-first-row__checkbox:not(:checked) + & {
grid-template-rows: 1fr repeat(calc(var(--items-count) - 1), 0px);
row-gap: 0; row-gap: 0;
} }
& > * {
align-self: center;
justify-self: center;
}
} }
.show-first-row__default-button { .show-first-row__default-button {

View File

@ -11,10 +11,15 @@ const showFirstRowIds = (function* () {
} }
})(); })();
function min_container_width(columns: number, column_width: number, gap: number) {
return columns * column_width + (columns - 1) * gap;
}
export async function showFirstRow({ export async function showFirstRow({
items, items,
min_column_width_px = 250, min_column_width_px = 250,
column_gap_px = 10, column_gap_px = 10,
row_gap_px = column_gap_px,
make_show_more_button = () => ( make_show_more_button = () => (
<span class="show-first-row__default-button">Show more</span> <span class="show-first-row__default-button">Show more</span>
), ),
@ -29,18 +34,21 @@ export async function showFirstRow({
</> </>
), ),
classes = [], classes = [],
how_many_rows = () => 1,
}: { }: {
items: FlatTemplatable[]; items: FlatTemplatable[];
min_column_width_px?: number; min_column_width_px?: number;
make_show_more_button?: () => JSX.Element; make_show_more_button?: () => JSX.Element;
make_show_less_button?: () => JSX.Element; make_show_less_button?: () => JSX.Element;
column_gap_px?: number; column_gap_px?: number;
row_gap_px?: number;
add_button_to_content?: ( add_button_to_content?: (
content: JSX.Element, content: JSX.Element,
show_more_button: JSX.Element, show_more_button: JSX.Element,
show_less_button: JSX.Element show_less_button: JSX.Element
) => JSX.Element; ) => JSX.Element;
classes?: classNames.ArgumentArray; classes?: classNames.ArgumentArray;
how_many_rows?: (columns_count: number) => number;
}): Promise<string> { }): Promise<string> {
const id = showFirstRowIds.next().value; const id = showFirstRowIds.next().value;
const checkbox_id = "show-first-row__checkbox--" + id; const checkbox_id = "show-first-row__checkbox--" + id;
@ -54,24 +62,58 @@ export async function showFirstRow({
]} ]}
style={`--min-column-width: ${min_column_width_px}px; --items-count: ${items.length}; --column-gap: ${column_gap_px}px`} style={`--min-column-width: ${min_column_width_px}px; --items-count: ${items.length}; --column-gap: ${column_gap_px}px`}
> >
{ {[1, 2, 3, 4, 5, 6, 7, 8, 9]
/* HTML */ `<style> .reverse()
${[1, 2, 3, 4, 5, 6, 7, 8, 9] .map((columns) => {
.reverse() const rows = how_many_rows(columns);
.map( return /* HTML */ `<style>
(n) => `@container (min-width: ${ @container (min-width: ${min_container_width(
n * min_column_width_px + (n - 1) * column_gap_px columns,
}px) { min_column_width_px,
.show-first-row--id-${id}:not(:has(.show-first-row__items > *:nth-child(${n + 1}))) column_gap_px
.show-first-row__button { ) + 1}px) and (max-width: ${min_container_width(
display: none; columns + 1,
min_column_width_px,
column_gap_px
)}px) {
.show-first-row--id-${id} {
&:not(
:has(
.show-first-row__items
> *:nth-child(${columns * rows + 1})
)
) {
.show-first-row__button {
display: none;
}
}
.show-first-row__checkbox:not(:checked)
+ .show-first-row__items {
grid-template-rows: ${"auto ".repeat(rows)} repeat(
calc(var(--items-count) - ${rows}),
0px
);
& > * {
margin-bottom: ${row_gap_px}px !important;
&:nth-child(n + ${columns * rows + 1}) {
opacity: 0;
pointer-events: none;
}
}
}
}
} }
}` </style>`;
) })
.join("\n")} .join("\n")}
</style>` <input
} class="show-first-row__checkbox"
<input type="checkbox" id={checkbox_id} style="display: none" /> type="checkbox"
id={checkbox_id}
style="display: none"
/>
{add_button_to_content( {add_button_to_content(
<div class={["show-first-row__items"]}>{items}</div>, <div class={["show-first-row__items"]}>{items}</div>,
<label <label

View File

@ -9,7 +9,7 @@ export const actionName = "ShowFirstRowDemo";
function makeBoxStyle() { function makeBoxStyle() {
return `width: 100%; max-width: 200px; height: ${ return `width: 100%; max-width: 200px; height: ${
100 + Math.random() * 100 100 + Math.random() * 100
}px; margin: auto; background-color: lime; text-align: center; color: #0000009e; font-size: 40px; padding-top: 20px; box-sizing: border-box;`; }px; background-color: lime; text-align: center; color: #0000009e; font-size: 40px; padding-top: 20px; box-sizing: border-box;`;
} }
export default new (class ShowFirstRowDemoPage extends Page { export default new (class ShowFirstRowDemoPage extends Page {
@ -30,10 +30,30 @@ export default new (class ShowFirstRowDemoPage extends Page {
<div style={makeBoxStyle()}>{e}</div> <div style={makeBoxStyle()}>{e}</div>
)), )),
})} })}
<h2> 3 elements (overflow depends on screen width)</h2> <h2> 3 elements (overflow depends on screen width)</h2>
{showFirstRow({ {showFirstRow({
items: [1, 2, 3].map((e) => <div style={makeBoxStyle()}>{e}</div>), items: [1, 2, 3].map((e) => <div style={makeBoxStyle()}>{e}</div>),
})} })}
<h2> 9 elements (always has two rows when collapsed)</h2>
{showFirstRow({
items: [1, 2, 3, 4, 5, 6, 7, 8, 9].map((e) => (
<div style={makeBoxStyle()}>{e}</div>
)),
how_many_rows: () => 2,
})}
<h2>
9 elements (4 rows in one column mode, two rows in two column mode,
one row otherwise)
</h2>
{showFirstRow({
items: [1, 2, 3, 4, 5, 6, 7, 8, 9].map((e) => (
<div style={makeBoxStyle()}>{e}</div>
)),
how_many_rows: (columns) => (columns == 1 ? 4 : columns == 2 ? 2 : 1),
})}
</div> </div>
); );
} }