vue-slim-tables 0.3.2 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,19 +9,19 @@ npm install vue-slim-tables
9
9
 
10
10
  ```html
11
11
  <template>
12
- <VueSlimTables :columns="columns" source="/users" />
12
+ <VueSlimTables :columns="columns" :source="asyncSource" />
13
13
  </template>
14
14
 
15
- <script>
16
- export default {
17
- created() {
18
- this.columns = [
19
- { key: 'id', title: 'ID' },
20
- { key: 'name', title: 'Name' },
21
- { key: 'phone', title: 'Phone' }
22
- ]
23
- }
24
- }
15
+ <script setup>
16
+ const columns = [
17
+ { key: 'id', title: 'ID' },
18
+ { key: 'name', title: 'Name' },
19
+ { key: 'phone', title: 'Phone' }
20
+ ]
21
+
22
+ const asyncSource = (params) => {
23
+ return fetch('...', params).then((res) => res.json())
24
+ }
25
25
  </script>
26
26
  ```
27
27
 
@@ -29,23 +29,25 @@ npm install vue-slim-tables
29
29
  | Prop | Type | Required | Description |
30
30
  | - | - | - | - |
31
31
  | columns | Array | true | Array of column objects described below |
32
- | source | [String, Function] | true | `string` is for async fetching rows<br/>`function` for more complicated async load |
33
- | perPage | Number | false | Number or rows to display |
32
+ | source | Function | true | async load |
33
+ | perPage | Number | false | Number or rows to display. By default 25 will be used |
34
34
 
35
35
  #### Column object
36
36
  | Key | Type | Required | Description |
37
37
  | - | - | - | - |
38
38
  | key | String | true | `Uniq` key that used for ordering and slots |
39
- | title | String | true | Displayed in thead |
39
+ | title | String | true | Displayed in thead cell |
40
40
  | orderable | Boolean | false | Ordering by column `key` |
41
41
 
42
42
  ### Slots
43
43
  | Slot | Props | Description |
44
44
  | - | - | - |
45
- | #thead | { columns, orders } | Rewrite whole thead row |
46
- | #thead:${column.key} | { column } | Rewrite column thead with custom html |
47
- | #row | { row, index, columns } | Rewrite whole row |
45
+ | #thead:before | - | Add a row before main |
46
+ | #thead | { columns, orders } | Rewrite the entire thead row |
47
+ | #thead:after | - | Add a row after main |
48
+ | #thead:${column.key} | { column } | Rewrite thead cell with custom html |
49
+ | #row | { row, index, columns } | Rewrite the entire tbody row |
48
50
  | #row:empty | - | Rewrite empty table row markup |
49
51
  | #row:loading | - | Rewrite loading table rows markup |
50
- | #cell:${column.key} | { row, index, column, value } | Rewrite cell with custom html |
52
+ | #cell:${column.key} | { row, index, column, value } | Rewrite tbody cell with custom html |
51
53
  | #pagination | { page, rows } | Rewrite pagination with your own implementation |
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";@keyframes moving-gradient{0%{background-position:-250px 0}to{background-position:250px 0}}.vst-th{line-height:20px}.vst-orderable div{display:flex;justify-content:space-between;align-items:center}.vst-orderable div:hover{cursor:pointer}.vst-orderable div:hover .vst-orderable-toggle{color:#555!important}.vst-orderable div .vst-orderable-toggle{font-size:20px;color:#ccc!important}.vst-orderable div .vst-orderable-toggle:after{content:" \2194";display:inline-block;transform:rotate(-90deg)}.vst-orderable div .vst-orderable-toggle.desc:after{content:" \2191";transform:rotate(0)}.vst-orderable div .vst-orderable-toggle.asc:after{content:" \2193";transform:rotate(0)}.vst-loading-row div{height:1.5rem;background:linear-gradient(to right,#eee 20%,#ddd 50%,#eee 80%);background-size:500px 1.5rem;animation-name:moving-gradient;animation-duration:1s;animation-iteration-count:infinite;animation-timing-function:linear;animation-fill-mode:forwards}.vst tr td.vst-loading-row-1 div{animation-delay:-1s}.vst tr td.vst-loading-row-2 div{animation-delay:-.9s}.vst tr td.vst-loading-row-3 div{animation-delay:-.8s}.vst tr td.vst-loading-row-4 div{animation-delay:-.7s}.vst tr td.vst-loading-row-5 div{animation-delay:-.6s}.vst tr td.vst-loading-row-6 div{animation-delay:-.5s}.vst tr td.vst-loading-row-7 div{animation-delay:-.4s}.vst tr td.vst-loading-row-8 div{animation-delay:-.3s}.vst tr td.vst-loading-row-9 div{animation-delay:-.2s}.vst tr td.vst-loading-row-10 div{animation-delay:-.1s}.vst-pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.vst-pagination a{position:relative;display:block;padding:8px 12px;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.vst-pagination a:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.vst-page-item.disabled .vst-page-link{pointer-events:none;color:#6c757d;cursor:auto;background-color:#fff}.vst-page-item .vst-page-link{cursor:pointer}
1
+ @charset "UTF-8";@keyframes moving-gradient{0%{background-position:-250px 0}to{background-position:250px 0}}.vst{--color-white: hsl(0, 0%, 100%);--color-light-grey: hsl(0, 0%, 90%);--color-grey: hsl(0, 0%, 75%);--color-dark-grey: hsl(0, 0%, 50%);--color-blue: hsl(211, 100%, 35%);--color-light-blue: hsl(211, 100%, 50%);width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent;border-collapse:separate;border-spacing:0}.vst th,.vst td{border-top:1px solid var(--color-light-grey);padding:1rem;vertical-align:top}.vst thead th{vertical-align:bottom}.vst-orderable div{display:flex;justify-content:space-between;align-items:center}.vst-orderable div:hover{cursor:pointer}.vst-orderable div:hover .vst-orderable-toggle{color:var(--color-dark-grey)}.vst-orderable div .vst-orderable-toggle{font-size:1.25rem;font-style:normal;color:var(--color-grey)}.vst-orderable div .vst-orderable-toggle:after{content:" ";display:inline-block;transform:rotate(-90deg)}.vst-orderable div .vst-orderable-toggle.desc:after{color:var(--color-dark-grey);content:" ";transform:rotate(0)}.vst-orderable div .vst-orderable-toggle.asc:after{color:var(--color-dark-grey);content:" ";transform:rotate(0)}.vst-loading-row div{height:1.125rem;background:linear-gradient(to right,var(--color-light-grey) 20%,var(--color-white) 50%,var(--color-light-grey) 80%);background-size:500px 1.125rem;animation-name:moving-gradient;animation-duration:1s;animation-iteration-count:infinite;animation-timing-function:ease;animation-fill-mode:forwards}.vst tr td.vst-loading-row-1 div{animation-delay:-1s}.vst tr td.vst-loading-row-2 div{animation-delay:-.9s}.vst tr td.vst-loading-row-3 div{animation-delay:-.8s}.vst tr td.vst-loading-row-4 div{animation-delay:-.7s}.vst tr td.vst-loading-row-5 div{animation-delay:-.6s}.vst tr td.vst-loading-row-6 div{animation-delay:-.5s}.vst tr td.vst-loading-row-7 div{animation-delay:-.4s}.vst tr td.vst-loading-row-8 div{animation-delay:-.3s}.vst tr td.vst-loading-row-9 div{animation-delay:-.2s}.vst tr td.vst-loading-row-10 div{animation-delay:-.1s}.vst-pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.vst-pagination a{font-size:1.25rem;position:relative;display:block;padding:.5rem .75rem;margin-right:-1px;line-height:1.25;color:var(--color-light-blue);background-color:var(--color-white);border:1px solid var(--color-light-grey)}.vst-pagination a:hover{z-index:2;text-decoration:none;color:var(--color-blue);background-color:var(--color-light-grey);border-color:var(--color-light-grey)}.vst-page-item.disabled .vst-page-link{pointer-events:none;color:var(--color-dark-grey);cursor:auto;background-color:var(--color-white)}.vst-page-item .vst-page-link{cursor:pointer}
@@ -0,0 +1,4 @@
1
+ import type { TableColumn, TableOrders, TableFetchParams, TableRow, TableFilters, TableProps } from './ts/types';
2
+ import VueSlimTable from './ts/components/slim_table.vue';
3
+ export default VueSlimTable;
4
+ export { TableColumn, TableOrders, TableFetchParams, TableRow, TableFilters, TableProps };
@@ -0,0 +1,12 @@
1
+ declare const _default: import("vue").DefineComponent<{
2
+ columnsLength: {
3
+ type: NumberConstructor;
4
+ required: true;
5
+ };
6
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
7
+ columnsLength: {
8
+ type: NumberConstructor;
9
+ required: true;
10
+ };
11
+ }>>, {}, {}>;
12
+ export default _default;
@@ -0,0 +1,121 @@
1
+ import type { TableOrders, TableRow, TableProps } from '../../ts/types';
2
+ declare const _default: <TRow extends TableRow>(__VLS_props: TableProps<TRow> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, __VLS_ctx?: Pick<{
3
+ props: TableProps<TRow>;
4
+ expose(exposed: {
5
+ refetch: () => void;
6
+ reload: () => Promise<void>;
7
+ rows: import("vue").Ref<TRow[]>;
8
+ }): void;
9
+ attrs: any;
10
+ slots: Partial<{
11
+ [key: `thead:${string}`]: (_props: {
12
+ column: import('../../ts/types').TableColumn;
13
+ orders: TableOrders;
14
+ }) => any;
15
+ [key: `cell:${string}`]: (_props: {
16
+ row: TRow;
17
+ index: number;
18
+ column: import('../../ts/types').TableColumn;
19
+ value: unknown;
20
+ }) => any;
21
+ 'thead:before': () => any;
22
+ thead: (_props: {
23
+ columns: import('../../ts/types').TableColumn[];
24
+ orders: TableOrders;
25
+ }) => any;
26
+ 'thead:after': () => any;
27
+ 'row:loading': () => any;
28
+ 'row:empty': () => any;
29
+ row: (_props: {
30
+ row: TRow;
31
+ index: number;
32
+ columns: import('../../ts/types').TableColumn[];
33
+ }) => any;
34
+ pagination: (_props: {
35
+ page: number;
36
+ rows: TRow[];
37
+ }) => any;
38
+ }>;
39
+ emit: any;
40
+ }, "attrs" | "emit" | "slots"> | undefined, __VLS_setup?: Promise<{
41
+ props: TableProps<TRow>;
42
+ expose(exposed: {
43
+ refetch: () => void;
44
+ reload: () => Promise<void>;
45
+ rows: import("vue").Ref<TRow[]>;
46
+ }): void;
47
+ attrs: any;
48
+ slots: Partial<{
49
+ [key: `thead:${string}`]: (_props: {
50
+ column: import('../../ts/types').TableColumn;
51
+ orders: TableOrders;
52
+ }) => any;
53
+ [key: `cell:${string}`]: (_props: {
54
+ row: TRow;
55
+ index: number;
56
+ column: import('../../ts/types').TableColumn;
57
+ value: unknown;
58
+ }) => any;
59
+ 'thead:before': () => any;
60
+ thead: (_props: {
61
+ columns: import('../../ts/types').TableColumn[];
62
+ orders: TableOrders;
63
+ }) => any;
64
+ 'thead:after': () => any;
65
+ 'row:loading': () => any;
66
+ 'row:empty': () => any;
67
+ row: (_props: {
68
+ row: TRow;
69
+ index: number;
70
+ columns: import('../../ts/types').TableColumn[];
71
+ }) => any;
72
+ pagination: (_props: {
73
+ page: number;
74
+ rows: TRow[];
75
+ }) => any;
76
+ }>;
77
+ emit: any;
78
+ }>) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
79
+ [key: string]: any;
80
+ }> & {
81
+ __ctx?: {
82
+ props: TableProps<TRow>;
83
+ expose(exposed: {
84
+ refetch: () => void;
85
+ reload: () => Promise<void>;
86
+ rows: import("vue").Ref<TRow[]>;
87
+ }): void;
88
+ attrs: any;
89
+ slots: Partial<{
90
+ [key: `thead:${string}`]: (_props: {
91
+ column: import('../../ts/types').TableColumn;
92
+ orders: TableOrders;
93
+ }) => any;
94
+ [key: `cell:${string}`]: (_props: {
95
+ row: TRow;
96
+ index: number;
97
+ column: import('../../ts/types').TableColumn;
98
+ value: unknown;
99
+ }) => any;
100
+ 'thead:before': () => any;
101
+ thead: (_props: {
102
+ columns: import('../../ts/types').TableColumn[];
103
+ orders: TableOrders;
104
+ }) => any;
105
+ 'thead:after': () => any;
106
+ 'row:loading': () => any;
107
+ 'row:empty': () => any;
108
+ row: (_props: {
109
+ row: TRow;
110
+ index: number;
111
+ columns: import('../../ts/types').TableColumn[];
112
+ }) => any;
113
+ pagination: (_props: {
114
+ page: number;
115
+ rows: TRow[];
116
+ }) => any;
117
+ }>;
118
+ emit: any;
119
+ } | undefined;
120
+ };
121
+ export default _default;
@@ -0,0 +1,53 @@
1
+ import { ShallowRef } from 'vue';
2
+ export type TableColumn = {
3
+ key: string;
4
+ title: string;
5
+ orderable?: boolean;
6
+ };
7
+ export type TableOrders = {
8
+ [key: string]: 'asc' | 'desc';
9
+ };
10
+ export type TableFilters = {
11
+ per_page: number;
12
+ orders: ShallowRef<TableOrders>;
13
+ };
14
+ export type TableFetchParams = {
15
+ page: number;
16
+ } & TableFilters;
17
+ export type TableRow = {
18
+ [key: string]: any;
19
+ };
20
+ export type TableProps<T> = {
21
+ columns: Array<TableColumn>;
22
+ perPage: number;
23
+ source: ((_: TableFetchParams) => Promise<T[]> | T[]);
24
+ };
25
+ export type TableSlots<T> = Partial<{
26
+ 'thead:before': () => any;
27
+ thead: (_props: {
28
+ columns: TableColumn[];
29
+ orders: TableOrders;
30
+ }) => any;
31
+ 'thead:after': () => any;
32
+ [key: `thead:${string}`]: (_props: {
33
+ column: TableColumn;
34
+ orders: TableOrders;
35
+ }) => any;
36
+ 'row:loading': () => any;
37
+ 'row:empty': () => any;
38
+ row: (_props: {
39
+ row: T;
40
+ index: number;
41
+ columns: TableColumn[];
42
+ }) => any;
43
+ [key: `cell:${string}`]: (_props: {
44
+ row: T;
45
+ index: number;
46
+ column: TableColumn;
47
+ value: unknown;
48
+ }) => any;
49
+ pagination: (_props: {
50
+ page: number;
51
+ rows: T[];
52
+ }) => any;
53
+ }>;
@@ -0,0 +1,28 @@
1
+ import { Ref } from 'vue';
2
+ type UseFiltetableArgs<T, S> = {
3
+ initialFilters: Ref<T>;
4
+ loadItems: (_params: T & {
5
+ page: number;
6
+ }) => Promise<S[]>;
7
+ };
8
+ export declare const SYNC_STATES: {
9
+ readonly INITIAL: "INITIAL";
10
+ readonly SYNCING: "SYNCING";
11
+ readonly SYNCED: "SYNCED";
12
+ readonly FAILED: "FAILED";
13
+ };
14
+ type SynsState = (typeof SYNC_STATES)[keyof typeof SYNC_STATES];
15
+ declare const _default: <TFilters, TItem>({ initialFilters, loadItems, }: UseFiltetableArgs<TFilters, TItem>) => {
16
+ page: Ref<number>;
17
+ items: Ref<TItem[]>;
18
+ syncState: Ref<SynsState>;
19
+ isSyncing: import("vue").ComputedRef<boolean>;
20
+ isSynced: import("vue").ComputedRef<boolean>;
21
+ isFailed: import("vue").ComputedRef<boolean>;
22
+ nextPage: () => void;
23
+ prevPage: () => void;
24
+ setPage: (num: number) => void;
25
+ reload: () => Promise<void>;
26
+ refetch: () => void;
27
+ };
28
+ export default _default;
package/dist/vst.es.js CHANGED
@@ -1,271 +1,213 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
- var __hasOwnProp = Object.prototype.hasOwnProperty;
4
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __spreadValues = (a, b) => {
7
- for (var prop in b || (b = {}))
8
- if (__hasOwnProp.call(b, prop))
9
- __defNormalProp(a, prop, b[prop]);
10
- if (__getOwnPropSymbols)
11
- for (var prop of __getOwnPropSymbols(b)) {
12
- if (__propIsEnum.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- }
15
- return a;
16
- };
17
- import { defineComponent, openBlock, createElementBlock, createElementVNode, normalizeClass, computed, ref, reactive, watch, shallowRef, renderSlot, unref, Fragment, renderList, mergeProps, toHandlers, createTextVNode, toDisplayString, createCommentVNode, createBlock, withModifiers } from "vue";
18
- var index = "";
19
- const _hoisted_1$1 = ["colspan"];
20
- const _hoisted_2$1 = /* @__PURE__ */ createElementVNode("div", null, null, -1);
21
- const _hoisted_3$1 = [
22
- _hoisted_2$1
23
- ];
24
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1
+ import { defineComponent as F, openBlock as n, createElementBlock as u, createElementVNode as a, normalizeClass as $, ref as I, watch as _, computed as b, shallowRef as B, renderSlot as d, Fragment as N, renderList as f, mergeProps as M, toHandlers as V, createTextVNode as E, toDisplayString as P, createCommentVNode as w, unref as t, createBlock as R, withModifiers as A } from "vue";
2
+ const q = ["colspan"], z = /* @__PURE__ */ a("div", null, null, -1), H = [
3
+ z
4
+ ], O = /* @__PURE__ */ F({
5
+ __name: "loading_row",
25
6
  props: {
26
- columnsLength: { type: Number, required: true }
7
+ columnsLength: { type: Number, required: !0 }
27
8
  },
28
- setup(__props) {
29
- const randNum = Math.floor(Math.random() * 10) + 1;
30
- return (_ctx, _cache) => {
31
- return openBlock(), createElementBlock("tr", null, [
32
- createElementVNode("td", {
33
- colspan: __props.columnsLength,
34
- class: normalizeClass(["vst-loading-row", `vst-loading-row-${randNum}`])
35
- }, _hoisted_3$1, 10, _hoisted_1$1)
36
- ]);
37
- };
9
+ setup(v) {
10
+ const h = Math.floor(Math.random() * 10) + 1;
11
+ return (o, l) => (n(), u("tr", null, [
12
+ a("td", {
13
+ colspan: v.columnsLength,
14
+ class: $(["vst-loading-row", `vst-loading-row-${h}`])
15
+ }, H, 10, q)
16
+ ]));
38
17
  }
39
- });
40
- const SYNC_STATES = {
41
- INITIAL: "initial",
42
- SYNCING: "syncing",
43
- SYNCED: "synced",
44
- FAILED: "failed"
45
- };
46
- const useFilterable = ({ initialFilters, loadItems }) => {
47
- const page = ref(1);
48
- const items = reactive({ value: [] });
49
- const syncState = ref(SYNC_STATES.INITIAL);
50
- const filters = reactive({ value: initialFilters });
51
- const combinedFilters = computed(() => __spreadValues({
52
- page: page.value
53
- }, filters.value));
54
- const load = () => {
55
- syncState.value = SYNC_STATES.SYNCING;
56
- return loadItems(combinedFilters.value).then((res) => {
57
- items.value = res;
58
- syncState.value = SYNC_STATES.SYNCED;
59
- }).catch(() => {
60
- items.value = [];
61
- syncState.value = SYNC_STATES.FAILED;
62
- });
18
+ }), g = {
19
+ INITIAL: "INITIAL",
20
+ SYNCING: "SYNCING",
21
+ SYNCED: "SYNCED",
22
+ FAILED: "FAILED"
23
+ }, j = ({
24
+ initialFilters: v,
25
+ loadItems: h
26
+ }) => {
27
+ const o = I(1), l = I([]), i = I(g.INITIAL), c = async () => {
28
+ i.value = g.SYNCING;
29
+ try {
30
+ l.value = await h({
31
+ ...v.value,
32
+ page: o.value
33
+ }), i.value = g.SYNCED;
34
+ } catch {
35
+ l.value = [], i.value = g.FAILED;
36
+ }
63
37
  };
64
- load();
65
- watch(combinedFilters, load);
66
- return {
67
- page,
68
- items,
69
- syncState,
38
+ return _(v, c), _(o, c), c(), {
39
+ page: o,
40
+ items: l,
41
+ syncState: i,
42
+ isSyncing: b(() => i.value === g.SYNCING),
43
+ isSynced: b(() => i.value === g.SYNCED),
44
+ isFailed: b(() => i.value === g.FAILED),
70
45
  nextPage: () => {
71
- page.value += 1;
46
+ o.value += 1;
72
47
  },
73
48
  prevPage: () => {
74
- page.value -= 1;
49
+ o.value -= 1;
75
50
  },
76
- isSyncing: computed(() => syncState.value === SYNC_STATES.SYNCING),
77
- isSynced: computed(() => syncState.value === SYNC_STATES.SYNCED),
78
- isFailed: computed(() => syncState.value === SYNC_STATES.FAILED),
79
- reload: () => {
80
- load();
51
+ setPage: (S) => {
52
+ o.value = S;
81
53
  },
54
+ reload: c,
82
55
  refetch: () => {
83
- if (page.value === 1) {
84
- load();
85
- } else {
86
- page.value = 1;
87
- }
56
+ o.value === 1 ? c() : o.value = 1;
88
57
  }
89
58
  };
90
- };
91
- const stringify = (obj, parentPrefix) => (outputArray, [key, val]) => {
92
- if (val === null || val === void 0) {
93
- return outputArray;
94
- }
95
- const encodedKey = encodeURIComponent(key);
96
- const prefix = parentPrefix ? `${parentPrefix}[${encodedKey}]` : encodedKey;
97
- if (["number", "string"].includes(typeof val)) {
98
- outputArray.push(`${prefix}=${encodeURIComponent(val)}`);
99
- return outputArray;
100
- }
101
- outputArray.push(Object.entries(val).reduce(stringify(val, prefix), []).join("&"));
102
- return outputArray;
103
- };
104
- var toQueryString = (obj) => Object.entries(obj).reduce(stringify(), []).join("&");
105
- const _hoisted_1 = { class: "vst" };
106
- const _hoisted_2 = { key: 0 };
107
- const _hoisted_3 = { key: 0 };
108
- const _hoisted_4 = ["colspan"];
109
- const _hoisted_5 = ["colspan"];
110
- const _hoisted_6 = {
59
+ }, J = { class: "vst" }, K = { key: 0 }, Q = { key: 0 }, U = ["colspan"], W = ["colspan"], X = {
111
60
  key: 0,
112
- class: "vst-pagination mt-3"
113
- };
114
- const _sfc_main = /* @__PURE__ */ defineComponent({
61
+ class: "vst-pagination"
62
+ }, x = /* @__PURE__ */ F({
63
+ __name: "slim_table",
115
64
  props: {
116
- columns: null,
117
- source: null,
118
- perPage: { default: 25 }
65
+ columns: {},
66
+ perPage: { default: 25 },
67
+ source: {}
119
68
  },
120
- setup(__props, { expose }) {
121
- const props = __props;
122
- const orders = shallowRef({});
123
- const loadItems = async (params) => {
124
- let data;
125
- if (typeof props.source === "string") {
126
- const response = await fetch(`${props.source}?${toQueryString(params)}`);
127
- data = await response.json();
128
- } else {
129
- data = await props.source(params);
69
+ setup(v, { expose: h }) {
70
+ const o = v, l = B({}), i = async (e) => {
71
+ let r = [];
72
+ try {
73
+ r = await o.source(e);
74
+ } catch {
130
75
  }
131
- return data;
132
- };
133
- const onOrderClick = (key) => {
134
- if (orders.value[key] === "asc") {
135
- orders.value = { [key]: "desc" };
136
- } else if (orders.value[key] === "desc") {
137
- orders.value = {};
138
- } else {
139
- orders.value = { [key]: "asc" };
140
- }
141
- };
142
- const {
143
- page,
144
- isSyncing,
145
- isSynced,
146
- prevPage,
147
- nextPage,
148
- reload,
149
- refetch,
150
- items: rows
151
- } = useFilterable({
152
- initialFilters: { per_page: props.perPage, orders: orders.value },
153
- loadItems
154
- });
155
- expose({
156
- refetch,
157
- reload,
158
- rows
76
+ return r;
77
+ }, c = (e, r) => {
78
+ e.preventDefault(), l.value[r] === "asc" ? l.value = { [r]: "desc" } : l.value[r] === "desc" ? l.value = {} : l.value = { [r]: "asc" };
79
+ }, S = I({
80
+ per_page: o.perPage,
81
+ orders: l
82
+ }), {
83
+ page: C,
84
+ isSyncing: m,
85
+ isSynced: D,
86
+ prevPage: L,
87
+ nextPage: Y,
88
+ reload: T,
89
+ refetch: G,
90
+ items: p
91
+ } = j({
92
+ initialFilters: S,
93
+ loadItems: i
159
94
  });
160
- return (_ctx, _cache) => {
161
- return openBlock(), createElementBlock("table", _hoisted_1, [
162
- __props.columns.length ? (openBlock(), createElementBlock("thead", _hoisted_2, [
163
- renderSlot(_ctx.$slots, "thead", {
164
- columns: __props.columns,
165
- orders: unref(orders)
166
- }, () => [
167
- createElementVNode("tr", null, [
168
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
169
- return openBlock(), createElementBlock("th", mergeProps({
170
- key: column.key,
171
- class: ["vst-th", { "vst-orderable": column.orderable }]
172
- }, toHandlers(column.orderable ? { click: () => onOrderClick(column.key) } : {})), [
173
- column.orderable ? (openBlock(), createElementBlock("div", _hoisted_3, [
174
- renderSlot(_ctx.$slots, `head:${column.key}`, { column }, () => [
175
- createTextVNode(toDisplayString(column.title), 1)
176
- ]),
177
- createElementVNode("a", {
178
- href: "#",
179
- class: normalizeClass(["vst-orderable-toggle", unref(orders)[column.key]])
180
- }, null, 2)
181
- ])) : renderSlot(_ctx.$slots, `thead:${column.key}`, {
182
- key: 1,
183
- column
184
- }, () => [
185
- createTextVNode(toDisplayString(column.title), 1)
186
- ])
187
- ], 16);
188
- }), 128))
189
- ])
95
+ return h({
96
+ refetch: G,
97
+ reload: T,
98
+ rows: p
99
+ }), (e, r) => (n(), u("table", J, [
100
+ e.columns.length ? (n(), u("thead", K, [
101
+ d(e.$slots, "thead:before"),
102
+ d(e.$slots, "thead", {
103
+ columns: e.columns,
104
+ orders: l.value
105
+ }, () => [
106
+ a("tr", null, [
107
+ (n(!0), u(N, null, f(e.columns, (s) => (n(), u("th", M({
108
+ key: s.key,
109
+ class: ["vst-th", { "vst-orderable": s.orderable }]
110
+ }, V(s.orderable ? { click: (y) => c(y, s.key) } : {}, !0)), [
111
+ s.orderable ? (n(), u("div", Q, [
112
+ d(e.$slots, `thead:${s.key}`, {
113
+ column: s,
114
+ orders: l.value
115
+ }, () => [
116
+ E(P(s.title), 1)
117
+ ]),
118
+ a("i", {
119
+ class: $(["vst-orderable-toggle", l.value[s.key]])
120
+ }, null, 2)
121
+ ])) : d(e.$slots, `thead:${s.key}`, {
122
+ key: 1,
123
+ column: s,
124
+ orders: l.value
125
+ }, () => [
126
+ E(P(s.title), 1)
127
+ ])
128
+ ], 16))), 128))
190
129
  ])
191
- ])) : createCommentVNode("", true),
192
- createElementVNode("tbody", null, [
193
- unref(isSyncing) ? renderSlot(_ctx.$slots, "row:loading", { key: 0 }, () => [
194
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.perPage, (i) => {
195
- return openBlock(), createBlock(_sfc_main$1, {
196
- key: `loadingRow${i}`,
197
- "columns-length": __props.columns.length
198
- }, null, 8, ["columns-length"]);
199
- }), 128))
200
- ]) : unref(isSynced) && unref(rows).value.length === 0 ? renderSlot(_ctx.$slots, "row:empty", { key: 1 }, () => [
201
- createElementVNode("tr", null, [
202
- createElementVNode("td", {
203
- colspan: __props.columns.length
204
- }, " No records found ", 8, _hoisted_4)
205
- ])
206
- ]) : unref(isSynced) && unref(rows).value.length ? (openBlock(true), createElementBlock(Fragment, { key: 2 }, renderList(unref(rows).value, (row, i) => {
207
- return renderSlot(_ctx.$slots, "row", {
208
- row,
209
- index: i,
210
- columns: __props.columns
211
- }, () => [
212
- (openBlock(), createElementBlock("tr", {
213
- key: row["id"] || i
214
- }, [
215
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
216
- return openBlock(), createElementBlock("td", {
217
- key: column.key
218
- }, [
219
- renderSlot(_ctx.$slots, `cell:${column.key}`, {
220
- row,
221
- value: row[column.key],
222
- column,
223
- index: i
224
- }, () => [
225
- createTextVNode(toDisplayString(row[column.key]), 1)
226
- ])
227
- ]);
228
- }), 128))
229
- ]))
230
- ]);
231
- }), 256)) : createCommentVNode("", true)
232
130
  ]),
233
- createElementVNode("tfoot", null, [
234
- createElementVNode("tr", null, [
235
- createElementVNode("td", {
236
- colspan: __props.columns.length
131
+ d(e.$slots, "thead:after")
132
+ ])) : w("", !0),
133
+ a("tbody", null, [
134
+ t(m) ? d(e.$slots, "row:loading", { key: 0 }, () => [
135
+ (n(!0), u(N, null, f(e.perPage, (s) => (n(), R(O, {
136
+ key: `loadingRow${s}`,
137
+ "columns-length": e.columns.length
138
+ }, null, 8, ["columns-length"]))), 128))
139
+ ]) : t(D) && t(p).length === 0 ? d(e.$slots, "row:empty", { key: 1 }, () => [
140
+ a("tr", null, [
141
+ a("td", {
142
+ colspan: e.columns.length
143
+ }, " No records found ", 8, U)
144
+ ])
145
+ ]) : t(D) && t(p).length ? (n(!0), u(N, { key: 2 }, f(t(p), (s, y) => d(e.$slots, "row", {
146
+ row: s,
147
+ index: y,
148
+ columns: e.columns
149
+ }, () => [
150
+ (n(), u("tr", {
151
+ key: s.id || y
152
+ }, [
153
+ (n(!0), u(N, null, f(e.columns, (k) => (n(), u("td", {
154
+ key: k.key
237
155
  }, [
238
- renderSlot(_ctx.$slots, "pagination", {
239
- page: unref(page),
240
- rows: unref(rows).value
156
+ d(e.$slots, `cell:${k.key}`, {
157
+ row: s,
158
+ value: s[k.key],
159
+ column: k,
160
+ index: y
241
161
  }, () => [
242
- unref(page) > 1 || unref(rows).value.length === __props.perPage || unref(isSyncing) ? (openBlock(), createElementBlock("ul", _hoisted_6, [
243
- createElementVNode("li", {
244
- class: normalizeClass(["vst-page-item", { disabled: unref(page) === 1 || unref(isSyncing) }])
245
- }, [
246
- createElementVNode("a", {
247
- class: "vst-page-link",
248
- onClick: _cache[0] || (_cache[0] = withModifiers((...args) => unref(prevPage) && unref(prevPage)(...args), ["prevent"]))
249
- }, "\u2190")
250
- ], 2),
251
- createElementVNode("li", {
252
- class: normalizeClass(["vst-page-item", {
253
- disabled: unref(rows).value.length < __props.perPage || unref(isSyncing)
254
- }])
255
- }, [
256
- createElementVNode("a", {
257
- class: "vst-page-link",
258
- onClick: _cache[1] || (_cache[1] = withModifiers((...args) => unref(nextPage) && unref(nextPage)(...args), ["prevent"]))
259
- }, "\u2192")
260
- ], 2)
261
- ])) : createCommentVNode("", true)
162
+ E(P(s[k.key]), 1)
262
163
  ])
263
- ], 8, _hoisted_5)
264
- ])
164
+ ]))), 128))
165
+ ]))
166
+ ])), 256)) : w("", !0)
167
+ ]),
168
+ a("tfoot", null, [
169
+ a("tr", null, [
170
+ a("td", {
171
+ colspan: e.columns.length
172
+ }, [
173
+ d(e.$slots, "pagination", {
174
+ page: t(C),
175
+ rows: t(p)
176
+ }, () => [
177
+ t(C) > 1 || t(p).length === e.perPage || t(m) ? (n(), u("ul", X, [
178
+ a("li", {
179
+ class: $(["vst-page-item", { disabled: t(C) === 1 || t(m) }])
180
+ }, [
181
+ a("a", {
182
+ class: "vst-page-link",
183
+ onClick: r[0] || (r[0] = A(
184
+ //@ts-ignore
185
+ (...s) => t(L) && t(L)(...s),
186
+ ["prevent"]
187
+ ))
188
+ }, "←")
189
+ ], 2),
190
+ a("li", {
191
+ class: $(["vst-page-item", { disabled: t(p).length < e.perPage || t(m) }])
192
+ }, [
193
+ a("a", {
194
+ class: "vst-page-link",
195
+ onClick: r[1] || (r[1] = A(
196
+ //@ts-ignore
197
+ (...s) => t(Y) && t(Y)(...s),
198
+ ["prevent"]
199
+ ))
200
+ }, "→")
201
+ ], 2)
202
+ ])) : w("", !0)
203
+ ])
204
+ ], 8, W)
265
205
  ])
266
- ]);
267
- };
206
+ ])
207
+ ]));
268
208
  }
269
209
  });
270
- export { _sfc_main as default };
210
+ export {
211
+ x as default
212
+ };
271
213
  //# sourceMappingURL=vst.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vst.es.js","sources":["../src/ts/components/loading_row.vue","../src/ts/use/filterable.ts","../src/ts/helpers/to_query_string.ts","../src/ts/components/table.vue"],"sourcesContent":["<template>\n <tr>\n <td\n :colspan=\"columnsLength\"\n :class=\"['vst-loading-row', `vst-loading-row-${randNum}`]\">\n <div />\n </td>\n </tr>\n</template>\n\n<script lang=\"ts\" setup>\ndefineProps({\n columnsLength: { type: Number, required: true },\n})\n\nconst randNum = Math.floor(Math.random() * 10) + 1\n</script>\n","import {\n ref, computed, reactive, watch,\n} from 'vue'\n\ntype CombinedFilters<Filters> = Filters & {\n page: number\n}\n\ninterface UseFiltetableArgs<Filters, Item> {\n initialFilters: Filters,\n loadItems: (_filters: CombinedFilters<Filters>) => Promise<Item[]>\n}\n\nconst SYNC_STATES = {\n INITIAL: 'initial',\n SYNCING: 'syncing',\n SYNCED: 'synced',\n FAILED: 'failed',\n}\n\nconst useFilterable = <Filters, Item>({ initialFilters, loadItems }: UseFiltetableArgs<Filters, Item>) => {\n const page = ref(1)\n const items = reactive({ value: [] as Item[] }) as { value: Item[] }\n const syncState = ref(SYNC_STATES.INITIAL)\n const filters = reactive({ value: initialFilters })\n\n const combinedFilters = computed(() => ({\n page: page.value,\n ...filters.value as Filters,\n }))\n\n const load = () => {\n syncState.value = SYNC_STATES.SYNCING\n\n return loadItems(combinedFilters.value)\n .then((res: Item[]) => {\n items.value = res\n syncState.value = SYNC_STATES.SYNCED\n })\n .catch(() => {\n items.value = []\n syncState.value = SYNC_STATES.FAILED\n })\n }\n load()\n\n watch(combinedFilters, load)\n\n return {\n page,\n items,\n syncState,\n nextPage: () => {\n page.value += 1\n },\n prevPage: () => {\n page.value -= 1\n },\n isSyncing: computed(() => syncState.value === SYNC_STATES.SYNCING),\n isSynced: computed(() => syncState.value === SYNC_STATES.SYNCED),\n isFailed: computed(() => syncState.value === SYNC_STATES.FAILED),\n reload: () => {\n load()\n },\n refetch: () => {\n if (page.value === 1) {\n load()\n } else {\n page.value = 1\n }\n },\n }\n}\n\nexport default useFilterable\n","const stringify = (obj, parentPrefix?: string) => (outputArray, [key, val]) => {\n if (val === null || val === undefined) {\n return outputArray\n }\n\n const encodedKey = encodeURIComponent(key)\n const prefix = parentPrefix ? `${parentPrefix}[${encodedKey}]` : encodedKey\n\n if (['number', 'string'].includes(typeof val)) {\n outputArray.push(`${prefix}=${encodeURIComponent(val)}`)\n return outputArray\n }\n\n outputArray.push(Object.entries(val).reduce(stringify(val, prefix), []).join('&'))\n return outputArray\n}\n\nexport default (obj): string => Object.entries(obj).reduce(stringify(obj), []).join('&')\n","<template>\n <table class=\"vst\">\n <thead v-if=\"columns.length\">\n <slot name=\"thead\" :columns=\"columns\" :orders=\"orders\">\n <tr>\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"['vst-th', { 'vst-orderable': column.orderable }]\"\n v-on=\"column.orderable ? { click: () => onOrderClick(column.key) } : {}\">\n <div v-if=\"column.orderable\">\n <slot\n :name=\"`head:${column.key}`\"\n :column=\"column\">\n {{ column.title }}\n </slot>\n\n <a href=\"#\" :class=\"['vst-orderable-toggle', orders[column.key]]\" />\n </div>\n\n <slot\n v-else\n :name=\"`thead:${column.key}`\"\n :column=\"column\">\n {{ column.title }}\n </slot>\n </th>\n </tr>\n </slot>\n </thead>\n <tbody>\n <slot v-if=\"isSyncing\" name=\"row:loading\">\n <LoadingRow\n v-for=\"i in perPage\"\n :key=\"`loadingRow${i}`\"\n :columns-length=\"columns.length\" />\n </slot>\n\n <slot v-else-if=\"isSynced && rows.value.length === 0\" name=\"row:empty\">\n <tr>\n <td :colspan=\"columns.length\">\n No records found\n </td>\n </tr>\n </slot>\n\n <template v-else-if=\"isSynced && rows.value.length\">\n <slot\n v-for=\"(row, i) in rows.value\"\n name=\"row\"\n :row=\"row\"\n :index=\"i\"\n :columns=\"columns\">\n <tr :key=\"row['id'] || i\">\n <td\n v-for=\"column in columns\"\n :key=\"column.key\">\n <slot\n :name=\"`cell:${column.key}`\"\n :row=\"row\"\n :value=\"row[column.key]\"\n :column=\"column\"\n :index=\"i\">\n {{ row[column.key] }}\n </slot>\n </td>\n </tr>\n </slot>\n </template>\n </tbody>\n <tfoot>\n <tr>\n <td :colspan=\"columns.length\">\n <slot name=\"pagination\" :page=\"page\" :rows=\"rows.value\">\n <ul\n v-if=\"page > 1 || rows.value.length === perPage || isSyncing\"\n class=\"vst-pagination mt-3\">\n <li :class=\"['vst-page-item', { disabled: page === 1 || isSyncing }]\">\n <a class=\"vst-page-link\" @click.prevent=\"prevPage\">←</a>\n </li>\n\n <li\n :class=\"['vst-page-item', {\n disabled: rows.value.length < perPage || isSyncing\n }]\">\n <a class=\"vst-page-link\" @click.prevent=\"nextPage\">→</a>\n </li>\n </ul>\n </slot>\n </td>\n </tr>\n </tfoot>\n </table>\n</template>\n\n<script setup lang=\"ts\">\nimport { shallowRef, ShallowRef } from 'vue'\nimport LoadingRow from './loading_row.vue'\n\nimport useFilterable from '../use/filterable'\nimport toQueryString from '../helpers/to_query_string'\n\ninterface TableColumn {\n key: string,\n title: string,\n orderable?: boolean\n}\n\ninterface TableOrders {\n [key: string]: 'asc' | 'desc'\n}\n\ninterface TableFetchParams {\n per_page: number,\n page: number,\n orders?: TableOrders\n}\n\ninterface TableRow {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\ninterface TableFilters {\n per_page: number,\n orders: TableOrders\n}\n\ninterface TableProps {\n columns: Array<TableColumn>\n source: string | ((_: TableFetchParams) => Promise<TableRow[]> | TableRow[])\n perPage?: number\n}\n\nconst props = withDefaults(defineProps<TableProps>(), {\n perPage: 25,\n})\n\nconst orders: ShallowRef<TableOrders> = shallowRef({})\n\nconst loadItems = async (params: TableFetchParams) => {\n let data: TableRow[]\n if (typeof props.source === 'string') {\n const response = await fetch(`${props.source}?${toQueryString(params)}`)\n data = await response.json()\n } else {\n data = await props.source(params) as TableRow[]\n }\n\n return data\n}\n\nconst onOrderClick = (key: string) => {\n if (orders.value[key] === 'asc') {\n orders.value = { [key]: 'desc' }\n } else if (orders.value[key] === 'desc') {\n orders.value = {}\n } else {\n orders.value = { [key]: 'asc' }\n }\n}\n\nconst {\n page, isSyncing, isSynced, prevPage, nextPage, reload, refetch, items: rows,\n} = useFilterable<TableFilters, TableRow>({\n initialFilters: { per_page: props.perPage, orders: orders.value },\n loadItems,\n})\n\ndefineExpose({\n refetch,\n reload,\n rows,\n})\n</script>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;UAeM,UAAU,KAAK,MAAM,KAAK,WAAW,EAAE,IAAI;;;;;;;;;;;ACFjD,MAAM,cAAc;AAAA,EAClB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,MAAM,gBAAgB,CAAgB,EAAE,gBAAgB,gBAAkD;QAClG,OAAO,IAAI,CAAC;QACZ,QAAQ,SAAS,EAAE,OAAO,IAAc;QACxC,YAAY,IAAI,YAAY,OAAO;QACnC,UAAU,SAAS,EAAE,OAAO,gBAAgB;QAE5C,kBAAkB,SAAS;IAC/B,MAAM,KAAK;AAAA,KACR,QAAQ,MACX;QAEI,OAAO,MAAM;cACP,QAAQ,YAAY;WAEvB,UAAU,gBAAgB,KAAK,EACnC,KAAK,CAAC,QAAgB;YACf,QAAQ;gBACJ,QAAQ,YAAY;AAAA,KAC/B,EACA,MAAM,MAAM;YACL,QAAQ;gBACJ,QAAQ,YAAY;AAAA,KAC/B;AAAA;;QAIC,iBAAiB,IAAI;SAEpB;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,MAAM;WACT,SAAS;AAAA;IAEhB,UAAU,MAAM;WACT,SAAS;AAAA;IAEhB,WAAW,SAAS,MAAM,UAAU,UAAU,YAAY,OAAO;AAAA,IACjE,UAAU,SAAS,MAAM,UAAU,UAAU,YAAY,MAAM;AAAA,IAC/D,UAAU,SAAS,MAAM,UAAU,UAAU,YAAY,MAAM;AAAA,IAC/D,QAAQ,MAAM;;;IAGd,SAAS,MAAM;UACT,KAAK,UAAU,GAAG;;aAEf;aACA,QAAQ;AAAA;;;AAIrB;ACxEA,MAAM,YAAY,CAAC,KAAK,iBAA0B,CAAC,aAAa,CAAC,KAAK,SAAS;MACzE,QAAQ,QAAQ,QAAQ,QAAW;WAC9B;AAAA;QAGH,aAAa,mBAAmB,GAAG;QACnC,SAAS,eAAe,GAAG,gBAAgB,gBAAgB;MAE7D,CAAC,UAAU,QAAQ,EAAE,SAAS,OAAO,GAAG,GAAG;gBACjC,KAAK,GAAG,UAAU,mBAAmB,GAAG,GAAG;WAChD;AAAA;cAGG,KAAK,OAAO,QAAQ,GAAG,EAAE,OAAO,UAAU,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC;SAC1E;AACT;AAEA,oBAAe,CAAC,QAAgB,OAAO,QAAQ,GAAG,EAAE,OAAO,UAAa,GAAG,EAAE,EAAE,KAAK,GAAG;;;;;;;;;;;;;;;;;;UCyHjF,SAAkC,WAAW,EAAE;UAE/C,YAAY,OAAO,WAA6B;UAChD;UACA,OAAO,MAAM,WAAW,UAAU;cAC9B,WAAW,MAAM,MAAM,GAAG,MAAM,UAAU,cAAc,MAAM,GAAG;eAChE,MAAM,SAAS;aACjB;eACE,MAAM,MAAM,OAAO,MAAM;AAAA;aAG3B;AAAA;UAGH,eAAe,CAAC,QAAgB;UAChC,OAAO,MAAM,SAAS,OAAO;eACxB,QAAQ,GAAG,MAAM;iBACf,OAAO,MAAM,SAAS,QAAQ;eAChC,QAAQ;aACV;eACE,QAAQ,GAAG,MAAM;;;UAItB;AAAA,MACJ;AAAA,MAAM;AAAA,MAAW;AAAA,MAAU;AAAA,MAAU;AAAA,MAAU;AAAA,MAAQ;AAAA,MAAS,OAAO;AAAA,QACrE,cAAsC;AAAA,MACxC,gBAAgB,EAAE,UAAU,MAAM,SAAS,QAAQ,OAAO;MAC1D;AAAA,KACD;WAEY;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,KACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"vst.es.js","sources":["../src/ts/components/loading_row.vue","../src/ts/use/filterable.ts","../src/ts/components/slim_table.vue"],"sourcesContent":["<template>\n <tr>\n <td\n :colspan=\"columnsLength\"\n :class=\"['vst-loading-row', `vst-loading-row-${randNum}`]\">\n <div />\n </td>\n </tr>\n</template>\n\n<script lang=\"ts\" setup>\ndefineProps({\n columnsLength: { type: Number, required: true },\n})\n\nconst randNum = Math.floor(Math.random() * 10) + 1\n</script>\n","import {\n ref, computed, watch, Ref,\n} from 'vue'\n\ntype UseFiltetableArgs<T, S> = {\n initialFilters: Ref<T>\n loadItems: (_params: T & { page: number }) => Promise<S[]>\n}\n\nexport const SYNC_STATES = {\n INITIAL: 'INITIAL',\n SYNCING: 'SYNCING',\n SYNCED: 'SYNCED',\n FAILED: 'FAILED',\n} as const\n\ntype SynsState = (typeof SYNC_STATES)[keyof typeof SYNC_STATES]\n\nexport default <TFilters, TItem>({\n initialFilters,\n loadItems,\n}: UseFiltetableArgs<TFilters, TItem>) => {\n const page = ref(1)\n const items: Ref<TItem[]> = ref([])\n const syncState = ref<SynsState>(SYNC_STATES.INITIAL)\n\n const reload = async () => {\n syncState.value = SYNC_STATES.SYNCING\n\n try {\n items.value = await loadItems({\n ...initialFilters.value,\n page: page.value,\n })\n syncState.value = SYNC_STATES.SYNCED\n } catch {\n items.value = []\n syncState.value = SYNC_STATES.FAILED\n }\n }\n\n watch(initialFilters, reload)\n watch(page, reload)\n reload()\n\n return {\n page,\n items,\n syncState,\n isSyncing: computed(() => syncState.value === SYNC_STATES.SYNCING),\n isSynced: computed(() => syncState.value === SYNC_STATES.SYNCED),\n isFailed: computed(() => syncState.value === SYNC_STATES.FAILED),\n nextPage: () => {\n page.value += 1\n },\n prevPage: () => {\n page.value -= 1\n },\n setPage: (num: number) => {\n page.value = num\n },\n reload,\n refetch: () => {\n if (page.value === 1) {\n reload()\n } else {\n page.value = 1\n }\n },\n }\n}\n","<template>\n <table class=\"vst\">\n <thead v-if=\"columns.length\">\n <slot name=\"thead:before\" />\n <slot name=\"thead\" :columns=\"columns\" :orders=\"orders\">\n <tr>\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"['vst-th', { 'vst-orderable': column.orderable }]\"\n v-on=\"column.orderable ? { click: (event: Event) => onOrderClick(event, column.key) } : {}\">\n <div v-if=\"column.orderable\">\n <slot\n :name=\"`thead:${column.key}`\"\n :column=\"column\"\n :orders=\"orders\">\n {{ column.title }}\n </slot>\n\n <i :class=\"['vst-orderable-toggle', orders[column.key]]\" />\n </div>\n\n <slot\n v-else\n :name=\"`thead:${column.key}`\"\n :column=\"column\"\n :orders=\"orders\">\n {{ column.title }}\n </slot>\n </th>\n </tr>\n </slot>\n <slot name=\"thead:after\" />\n </thead>\n <tbody>\n <slot v-if=\"isSyncing\" name=\"row:loading\">\n <LoadingRow v-for=\"i in perPage\" :key=\"`loadingRow${i}`\" :columns-length=\"columns.length\" />\n </slot>\n\n <slot v-else-if=\"isSynced && rows.length === 0\" name=\"row:empty\">\n <tr>\n <td :colspan=\"columns.length\">\n No records found\n </td>\n </tr>\n </slot>\n\n <template v-else-if=\"isSynced && rows.length\">\n <slot\n v-for=\"(row, i) in rows\"\n name=\"row\"\n :row=\"row\"\n :index=\"i\"\n :columns=\"columns\">\n <tr :key=\"row['id'] || i\">\n <td v-for=\"column in columns\" :key=\"column.key\">\n <slot\n :name=\"`cell:${column.key}`\"\n :row=\"row\"\n :value=\"row[column.key]\"\n :column=\"column\"\n :index=\"i\">\n {{ row[column.key] }}\n </slot>\n </td>\n </tr>\n </slot>\n </template>\n </tbody>\n <tfoot>\n <tr>\n <td :colspan=\"columns.length\">\n <slot name=\"pagination\" :page=\"page\" :rows=\"rows\">\n <ul v-if=\"page > 1 || rows.length === perPage || isSyncing\" class=\"vst-pagination\">\n <li :class=\"['vst-page-item', { disabled: page === 1 || isSyncing }]\">\n <a class=\"vst-page-link\" @click.prevent=\"prevPage\">←</a>\n </li>\n\n <li :class=\"['vst-page-item', { disabled: rows.length < perPage || isSyncing }]\">\n <a class=\"vst-page-link\" @click.prevent=\"nextPage\">→</a>\n </li>\n </ul>\n </slot>\n </td>\n </tr>\n </tfoot>\n </table>\n</template>\n\n<script setup lang=\"ts\" generic=\"TRow extends TableRow\">\nimport { ref, shallowRef } from 'vue'\nimport LoadingRow from './loading_row.vue'\n\nimport useFilterable from '../use/filterable'\n\nimport type {\n TableOrders, TableFetchParams, TableRow, TableFilters, TableProps, TableSlots,\n} from '@/ts/types'\n\nconst orders = shallowRef<TableOrders>({})\nconst props = withDefaults(defineProps<TableProps<TRow>>(), {\n perPage: 25,\n})\n\nconst loadItems = async (params: TableFetchParams) => {\n let data: TRow[] = []\n\n try {\n data = await props.source(params)\n } catch {\n // TODO: show errors\n }\n\n return data\n}\n\nconst onOrderClick = (event: Event, key: string) => {\n event.preventDefault()\n\n if (orders.value[key] === 'asc') {\n orders.value = { [key]: 'desc' }\n } else if (orders.value[key] === 'desc') {\n orders.value = {}\n } else {\n orders.value = { [key]: 'asc' }\n }\n}\n\nconst initialFilters = ref<TableFilters>({\n per_page: props.perPage,\n orders,\n})\n\nconst {\n page, isSyncing, isSynced, prevPage, nextPage, reload, refetch, items: rows,\n} = useFilterable<TableFilters, TRow>({\n initialFilters,\n loadItems,\n})\n\ndefineSlots<TableSlots<TRow>>()\n\ndefineExpose({\n refetch,\n reload,\n rows,\n})\n</script>\n"],"names":["randNum","SYNC_STATES","useFilterable","initialFilters","loadItems","page","ref","items","syncState","reload","watch","computed","num","orders","shallowRef","params","data","props","onOrderClick","event","key","isSyncing","isSynced","prevPage","nextPage","refetch","rows","__expose"],"mappings":";;;;;;;;;AAeA,UAAMA,IAAU,KAAK,MAAM,KAAK,WAAW,EAAE,IAAI;;;;;;;;ICNpCC,IAAc;AAAA,EACzB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AACV,GAIAC,IAAe,CAAkB;AAAA,EAC/B,gBAAAC;AAAA,EACA,WAAAC;AACF,MAA0C;AAClC,QAAAC,IAAOC,EAAI,CAAC,GACZC,IAAsBD,EAAI,CAAA,CAAE,GAC5BE,IAAYF,EAAeL,EAAY,OAAO,GAE9CQ,IAAS,YAAY;AACzB,IAAAD,EAAU,QAAQP,EAAY;AAE1B,QAAA;AACI,MAAAM,EAAA,QAAQ,MAAMH,EAAU;AAAA,QAC5B,GAAGD,EAAe;AAAA,QAClB,MAAME,EAAK;AAAA,MAAA,CACZ,GACDG,EAAU,QAAQP,EAAY;AAAA,IAAA,QACxB;AACN,MAAAM,EAAM,QAAQ,IACdC,EAAU,QAAQP,EAAY;AAAA,IAChC;AAAA,EAAA;AAGF,SAAAS,EAAMP,GAAgBM,CAAM,GAC5BC,EAAML,GAAMI,CAAM,GACXA,KAEA;AAAA,IACL,MAAAJ;AAAA,IACA,OAAAE;AAAA,IACA,WAAAC;AAAA,IACA,WAAWG,EAAS,MAAMH,EAAU,UAAUP,EAAY,OAAO;AAAA,IACjE,UAAUU,EAAS,MAAMH,EAAU,UAAUP,EAAY,MAAM;AAAA,IAC/D,UAAUU,EAAS,MAAMH,EAAU,UAAUP,EAAY,MAAM;AAAA,IAC/D,UAAU,MAAM;AACd,MAAAI,EAAK,SAAS;AAAA,IAChB;AAAA,IACA,UAAU,MAAM;AACd,MAAAA,EAAK,SAAS;AAAA,IAChB;AAAA,IACA,SAAS,CAACO,MAAgB;AACxB,MAAAP,EAAK,QAAQO;AAAA,IACf;AAAA,IACA,QAAAH;AAAA,IACA,SAAS,MAAM;AACT,MAAAJ,EAAK,UAAU,IACVI,MAEPJ,EAAK,QAAQ;AAAA,IAEjB;AAAA,EAAA;AAEJ;;;;;;;;;;;iBC6BMQ,IAASC,EAAwB,CAAA,CAAE,GAKnCV,IAAY,OAAOW,MAA6B;AACpD,UAAIC,IAAe,CAAA;AAEf,UAAA;AACK,QAAAA,IAAA,MAAMC,EAAM,OAAOF,CAAM;AAAA,MAAA,QAC1B;AAAA,MAER;AAEO,aAAAC;AAAA,IAAA,GAGHE,IAAe,CAACC,GAAcC,MAAgB;AAClD,MAAAD,EAAM,eAAe,GAEjBN,EAAO,MAAMO,CAAG,MAAM,QACxBP,EAAO,QAAQ,EAAE,CAACO,CAAG,GAAG,OAAO,IACtBP,EAAO,MAAMO,CAAG,MAAM,SAC/BP,EAAO,QAAQ,KAEfA,EAAO,QAAQ,EAAE,CAACO,CAAG,GAAG,MAAM;AAAA,IAChC,GAGIjB,IAAiBG,EAAkB;AAAA,MACvC,UAAUW,EAAM;AAAA,MAChB,QAAAJ;AAAA,IAAA,CACD,GAEK;AAAA,MACJ,MAAAR;AAAA,MAAM,WAAAgB;AAAA,MAAW,UAAAC;AAAA,MAAU,UAAAC;AAAA,MAAU,UAAAC;AAAA,MAAU,QAAAf;AAAA,MAAQ,SAAAgB;AAAA,MAAS,OAAOC;AAAA,QACrExB,EAAkC;AAAA,MACpC,gBAAAC;AAAA,MACA,WAAAC;AAAA,IAAA,CACD;AAIY,WAAAuB,EAAA;AAAA,MACX,SAAAF;AAAA,MACA,QAAAhB;AAAA,MACA,MAAAiB;AAAA,IAAA,CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/vst.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(e,s){typeof exports=="object"&&typeof module!="undefined"?module.exports=s(require("vue")):typeof define=="function"&&define.amd?define(["vue"],s):(e=typeof globalThis!="undefined"?globalThis:e||self,e.VueSlimTable=s(e.Vue))})(this,function(e){"use strict";var z=Object.defineProperty;var $=Object.getOwnPropertySymbols;var M=Object.prototype.hasOwnProperty,R=Object.prototype.propertyIsEnumerable;var V=(e,s,c)=>s in e?z(e,s,{enumerable:!0,configurable:!0,writable:!0,value:c}):e[s]=c,C=(e,s)=>{for(var c in s||(s={}))M.call(s,c)&&V(e,c,s[c]);if($)for(var c of $(s))R.call(s,c)&&V(e,c,s[c]);return e};var s="";const c=["colspan"],b=[e.createElementVNode("div",null,null,-1)],u=e.defineComponent({props:{columnsLength:{type:Number,required:!0}},setup(n){const m=Math.floor(Math.random()*10)+1;return(l,a)=>(e.openBlock(),e.createElementBlock("tr",null,[e.createElementVNode("td",{colspan:n.columnsLength,class:e.normalizeClass(["vst-loading-row",`vst-loading-row-${m}`])},b,10,c)]))}}),g={INITIAL:"initial",SYNCING:"syncing",SYNCED:"synced",FAILED:"failed"},I=({initialFilters:n,loadItems:m})=>{const l=e.ref(1),a=e.reactive({value:[]}),o=e.ref(g.INITIAL),p=e.reactive({value:n}),i=e.computed(()=>C({page:l.value},p.value)),d=()=>(o.value=g.SYNCING,m(i.value).then(N=>{a.value=N,o.value=g.SYNCED}).catch(()=>{a.value=[],o.value=g.FAILED}));return d(),e.watch(i,d),{page:l,items:a,syncState:o,nextPage:()=>{l.value+=1},prevPage:()=>{l.value-=1},isSyncing:e.computed(()=>o.value===g.SYNCING),isSynced:e.computed(()=>o.value===g.SYNCED),isFailed:e.computed(()=>o.value===g.FAILED),reload:()=>{d()},refetch:()=>{l.value===1?d():l.value=1}}},E=(n,m)=>(l,[a,o])=>{if(o==null)return l;const p=encodeURIComponent(a),i=m?`${m}[${p}]`:p;return["number","string"].includes(typeof o)?(l.push(`${i}=${encodeURIComponent(o)}`),l):(l.push(Object.entries(o).reduce(E(o,i),[]).join("&")),l)};var w=n=>Object.entries(n).reduce(E(),[]).join("&");const F={class:"vst"},L={key:0},T={key:0},D=["colspan"],P=["colspan"],j={key:0,class:"vst-pagination mt-3"};return e.defineComponent({props:{columns:null,source:null,perPage:{default:25}},setup(n,{expose:m}){const l=n,a=e.shallowRef({}),o=async r=>{let f;return typeof l.source=="string"?f=await(await fetch(`${l.source}?${w(r)}`)).json():f=await l.source(r),f},p=r=>{a.value[r]==="asc"?a.value={[r]:"desc"}:a.value[r]==="desc"?a.value={}:a.value={[r]:"asc"}},{page:i,isSyncing:d,isSynced:N,prevPage:S,nextPage:B,reload:Y,refetch:x,items:k}=I({initialFilters:{per_page:l.perPage,orders:a.value},loadItems:o});return m({refetch:x,reload:Y,rows:k}),(r,f)=>(e.openBlock(),e.createElementBlock("table",F,[n.columns.length?(e.openBlock(),e.createElementBlock("thead",L,[e.renderSlot(r.$slots,"thead",{columns:n.columns,orders:e.unref(a)},()=>[e.createElementVNode("tr",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.columns,t=>(e.openBlock(),e.createElementBlock("th",e.mergeProps({key:t.key,class:["vst-th",{"vst-orderable":t.orderable}]},e.toHandlers(t.orderable?{click:()=>p(t.key)}:{})),[t.orderable?(e.openBlock(),e.createElementBlock("div",T,[e.renderSlot(r.$slots,`head:${t.key}`,{column:t},()=>[e.createTextVNode(e.toDisplayString(t.title),1)]),e.createElementVNode("a",{href:"#",class:e.normalizeClass(["vst-orderable-toggle",e.unref(a)[t.key]])},null,2)])):e.renderSlot(r.$slots,`thead:${t.key}`,{key:1,column:t},()=>[e.createTextVNode(e.toDisplayString(t.title),1)])],16))),128))])])])):e.createCommentVNode("",!0),e.createElementVNode("tbody",null,[e.unref(d)?e.renderSlot(r.$slots,"row:loading",{key:0},()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.perPage,t=>(e.openBlock(),e.createBlock(u,{key:`loadingRow${t}`,"columns-length":n.columns.length},null,8,["columns-length"]))),128))]):e.unref(N)&&e.unref(k).value.length===0?e.renderSlot(r.$slots,"row:empty",{key:1},()=>[e.createElementVNode("tr",null,[e.createElementVNode("td",{colspan:n.columns.length}," No records found ",8,D)])]):e.unref(N)&&e.unref(k).value.length?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:2},e.renderList(e.unref(k).value,(t,y)=>e.renderSlot(r.$slots,"row",{row:t,index:y,columns:n.columns},()=>[(e.openBlock(),e.createElementBlock("tr",{key:t.id||y},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.columns,h=>(e.openBlock(),e.createElementBlock("td",{key:h.key},[e.renderSlot(r.$slots,`cell:${h.key}`,{row:t,value:t[h.key],column:h,index:y},()=>[e.createTextVNode(e.toDisplayString(t[h.key]),1)])]))),128))]))])),256)):e.createCommentVNode("",!0)]),e.createElementVNode("tfoot",null,[e.createElementVNode("tr",null,[e.createElementVNode("td",{colspan:n.columns.length},[e.renderSlot(r.$slots,"pagination",{page:e.unref(i),rows:e.unref(k).value},()=>[e.unref(i)>1||e.unref(k).value.length===n.perPage||e.unref(d)?(e.openBlock(),e.createElementBlock("ul",j,[e.createElementVNode("li",{class:e.normalizeClass(["vst-page-item",{disabled:e.unref(i)===1||e.unref(d)}])},[e.createElementVNode("a",{class:"vst-page-link",onClick:f[0]||(f[0]=e.withModifiers((...t)=>e.unref(S)&&e.unref(S)(...t),["prevent"]))},"\u2190")],2),e.createElementVNode("li",{class:e.normalizeClass(["vst-page-item",{disabled:e.unref(k).value.length<n.perPage||e.unref(d)}])},[e.createElementVNode("a",{class:"vst-page-link",onClick:f[1]||(f[1]=e.withModifiers((...t)=>e.unref(B)&&e.unref(B)(...t),["prevent"]))},"\u2192")],2)])):e.createCommentVNode("",!0)])],8,P)])])]))}})});
1
+ (function(e,g){typeof exports=="object"&&typeof module<"u"?module.exports=g(require("vue")):typeof define=="function"&&define.amd?define(["vue"],g):(e=typeof globalThis<"u"?globalThis:e||self,e.VueSlimTable=g(e.Vue))})(this,function(e){"use strict";const g="",B=["colspan"],V=[e.createElementVNode("div",null,null,-1)],C=e.defineComponent({__name:"loading_row",props:{columnsLength:{type:Number,required:!0}},setup(i){const p=Math.floor(Math.random()*10)+1;return(r,l)=>(e.openBlock(),e.createElementBlock("tr",null,[e.createElementVNode("td",{colspan:i.columnsLength,class:e.normalizeClass(["vst-loading-row",`vst-loading-row-${p}`])},V,10,B)]))}}),a={INITIAL:"INITIAL",SYNCING:"SYNCING",SYNCED:"SYNCED",FAILED:"FAILED"},$=({initialFilters:i,loadItems:p})=>{const r=e.ref(1),l=e.ref([]),s=e.ref(a.INITIAL),c=async()=>{s.value=a.SYNCING;try{l.value=await p({...i.value,page:r.value}),s.value=a.SYNCED}catch{l.value=[],s.value=a.FAILED}};return e.watch(i,c),e.watch(r,c),c(),{page:r,items:l,syncState:s,isSyncing:e.computed(()=>s.value===a.SYNCING),isSynced:e.computed(()=>s.value===a.SYNCED),isFailed:e.computed(()=>s.value===a.FAILED),nextPage:()=>{r.value+=1},prevPage:()=>{r.value-=1},setPage:h=>{r.value=h},reload:c,refetch:()=>{r.value===1?c():r.value=1}}},I={class:"vst"},b={key:0},L={key:0},_=["colspan"],w=["colspan"],D={key:0,class:"vst-pagination"};return e.defineComponent({__name:"slim_table",props:{columns:{},perPage:{default:25},source:{}},setup(i,{expose:p}){const r=i,l=e.shallowRef({}),s=async t=>{let o=[];try{o=await r.source(t)}catch{}return o},c=(t,o)=>{t.preventDefault(),l.value[o]==="asc"?l.value={[o]:"desc"}:l.value[o]==="desc"?l.value={}:l.value={[o]:"asc"}},h=e.ref({per_page:r.perPage,orders:l}),{page:N,isSyncing:k,isSynced:E,prevPage:y,nextPage:S,reload:P,refetch:T,items:d}=$({initialFilters:h,loadItems:s});return p({refetch:T,reload:P,rows:d}),(t,o)=>(e.openBlock(),e.createElementBlock("table",I,[t.columns.length?(e.openBlock(),e.createElementBlock("thead",b,[e.renderSlot(t.$slots,"thead:before"),e.renderSlot(t.$slots,"thead",{columns:t.columns,orders:l.value},()=>[e.createElementVNode("tr",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.columns,n=>(e.openBlock(),e.createElementBlock("th",e.mergeProps({key:n.key,class:["vst-th",{"vst-orderable":n.orderable}]},e.toHandlers(n.orderable?{click:m=>c(m,n.key)}:{},!0)),[n.orderable?(e.openBlock(),e.createElementBlock("div",L,[e.renderSlot(t.$slots,`thead:${n.key}`,{column:n,orders:l.value},()=>[e.createTextVNode(e.toDisplayString(n.title),1)]),e.createElementVNode("i",{class:e.normalizeClass(["vst-orderable-toggle",l.value[n.key]])},null,2)])):e.renderSlot(t.$slots,`thead:${n.key}`,{key:1,column:n,orders:l.value},()=>[e.createTextVNode(e.toDisplayString(n.title),1)])],16))),128))])]),e.renderSlot(t.$slots,"thead:after")])):e.createCommentVNode("",!0),e.createElementVNode("tbody",null,[e.unref(k)?e.renderSlot(t.$slots,"row:loading",{key:0},()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.perPage,n=>(e.openBlock(),e.createBlock(C,{key:`loadingRow${n}`,"columns-length":t.columns.length},null,8,["columns-length"]))),128))]):e.unref(E)&&e.unref(d).length===0?e.renderSlot(t.$slots,"row:empty",{key:1},()=>[e.createElementVNode("tr",null,[e.createElementVNode("td",{colspan:t.columns.length}," No records found ",8,_)])]):e.unref(E)&&e.unref(d).length?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:2},e.renderList(e.unref(d),(n,m)=>e.renderSlot(t.$slots,"row",{row:n,index:m,columns:t.columns},()=>[(e.openBlock(),e.createElementBlock("tr",{key:n.id||m},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.columns,f=>(e.openBlock(),e.createElementBlock("td",{key:f.key},[e.renderSlot(t.$slots,`cell:${f.key}`,{row:n,value:n[f.key],column:f,index:m},()=>[e.createTextVNode(e.toDisplayString(n[f.key]),1)])]))),128))]))])),256)):e.createCommentVNode("",!0)]),e.createElementVNode("tfoot",null,[e.createElementVNode("tr",null,[e.createElementVNode("td",{colspan:t.columns.length},[e.renderSlot(t.$slots,"pagination",{page:e.unref(N),rows:e.unref(d)},()=>[e.unref(N)>1||e.unref(d).length===t.perPage||e.unref(k)?(e.openBlock(),e.createElementBlock("ul",D,[e.createElementVNode("li",{class:e.normalizeClass(["vst-page-item",{disabled:e.unref(N)===1||e.unref(k)}])},[e.createElementVNode("a",{class:"vst-page-link",onClick:o[0]||(o[0]=e.withModifiers((...n)=>e.unref(y)&&e.unref(y)(...n),["prevent"]))},"")],2),e.createElementVNode("li",{class:e.normalizeClass(["vst-page-item",{disabled:e.unref(d).length<t.perPage||e.unref(k)}])},[e.createElementVNode("a",{class:"vst-page-link",onClick:o[1]||(o[1]=e.withModifiers((...n)=>e.unref(S)&&e.unref(S)(...n),["prevent"]))},"")],2)])):e.createCommentVNode("",!0)])],8,w)])])]))}})});
2
2
  //# sourceMappingURL=vst.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vst.umd.js","sources":["../src/ts/components/loading_row.vue","../src/ts/use/filterable.ts","../src/ts/helpers/to_query_string.ts","../src/ts/components/table.vue"],"sourcesContent":["<template>\n <tr>\n <td\n :colspan=\"columnsLength\"\n :class=\"['vst-loading-row', `vst-loading-row-${randNum}`]\">\n <div />\n </td>\n </tr>\n</template>\n\n<script lang=\"ts\" setup>\ndefineProps({\n columnsLength: { type: Number, required: true },\n})\n\nconst randNum = Math.floor(Math.random() * 10) + 1\n</script>\n","import {\n ref, computed, reactive, watch,\n} from 'vue'\n\ntype CombinedFilters<Filters> = Filters & {\n page: number\n}\n\ninterface UseFiltetableArgs<Filters, Item> {\n initialFilters: Filters,\n loadItems: (_filters: CombinedFilters<Filters>) => Promise<Item[]>\n}\n\nconst SYNC_STATES = {\n INITIAL: 'initial',\n SYNCING: 'syncing',\n SYNCED: 'synced',\n FAILED: 'failed',\n}\n\nconst useFilterable = <Filters, Item>({ initialFilters, loadItems }: UseFiltetableArgs<Filters, Item>) => {\n const page = ref(1)\n const items = reactive({ value: [] as Item[] }) as { value: Item[] }\n const syncState = ref(SYNC_STATES.INITIAL)\n const filters = reactive({ value: initialFilters })\n\n const combinedFilters = computed(() => ({\n page: page.value,\n ...filters.value as Filters,\n }))\n\n const load = () => {\n syncState.value = SYNC_STATES.SYNCING\n\n return loadItems(combinedFilters.value)\n .then((res: Item[]) => {\n items.value = res\n syncState.value = SYNC_STATES.SYNCED\n })\n .catch(() => {\n items.value = []\n syncState.value = SYNC_STATES.FAILED\n })\n }\n load()\n\n watch(combinedFilters, load)\n\n return {\n page,\n items,\n syncState,\n nextPage: () => {\n page.value += 1\n },\n prevPage: () => {\n page.value -= 1\n },\n isSyncing: computed(() => syncState.value === SYNC_STATES.SYNCING),\n isSynced: computed(() => syncState.value === SYNC_STATES.SYNCED),\n isFailed: computed(() => syncState.value === SYNC_STATES.FAILED),\n reload: () => {\n load()\n },\n refetch: () => {\n if (page.value === 1) {\n load()\n } else {\n page.value = 1\n }\n },\n }\n}\n\nexport default useFilterable\n","const stringify = (obj, parentPrefix?: string) => (outputArray, [key, val]) => {\n if (val === null || val === undefined) {\n return outputArray\n }\n\n const encodedKey = encodeURIComponent(key)\n const prefix = parentPrefix ? `${parentPrefix}[${encodedKey}]` : encodedKey\n\n if (['number', 'string'].includes(typeof val)) {\n outputArray.push(`${prefix}=${encodeURIComponent(val)}`)\n return outputArray\n }\n\n outputArray.push(Object.entries(val).reduce(stringify(val, prefix), []).join('&'))\n return outputArray\n}\n\nexport default (obj): string => Object.entries(obj).reduce(stringify(obj), []).join('&')\n","<template>\n <table class=\"vst\">\n <thead v-if=\"columns.length\">\n <slot name=\"thead\" :columns=\"columns\" :orders=\"orders\">\n <tr>\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"['vst-th', { 'vst-orderable': column.orderable }]\"\n v-on=\"column.orderable ? { click: () => onOrderClick(column.key) } : {}\">\n <div v-if=\"column.orderable\">\n <slot\n :name=\"`head:${column.key}`\"\n :column=\"column\">\n {{ column.title }}\n </slot>\n\n <a href=\"#\" :class=\"['vst-orderable-toggle', orders[column.key]]\" />\n </div>\n\n <slot\n v-else\n :name=\"`thead:${column.key}`\"\n :column=\"column\">\n {{ column.title }}\n </slot>\n </th>\n </tr>\n </slot>\n </thead>\n <tbody>\n <slot v-if=\"isSyncing\" name=\"row:loading\">\n <LoadingRow\n v-for=\"i in perPage\"\n :key=\"`loadingRow${i}`\"\n :columns-length=\"columns.length\" />\n </slot>\n\n <slot v-else-if=\"isSynced && rows.value.length === 0\" name=\"row:empty\">\n <tr>\n <td :colspan=\"columns.length\">\n No records found\n </td>\n </tr>\n </slot>\n\n <template v-else-if=\"isSynced && rows.value.length\">\n <slot\n v-for=\"(row, i) in rows.value\"\n name=\"row\"\n :row=\"row\"\n :index=\"i\"\n :columns=\"columns\">\n <tr :key=\"row['id'] || i\">\n <td\n v-for=\"column in columns\"\n :key=\"column.key\">\n <slot\n :name=\"`cell:${column.key}`\"\n :row=\"row\"\n :value=\"row[column.key]\"\n :column=\"column\"\n :index=\"i\">\n {{ row[column.key] }}\n </slot>\n </td>\n </tr>\n </slot>\n </template>\n </tbody>\n <tfoot>\n <tr>\n <td :colspan=\"columns.length\">\n <slot name=\"pagination\" :page=\"page\" :rows=\"rows.value\">\n <ul\n v-if=\"page > 1 || rows.value.length === perPage || isSyncing\"\n class=\"vst-pagination mt-3\">\n <li :class=\"['vst-page-item', { disabled: page === 1 || isSyncing }]\">\n <a class=\"vst-page-link\" @click.prevent=\"prevPage\">←</a>\n </li>\n\n <li\n :class=\"['vst-page-item', {\n disabled: rows.value.length < perPage || isSyncing\n }]\">\n <a class=\"vst-page-link\" @click.prevent=\"nextPage\">→</a>\n </li>\n </ul>\n </slot>\n </td>\n </tr>\n </tfoot>\n </table>\n</template>\n\n<script setup lang=\"ts\">\nimport { shallowRef, ShallowRef } from 'vue'\nimport LoadingRow from './loading_row.vue'\n\nimport useFilterable from '../use/filterable'\nimport toQueryString from '../helpers/to_query_string'\n\ninterface TableColumn {\n key: string,\n title: string,\n orderable?: boolean\n}\n\ninterface TableOrders {\n [key: string]: 'asc' | 'desc'\n}\n\ninterface TableFetchParams {\n per_page: number,\n page: number,\n orders?: TableOrders\n}\n\ninterface TableRow {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\ninterface TableFilters {\n per_page: number,\n orders: TableOrders\n}\n\ninterface TableProps {\n columns: Array<TableColumn>\n source: string | ((_: TableFetchParams) => Promise<TableRow[]> | TableRow[])\n perPage?: number\n}\n\nconst props = withDefaults(defineProps<TableProps>(), {\n perPage: 25,\n})\n\nconst orders: ShallowRef<TableOrders> = shallowRef({})\n\nconst loadItems = async (params: TableFetchParams) => {\n let data: TableRow[]\n if (typeof props.source === 'string') {\n const response = await fetch(`${props.source}?${toQueryString(params)}`)\n data = await response.json()\n } else {\n data = await props.source(params) as TableRow[]\n }\n\n return data\n}\n\nconst onOrderClick = (key: string) => {\n if (orders.value[key] === 'asc') {\n orders.value = { [key]: 'desc' }\n } else if (orders.value[key] === 'desc') {\n orders.value = {}\n } else {\n orders.value = { [key]: 'asc' }\n }\n}\n\nconst {\n page, isSyncing, isSynced, prevPage, nextPage, reload, refetch, items: rows,\n} = useFilterable<TableFilters, TableRow>({\n initialFilters: { per_page: props.perPage, orders: orders.value },\n loadItems,\n})\n\ndefineExpose({\n refetch,\n reload,\n rows,\n})\n</script>\n"],"names":["ref","reactive","computed","shallowRef"],"mappings":"iwBAeM,GAAU,KAAK,MAAM,KAAK,SAAW,EAAE,EAAI,mMCF3C,EAAc,CAClB,QAAS,UACT,QAAS,UACT,OAAQ,SACR,OAAQ,QACV,EAEM,EAAgB,CAAgB,CAAE,iBAAgB,eAAkD,MAClG,GAAOA,MAAI,CAAC,EACZ,EAAQC,WAAS,CAAE,MAAO,GAAc,EACxC,EAAYD,MAAI,EAAY,OAAO,EACnC,EAAUC,WAAS,CAAE,MAAO,EAAgB,EAE5C,EAAkBC,WAAS,OAC/B,KAAM,EAAK,OACR,EAAQ,MACX,EAEI,EAAO,OACD,MAAQ,EAAY,QAEvB,EAAU,EAAgB,KAAK,EACnC,KAAK,AAAC,GAAgB,GACf,MAAQ,IACJ,MAAQ,EAAY,OAC/B,EACA,MAAM,IAAM,GACL,MAAQ,KACJ,MAAQ,EAAY,OAC/B,sBAIC,EAAiB,CAAI,EAEpB,CACL,OACA,QACA,YACA,SAAU,IAAM,GACT,OAAS,GAEhB,SAAU,IAAM,GACT,OAAS,GAEhB,UAAWA,WAAS,IAAM,EAAU,QAAU,EAAY,OAAO,EACjE,SAAUA,WAAS,IAAM,EAAU,QAAU,EAAY,MAAM,EAC/D,SAAUA,WAAS,IAAM,EAAU,QAAU,EAAY,MAAM,EAC/D,OAAQ,IAAM,MAGd,QAAS,IAAM,CACT,EAAK,QAAU,QAGZ,MAAQ,GAIrB,ECxEM,EAAY,CAAC,EAAK,IAA0B,CAAC,EAAa,CAAC,EAAK,KAAS,IACzE,GAAQ,WACH,QAGH,GAAa,mBAAmB,CAAG,EACnC,EAAS,EAAe,GAAG,KAAgB,KAAgB,QAE7D,CAAC,SAAU,QAAQ,EAAE,SAAS,MAAO,EAAG,KAC9B,KAAK,GAAG,KAAU,mBAAmB,CAAG,GAAG,EAChD,MAGG,KAAK,OAAO,QAAQ,CAAG,EAAE,OAAO,EAAU,EAAK,CAAM,EAAG,EAAE,EAAE,KAAK,GAAG,CAAC,EAC1E,EACT,QAEe,AAAC,GAAgB,OAAO,QAAQ,CAAG,EAAE,OAAO,EAAa,EAAG,EAAE,EAAE,KAAK,GAAG,4NCyHjF,EAAkCC,aAAW,EAAE,EAE/C,EAAY,KAAO,IAA6B,IAChD,SACA,OAAO,GAAM,QAAW,WAEnB,KAAM,AADI,MAAM,OAAM,GAAG,EAAM,UAAU,EAAc,CAAM,GAAG,GACjD,SAEf,KAAM,GAAM,OAAO,CAAM,EAG3B,GAGH,EAAe,AAAC,GAAgB,CAChC,EAAO,MAAM,KAAS,QACjB,MAAQ,EAAG,GAAM,QACf,EAAO,MAAM,KAAS,SACxB,MAAQ,KAER,MAAQ,EAAG,GAAM,QAItB,CACJ,OAAM,YAAW,WAAU,WAAU,WAAU,SAAQ,UAAS,MAAO,GACrE,EAAsC,CACxC,eAAgB,CAAE,SAAU,EAAM,QAAS,OAAQ,EAAO,OAC1D,YACD,WAEY,CACX,UACA,SACA,OACD"}
1
+ {"version":3,"file":"vst.umd.js","sources":["../src/ts/components/loading_row.vue","../src/ts/use/filterable.ts","../src/ts/components/slim_table.vue"],"sourcesContent":["<template>\n <tr>\n <td\n :colspan=\"columnsLength\"\n :class=\"['vst-loading-row', `vst-loading-row-${randNum}`]\">\n <div />\n </td>\n </tr>\n</template>\n\n<script lang=\"ts\" setup>\ndefineProps({\n columnsLength: { type: Number, required: true },\n})\n\nconst randNum = Math.floor(Math.random() * 10) + 1\n</script>\n","import {\n ref, computed, watch, Ref,\n} from 'vue'\n\ntype UseFiltetableArgs<T, S> = {\n initialFilters: Ref<T>\n loadItems: (_params: T & { page: number }) => Promise<S[]>\n}\n\nexport const SYNC_STATES = {\n INITIAL: 'INITIAL',\n SYNCING: 'SYNCING',\n SYNCED: 'SYNCED',\n FAILED: 'FAILED',\n} as const\n\ntype SynsState = (typeof SYNC_STATES)[keyof typeof SYNC_STATES]\n\nexport default <TFilters, TItem>({\n initialFilters,\n loadItems,\n}: UseFiltetableArgs<TFilters, TItem>) => {\n const page = ref(1)\n const items: Ref<TItem[]> = ref([])\n const syncState = ref<SynsState>(SYNC_STATES.INITIAL)\n\n const reload = async () => {\n syncState.value = SYNC_STATES.SYNCING\n\n try {\n items.value = await loadItems({\n ...initialFilters.value,\n page: page.value,\n })\n syncState.value = SYNC_STATES.SYNCED\n } catch {\n items.value = []\n syncState.value = SYNC_STATES.FAILED\n }\n }\n\n watch(initialFilters, reload)\n watch(page, reload)\n reload()\n\n return {\n page,\n items,\n syncState,\n isSyncing: computed(() => syncState.value === SYNC_STATES.SYNCING),\n isSynced: computed(() => syncState.value === SYNC_STATES.SYNCED),\n isFailed: computed(() => syncState.value === SYNC_STATES.FAILED),\n nextPage: () => {\n page.value += 1\n },\n prevPage: () => {\n page.value -= 1\n },\n setPage: (num: number) => {\n page.value = num\n },\n reload,\n refetch: () => {\n if (page.value === 1) {\n reload()\n } else {\n page.value = 1\n }\n },\n }\n}\n","<template>\n <table class=\"vst\">\n <thead v-if=\"columns.length\">\n <slot name=\"thead:before\" />\n <slot name=\"thead\" :columns=\"columns\" :orders=\"orders\">\n <tr>\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"['vst-th', { 'vst-orderable': column.orderable }]\"\n v-on=\"column.orderable ? { click: (event: Event) => onOrderClick(event, column.key) } : {}\">\n <div v-if=\"column.orderable\">\n <slot\n :name=\"`thead:${column.key}`\"\n :column=\"column\"\n :orders=\"orders\">\n {{ column.title }}\n </slot>\n\n <i :class=\"['vst-orderable-toggle', orders[column.key]]\" />\n </div>\n\n <slot\n v-else\n :name=\"`thead:${column.key}`\"\n :column=\"column\"\n :orders=\"orders\">\n {{ column.title }}\n </slot>\n </th>\n </tr>\n </slot>\n <slot name=\"thead:after\" />\n </thead>\n <tbody>\n <slot v-if=\"isSyncing\" name=\"row:loading\">\n <LoadingRow v-for=\"i in perPage\" :key=\"`loadingRow${i}`\" :columns-length=\"columns.length\" />\n </slot>\n\n <slot v-else-if=\"isSynced && rows.length === 0\" name=\"row:empty\">\n <tr>\n <td :colspan=\"columns.length\">\n No records found\n </td>\n </tr>\n </slot>\n\n <template v-else-if=\"isSynced && rows.length\">\n <slot\n v-for=\"(row, i) in rows\"\n name=\"row\"\n :row=\"row\"\n :index=\"i\"\n :columns=\"columns\">\n <tr :key=\"row['id'] || i\">\n <td v-for=\"column in columns\" :key=\"column.key\">\n <slot\n :name=\"`cell:${column.key}`\"\n :row=\"row\"\n :value=\"row[column.key]\"\n :column=\"column\"\n :index=\"i\">\n {{ row[column.key] }}\n </slot>\n </td>\n </tr>\n </slot>\n </template>\n </tbody>\n <tfoot>\n <tr>\n <td :colspan=\"columns.length\">\n <slot name=\"pagination\" :page=\"page\" :rows=\"rows\">\n <ul v-if=\"page > 1 || rows.length === perPage || isSyncing\" class=\"vst-pagination\">\n <li :class=\"['vst-page-item', { disabled: page === 1 || isSyncing }]\">\n <a class=\"vst-page-link\" @click.prevent=\"prevPage\">←</a>\n </li>\n\n <li :class=\"['vst-page-item', { disabled: rows.length < perPage || isSyncing }]\">\n <a class=\"vst-page-link\" @click.prevent=\"nextPage\">→</a>\n </li>\n </ul>\n </slot>\n </td>\n </tr>\n </tfoot>\n </table>\n</template>\n\n<script setup lang=\"ts\" generic=\"TRow extends TableRow\">\nimport { ref, shallowRef } from 'vue'\nimport LoadingRow from './loading_row.vue'\n\nimport useFilterable from '../use/filterable'\n\nimport type {\n TableOrders, TableFetchParams, TableRow, TableFilters, TableProps, TableSlots,\n} from '@/ts/types'\n\nconst orders = shallowRef<TableOrders>({})\nconst props = withDefaults(defineProps<TableProps<TRow>>(), {\n perPage: 25,\n})\n\nconst loadItems = async (params: TableFetchParams) => {\n let data: TRow[] = []\n\n try {\n data = await props.source(params)\n } catch {\n // TODO: show errors\n }\n\n return data\n}\n\nconst onOrderClick = (event: Event, key: string) => {\n event.preventDefault()\n\n if (orders.value[key] === 'asc') {\n orders.value = { [key]: 'desc' }\n } else if (orders.value[key] === 'desc') {\n orders.value = {}\n } else {\n orders.value = { [key]: 'asc' }\n }\n}\n\nconst initialFilters = ref<TableFilters>({\n per_page: props.perPage,\n orders,\n})\n\nconst {\n page, isSyncing, isSynced, prevPage, nextPage, reload, refetch, items: rows,\n} = useFilterable<TableFilters, TRow>({\n initialFilters,\n loadItems,\n})\n\ndefineSlots<TableSlots<TRow>>()\n\ndefineExpose({\n refetch,\n reload,\n rows,\n})\n</script>\n"],"names":["randNum","SYNC_STATES","useFilterable","initialFilters","loadItems","page","ref","items","syncState","reload","watch","computed","num","orders","shallowRef","params","data","props","onOrderClick","event","key","isSyncing","isSynced","prevPage","nextPage","refetch","rows","__expose"],"mappings":"kaAeA,MAAMA,EAAU,KAAK,MAAM,KAAK,SAAW,EAAE,EAAI,mMCNpCC,EAAc,CACzB,QAAS,UACT,QAAS,UACT,OAAQ,SACR,OAAQ,QACV,EAIAC,EAAe,CAAkB,CAC/B,eAAAC,EACA,UAAAC,CACF,IAA0C,CAClC,MAAAC,EAAOC,MAAI,CAAC,EACZC,EAAsBD,MAAI,CAAA,CAAE,EAC5BE,EAAYF,EAAAA,IAAeL,EAAY,OAAO,EAE9CQ,EAAS,SAAY,CACzBD,EAAU,MAAQP,EAAY,QAE1B,GAAA,CACIM,EAAA,MAAQ,MAAMH,EAAU,CAC5B,GAAGD,EAAe,MAClB,KAAME,EAAK,KAAA,CACZ,EACDG,EAAU,MAAQP,EAAY,MAAA,MACxB,CACNM,EAAM,MAAQ,GACdC,EAAU,MAAQP,EAAY,MAChC,CAAA,EAGFS,OAAAA,QAAMP,EAAgBM,CAAM,EAC5BC,QAAML,EAAMI,CAAM,EACXA,IAEA,CACL,KAAAJ,EACA,MAAAE,EACA,UAAAC,EACA,UAAWG,EAAS,SAAA,IAAMH,EAAU,QAAUP,EAAY,OAAO,EACjE,SAAUU,EAAS,SAAA,IAAMH,EAAU,QAAUP,EAAY,MAAM,EAC/D,SAAUU,EAAS,SAAA,IAAMH,EAAU,QAAUP,EAAY,MAAM,EAC/D,SAAU,IAAM,CACdI,EAAK,OAAS,CAChB,EACA,SAAU,IAAM,CACdA,EAAK,OAAS,CAChB,EACA,QAAUO,GAAgB,CACxBP,EAAK,MAAQO,CACf,EACA,OAAAH,EACA,QAAS,IAAM,CACTJ,EAAK,QAAU,EACVI,IAEPJ,EAAK,MAAQ,CAEjB,CAAA,CAEJ,iOC6BMQ,EAASC,aAAwB,CAAA,CAAE,EAKnCV,EAAY,MAAOW,GAA6B,CACpD,IAAIC,EAAe,CAAA,EAEf,GAAA,CACKA,EAAA,MAAMC,EAAM,OAAOF,CAAM,CAAA,MAC1B,CAER,CAEO,OAAAC,CAAA,EAGHE,EAAe,CAACC,EAAcC,IAAgB,CAClDD,EAAM,eAAe,EAEjBN,EAAO,MAAMO,CAAG,IAAM,MACxBP,EAAO,MAAQ,CAAE,CAACO,CAAG,EAAG,MAAO,EACtBP,EAAO,MAAMO,CAAG,IAAM,OAC/BP,EAAO,MAAQ,GAEfA,EAAO,MAAQ,CAAE,CAACO,CAAG,EAAG,KAAM,CAChC,EAGIjB,EAAiBG,EAAAA,IAAkB,CACvC,SAAUW,EAAM,QAChB,OAAAJ,CAAA,CACD,EAEK,CACJ,KAAAR,EAAM,UAAAgB,EAAW,SAAAC,EAAU,SAAAC,EAAU,SAAAC,EAAU,OAAAf,EAAQ,QAAAgB,EAAS,MAAOC,GACrExB,EAAkC,CACpC,eAAAC,EACA,UAAAC,CAAA,CACD,EAIY,OAAAuB,EAAA,CACX,QAAAF,EACA,OAAAhB,EACA,KAAAiB,CAAA,CACD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-slim-tables",
3
- "version": "0.3.2",
3
+ "version": "0.3.5",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -12,13 +12,12 @@
12
12
  "require": "./dist/vst.umd.js"
13
13
  },
14
14
  "./stylesheets": "dist/style.css",
15
- "./src/ts/index": "./src/ts/index.ts",
16
- "./filterable": "./src/ts/use/filterable",
17
- "./dist/vst.umd.js": "./dist/vst.umd.js"
15
+ "./src/main": "./src/main.ts",
16
+ "./filterable": "./src/ts/use/filterable"
18
17
  },
19
18
  "scripts": {
20
19
  "build": "vite build",
21
- "lint": "eslint ./src/ts/ --ext 'ts,vue'",
20
+ "lint": "eslint ./src/ts/ --ext 'ts,vue' --fix",
22
21
  "test": "vitest",
23
22
  "coverage": "vitest run --coverage"
24
23
  },
@@ -33,28 +32,28 @@
33
32
  },
34
33
  "author": "fLa <flatra66@gmail.com>",
35
34
  "license": "MIT",
36
- "private": false,
37
35
  "devDependencies": {
38
- "@babel/types": "^7.17.10",
39
- "@typescript-eslint/eslint-plugin": "^5.22.0",
40
- "@typescript-eslint/parser": "^5.22.0",
41
- "@vitejs/plugin-vue": "^2.3.1",
42
- "@vue/test-utils": "^2.0.0-rc.21",
43
- "c8": "^7.11.2",
44
- "eslint": "^8.14.0",
36
+ "@babel/types": "^7.20.7",
37
+ "@typescript-eslint/eslint-plugin": "^6.2.1",
38
+ "@typescript-eslint/parser": "^6.2.1",
39
+ "@vitejs/plugin-vue": "^4.2.3",
40
+ "@vitest/coverage-v8": "^0.34.1",
41
+ "@vue/test-utils": "^2.4.1",
42
+ "eslint": "^8.51.0",
45
43
  "eslint-config-airbnb-base": "^15.0.0",
46
- "eslint-plugin-import": "^2.26.0",
47
- "eslint-plugin-vue": "^8.7.1",
48
- "happy-dom": "^3.1.0",
49
- "sass": "^1.51.0",
50
- "typescript": "4.6.4",
51
- "vite": "^2.9.7",
52
- "vite-plugin-dts": "^1.1.1",
53
- "vitest": "^0.10.2",
54
- "vue-eslint-parser": "^8.3.0"
44
+ "eslint-plugin-import": "^2.28.1",
45
+ "eslint-plugin-vue": "^9.17.0",
46
+ "happy-dom": "^10.8.0",
47
+ "sass": "^1.64.2",
48
+ "typescript": "^5.1.6",
49
+ "vite": "^4.4.8",
50
+ "vite-plugin-dts": "^3.5.1",
51
+ "vitest": "^0.34.1",
52
+ "vue-eslint-parser": "^9.3.1"
55
53
  },
56
54
  "dependencies": {
57
- "vue": "^3.2.33"
55
+ "vue": "^3.3.0"
58
56
  },
59
- "types": "dist/types/index.d.ts"
57
+ "types": "dist/types/main.d.ts",
58
+ "packageManager": "yarn@3.4.1"
60
59
  }
@@ -1,14 +0,0 @@
1
- declare const _sfc_main: import("vue").DefineComponent<{
2
- columnsLength: {
3
- type: NumberConstructor;
4
- required: true;
5
- };
6
- }, {
7
- randNum: number;
8
- }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
9
- columnsLength: {
10
- type: NumberConstructor;
11
- required: true;
12
- };
13
- }>>, {}>;
14
- export default _sfc_main;
@@ -1,81 +0,0 @@
1
- import { ShallowRef } from 'vue';
2
- interface TableColumn {
3
- key: string;
4
- title: string;
5
- orderable?: boolean;
6
- }
7
- interface TableOrders {
8
- [key: string]: 'asc' | 'desc';
9
- }
10
- interface TableFetchParams {
11
- per_page: number;
12
- page: number;
13
- orders?: TableOrders;
14
- }
15
- interface TableRow {
16
- [key: string]: any;
17
- }
18
- declare const _sfc_main: import("vue").DefineComponent<{
19
- columns: {
20
- type: ArrayConstructor;
21
- required: true;
22
- };
23
- source: {
24
- type: (StringConstructor | FunctionConstructor)[];
25
- required: true;
26
- };
27
- perPage: {
28
- type: NumberConstructor;
29
- required: false;
30
- default: number;
31
- };
32
- }, {
33
- props: {
34
- columns: Array<TableColumn>;
35
- source: string | ((_: TableFetchParams) => Promise<TableRow[]> | TableRow[]);
36
- perPage: number;
37
- };
38
- orders: ShallowRef<TableOrders>;
39
- loadItems: (params: TableFetchParams) => Promise<TableRow[]>;
40
- onOrderClick: (key: string) => void;
41
- page: import("vue").Ref<number>;
42
- isSyncing: import("vue").ComputedRef<boolean>;
43
- isSynced: import("vue").ComputedRef<boolean>;
44
- prevPage: () => void;
45
- nextPage: () => void;
46
- reload: () => void;
47
- refetch: () => void;
48
- rows: {
49
- value: TableRow[];
50
- };
51
- LoadingRow: import("vue").DefineComponent<{
52
- columnsLength: {
53
- type: NumberConstructor;
54
- required: true;
55
- };
56
- }, {
57
- randNum: number;
58
- }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
59
- columnsLength: {
60
- type: NumberConstructor;
61
- required: true;
62
- };
63
- }>>, {}>;
64
- }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
65
- columns: {
66
- type: ArrayConstructor;
67
- required: true;
68
- };
69
- source: {
70
- type: (StringConstructor | FunctionConstructor)[];
71
- required: true;
72
- };
73
- perPage: {
74
- type: NumberConstructor;
75
- required: false;
76
- default: number;
77
- };
78
- }>>, {
79
- perPage: number;
80
- }>;
81
- export default _sfc_main;
@@ -1,2 +0,0 @@
1
- declare const _default: (obj: any) => string;
2
- export default _default;
@@ -1,2 +0,0 @@
1
- import VueSlimTable from './components/table.vue';
2
- export default VueSlimTable;
@@ -1,22 +0,0 @@
1
- declare type CombinedFilters<Filters> = Filters & {
2
- page: number;
3
- };
4
- interface UseFiltetableArgs<Filters, Item> {
5
- initialFilters: Filters;
6
- loadItems: (_filters: CombinedFilters<Filters>) => Promise<Item[]>;
7
- }
8
- declare const useFilterable: <Filters, Item>({ initialFilters, loadItems }: UseFiltetableArgs<Filters, Item>) => {
9
- page: import("vue").Ref<number>;
10
- items: {
11
- value: Item[];
12
- };
13
- syncState: import("vue").Ref<string>;
14
- nextPage: () => void;
15
- prevPage: () => void;
16
- isSyncing: import("vue").ComputedRef<boolean>;
17
- isSynced: import("vue").ComputedRef<boolean>;
18
- isFailed: import("vue").ComputedRef<boolean>;
19
- reload: () => void;
20
- refetch: () => void;
21
- };
22
- export default useFilterable;