Coder Social home page Coder Social logo

dasdaniel / svelte-table Goto Github PK

View Code? Open in Web Editor NEW
507.0 9.0 39.0 881 KB

A svelte table implementation that allows sorting and filtering

Home Page: https://dasdaniel.github.io/svelte-table/

License: MIT License

JavaScript 5.77% CSS 1.36% HTML 17.22% Svelte 75.22% TypeScript 0.43%
component svelte svelte3 table

svelte-table's Introduction

svelte-table

A relatively minimal table component. Allows sorting and filtering based on column values, and row selection/expanding.

Example

github pages IIFE example

Install

npm install -save svelte-table

Usage

The package includes exports for raw svelte, ES Module(.mjs) and CJS (.js) exports. Your bundler will likely know which one to pick by using import SvelteTable from "svelte-table"

<script>
  import SvelteTable from "svelte-table";
  const rows = [
    /** data (example below) */
  ];
  const columns = [
    /** columns config (example below) */
  ];
</script>

<SvelteTable columns="{columns}" rows="{rows}"></SvelteTable>

An iife version is also available in the /dist/iife folder. This allows for easy run-time use, such as a direct uncompiled dependency for a use outside of a svelte project.

<script src="iife/SvelteTable.js"></script>
<div id="my-table"></div>
<script>
  var rows = [
    /** data (example below) */
  ];
  var columns = [
    /** columns config (example below) */
  ];
  new SvelteTable({
    target: document.querySelector("#my-table"),
    props: { rows, columns },
  });
</script>

Sample Data and config

// define some sample data...
const rows = [
  { id: 1, first_name: "Marilyn", last_name: "Monroe", pet: "dog" },
  { id: 2, first_name: "Abraham", last_name: "Lincoln", pet: "dog" },
  { id: 3, first_name: "Mother", last_name: "Teresa", pet: "" },
  { id: 4, first_name: "John F.", last_name: "Kennedy", pet: "dog" },
  { id: 5, first_name: "Martin Luther", last_name: "King", pet: "dog" },
  { id: 6, first_name: "Nelson", last_name: "Mandela", pet: "cat" },
  { id: 7, first_name: "Winston", last_name: "Churchill", pet: "cat" },
  { id: 8, first_name: "George", last_name: "Soros", pet: "bird" },
  { id: 9, first_name: "Bill", last_name: "Gates", pet: "cat" },
  { id: 10, first_name: "Muhammad", last_name: "Ali", pet: "dog" },
  { id: 11, first_name: "Mahatma", last_name: "Gandhi", pet: "bird" },
  { id: 12, first_name: "Margaret", last_name: "Thatcher", pet: "cat" },
  { id: 13, first_name: "Christopher", last_name: "Columbus", pet: "dog" },
  { id: 14, first_name: "Charles", last_name: "Darwin", pet: "dog" },
  { id: 15, first_name: "Elvis", last_name: "Presley", pet: "dog" },
  { id: 16, first_name: "Albert", last_name: "Einstein", pet: "dog" },
  { id: 17, first_name: "Paul", last_name: "McCartney", pet: "cat" },
  { id: 18, first_name: "Queen", last_name: "Victoria", pet: "dog" },
  { id: 19, first_name: "Pope", last_name: "Francis", pet: "cat" },
  // etc...
];

// define column configs
const columns = [
  {
    key: "id",
    title: "ID",
    value: v => v.id,
    sortable: true,
    filterOptions: rows => {
      // generate groupings of 0-10, 10-20 etc...
      let nums = {};
      rows.forEach(row => {
        let num = Math.floor(row.id / 10);
        if (nums[num] === undefined)
          nums[num] = { name: `${num * 10} to ${(num + 1) * 10}`, value: num };
      });
      // fix order
      nums = Object.entries(nums)
        .sort()
        .reduce((o, [k, v]) => ((o[k] = v), o), {});
      return Object.values(nums);
    },
    filterValue: v => Math.floor(v.id / 10),
    headerClass: "text-left",
  },
  {
    key: "first_name",
    title: "FIRST_NAME",
    value: v => v.first_name,
    sortable: true,
    filterOptions: rows => {
      // use first letter of first_name to generate filter
      let letrs = {};
      rows.forEach(row => {
        let letr = row.first_name.charAt(0);
        if (letrs[letr] === undefined)
          letrs[letr] = {
            name: `${letr.toUpperCase()}`,
            value: letr.toLowerCase(),
          };
      });
      // fix order
      letrs = Object.entries(letrs)
        .sort()
        .reduce((o, [k, v]) => ((o[k] = v), o), {});
      return Object.values(letrs);
    },
    filterValue: v => v.first_name.charAt(0).toLowerCase(),
  },
  {
    key: "last_name",
    title: "LAST_NAME",
    value: v => v.last_name,
    sortable: true,
    filterOptions: rows => {
      // use first letter of last_name to generate filter
      let letrs = {};
      rows.forEach(row => {
        let letr = row.last_name.charAt(0);
        if (letrs[letr] === undefined)
          letrs[letr] = {
            name: `${letr.toUpperCase()}`,
            value: letr.toLowerCase(),
          };
      });
      // fix order
      letrs = Object.entries(letrs)
        .sort()
        .reduce((o, [k, v]) => ((o[k] = v), o), {});
      return Object.values(letrs);
    },
    filterValue: v => v.last_name.charAt(0).toLowerCase(),
  },
  {
    key: "pet",
    title: "Pet",
    value: v => v.pet,
    renderValue: v => v.pet.charAt(0).toUpperCase() + v.pet.substring(1), // capitalize
    sortable: true,
    filterOptions: ["bird", "cat", "dog"], // provide array
  },
];

Props

Option Type Description
columns Object[] column config (details below)
rows Object[] row (data) array
sortBy String ‡ Sorting key
sortOrder Number 1 = Ascending, -1 Descending, 0 no filtering
sortOrders Number[] availability of order options
iconAsc String (html) override ascending order indication
iconDesc String (html) override descending order indication
iconFilterable String (html) override filterable column indication
iconExpand String row collapsed indicator/button
iconExpanded String row expanded indicator/button
iconSortable String indicate column is sortable
classNameTable String/Array optional class name(s) for table element
classNameThead String/Array optional class name(s) for thead element
classNameTbody String/Array optional class name(s) for tbody element
classNameSelect String/Array optional class name(s) for filter select elements
classNameInput String/Array optional class name(s) for search input elements
classNameRow String/function optional class name(s) for row elements. Supports passing function
classNameRowExpanded String/Array optional class name(s) for expanded row
classNameExpandedContent String/Array optional class name(s) for expanded row content
classNameRowSelected String/Array optional class name(s) for selected row
classNameCell String/Array optional class name(s) for cell elements
classNameCellExpand String/Array optional class name(s) for cell with expand icon
expanded String[] optional array of key values of expanded rows
expandRowKey String optional deprecated use rowKey
rowKey String optional key for expanded or selected row (use unique values like id)
expandSingle Boolean optional default: false allow only one row to be selected
selected String[] optional array of key values of selected rows
selectSingle Boolean optional default: false allow only one row to be selected
selectOnClick Boolean optional default: false will clicking on row will update selection
filterSelections Object[] optional search or filter selection
showExpandIcon Boolean should a expand column be visible

field allows 2-way binding

Events

Events pass a CustomEvent object with the following params in the detail object

event detail parameters Description
clickCol event, col, key click on column
clickRow event, row click on a row
clickCell event, row, key click on a cell
clickExpand event, row click expand

Expanding Rows

  • Row expanding is tracked using the expanded property. (supports 2-way binding)
  • The keys are defined using the rowKey property (previously expandRowKey which is getting deprecated). It is recommended to use a key that is unique to each row like a dedicated id or key field, to prevent conflict.
  • The content for the field is passed through the expanded slot.
  • The expanding can be managed manually or by using the built-in column using showExpandIcon property
  • Expand events can be listened to using on:clickExpand which will include the row object in the event.detail object.
  • expandSingle can be set to true to only allow a single column open at a time
  • expandSingle does not inforce single row expansion when multiple keys are is passed to expanded
  • Row expanded status is available through the $expanded property of the row, but is consdered an internal and may be removed

Example:

<div class="row">
  <SvelteTable
    columns="{cols}"
    rows="{data}"
    showExpandIcon="{true}"
    expandSingle="{true}"
    rowKey="id"
  >
    <svelte:fragment slot="expanded" let:row>{row.detail}</svelte:fragment>
  </SvelteTable>
</div>

Selecting Rows

  • By default, selection functionality is disabled, enable through selectOnClick
  • Row selection is tracked by selection property and supports 2-way binding
  • Selection happens when user clicks on row
  • Use classNameRowSelected to assign class to a selected row
  • Selection is tracked using the key defined by the rowKey property
  • The selection prop is an array because it supports both single and multiple selections
  • Multiple vs. single selection is handled through selectSingle
  • selectSingle does not enforce single row selection when multiple keys are is passed to selection
  • Row selection status is available through the $selected property of the row, but is considered an internal and may be removed

Filtering order

Providing sortOrders specifies the column filtering orders. sortOrders = [1, -1, 0] indicates that the row will be sorted ascending (1), then descending (-1), then going back without any filter (0),

filterSelections

Allows getting and setting the search or filter value. The filterSelections will update as the filter and search selection changes. Inside the object keys (matching row keys) will be used to get/set the filter and search values. Setting key to undefined or deleting it will remove filter or search setting.

example: (will preset column with key first_name to a)

<script>
  const selection = { first_name: "A" };
</script>
<SvelteTable
  columns="{columns}"
  rows="{data}"
  bind:filterSelections="{selection}"
/>

Column array object values

Option Type Description
key String Unique key identifying the column
title String Title for header
value Function table cell value. The function is passed row data
[class] String optional table cell class name
[sortable] Boolean optional Whether the table can be sorted on column
[searchValue] Function optional search value function. function is passed row data.
[filterOptions] Array/Function optional array of objects with name and value. Function is provided array of rows
[filterValue] String optional value to filter on, usually same as value
[filterPlaceholder] String optional placeholder attribute for the filter input or select dropdown
[hideFilterHeader] Boolean optional will hide search or filter input in header
[headerClass] String optional class to assign to header element
[headerFilterClass] String optional class to assign to search/filter header element
[renderValue] Function optional render function for rendering html content
[renderComponent] Component optional pass a Svelte component, it will receive row and col variables (replaces renderValue)
[parseHTML] Boolean optional if true, it will render the cell value with @html

searchValue

Option 1: searchValue(row, searchTerm):boolean

Define a function that accepts a row and the searchTerm, the comparison is defined within the function and the match is returned in the form of a boolean.

This is the recommended way of using the search (added in v0.5.3)

Option 2: searchValue(row):string

Define a function that accepts a row and returns a string. SveltTable does the comparison internally, but only supports case-insensitive compare using includes

This behaviour is set for deprecation and should not be used.

If you want to migrate the existing behaviour you can use this example:

searchValue: (v, s) =>
  v["some_key"].toString().toLowerCase().includes(s.toLowerCase()),

renderComponent

Defining a component can be done directly by passing the component as a value

[
  {
    key: "myColumn",
    //...
    renderComponent: myComponent,
  },
];

Or, if props need to be passed, an object with component and props can be passed.

[
  {
    key: "myColumn",
    //...
    renderComponent: {
      component: myComponent,
      props: {
        myProp: "someValue",
      },
    },
  },
];

Slots

Option Description
header slot for rendering the tr and th content. This will replace title in the header
row slot for rendering the tr and td content. This will replace the rendering of renderValue
expanded slot for rendering the content of the expanded row

Conditional row and cell class names

By passing a function to classNameRow the rows can have class assigned for the tr element based on the row value. The function is provided two arguments, the row value, and the row index.

// classNameRow function type definition
(row: Row, rowIndex?: number) => string | null;

This is an example of using the row index make a striped table, which may be needed when rows are expandable.

(row, rowIndex) => (rowIndex % 2 == 0 ? null : "row-odd");

Individual cells can also be formatted by passing a function to the class prop in the column object. The class function is provided three parameters. In addition to the row and rowIndex, it also provides the column index

// classs function type definition
(row: Row, rowIndex?: number, colIndex?: number) => string | null;

example for a checker-board pattern:

(row, rowIndex, colIndex) =>
  (rowIndex + colIndex) % 2 == 0 ? null : "cell-odd";

example using a value from the row object:

row => row.count > 10 && "cell-valid";

svelte-table's People

Contributors

alexz12948 avatar andrewsalemi avatar conni2461 avatar dasdaniel avatar dennisjlee avatar dependabot[bot] avatar dysfunc avatar pavelapk avatar saibamen avatar thilo-behnke avatar tristaaan avatar x64v avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

svelte-table's Issues

Not rendering table?

Currently my project is set up like this ->

<script>
  	import SvelteTable from "svelte-table";

let rows = [];

querySomething.forEach(i => rows.push(i))
</script>

<SvelteTable columns="{columns}" rows="{rows}"></SvelteTable>

then I push an object into the rows, where is declared outside of the script but the table is not rendering to show the new rows... why?

Side effect of handleClickCol is not ideal for pagination usage

I'm using the this table for paginating lots of data. When the headers are clicked on I am sending an API call from which results will already be sorted and so the table need not do any sorting itself. I think it's an interesting side effect that handleClickCol also sorts as well as triggering the clickCol event. I'm interested in preventing a call to updateSortOrder(... if a certain flag is passed in preventSortOnClickCol maybe?

I'm willing to implement this and update relevant documentation but I thought I would ask for some feedback first.
The method in question:

  const handleClickCol = (event, col) => {
    updateSortOrder(col.key)  # planning on wrapping these 
    sortBy = col.key;         # two lines in a conditional
    dispatch('clickCol', {event, col, key:col.key} ); 
  }

Example7.html not produced

I've made a local copy of your repo and build it.
When I serve and run the examples, they work but Example7 not and example7.html is not produced..
Have you any clue for this?

Search & Filtering issue with custom cell components

I'm sorry that I have not created an example to show this error, but there is a render issue with search / filter + renderComponent. When rows get filtered, the view of the renderComponents don't get refreshed.

This is actually a known thing in Svelte. If #each blocks get changed, you should use keyed blocks.

The fix is very easy, actually. All you have to do is add a key to your #each loop.

error, can't run "npm run dev"

Hi,
index.html after changing

<script src='dist/main.js'></script>

to

<script src='bundle/main.js'></script>

will work ok!

how get filterOptions get reactive

Hi Daniel,

Thx for sharing this lovely component. I would like to use it, but anyhow I do not know how to deal with the filter option.

I'm fetching some data from a REST API, once all data are there, I pass them to the variable rows and the data get rendered. but the list of filter values stay empty. Maybe you have an advice?

Thanks in advance,
Henrik

Demo 404

The example demo linked in the readme returns a 404 :(

Make sortByValue configurable

Hello,

I noticed a problem when I wanted to display currency data in a table (e. g. "19,51 €"). The sort function didn't work, because in its logic the string "19,51 €" comes before "2,24 €" before "24,22 €" before "3,02 €".

The problem was of course that svelte-table handles these values as a string and therefore technically it's sorted correctly. I made a little adjustment that provides an optional column parameter (sortByValue) to set a different sort value than the original displayed value.

I didn't open a pull request, because I guess this could be done also a bit more clean and less dirty.
If this already can be done somehow and I just missed it in the documentation, I'm sorry and you can just ignore this issue.

$: {
      let col = columnByKey[sortBy];
      if (col !== undefined && col.sortable === true && typeof col.value === "function") {
        sortFunction = typeof columnByKey[sortBy].sortByValue == "undefined" ? r => col.value(r) : columnByKey[sortBy].sortByValue;
      }
    };

Thank you for providing this awesome svelte component! :)

Demo?

Please add demo to readme.

switch beetween ASC, DESC, NO filter

Hello,

It's me again.

When clicking on a column, if the column is sortable, it is sorted ASC, then DESC and there is no way to remove the sorting criteria. I would maybe suggest to have a prop to either switching from ASC to DESC or from ASC to DESC to NO filter. Also, usually, when a column if sortable, there is a two-arrow icon indicating that the column is sortable.

I haven't tried but it is theoretically possible to override this behavior with the exposed clickCol event and sortorder / sortby props.

If you find this relevant, I can submit a PR.

No tests

tests are great, need to add them before releasing a major version of 1+

svelte-table impacted by bug in Svelte > 3.39.0

The distribution versions of svelte-table are compiled with svelte > 3.39.0 which has this issue:

sveltejs/svelte#6584
Introduced here: sveltejs/svelte#5870

The easiest workaround I found was to directly import the .svelte file. Change:
import SvelteTable from "svelte-table";
to
import SvelteTable from "svelte-table/src/SvelteTable.svelte";

This gets around the use of the dist/ folder versions in the NPM package.

Here's where you can hack the dist/es/SvelteTable.mjs file to confirm:

function Y(t, n, c, s, r, a, i, d = [-1]) {
    const u = O;
    S(t);
    const f = t.$$ = {
        fragment: null,
        ctx: null,
        props: a,
        update: e,
        not_equal: r,
        bound: o(),
        on_mount: [],
        on_destroy: [],
        on_disconnect: [],
        before_update: [],
        after_update: [],
        context: new Map(n.context || (u ? u.$$.context : [])),
        callbacks: o(),
        dirty: d,
        skip_bound: !1,
        root: n.target || (u && u.$$.root)
    };

... to add u && u.$$.root. This is be the parent_component pointer is not checked - see sveltejs/svelte@5cfefeb#diff-da9bae4e28c441de5ba3a074e30775fe69109100b3d921ad8f2592d93cd67b7fR133.

The error is:

SvelteTable.mjs:404 
Uncaught TypeError: Cannot read properties of undefined (reading '$$')
    at Y (SvelteTable.mjs:404)
    at new Ce (SvelteTable.mjs:1411)
    at Array.create_default_slot_13 (Board.svelte:138)
    at create_slot (index.mjs:141)
    at create_fragment (CardBody.svelte:2)
    at init (index.mjs:2129)
    at new CardBody (CardBody.svelte:7)
    at Array.create_default_slot_12 (Board.svelte:138)
    at create_slot (index.mjs:141)
    at create_fragment (Card.svelte:2)

It would be nice...

It would be nice if in a future version :
Could the column have
a property breakpoint which automaticall put a column content in the details section... depending of "xs,sm etc " value
a property formatter giving a function to allow change of the rendering of the column original value
These nice things are present in a very smart jquery module which is named footable.
Badly I'm not good enough to write this myself....

Filter a column where the value match multiple values

Is there a way to filter a column with multiple values ?
An example : filter the rows where a column equal 'value1' OR 'value2'.
Maybe on using an array despite a value in the bind with filterSelection I tried to add an array despite a value :

selection {
  'col1': ['value1', 'value2']
}

<SvelteTable> was created with unknown prop 'classNameRowSelected'

Code:

<SvelteTable
	columns="{columns}"
	rows="{rows}"
	classNameTable="border-2 border-collapse mt-4 mb-4"
	classNameThead="border-2 border-collapse"
	classNameRow="border-2 border-collapse odd:bg-gray-100 hover:bg-gray-300"
	classNameCell="pr-4"
	classNameRowSelected="bg-gray-500" />

Version: 0.3.5

How to clear filter/searchValue?

I'm new to Svelte and this should probably be obvious, but how do I access/set the searchValue value from my own function? I want to create a button to clear the user-entered values passed to the searchValue defined for several columns.

How to use all the slots?

Hi,

Thanks for this component, very useful and easy to adapt to custom data.
image

I managed to do almost everything I need, except extending the header and row slot.
What I'm truly after would be a cell slot to be honest but I could do that with the row slot I think.

I'm not sure how to properly get the needed values to construct it, can you provide a small sample of each?

I tried:

<svelte:fragment slot="row" let:row let:n>
    <h2>{row.name}</h2>
</svelte:fragment>

Returns:
image

And for the header one we seem to only have access to order options.

Thanks

Feature: reactivity so you can update the data and generate columns programatically for it

Firstly, thanks for a very helpful component!

This is to share that I made a fork which adds reactivity, explained here. The changes are minor, and I tweaked the README in a couple of places (as well as documenting the 'reactivity' feature.

The feature can be seen in use in my Visualisation Lab project. It is a work in progress, but usually up to date at http://vlab.happybeing.com

Hope the fork is of interest. Let me know if you would like a PR.

Is there a way of highlighting the expanded row ant its details

As the title says, I would like to emphasize the selected row and it's details so wondering if there is already something either in SvelteTable or in your example7 which could do the trick. Without it ( I didn' find anything...) I think I will need to modify the code in the SvelteTable component code to add a class on both tr: the one which trigger the expansion and the expanded one...
Any advice would be appreciated greatly...

Dynamic row class

Right now, columns.class accept only string.

It could also accept function to be able to add custom classes based on cell value.

Example usage:

const columns = [
{
	key: "id",
	title: "Run #",
	value: v => v.id,
	class: v => (v.id > 5) ? "text-red-600" : "",
},
];

Pass data value to renderComponent?

Is there a way to pass rows value to renderComponent? This would be helpful when using renderComponent to render a component that depends on the row.

For example, I am using svelte-table to create a table with a list of users. Each table row shows the data of a user, and needs to have a dropdown with actions specific to that user.

Example:

const colUsers = [
	{
		key: 'is_admin',
		title: 'role',
		value: (v: User) => (v.is_admin ? 'admin' : 'user'),
		sortable: true,
		headerClass: 'text-left'
	},
	{
		key: 'action',
		title: '',
		sortable: false,
		renderComponent: {
			component: Dropdown,
			props: { name: '...', dropdownItems: generateItems(user) } // I'd like to pass User data as a prop here
	        }
	}
]

function generateItems(user){
	return {profileLink:user["profileLink"], id:user["id"]}
}

In an ideal world, props takes a function of the current row.

props: (v:User) => {name: '...', dropdownItems: generateItems(v)  }

If this is already possible, sorry about the noise 🙏, I'm happy to make a small PR to the docs to surface it more clearly.

How to group columns visually

I am loving svelte-table so far and find it easy to use, but I need some help with this.

I am making something for a game and I want three columns (Kills, Deaths, Assists).

Currently I have one column (KDA), with a value of v.kills + '/' + v.deaths + '/' + v.assists.

Obviously I can't sort on all three fields using that one column, but if I split them up into separate columns, the content will no longer be visually grouped together. How do I solve this? Thanks for svelte-table and any help!

Current

Player KDA Other

With separate columns

Player K D A Other

I want it to visually look like the former using separate columns so I can sort on each field.

Make the table a grid css property based table

This library is awesome. 🌟 I have used it in two projects so far.

My first need is to have an explanatory row that shows below a row when the row itself is clicked is clicked. I tried to achieve that by various way in defining a second <tr/> in the Row slot. It works but then it's quite difficult to style the <tr/> element to have a nice in/out effect.

I'd like to suggest an evolution (I could make a PR if it makes sense and according to the best solution) : making the table a grid based table

There are many options to achieve that but none of them fills the right way to do it:

  • a property isGrid: it comes with drawbacks: the header slot would not have a sense anymore.
  • a table, tbody and thead slots: I did not achieved to successfully insert a slot in a slot but it might be possible.
  • a table, tbody and thead components / rendering methods: it will work and like the previous option, it will allow anyone to not display a table, tbody and thead tag but it fills quite complicated

I'd like to have access to a row value for a renderComponent

Maybe I am looking at this the wrong way. I am using a simple 3rd party component, StarRating. The component has a required prop for rating, which is a number from 0-5 and produces stars representing the rating.

I want each row to display ratings this way as so:
screenshot_293

The only way I can think to pass the row value to this component, is to create an intermediary one, which takes the row and calls the component.

<script lang="ts">
	import StarRating from 'svelte-star-rating';
	export let row;
</script>

<StarRating rating={row.rating} />

Then call this intermediary as my renderComponent:

renderComponent: {
component: TableRating
}

This works, but seems like a waste to create a component just to parse the value of the row. Is there a better way to do this?

Document renderValue

Browsing the code I found renderValue which appears to be a pretty useful feature, however it is not mentioned in the documentation.

Horizontal scroll?

My table has many columns, is there any configuration to have horizontal scrolling?

sorting and pagination?

I’m curious about how to go about having pagination and sorting using a backend, such as firebase / sapper in order to don’t load all documents from a huge collection all at once on the frontend.

is there any examples / recommendations on how to go about it?

Style search input fields

Is there a way to add custom style to the search input field in the th element? Maybe a classNameInput property can be added with the same functionality as the classNameSelect.

Expanded Row

I came back with breakpoints notion for columns.
I'm trying to work on your code but it's really hard for me.
I'm trying to do the following:
1°) Add device resolution changes: Ok done by creating a store and doing an import watchMedia from "svelte-media"; and declaring :
const mediaqueries = { xs: "(max-width: 480px)", sm: "(max-width: 768px)", md: "(max-width: 992px)", lg: "(min-width: 993px)"
2°) Modify the const COLUMNS = { declaration by adding the fields which would be affected by the space available on the device screen.
A column could either be directly shown whatever is the device screen (xs, sm, md or lg)
Or a column could be linked to one or multiple breakpoints

  • no breakpoints means the column is always visible
  • all means this field will be shown in the expanded detail table whatever is the screen size
  • xs,sm,md lg means this field will be shown in the expanded detail table for one or a combination of sizes (could be for example [xs,sm]

I've seen that actually the expanded data have no header and the colspan of the detail table is linked to the real columns displayed
3°) So I need to make the selected columns selectedCols to depend on the columns description
4°) the actual expanded3 (for exemple in Example7.svelte should be also replace by an array depending on the columns description and bind to the watchMedia store
Here are my first thoughts and I found these a good objective for me to learn Svelte but It sounds easier that it is...
Could you tell me if you are working on such points

Handle dynamic column definitions correctly

I have a situation where my column definitions are dynamic (based on a toggle in the UI). It's similar to this:

let columns = showDailyMax ? [
  { 
    key: 'sales',
    title: 'Sales (daily max)',
    value: row => row.dailyMaxSales
  }
] : [
  { 
    key: 'sales',
    title: 'Sales (annual)',
    value: row => row.annualSales
  }
];

And then I pass the dynamic columns variable into <SvelteTable>. (I set up those columns with the same key so that when the user toggles, that column will remain sorted if it was before.)

When I do this, there's a bug in how SvelteTable handles sorting, due to the fact that the columnsByKey variable isn't declared in a reactive way. The table will still be sorted by the daily max column definition (because columnsByKey['sales'] will still have that cached value) instead of the annual column definition.

Sort on component cell

Hello, nice component!
Am I right to say that if there are component, sorting does not work?
It seems (but maybe I did smthing wrong) that when some cells are component and you click on the header to sort the table, only the columns that are simple values will be sorted, the columns that are components don't change?

Dynamically Populated Value Option

Working to dynamically create columns. Seems like I should be able to either set the value option by doing value: v => v[Object.keys(data[0])[i]] but it raises an error (Cannot read property 'keys' of undefined). Is there a way to set the value option dynamically?

response.then(function(data){
			rows = data
			for (var i = 0; i < Object.keys(data[0]).length; i++) {
			
				columns.push({key: Object.keys(data[0])[i], title: Object.keys(data[0])[i], value: v => v[Object.keys(data[0])[i]], sortable: true})
			})

How do you set the width of a cell?

example column
{
key: "blah"
...
...
class: "tableCell"
}

style

.tableCell {
width: 200px
}

I also tried min-width and max-width but apparently these don't apply to td elements. I also tried :global(.tableCell)

Scrollable tbody?

I'd like to set the table to expand to 100% of the parent container with the thead fixed and the tbody scrollable. Is there a configuration for this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.