Skip to content

Commit

Permalink
Merge pull request #30 from gzimbron/resizable-columns
Browse files Browse the repository at this point in the history
feat(DataGrid): ✨ Add resizable columns
  • Loading branch information
gzimbron authored Feb 16, 2024
2 parents c32bcab + d974e50 commit 61b74ec
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/kind-trees-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"website": patch
---

Add resizable columns example
5 changes: 5 additions & 0 deletions .changeset/metal-seahorses-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gzim/svelte-datagrid": minor
---

Add resizable columns feature
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ Svelte DataGrid is a high-performance, feature-rich grid component for Svelte. I

It's based on the excellent (but deprecated) [svelte-data-grid](https://github.com/bsssshhhhhhh/svelte-data-grid).

## Demo website
## 👀 Demo website

[![Demo website](./assets/demo-screenshot.webp)](https://gzimbron.github.io/svelte-datagrid)

## Features
## 🚀 Features

- High scrolling performance
- ARIA attributes set on elements
- Lightweight even when displaying a huge dataset due to implementation of a "virtual list" mechanism
- Column headers remain fixed at the top of the grid
- Custom components can be specified to control how individual table cells or column headers are displayed

## TODO
## 📋 TODO

- [x] Demo website
- [x] Re-ordering columns
- [ ] Resizing columns
- [ ] Feel free to suggest more features or contribute to the project
- [x] Resizing columns
- ⭐️ Feel free to suggest more features or contribute to the project

## Usage:
## ℹ️ Usage:

If using within Sapper:

Expand Down Expand Up @@ -85,7 +85,7 @@ Datagrid requires 2 properties to be passed in order to display data: `rows` and
];
```

## Editing Data
## 📝 Editing Data

You can use this 3 componets as cellComponent to edit data:

Expand Down Expand Up @@ -156,7 +156,7 @@ CheckboxCell will set the checked state of the checkbox depending on the boolean
}
```

## Custom Cell Components
## Custom Cell Components

To create a custom cell component, create a new Svelte component following the example below.

Expand Down Expand Up @@ -220,7 +220,7 @@ import MyCustomCell from './MyCustomCell.svelte';
]
```

## Custom Header Components
## Custom Header Components

Header components can also be specified in `columns` entries as the `headerComponent` property. Header components are only passed `column`, the column object from `columns`.

Expand All @@ -240,19 +240,19 @@ Header components can also be specified in `columns` entries as the `headerCompo
</style>
```

## Properties:
## 🛠️ Options and Functions:

Datagrid provides a few options for controlling the grid and its interactions:

### Configurations
### ⚙️ Properties

- `rowHeight` - The row height in pixels _(Default: 24)_
- `headerRowHeight` - The row height in pixels _(Default: 24)_
- `rowsPerPage` - The number of rows to render per page _(Default: rows lenght up to 10)_
- `extraRows` - Add extra rows to the virtual list to improve scrolling performance _(Default: 0)_
- `allColumnsDraggable` - Set all columns draggable by default, ignoring the `draggable` property of each column _(Default: false)_

### Functions exported
### 💫 Functions exported

Yoy can bind to the following functions to control the grid:

Expand All @@ -274,10 +274,10 @@ const getGridState: () => {
- `scrollToRow` - A function that scrolls the grid to a specific row index.

```typescript
const scrollToRow: (rowIndex: number) => void;
const scrollToRow: (rowIndex: number, behavior: ScrollBehavior = 'smooth') => void;
```

### Styling
### 💄 Styling

- `--border` Css: Custom style for grid borders _(Default: 1px)_
- `--header-border` Custom width for header row border bottom _(Default: 2px)_
Expand Down
13 changes: 12 additions & 1 deletion apps/website/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
dataKey: 'firstName',
width: 200,
cellComponent: TextboxCell,
draggable: true
draggable: true,
resizable: true
},
{
label: 'Last Name',
Expand Down Expand Up @@ -130,6 +131,7 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let getGridState: () => any | undefined;
let scrollToRow: (index: number) => void | undefined;
let allColumnsResizable = true;
</script>

<Progressbar {progress}></Progressbar>
Expand All @@ -145,6 +147,7 @@
on:valueUpdated={onValueUpdated}
on:scroll={gridScrolled}
on:columnsSwapped={({ detail }) => console.log(detail)}
{allColumnsResizable}
/>
</section>

Expand Down Expand Up @@ -175,6 +178,10 @@
</div>

<div class="flexy">
<label for="allColumnsResizable">
<p>Resizable Columns</p>
<input type="checkbox" id="allColumnsResizable" bind:checked={allColumnsResizable} />
</label>
<label for="rowheight">
<p>Row Height: {rowHeight}</p>
<input type="range" min={20} max={50} step={1} id="rowheight" bind:value={rowHeight} />
Expand All @@ -198,4 +205,8 @@
.flexy {
@apply flex flex-wrap gap-4 justify-center;
}
.flexy label {
@apply flex flex-col items-center gap-2;
}
</style>
19 changes: 16 additions & 3 deletions packages/svelte-datagrid/src/lib/actions/dragAndDrop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,23 @@ export const dragAndDrop: Action<HTMLElement, ActionParams> = (
{ draggable, dragEnd, dragStart }: ActionParams = {}
) => {
if (draggable) {
node.draggable = true;

node.addEventListener('dragstart', (e) => {
const div = e.target as HTMLElement;
const isRezisable = div.classList.contains('resizable');

if (isRezisable) {
const resizableWidth = parseInt(
window.getComputedStyle(div, '::after').width.replace('px', '')
);

const clickPosition = e.clientX - div.getBoundingClientRect().left;

if (clickPosition >= div.offsetWidth - resizableWidth - 2) {
e.preventDefault();
return;
}
}

dragStart && dragStart(e);
node.classList.add('dragging');
});
Expand All @@ -27,7 +41,6 @@ export const dragAndDrop: Action<HTMLElement, ActionParams> = (

return {
destroy() {
node.draggable = false;
node.removeEventListener('dragstart', () => {});
node.removeEventListener('dragend', () => {});
}
Expand Down
58 changes: 58 additions & 0 deletions packages/svelte-datagrid/src/lib/actions/resizeColumn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type { Action } from 'svelte/action';

interface ActionParams {
resizable?: boolean;
startResize?: () => void;
endResize?: () => void;
onResize?: (data: number) => void;
}

export const reziseColumn: Action<HTMLElement, ActionParams> = (
node,
{ resizable, onResize, startResize, endResize }: ActionParams = {}
) => {
if (!resizable) return;

let lastX = 0;

const mouseMoveEvent = (e: MouseEvent) => {
if (!onResize) return;
if (e.clientX === lastX) return;
lastX = e.clientX;
onResize(lastX - node.getBoundingClientRect().left);
};

const mouseDownEvent = (e: MouseEvent) => {
if (e.button !== 0) {
return;
}
lastX = e.clientX;

// get node width and style ::after
const nodeAfterWidth = parseInt(
window.getComputedStyle(node, ':after').width.replace('px', '')
);
const clickPosition = e.clientX - node.getBoundingClientRect().left;

if (clickPosition < node.offsetWidth - nodeAfterWidth - 2) return;

startResize && startResize();

document.addEventListener('mousemove', mouseMoveEvent);
document.addEventListener('mouseup', mouseUpEvent);
};

const mouseUpEvent = () => {
endResize && endResize();
document.removeEventListener('mousemove', mouseMoveEvent);
};

node.addEventListener('mousedown', mouseDownEvent);

return {
destroy() {
document.removeEventListener('mousedown', mouseDownEvent);
node.removeEventListener('mouseup', () => mouseUpEvent);
}
};
};
Loading

0 comments on commit 61b74ec

Please sign in to comment.