Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions v2/pink-sb/src/lib/table/Cell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@
class:vertical-end={isVerticalEnd}
class:horizontal-start={isHorizontalStart}
class:horizontal-end={isHorizontalEnd}
style:--cell-height={root.cellHeight}
>
<slot />
</div>
{/if}

<style lang="scss">
[role='cell'] {
--p-cell-width: var(--cell-width);
--p-cell-max-width: var(--cell-max-width);
--p-cell-alignment: var(--cell-alignment);
--p-cell-height: var(--cell-height);

display: flex;
align-items: center;
padding-inline: var(--space-6);
height: 40px;
height: var(--p-cell-height);
border-bottom: var(--border-width-s) solid var(--border-neutral);
overflow: hidden;

Expand Down
37 changes: 24 additions & 13 deletions v2/pink-sb/src/lib/table/Root.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
export let columns: Array<Column> | number;
export let allowSelection: boolean = false;
export let selectedRows: Array<string> = [];
export let maxRows: number = Infinity;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does maxRows sound a bit misleading? maybe maxVisibleRows?

export let stickyHeader: boolean = false;
export let cellHeight: string = '40px';

let availableIds: Set<string> = new Set();

Expand Down Expand Up @@ -34,7 +37,7 @@
}
return acc;
},
allowSelection ? ' 40px' : '' // Default width for selection column
allowSelection ? ` ${cellHeight}px` : '' // Default width for selection column
);
}

Expand All @@ -48,13 +51,6 @@
}, {});
}

$: someRowsSelected =
availableIds.size > 0 &&
selectedRows.length > 0 &&
selectedRows.some((row) => availableIds.has(row));
$: allRowsSelected =
availableIds.size > 0 && [...availableIds].every((row) => selectedRows.includes(row));

function toggleAll() {
if (allRowsSelected) {
selectedRows = selectedRows.filter((row) => !availableIds.has(row));
Expand Down Expand Up @@ -83,6 +79,18 @@
availableIds = availableIds;
}

function calculateMaxHeight(maxRows: number, cellHeight: string, hasHeader: boolean) {
if (maxRows === Infinity) return undefined;
const totalRows = hasHeader ? maxRows + 1 : maxRows;
return `calc(${totalRows} * ${cellHeight})`;
}

$: someRowsSelected =
availableIds.size > 0 &&
selectedRows.length > 0 &&
selectedRows.some((row) => availableIds.has(row));
$: allRowsSelected =
availableIds.size > 0 && [...availableIds].every((row) => selectedRows.includes(row));
$: root = {
allowSelection,
selectedRows,
Expand All @@ -93,14 +101,17 @@
selectedNone: !someRowsSelected,
selectedAll: allRowsSelected,
addAvailableId,
removeAvailableId
removeAvailableId,
cellHeight,
hasHeader: $$slots.header !== undefined
} as RootProp;
$: maxHeight = calculateMaxHeight(maxRows, cellHeight, root.hasHeader);
</script>

<div class="root">
<div class="root" style:max-height={maxHeight}>
<div role="table" style:--grid-template-columns={createGridTemplateColumns(columns)}>
{#if $$slots.header}
<Row type="header" {root}>
{#if root.hasHeader}
<Row type="header" {root} sticky={stickyHeader}>
<slot name="header" {root} />
</Row>
{/if}
Expand All @@ -110,7 +121,7 @@

<style lang="scss">
.root {
overflow-x: auto;
overflow: auto;
border: 1px solid var(--border-neutral);
border-radius: var(--border-radius-s);
background: var(--bgcolor-neutral-primary);
Expand Down
2 changes: 2 additions & 0 deletions v2/pink-sb/src/lib/table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export type RootProp = {
toggleAll: () => void;
addAvailableId: (id: string) => void;
removeAvailableId: (id: string) => void;
cellHeight: string;
hasHeader: boolean;
};

export type Alignment =
Expand Down
16 changes: 15 additions & 1 deletion v2/pink-sb/src/lib/table/row/Base.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,19 @@
export let root: $$Props['root'];
export let id: $$Props['id'] = undefined;
export let type: $$Props['type'] = 'row';
export let sticky: $$Props['sticky'] = false;

function toggle() {
if (id) root.toggle(id);
}

function calculateTop(sticky: $$Props['sticky'], cellHeight: $$Props['root']['cellHeight']) {
if (sticky !== false && Number.isInteger(sticky)) {
return `calc(${sticky} * ${cellHeight})`;
}
return undefined;
}

onMount(() => {
if (id) root.addAvailableId(id);

Expand All @@ -26,9 +34,10 @@
});

$: selected = id ? root.selectedRows.includes(id) : false;
$: top = calculateTop(sticky, root.cellHeight);
</script>

<div role={type === 'row' ? 'row' : 'rowheader'}>
<div role={type === 'row' ? 'row' : 'rowheader'} class:sticky style:top>
{#if root.allowSelection}
{@const isHeader = type === 'header'}
<Cell column={`__select_${id}`} {root}>
Expand Down Expand Up @@ -66,5 +75,10 @@
border-bottom: 0;
}
}

&.sticky {
position: sticky;
top: 0;
}
}
</style>
1 change: 1 addition & 0 deletions v2/pink-sb/src/lib/table/row/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Link from './Link.svelte';

export type RowBaseProps = {
id?: string;
sticky?: boolean | number;
root: RootProp;
};

Expand Down
75 changes: 75 additions & 0 deletions v2/pink-sb/src/stories/Table.stories.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,81 @@
</Table.Root>
</Story>

<Story name="Sticky rows">
<Table.Root columns={3} let:root maxRows={5} stickyHeader>
<svelte:fragment slot="header" let:root>
<Table.Header.Cell {root}>Lorem</Table.Header.Cell>
<Table.Header.Cell {root}>Ipsum</Table.Header.Cell>
<Table.Header.Cell {root}>Dolor</Table.Header.Cell>
</svelte:fragment>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root} sticky={1}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root} sticky={2}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
<Table.Row.Base {root}>
<Table.Cell {root}>Lorem</Table.Cell>
<Table.Cell {root}>Ipsum</Table.Cell>
<Table.Cell {root}>Dolor</Table.Cell>
</Table.Row.Base>
</Table.Root>
</Story>

<Story name="Column sizing">
<Table.Root
columns={[
Expand Down