@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>