npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@healthtree/svelte-data-table

v1.0.4

Published

svelte-data-table

Downloads

4

Readme

Svelte Datatable

This is a reactive svelte-datatable. Feats:

  • In reactive: If you change rows, the dataTable updates accordingly
  • FrontEnd paginator
  • FrontEnd included Searchbar
  • You can pass SvelteComponent to render on a column
  • You can pass SvelteComponent to render a header
  • Sticky 1 column (can sticky just 1 col for now)

Documentation

|Param|type|Required|Default| | ------ | ------ | ------ | ----- | |columns| Column[] | true | -- |rows| object[] | true | -- |fuseConfig| object | false | -- |paginated|boolean|false|true| |searchable|boolean|false|true| |itemsPerPages|number[]|false| [5,10,15]

If searchable == true, by default all columns will be searchable. If you wish to exclude a column from search, specify searchable = false in the column definition.

Custom fuse parameters may also be provided through the fuseConfig prop

Icons

This project uses material icons, this dependency need to be installed on the project that use svelte-data-table

Follow the instructions here

Interfaces

interface SvelteComponent {
}

interface Column {
	label: string, // header of column
	field: string, // property on rows to display;accessed by _.get
	component?: SvelteComponent //must export row, column rowIndex and columnIndex  to have scopes 
	headerComponent?: SvelteComponent // must export column and columnIndex  to have scopes     
	sortable?: boolean, // false by default
	searchable?: boolean, // true by default
	type?: string, // string by default can be: number | date
	sticky?: boolean,
	sortFnc?: 'function' // eg: (a,b, currentSort) => {}  currentSort can be asc|desc|null
	transform?: 'function' // can also be an object --> see 'Transform' section below
}

CustomStyle

Each element affected by css is divided by 2 classes: Layout and style. You can easily overwrite this css classes to make changes in style. We recommend only changing the styles ones which are:

|Component|Class| | ------ |-------| |Search|dt-search-container-style| |Search|dt-search-input-style| |Table|dt-table-container-style| |Table|dt-table-wrapper-style| |Table|dt-table-header-th-style| |Table|dt-table-body-td-style| |Paginator|dt-paginator-style| |Paginator|dt-paginator-items-per-page-style| |Paginator|dt-paginator-status-style| |Paginator|dt-paginator-current-page-style| |Paginator|dt-paginator-arrows-style|

DataTable Events Events

|Name|Description|Notes| | ------ |-------|------| |headerClick|Sent on clicking header with column and columnIndex as information| | |headerCustomHandler|Event used to be forwarded by the DataTable| If you have a custom header with two parts, and want to do a specific action when clicking one see "Header Custom handler" section|

Header Custom handler

To make the table emit a headerCustomHandler event, the column.headerComponent must dispatch an event called headerCustomHandler to be forwarded to the datable.

<script>
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();

    function onClick1(){
        dispatch('headerCustomHandler', {clickOne:true});
    }
    function onClick2(){
        dispatch('headerCustomHandler', {clickTwo:true});
    }
</script>

<div>
    <p on:click={onClick1}>Click1</p>
    <p on:click={onClick2}>Click2</p>
</div>

Transform

Interfaces

// for all cases, note that pre-transformed data still exists and is never overwritten

transform: 'function' // e.g. (data) => { transform logic here }
// or
interface transform {
	sourceField?: string            // accessed by _.get; path of target to transform; Defaults to value stored in column.field;
	destinationField?: string       // accessed by _.set; new location to store the transformed data; Defaults to value stored in 'column.field';
	cull?: boolean                  // defaults to false; flag to ONLY return an object containing the transformed data
	fnc: 'function'                 // e.g. (data) => { transform logic here }
}

// if the property pointed to by 'field' or 'sourceField' is 
// null or undefined, then transform does nothing

Example Code

const rows = [
	{
		data: {
			title: "   my Title ",
			values: [0, 1, 2, 3, 4, 5],
			obj: {
				world: "world"
			}
		}
	}
];

function trimAndCAPS(title) {
	return title.trim().toUpperCase() + '!!!';
}

function reduce(valuesArray) {
	return valuesArray.reduce((a, b) => {
		return a + b;
	}, 0);
}

const columns = [
	{
		label: "Title",
		field: "data.title",        // note that if this data does not exist, the value is set to 'null'
		component: myComponent,     // optional svelte component : receives newly created, transformed object
		transform: trimAndCAPS
		//  new object returned after transform :
		//      {
		//          data: {
		//              title: "MY TITLE!!!",
		//              values: [0, 1, 2, 3, 4, 5],
		//              obj: { world: "world" },
		//          }
		//      }
	},
	{
		// this example works exactly the same as example above
		label: "transform as an object -- example 2",
		field: "data.title",
		transform: {
			fnc: trimAndCAPS
		}
	},
	{
		label: "Storing Transform Separately",
		field: "transformed.value",       // set default field to look at the newly created 'transformed.value' propery
		component: myComponent,           // optional svelte component : receives newly created, transformed object
		transform: {
			sourceField: 'data.values',                 // note again that this defaults to the 'column.field' property
			destinationField: 'transformed.value',      // note that this path need not exist, and will be created on the fly.
			fnc: reduce
		}
		//  new object returned after transform :
		//      {
		//          data: {
		//              title: "   my Title ",
		//              values: [0, 1, 2, 3, 4, 5],
		//              obj: { world: "world" },
		//          }
		//          transformed: {
		//              value: 15
		//          }
		//      }
	},
	{
		label: "culled transform",
		field: "transformed.value",
		transform: {
			sourceField: 'data.values',
			destinationField: 'transformed.value',
			cull: true,                   // only return transformed values
			fnc: reduce
		}
		//  new object returned after transform :
		//      {
		//          transformed: {
		//              value: 15
		//          }
		//      }
	},
	{
		// the object syntax adds a little bit more flexibility, especially for use-cases with components
		label: "Examining Scope",
		field: "transformed.obj.concat",
		component: myComponent,
		transform: {
			sourceField: 'data',                 // note again that this defaults to the 'column.field' property
			destinationField: 'transformed',     // note that this path need not exist, and will be created on the fly.
			fnc: (data) => {
				if (!data.obj.hello) data.obj.hello = 'hello';
				data.obj.concat = `${data.title.trim()} says '${data.obj.hello} ${data.obj.world}' : sum = ${reduce(data.values)}`;
				data.values.push(6);
				data.title = trimAndCAPS(data.title);
				return data;
			}
		}
		//  new object returned after transform :
		//      {
		//          data: {
		//              title: "   my Title ",
		//              values: [0, 1, 2, 3, 4, 5],
		//              obj: { world: "world" },
		//          }
		//          transformed: {
		//              title: "MY TITLE!!!",
		//              values: [0, 1, 2, 3, 4, 5, 6],
		//              obj: {
		//                  concat: "my Title says 'hello world' : sum = 15",
		//                  hello: "hello",
		//                  world: "world"
		//              }
		//          }
		//      }
	},
	{
		label: "truncating & overwriting side-effect of passing objects",
		field: "data",
		transform: (data) => {
			return `there are ${reduce(data.values)} ${data.obj.world}s out there`;
		}
		//  new object returned after transform :
		//      {
		//          data: "there are 15 worlds out there"
		//      }
	}
];