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

@tanglemedia/svelte-starter-data-view

v1.1.2

Published

Styles and components for use in svelte websites

Downloads

38

Readme

Data View

This package is experimental and is meant for internal use only.

The data view package provides a basic way for creating your generic table view with some opinionated features. The library consists of store and component libraries. Each can be used independently.

Store

This provides factory functions for creating writable store filters that are common with data views. It automatically writes to the url query/searchParams in order to persist between pages.

NOTE! This does sync bi-directionally with the url. If the URL search parameters is changed manually or programatically, it will NOT update the store values.

Basic Usage

A convinience function has been provided for quick intialization.

When using this, make sure to initialize them as high up the component tree as possible, the +page.ts is a good place to use these. This is because it automatically sets the context via the setContext svelte api.


<script lang="ts">
  import { initFilterContext } from '@tanglemedia/svelte-starter-data-view';

  initFilterContext({
    /**
     * Setup the intial values. Note that these are all optional
     */
    initialValues: {
      limit: 25,
      sort: 'name',
      searchTerm: 'Default search term',
      pagination: 1,
      filter: {}
    },
    // This will prefix all the arguments in the url
    scope: 'my-prefix',
    // optionally override the encoder
    // encoderProvider: () => myEncoder,
    // optionally override the storage provider
    // storageProvider: () => myStorageProvider,
    // optional custom configuration for each store,
    configure: {
      // ... todo
    }
	});
</script>
<!-- My component -->

Somewhere down the component tree


<script lang="ts">
  import { getLimitFilter, getSortFilter, getSearchTermFilter, getSearchFilter, getPaginationFilter } from '@tanglemedia/svelte-starter-data-view';

  /** Your typical writable store */
  const limit = getLimitFilter();
  const sort = getSortFilter();
  const query = getSearchTermFilter();
  const filter = getSearchFilter();
  const page = getPaginationFilter();

  /** You can access or edit these values like so */
  const onPage = () => $page = $page + 1;
  $: console.log($limit, $sort, $query, $filter, $page)

</script>

<button on:click={onPage}>Next page</button>

Data View

This component renders your basic table. Here are the configurable property definitions.

Columns

Note that the base columns extends @tanstack/svelte-table column def, so you may specify the columns as such.

import type { ColumnDef } from '@tanstack/svelte-table';
import type { SvelteComponent } from 'svelte';

type BaseColDef<T extends object> = Omit<ColumnDef<T>, 'columns'>;

/**
 * These are keys with arguments that map to predefined functions that will format/decorate the column value.
 * Use the formatter property on the data view for further configurations and ways to add custom formatters
 * todo: Handle ":" options
 */
export type DataViewColumnFormatter = 'currency';

export type ActionComponent = typeof SvelteComponent;

export type ActionItem = {
  href: string;
  text?: string | (() => ActionComponent | string);
  target?: string;
};

export type ActionExtend = {
  type?: 'action';
  actions?: ActionItem[];
  // accessorKey: string | undefined;
};

/**
 * We don't want to drift too far from the undelying package, so we attempt to extend this.
 */
export type DataViewColumnDef<
  T extends object,
  U extends object = Record<string, unknown>
> = BaseColDef<T> & {
  /**
   *
   */
  // accessorKey?: string;
  columns?: DataViewColumnDef<T>[];

  /**
   * A list of predefined formatters
   */
  formatters?: DataViewColumnFormatter[];

  /**
   * Tailwind classes which will be added to the cell container
   */
  class?: string;

  /**
   * Defaults to accessor to indicate this column is meant to diplay data by accessing the datasource.
   * options:
   *  - accessor
   *  - display
   *  - group (not supported yet)
   */
  type?: string | 'accessor' | 'display' | 'action';
} & U;

/**
 * Allow a definition to be a string for the simpliest definition.
 */
export type DataViewColumn<T extends object, U extends object = Record<string, unknown>> =
  | string
  | (DataViewColumnDef<T, U> & ActionExtend);

Data view

These relate to the props you can pass to the data view component

import type { DataViewColumn } from './column.type';
import type { FormatterConfiguration } from './formatter.type';

export interface DataViewPaginationProps {
  pagination?: boolean;
  // pageOptions?: {};
}

export interface DataSource<T extends object> {
  data: T[];
  meta?: {
    pagination?: {
      total: number;
    };
  };
}

export interface DataSourceContext {
  page?: {
    limit?: number;
    offset?: number;
  };
}

export type DataSourceProvider<T extends object> = (
  filter?: DataSourceContext
) => Promise<DataSource<T>>;

export interface DataViewProps<T extends object> extends DataViewPaginationProps {
  /**
   * Defined the method to fetch the data
   */
  dataSource: DataSourceProvider<T>;
  /**
   * Used as the query key for refetching and cache invalidation
   */
  key?: string;

  /**
   * Column definition
   */
  columns: DataViewColumn<T>[];

  formatters?: FormatterConfiguration;

  filterScope?: string;
}

Basic Usage

On version 1 onwards, the states have been lifted up to an object that is passed to the DataView components. This provides you access and abitlity to control the states within your component.

<script lang="ts">
  import {
		createDataView,
		DataView,
	} from '@tanglemedia/svelte-starter-data-view';

  const dataSource: DataSourceProvider<Specie> = async (filter) => {
    // imagine make data provides data with id, name, amount
		const data = await makeData(1000);

    // provide the total as meta information to handle pagination
		return { data, meta: { pagination: { total: 1000 } } };
	};

  // using the createDataView provides helper functions for creating columns.
  const dataview = createDataView<Drug>(({ checkmark, action, selection }) => ({
    dataSource: source,
		enableRowSelection: true,
    columns: [
      selection(true),
      // string definitions indicate you want to display the
      // value as is, without any modifiers
      'id',
      'name',
      // Display the amount but also format it as currency and disable the sorting
      { accessorKey: 'amount', formatters: ['currency'], enableSorting: false },
      checkmark('boolean_field'),
      action(({ row: { original } }) => [{
        text: 'Edit',
        href: `/library/drugs/${original.id}/edit`
      }])
    ]
  });
</script>

<DataView striped {dataview} />

Basic Usage (Legacy < v1)

<script lang="ts">

	import {
		DataView,
		type DataSourceProvider,
		type DataViewColumn
	} from '@tanglemedia/svelte-starter-data-view';

	const dataSource: DataSourceProvider<Specie> = async (filter) => {
    // imagine make data provides data with id, name, amount
		const data = await makeData(1000);

    // provide the total as meta information to handle pagination
		return { data, meta: { pagination: { total: 1000 } } };
	};

	const cols: DataViewColumn<Specie>[] = [
    // string definitions indicate you want to display the
    // value as is, without any modifiers
		'id',
		'name',
    // Display the amount but also format it as currency and disable the sorting
		{ accessorKey: 'amount', formatters: ['currency'], enableSorting: false },
    // draws a dropdown with "Edit" as the url
		{
			type: 'action',
			actions: [
				{
					href: '#',
					text: 'Edit'
				}
			]
		}
	];
</script>

<DataView filterScope={'my-app'} {dataSource} columns={cols}>
   <!-- Add your own custom filter -->
    <span slot="filter-right">
      Custom right filter
    </span>
</DataView>