@shotleybuilder/svelte-table-kit 0.1.0
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/LICENSE +21 -0
- package/README.md +247 -0
- package/dist/TableKit.svelte +838 -0
- package/dist/TableKit.svelte.d.ts +31 -0
- package/dist/components/FilterBar.svelte +291 -0
- package/dist/components/FilterBar.svelte.d.ts +24 -0
- package/dist/components/FilterCondition.svelte +135 -0
- package/dist/components/FilterCondition.svelte.d.ts +23 -0
- package/dist/components/GroupBar.svelte +283 -0
- package/dist/components/GroupBar.svelte.d.ts +21 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +15 -0
- package/dist/presets/index.d.ts +6 -0
- package/dist/presets/index.js +27 -0
- package/dist/stores/persistence.d.ts +58 -0
- package/dist/stores/persistence.js +127 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.js +2 -0
- package/dist/utils/config.d.ts +18 -0
- package/dist/utils/config.js +32 -0
- package/dist/utils/filters.d.ts +21 -0
- package/dist/utils/filters.js +101 -0
- package/dist/utils/formatters.d.ts +16 -0
- package/dist/utils/formatters.js +39 -0
- package/package.json +78 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FilterCondition, FilterLogic } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a single filter condition against a row value
|
|
4
|
+
*/
|
|
5
|
+
export declare function evaluateCondition(condition: FilterCondition, rowValue: any): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Filter data array by multiple conditions with AND or OR logic
|
|
8
|
+
*/
|
|
9
|
+
export declare function applyFilters<T extends Record<string, any>>(data: T[], conditions: FilterCondition[], logic?: FilterLogic): T[];
|
|
10
|
+
/**
|
|
11
|
+
* Create a text filter configuration
|
|
12
|
+
*/
|
|
13
|
+
export declare function createTextFilter(columnId: string, value: string): FilterCondition;
|
|
14
|
+
/**
|
|
15
|
+
* Create a select/dropdown filter configuration
|
|
16
|
+
*/
|
|
17
|
+
export declare function createSelectFilter(columnId: string, value: string): FilterCondition;
|
|
18
|
+
/**
|
|
19
|
+
* Create a numeric filter configuration
|
|
20
|
+
*/
|
|
21
|
+
export declare function createNumericFilter(columnId: string, operator: 'greater_than' | 'less_than' | 'greater_or_equal' | 'less_or_equal', value: number): FilterCondition;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Filter creation and evaluation utilities
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a single filter condition against a row value
|
|
4
|
+
*/
|
|
5
|
+
export function evaluateCondition(condition, rowValue) {
|
|
6
|
+
const { operator, value } = condition;
|
|
7
|
+
// Convert to strings for comparison (handles null/undefined)
|
|
8
|
+
const rowStr = String(rowValue || '').toLowerCase();
|
|
9
|
+
const filterStr = String(value || '').toLowerCase();
|
|
10
|
+
switch (operator) {
|
|
11
|
+
case 'equals':
|
|
12
|
+
return rowStr === filterStr;
|
|
13
|
+
case 'not_equals':
|
|
14
|
+
return rowStr !== filterStr;
|
|
15
|
+
case 'contains':
|
|
16
|
+
return rowStr.includes(filterStr);
|
|
17
|
+
case 'not_contains':
|
|
18
|
+
return !rowStr.includes(filterStr);
|
|
19
|
+
case 'starts_with':
|
|
20
|
+
return rowStr.startsWith(filterStr);
|
|
21
|
+
case 'ends_with':
|
|
22
|
+
return rowStr.endsWith(filterStr);
|
|
23
|
+
case 'is_empty':
|
|
24
|
+
return !rowValue || rowStr === '';
|
|
25
|
+
case 'is_not_empty':
|
|
26
|
+
return !!rowValue && rowStr !== '';
|
|
27
|
+
case 'greater_than':
|
|
28
|
+
return Number(rowValue) > Number(value);
|
|
29
|
+
case 'less_than':
|
|
30
|
+
return Number(rowValue) < Number(value);
|
|
31
|
+
case 'greater_or_equal':
|
|
32
|
+
return Number(rowValue) >= Number(value);
|
|
33
|
+
case 'less_or_equal':
|
|
34
|
+
return Number(rowValue) <= Number(value);
|
|
35
|
+
default:
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Filter data array by multiple conditions with AND or OR logic
|
|
41
|
+
*/
|
|
42
|
+
export function applyFilters(data, conditions, logic = 'and') {
|
|
43
|
+
if (conditions.length === 0)
|
|
44
|
+
return data;
|
|
45
|
+
// Filter out invalid conditions (empty field or value)
|
|
46
|
+
const validConditions = conditions.filter((c) => c.field &&
|
|
47
|
+
(c.operator === 'is_empty' ||
|
|
48
|
+
c.operator === 'is_not_empty' ||
|
|
49
|
+
(c.value !== null && c.value !== undefined && c.value !== '')));
|
|
50
|
+
if (validConditions.length === 0)
|
|
51
|
+
return data;
|
|
52
|
+
return data.filter((row) => {
|
|
53
|
+
if (logic === 'and') {
|
|
54
|
+
// All conditions must pass (AND logic)
|
|
55
|
+
return validConditions.every((condition) => {
|
|
56
|
+
const rowValue = row[condition.field];
|
|
57
|
+
return evaluateCondition(condition, rowValue);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// At least one condition must pass (OR logic)
|
|
62
|
+
return validConditions.some((condition) => {
|
|
63
|
+
const rowValue = row[condition.field];
|
|
64
|
+
return evaluateCondition(condition, rowValue);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create a text filter configuration
|
|
71
|
+
*/
|
|
72
|
+
export function createTextFilter(columnId, value) {
|
|
73
|
+
return {
|
|
74
|
+
id: `filter-${Date.now()}`,
|
|
75
|
+
field: columnId,
|
|
76
|
+
operator: 'contains',
|
|
77
|
+
value
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a select/dropdown filter configuration
|
|
82
|
+
*/
|
|
83
|
+
export function createSelectFilter(columnId, value) {
|
|
84
|
+
return {
|
|
85
|
+
id: `filter-${Date.now()}`,
|
|
86
|
+
field: columnId,
|
|
87
|
+
operator: 'equals',
|
|
88
|
+
value
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a numeric filter configuration
|
|
93
|
+
*/
|
|
94
|
+
export function createNumericFilter(columnId, operator, value) {
|
|
95
|
+
return {
|
|
96
|
+
id: `filter-${Date.now()}`,
|
|
97
|
+
field: columnId,
|
|
98
|
+
operator,
|
|
99
|
+
value
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format date string to localized format
|
|
3
|
+
*/
|
|
4
|
+
export declare function formatDate(dateStr: string | Date, locale?: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Format number as currency
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatCurrency(value: number, currency?: string, locale?: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Format number with locale-specific separators
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatNumber(value: number, locale?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Format number as percentage
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatPercent(value: number, decimals?: number, locale?: string): string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Cell formatting utilities
|
|
2
|
+
/**
|
|
3
|
+
* Format date string to localized format
|
|
4
|
+
*/
|
|
5
|
+
export function formatDate(dateStr, locale = 'en-GB') {
|
|
6
|
+
if (!dateStr)
|
|
7
|
+
return '-';
|
|
8
|
+
const date = typeof dateStr === 'string' ? new Date(dateStr) : dateStr;
|
|
9
|
+
return date.toLocaleDateString(locale, {
|
|
10
|
+
day: '2-digit',
|
|
11
|
+
month: 'short',
|
|
12
|
+
year: 'numeric'
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Format number as currency
|
|
17
|
+
*/
|
|
18
|
+
export function formatCurrency(value, currency = 'GBP', locale = 'en-GB') {
|
|
19
|
+
return new Intl.NumberFormat(locale, {
|
|
20
|
+
style: 'currency',
|
|
21
|
+
currency
|
|
22
|
+
}).format(value);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Format number with locale-specific separators
|
|
26
|
+
*/
|
|
27
|
+
export function formatNumber(value, locale = 'en-GB') {
|
|
28
|
+
return new Intl.NumberFormat(locale).format(value);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format number as percentage
|
|
32
|
+
*/
|
|
33
|
+
export function formatPercent(value, decimals = 1, locale = 'en-GB') {
|
|
34
|
+
return new Intl.NumberFormat(locale, {
|
|
35
|
+
style: 'percent',
|
|
36
|
+
minimumFractionDigits: decimals,
|
|
37
|
+
maximumFractionDigits: decimals
|
|
38
|
+
}).format(value / 100);
|
|
39
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shotleybuilder/svelte-table-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A comprehensive, AI-configurable data table component for Svelte and SvelteKit, built on TanStack Table v8",
|
|
5
|
+
"author": "Sertantai",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"svelte",
|
|
9
|
+
"sveltekit",
|
|
10
|
+
"table",
|
|
11
|
+
"datagrid",
|
|
12
|
+
"tanstack",
|
|
13
|
+
"data-table",
|
|
14
|
+
"airtable",
|
|
15
|
+
"headless",
|
|
16
|
+
"typescript"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/shotleybuilder/svelte-table-kit.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/shotleybuilder/svelte-table-kit/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/shotleybuilder/svelte-table-kit#readme",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"svelte": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"svelte": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./styles": "./dist/styles/table-kit.css"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"!dist/**/*.test.*",
|
|
39
|
+
"!dist/**/*.spec.*"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"dev": "vite dev",
|
|
43
|
+
"build": "vite build && npm run package",
|
|
44
|
+
"package": "svelte-kit sync && svelte-package && publint",
|
|
45
|
+
"prepublishOnly": "npm run package",
|
|
46
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
47
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
48
|
+
"test": "vitest",
|
|
49
|
+
"test:ui": "vitest --ui",
|
|
50
|
+
"test:run": "vitest run",
|
|
51
|
+
"lint": "prettier --check . && eslint .",
|
|
52
|
+
"format": "prettier --write ."
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"svelte": "^4.0.0 || ^5.0.0",
|
|
56
|
+
"@tanstack/svelte-table": "^8.0.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@sveltejs/adapter-auto": "^3.0.0",
|
|
60
|
+
"@sveltejs/kit": "^2.0.0",
|
|
61
|
+
"@sveltejs/package": "^2.0.0",
|
|
62
|
+
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
|
63
|
+
"@tanstack/svelte-table": "^8.21.3",
|
|
64
|
+
"@types/eslint": "^9.6.0",
|
|
65
|
+
"eslint": "^9.0.0",
|
|
66
|
+
"eslint-config-prettier": "^9.1.0",
|
|
67
|
+
"eslint-plugin-svelte": "^2.36.0",
|
|
68
|
+
"prettier": "^3.1.1",
|
|
69
|
+
"prettier-plugin-svelte": "^3.1.2",
|
|
70
|
+
"publint": "^0.1.9",
|
|
71
|
+
"svelte": "^4.2.7",
|
|
72
|
+
"svelte-check": "^3.6.0",
|
|
73
|
+
"tslib": "^2.4.1",
|
|
74
|
+
"typescript": "^5.0.0",
|
|
75
|
+
"vite": "^5.0.11",
|
|
76
|
+
"vitest": "^2.0.0"
|
|
77
|
+
}
|
|
78
|
+
}
|