tablevu 0.3.0-beta.3 → 0.3.0-beta.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
@@ -1,76 +1,36 @@
1
- # tablevu
1
+ # TableVu TypeScript package
2
2
 
3
- A simple, fast, and easy-to-use Vue 3 data table component.
3
+ This is a standalone TypeScript implementation of the Vue 3 table component. It is intentionally isolated from the legacy JavaScript package at the repository root. Build it from this directory with `npm install` and `npm run build`.
4
4
 
5
- ## Installation
5
+ ## Run the browser example locally
6
6
 
7
- ```bash
8
- npm install tablevu
9
- ```
10
-
11
- ## Usage
12
-
13
- ```vue
14
- <script setup>
15
- import { TableVu } from 'tablevu'
16
-
17
- const columns = [
18
- { name: 'id', label: 'ID' },
19
- { name: 'name', label: 'Name' },
20
- { name: 'email', label: 'Email' }
21
- ]
7
+ From the `typescript/` directory, install dependencies and build the local bundle. Then start a static server from the same directory and open the example. This uses the local build and does not publish or install the package elsewhere.
22
8
 
23
- const data = [
24
- { id: 1, name: 'John', email: 'john@example.com' },
25
- { id: 2, name: 'Jane', email: 'jane@example.com' }
26
- ]
27
- </script>
28
-
29
- <template>
30
- <TableVu :data="data" :columns="columns" />
31
- </template>
9
+ ```sh
10
+ npm install
11
+ npm run build
12
+ python3 -m http.server 8080
32
13
  ```
33
14
 
34
- ## Props
35
-
36
- | Prop | Type | Default | Description |
37
- |------|------|---------|-------------|
38
- | `data` | `Object` | - | Must contain `columns`, `pageSize`, `currPage`, `sort`, and `value`/`@count` properties, or an array |
39
- | `columns` | `Array` | - | Column definitions with `name`, `label`, `type`, `align`, `width`, `render` properties |
40
- | `search` | `String` | - | Search term (debounced) |
41
- | `filter` | `Array` / `Object` | - | Filter objects |
42
- | `command` | `Array` | `[]` | Commands like `refresh`, `first`, `previous`, `next`, `last` |
43
- | `rowid` | `String` | - | Row ID field name |
44
- | `onRowClick` | `Function` | - | Row click handler |
45
- | `onRowDblClick` | `Function` | - | Row double-click handler |
46
- | `class` | `String` | `'table'` | CSS class for the table |
47
- | `buttonclass` | `String` | `'btn'` | CSS class for pagination buttons |
15
+ Open `http://localhost:8080/example/test-northwind.html`. The browser needs internet access for Vue from the import map and the public Northwind OData service.
48
16
 
49
- ## Events
17
+ ```ts
18
+ import { TableVu, odata, type Filter, type TableVuExpose } from 'tablevu';
50
19
 
51
- - `row-click` - Emitted when a row is clicked
52
- - `row-dbl-click` - Emitted when a row is double-clicked
20
+ const filter: Filter = {
21
+ operator: 'and',
22
+ filters: [
23
+ { column: 'status', operator: 'in', value: ['active', 'pending'] },
24
+ { column: 'createdAt', operator: 'between', value: [new Date('2025-01-01'), new Date()] },
25
+ { column: 'deletedAt', operator: 'isNull' },
26
+ { column: 'Orders', operator: 'any', variable: 'order', filter: { column: 'Freight', operator: 'gt', value: 100 } },
27
+ { column: 'Orders', operator: 'all', variable: 'order', filter: { column: 'Freight', operator: 'ge', value: 0 } }
28
+ ]
29
+ };
53
30
 
54
- ## Example
55
-
56
- ```vue
57
- <script setup>
58
- import { ref } from 'vue'
59
- import { TableVu } from 'tablevu'
31
+ const data = odata({ url: 'https://api.example.com/items', count: true, filter });
32
+ ```
60
33
 
61
- const data = ref([])
62
- const columns = ref([
63
- { name: 'id', label: 'ID' },
64
- { name: 'name', label: 'Name' }
65
- ])
66
- </script>
34
+ The component exposes `first()`, `prior()`, `next()`, `last()`, `go(pageNumber)`, `page(pageNumber)`, `refresh()`, `sortBy(columnIndex, direction?)`, `getRows()` and `setRows(rows)` through its Vue template ref. `go` validates and clamps pages when the adapter reports a page count. `page` performs a direct reload even when the requested page is already current.
67
35
 
68
- <template>
69
- <TableVu
70
- :data="data"
71
- :columns="columns"
72
- @row-click="handleRowClick"
73
- @row-dbl-click="handleRowDblClick"
74
- />
75
- </template>
76
- ```
36
+ Supported filter operators are `eq`, `ne`, `gt`, `ge`, `lt`, `le`, `contains`, `startsWith`, `endsWith`, `in`, `between`, `isNull`, `isNotNull`, `and`, `or`, `not`, `any`, `all`, `countGt`, `countGe`, `countLt`, and `countLe`. `field` accepts dotted paths; `column` is also accepted as an alias. `any` and `all` take a nested `filter` and may specify a `variable` (default `item`).
@@ -0,0 +1,3 @@
1
+ import type { AdapterFunction } from '../types';
2
+ declare const adaptArray: AdapterFunction;
3
+ export default adaptArray;
@@ -0,0 +1,4 @@
1
+ import type { AdapterParams, AdapterResult, Filter, ODataOptions } from '../types';
2
+ /** Converts the typed filter tree into an OData `$filter` expression. */
3
+ export declare function buildFilter(filter: Filter | string | null | undefined): string;
4
+ export declare function createODataAdapter(options: ODataOptions): (params?: AdapterParams) => Promise<AdapterResult>;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export { default as TableVu } from './table';
2
2
  export * from './table';
3
- export { default as odata, toODataFilter as buildFilter, } from './odata';
4
- export type { FilterOperator, Filter, Column, Sort, Expand, DataTableProps, ODataOptions } from './odata';
5
- export { default as webapi } from './webapi';
6
- export * from './webapi';
7
- export { default as adaptArray, type ArrayAdapterParams, type AdapterResult } from './array';
3
+ export * from './types';
4
+ export { createODataAdapter as odata, buildFilter } from './adapters/odata';
5
+ export { default as adaptArray } from './adapters/array';
6
+ export * from './adapters/array';
@@ -0,0 +1,174 @@
1
+ import { TablevuStatus } from './types';
2
+ import type { TablevuSettings, AdapterFunction } from './types';
3
+ export interface TableVuExpose {
4
+ first: () => Promise<void>;
5
+ prior: () => void | Promise<void>;
6
+ next: () => void | Promise<void>;
7
+ last: () => void | Promise<void>;
8
+ go: (pageNumber: number) => void | Promise<void>;
9
+ page: (pageNumber: number) => Promise<void>;
10
+ refresh: () => Promise<void>;
11
+ sortBy: (columnIndex: number, direction?: string) => void | Promise<void>;
12
+ getRows: () => any[];
13
+ setRows: (rows: any[]) => void;
14
+ }
15
+ declare const tablevu: import("vue").DefineComponent<{
16
+ settings?: (TablevuSettings | null) | undefined;
17
+ data?: (any[] | AdapterFunction) | undefined;
18
+ group?: (string | import("./types").TablevuGroup) | undefined;
19
+ search?: string | undefined;
20
+ filter?: any;
21
+ command?: Array<{
22
+ name: "refresh" | "first" | "prior" | "next" | "last" | "go" | string;
23
+ page?: number;
24
+ }> | undefined;
25
+ rowid?: string | undefined;
26
+ onRowClick?: ((event: MouseEvent, row: any) => void) | undefined;
27
+ onRowDblClick?: ((event: MouseEvent, row: any) => void) | undefined;
28
+ class?: string | undefined;
29
+ style?: (string | Record<string, string> | null) | undefined;
30
+ }, {
31
+ renderHeader: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
32
+ [key: string]: any;
33
+ }>[];
34
+ renderBody: () => any[];
35
+ renderFooter: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
36
+ [key: string]: any;
37
+ }>[];
38
+ renderCaption: () => string;
39
+ first: () => Promise<void>;
40
+ prior: () => Promise<void> | undefined;
41
+ next: () => Promise<void> | undefined;
42
+ last: () => Promise<void> | undefined;
43
+ go: (pageNumber: number) => Promise<void> | undefined;
44
+ page: (pageNumber: number) => Promise<void>;
45
+ refresh: () => Promise<void>;
46
+ sortBy: (columnIndex: number, direction?: string) => Promise<void>;
47
+ getRows: () => any[];
48
+ setRows: (newRows: any[]) => void;
49
+ state: {
50
+ caption: any;
51
+ group: {
52
+ value: any;
53
+ content: any;
54
+ expandAll: boolean;
55
+ class: string;
56
+ };
57
+ page: {
58
+ count: number;
59
+ size: number;
60
+ current: number;
61
+ type: string | null;
62
+ };
63
+ sort: {
64
+ index?: number | undefined;
65
+ name?: string | undefined;
66
+ dir?: "asc" | "desc" | null | string | undefined;
67
+ }[];
68
+ columns: {
69
+ name: string;
70
+ label?: string | undefined;
71
+ type?: "string" | "number" | "numeric" | "integer" | "date" | "time" | "datetime" | "boolean" | undefined;
72
+ align?: "left" | "center" | "right" | undefined;
73
+ width?: string | undefined;
74
+ style?: Record<string, string> | undefined;
75
+ render?: ((row: any) => any) | undefined;
76
+ colspan?: number | undefined;
77
+ depth?: string[] | undefined;
78
+ header?: {
79
+ colspan?: number | undefined;
80
+ style?: Record<string, string> | undefined;
81
+ align?: string | undefined;
82
+ } | undefined;
83
+ popup?: boolean | undefined;
84
+ filter?: any;
85
+ searchable?: boolean | undefined;
86
+ resizable?: boolean | undefined;
87
+ draggable?: boolean | undefined;
88
+ visible?: boolean | undefined;
89
+ }[];
90
+ footer: {
91
+ button: {
92
+ class: string;
93
+ };
94
+ };
95
+ status: TablevuStatus;
96
+ time: number | null;
97
+ search: string | null;
98
+ filter: any;
99
+ onData?: ((rows: any[]) => any[]) | undefined;
100
+ settings?: {
101
+ group?: {
102
+ value?: string | number | bigint | ((row: any) => any) | undefined;
103
+ content?: string | number | ((row: any) => any) | undefined;
104
+ expandAll?: boolean | undefined;
105
+ class?: string | undefined;
106
+ } | undefined;
107
+ page?: {
108
+ size?: number | undefined;
109
+ type?: "incremental" | "dynamic" | undefined;
110
+ } | undefined;
111
+ sort?: {
112
+ index?: number | undefined;
113
+ name?: string | undefined;
114
+ dir?: "asc" | "desc" | null | string | undefined;
115
+ }[] | undefined;
116
+ columns?: {
117
+ name: string;
118
+ label?: string | undefined;
119
+ type?: "string" | "number" | "numeric" | "integer" | "date" | "time" | "datetime" | "boolean" | undefined;
120
+ align?: "left" | "center" | "right" | undefined;
121
+ width?: string | undefined;
122
+ style?: Record<string, string> | undefined;
123
+ render?: ((row: any) => any) | undefined;
124
+ colspan?: number | undefined;
125
+ depth?: string[] | undefined;
126
+ header?: {
127
+ colspan?: number | undefined;
128
+ style?: Record<string, string> | undefined;
129
+ align?: string | undefined;
130
+ } | undefined;
131
+ popup?: boolean | undefined;
132
+ filter?: any;
133
+ searchable?: boolean | undefined;
134
+ resizable?: boolean | undefined;
135
+ draggable?: boolean | undefined;
136
+ visible?: boolean | undefined;
137
+ }[] | undefined;
138
+ searchMinChar?: number | undefined;
139
+ footer?: {
140
+ button?: {
141
+ class?: string | undefined;
142
+ } | undefined;
143
+ } | undefined;
144
+ onData?: ((rows: any[]) => any[]) | undefined;
145
+ emptyMessage?: string | undefined;
146
+ } | undefined;
147
+ };
148
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("row-click" | "row-dbl-click")[], "row-click" | "row-dbl-click", import("vue").PublicProps, Readonly<{
149
+ settings?: (TablevuSettings | null) | undefined;
150
+ data?: (any[] | AdapterFunction) | undefined;
151
+ group?: (string | import("./types").TablevuGroup) | undefined;
152
+ search?: string | undefined;
153
+ filter?: any;
154
+ command?: Array<{
155
+ name: "refresh" | "first" | "prior" | "next" | "last" | "go" | string;
156
+ page?: number;
157
+ }> | undefined;
158
+ rowid?: string | undefined;
159
+ onRowClick?: ((event: MouseEvent, row: any) => void) | undefined;
160
+ onRowDblClick?: ((event: MouseEvent, row: any) => void) | undefined;
161
+ class?: string | undefined;
162
+ style?: (string | Record<string, string> | null) | undefined;
163
+ }> & Readonly<{
164
+ "onRow-click"?: ((...args: any[]) => any) | undefined;
165
+ "onRow-dbl-click"?: ((...args: any[]) => any) | undefined;
166
+ }>, {
167
+ readonly settings: TablevuSettings | null;
168
+ readonly command: {
169
+ name: string;
170
+ }[];
171
+ readonly class: string;
172
+ readonly style: string | Record<string, string>;
173
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
174
+ export default tablevu;
package/dist/table.d.ts CHANGED
@@ -1,52 +1,174 @@
1
- import { PropType, EmitsOptions } from 'vue';
2
- import type { TablevuSettings, TablevuProps, TablevuSpec, AdapterFunction } from './types';
3
- interface TableSetupReturn {
4
- spec: TablevuSpec;
5
- renderHeader: () => any[];
6
- renderBody: () => any[];
7
- renderFooter: () => any[];
8
- renderCaption: () => any;
1
+ import { TablevuStatus } from './types';
2
+ import type { TablevuSettings, AdapterFunction } from './types';
3
+ export interface TableVuExpose {
4
+ first: () => Promise<void>;
5
+ prior: () => void | Promise<void>;
6
+ next: () => void | Promise<void>;
7
+ last: () => void | Promise<void>;
8
+ go: (pageNumber: number) => void | Promise<void>;
9
+ page: (pageNumber: number) => Promise<void>;
10
+ refresh: () => Promise<void>;
11
+ sortBy: (columnIndex: number, direction?: string) => void | Promise<void>;
12
+ getRows: () => any[];
13
+ setRows: (rows: any[]) => void;
9
14
  }
10
- declare const tablevu: {
11
- props: {
12
- readonly settings: {
13
- readonly type: PropType<TablevuSettings>;
14
- readonly default: null;
15
- };
16
- readonly data: {
17
- readonly type: PropType<any[] | AdapterFunction>;
18
- };
19
- readonly group: {
20
- readonly type: PropType<string | object>;
21
- };
22
- readonly search: {
23
- readonly type: PropType<string>;
24
- };
25
- readonly filter: {
26
- readonly type: PropType<any>;
27
- };
28
- readonly rowid: {
29
- readonly type: PropType<string>;
30
- };
31
- readonly onRowClick: {
32
- readonly type: PropType<(event: MouseEvent, row: any) => void>;
33
- };
34
- readonly onRowDblClick: {
35
- readonly type: PropType<(event: MouseEvent, row: any) => void>;
15
+ declare const tablevu: import("vue").DefineComponent<{
16
+ settings?: (TablevuSettings | null) | undefined;
17
+ data?: (any[] | AdapterFunction) | undefined;
18
+ group?: (string | import("./types").TablevuGroup) | undefined;
19
+ search?: string | undefined;
20
+ filter?: any;
21
+ command?: Array<{
22
+ name: "refresh" | "first" | "prior" | "next" | "last" | "go" | string;
23
+ page?: number;
24
+ }> | undefined;
25
+ rowid?: string | undefined;
26
+ onRowClick?: ((event: MouseEvent, row: any) => void) | undefined;
27
+ onRowDblClick?: ((event: MouseEvent, row: any) => void) | undefined;
28
+ class?: string | undefined;
29
+ style?: (string | Record<string, string> | null) | undefined;
30
+ }, {
31
+ renderHeader: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
32
+ [key: string]: any;
33
+ }>[];
34
+ renderBody: () => any[];
35
+ renderFooter: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
36
+ [key: string]: any;
37
+ }>[];
38
+ renderCaption: () => string;
39
+ first: () => Promise<void>;
40
+ prior: () => Promise<void> | undefined;
41
+ next: () => Promise<void> | undefined;
42
+ last: () => Promise<void> | undefined;
43
+ go: (pageNumber: number) => Promise<void> | undefined;
44
+ page: (pageNumber: number) => Promise<void>;
45
+ refresh: () => Promise<void>;
46
+ sortBy: (columnIndex: number, direction?: string) => Promise<void>;
47
+ getRows: () => any[];
48
+ setRows: (newRows: any[]) => void;
49
+ state: {
50
+ caption: any;
51
+ group: {
52
+ value: any;
53
+ content: any;
54
+ expandAll: boolean;
55
+ class: string;
36
56
  };
37
- readonly class: {
38
- readonly type: PropType<string>;
39
- readonly default: "table";
57
+ page: {
58
+ count: number;
59
+ size: number;
60
+ current: number;
61
+ type: string | null;
40
62
  };
41
- readonly style: {
42
- readonly type: PropType<string>;
43
- readonly default: null;
63
+ sort: {
64
+ index?: number | undefined;
65
+ name?: string | undefined;
66
+ dir?: "asc" | "desc" | null | string | undefined;
67
+ }[];
68
+ columns: {
69
+ name: string;
70
+ label?: string | undefined;
71
+ type?: "string" | "number" | "numeric" | "integer" | "date" | "time" | "datetime" | "boolean" | undefined;
72
+ align?: "left" | "center" | "right" | undefined;
73
+ width?: string | undefined;
74
+ style?: Record<string, string> | undefined;
75
+ render?: ((row: any) => any) | undefined;
76
+ colspan?: number | undefined;
77
+ depth?: string[] | undefined;
78
+ header?: {
79
+ colspan?: number | undefined;
80
+ style?: Record<string, string> | undefined;
81
+ align?: string | undefined;
82
+ } | undefined;
83
+ popup?: boolean | undefined;
84
+ filter?: any;
85
+ searchable?: boolean | undefined;
86
+ resizable?: boolean | undefined;
87
+ draggable?: boolean | undefined;
88
+ visible?: boolean | undefined;
89
+ }[];
90
+ footer: {
91
+ button: {
92
+ class: string;
93
+ };
44
94
  };
95
+ status: TablevuStatus;
96
+ time: number | null;
97
+ search: string | null;
98
+ filter: any;
99
+ onData?: ((rows: any[]) => any[]) | undefined;
100
+ settings?: {
101
+ group?: {
102
+ value?: string | number | bigint | ((row: any) => any) | undefined;
103
+ content?: string | number | ((row: any) => any) | undefined;
104
+ expandAll?: boolean | undefined;
105
+ class?: string | undefined;
106
+ } | undefined;
107
+ page?: {
108
+ size?: number | undefined;
109
+ type?: "incremental" | "dynamic" | undefined;
110
+ } | undefined;
111
+ sort?: {
112
+ index?: number | undefined;
113
+ name?: string | undefined;
114
+ dir?: "asc" | "desc" | null | string | undefined;
115
+ }[] | undefined;
116
+ columns?: {
117
+ name: string;
118
+ label?: string | undefined;
119
+ type?: "string" | "number" | "numeric" | "integer" | "date" | "time" | "datetime" | "boolean" | undefined;
120
+ align?: "left" | "center" | "right" | undefined;
121
+ width?: string | undefined;
122
+ style?: Record<string, string> | undefined;
123
+ render?: ((row: any) => any) | undefined;
124
+ colspan?: number | undefined;
125
+ depth?: string[] | undefined;
126
+ header?: {
127
+ colspan?: number | undefined;
128
+ style?: Record<string, string> | undefined;
129
+ align?: string | undefined;
130
+ } | undefined;
131
+ popup?: boolean | undefined;
132
+ filter?: any;
133
+ searchable?: boolean | undefined;
134
+ resizable?: boolean | undefined;
135
+ draggable?: boolean | undefined;
136
+ visible?: boolean | undefined;
137
+ }[] | undefined;
138
+ searchMinChar?: number | undefined;
139
+ footer?: {
140
+ button?: {
141
+ class?: string | undefined;
142
+ } | undefined;
143
+ } | undefined;
144
+ onData?: ((rows: any[]) => any[]) | undefined;
145
+ emptyMessage?: string | undefined;
146
+ } | undefined;
45
147
  };
46
- emits: EmitsOptions;
47
- setup(props: TablevuProps, { attrs, slots, emit, expose }: any): TableSetupReturn;
48
- render(props: TablevuProps): import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
49
- [key: string]: any;
50
- }>;
51
- };
148
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("row-click" | "row-dbl-click")[], "row-click" | "row-dbl-click", import("vue").PublicProps, Readonly<{
149
+ settings?: (TablevuSettings | null) | undefined;
150
+ data?: (any[] | AdapterFunction) | undefined;
151
+ group?: (string | import("./types").TablevuGroup) | undefined;
152
+ search?: string | undefined;
153
+ filter?: any;
154
+ command?: Array<{
155
+ name: "refresh" | "first" | "prior" | "next" | "last" | "go" | string;
156
+ page?: number;
157
+ }> | undefined;
158
+ rowid?: string | undefined;
159
+ onRowClick?: ((event: MouseEvent, row: any) => void) | undefined;
160
+ onRowDblClick?: ((event: MouseEvent, row: any) => void) | undefined;
161
+ class?: string | undefined;
162
+ style?: (string | Record<string, string> | null) | undefined;
163
+ }> & Readonly<{
164
+ "onRow-click"?: ((...args: any[]) => any) | undefined;
165
+ "onRow-dbl-click"?: ((...args: any[]) => any) | undefined;
166
+ }>, {
167
+ readonly settings: TablevuSettings | null;
168
+ readonly command: {
169
+ name: string;
170
+ }[];
171
+ readonly class: string;
172
+ readonly style: string | Record<string, string>;
173
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
52
174
  export default tablevu;