runeforge 0.0.53 → 0.0.55
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 -21
- package/README.md +1342 -1222
- package/dist/components/Avatar.svelte +31 -31
- package/dist/components/IconRenderer.svelte +22 -22
- package/dist/components/Modal.svelte +75 -75
- package/dist/components/common/Header.svelte +40 -40
- package/dist/components/crud/EmbeddedField.svelte +175 -175
- package/dist/components/crud/Field.svelte +376 -376
- package/dist/components/crud/GenericCRUD.svelte +426 -435
- package/dist/components/crud/GenericCRUD.svelte.d.ts +6 -9
- package/dist/components/crud/SearchInput.svelte +53 -53
- package/dist/components/crud/columns/Avatar.svelte +15 -15
- package/dist/components/crud/columns/Icon.svelte +8 -8
- package/dist/components/crud/utils/reorder.d.ts +4 -0
- package/dist/components/crud/utils/reorder.js +13 -0
- package/dist/components/crud/views/Create.svelte +232 -232
- package/dist/components/crud/views/Read.svelte +124 -124
- package/dist/components/crud/views/Update.svelte +208 -208
- package/dist/components/crud/views/list/List.svelte +291 -0
- package/dist/components/crud/views/{List.svelte.d.ts → list/List.svelte.d.ts} +4 -14
- package/dist/components/crud/views/list/Modals.svelte +56 -0
- package/dist/components/crud/views/list/Modals.svelte.d.ts +36 -0
- package/dist/components/crud/views/list/Table.svelte +176 -0
- package/dist/components/crud/views/list/Table.svelte.d.ts +59 -0
- package/dist/components/crud/views/list/Toolbar.svelte +341 -0
- package/dist/components/crud/views/list/Toolbar.svelte.d.ts +46 -0
- package/dist/components/form/Button.svelte +27 -27
- package/dist/components/form/Label.svelte +37 -37
- package/dist/components/form/MultiSelect.svelte +248 -248
- package/dist/components/form/PasswordInput.svelte +68 -68
- package/dist/components/form/Required.svelte +1 -1
- package/dist/components/form/Select.svelte +209 -209
- package/dist/components/form/Tree.svelte +62 -62
- package/dist/components/form/TreeNode.svelte +66 -66
- package/dist/components/navigation/Breadcrumbs.svelte +111 -111
- package/dist/components/table/ColumnFilter.svelte +168 -168
- package/dist/components/table/PaginatedTable.svelte +536 -215
- package/dist/components/table/PaginatedTable.svelte.d.ts +11 -2
- package/dist/components/table/Paginator.svelte +113 -113
- package/dist/components/table/SortHeader.svelte +43 -43
- package/dist/components/table/TableBody.svelte +150 -70
- package/dist/components/table/TableBody.svelte.d.ts +14 -1
- package/dist/components/table/TableHeader.svelte +88 -83
- package/dist/components/table/TableHeader.svelte.d.ts +1 -0
- package/dist/components/table/sortable.d.ts +27 -0
- package/dist/components/table/sortable.js +55 -0
- package/dist/components/table/utils.d.ts +28 -1
- package/dist/components/table/utils.js +75 -0
- package/dist/i18n/en.js +2 -0
- package/dist/i18n/es.js +2 -0
- package/dist/i18n/types.d.ts +2 -0
- package/dist/icons/defaults/Clear.svelte +6 -6
- package/dist/icons/defaults/Create.svelte +6 -6
- package/dist/icons/defaults/Delete.svelte +6 -6
- package/dist/icons/defaults/Download.svelte +7 -7
- package/dist/icons/defaults/Edit.svelte +7 -7
- package/dist/icons/defaults/Filter.svelte +6 -6
- package/dist/icons/defaults/FilterActive.svelte +6 -6
- package/dist/icons/defaults/Folder.svelte +6 -6
- package/dist/icons/defaults/Grip.svelte +7 -0
- package/dist/icons/defaults/Grip.svelte.d.ts +7 -0
- package/dist/icons/defaults/Home.svelte +6 -6
- package/dist/icons/defaults/PasswordHide.svelte +9 -9
- package/dist/icons/defaults/PasswordShow.svelte +7 -7
- package/dist/icons/defaults/SortAsc.svelte +6 -6
- package/dist/icons/defaults/SortDesc.svelte +6 -6
- package/dist/icons/defaults/SortNone.svelte +6 -6
- package/dist/icons/defaults/View.svelte +7 -7
- package/dist/icons/sets/bootstrap.js +2 -1
- package/dist/icons/sets/default.js +2 -0
- package/dist/icons/types.d.ts +3 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -2
- package/dist/types/attribute.d.ts +9 -0
- package/dist/types/crud.d.ts +72 -1
- package/dist/types/table.d.ts +56 -0
- package/package.json +3 -1
- package/dist/components/crud/views/List.svelte +0 -584
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
let { size = '1em', class: cls = '' }: { size?: string | number; class?: string } = $props();
|
|
3
|
-
</script>
|
|
4
|
-
<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 16 16" fill="currentColor" class={cls}>
|
|
5
|
-
<path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/>
|
|
6
|
-
</svg>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let { size = '1em', class: cls = '' }: { size?: string | number; class?: string } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 16 16" fill="currentColor" class={cls}>
|
|
5
|
+
<path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/>
|
|
6
|
+
</svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
let { size = '1em', class: cls = '' }: { size?: string | number; class?: string } = $props();
|
|
3
|
-
</script>
|
|
4
|
-
<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 16 16" fill="currentColor" class={cls}>
|
|
5
|
-
<path d="M3.646 9.146a.5.5 0 0 1 .708 0L8 12.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708zm0-2.292a.5.5 0 0 0 .708 0L8 3.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708"/>
|
|
6
|
-
</svg>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let { size = '1em', class: cls = '' }: { size?: string | number; class?: string } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 16 16" fill="currentColor" class={cls}>
|
|
5
|
+
<path d="M3.646 9.146a.5.5 0 0 1 .708 0L8 12.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708zm0-2.292a.5.5 0 0 0 .708 0L8 3.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708"/>
|
|
6
|
+
</svg>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
let { size = '1em', class: cls = '' }: { size?: string | number; class?: string } = $props();
|
|
3
|
-
</script>
|
|
4
|
-
<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 16 16" fill="currentColor" class={cls}>
|
|
5
|
-
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8M1.173 8a13 13 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5s3.879 1.168 5.168 2.457A13 13 0 0 1 14.828 8q-.086.13-.195.288c-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5s-3.879-1.168-5.168-2.457A13 13 0 0 1 1.172 8z"/>
|
|
6
|
-
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5M4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0"/>
|
|
7
|
-
</svg>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let { size = '1em', class: cls = '' }: { size?: string | number; class?: string } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 16 16" fill="currentColor" class={cls}>
|
|
5
|
+
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8M1.173 8a13 13 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5s3.879 1.168 5.168 2.457A13 13 0 0 1 14.828 8q-.086.13-.195.288c-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5s-3.879-1.168-5.168-2.457A13 13 0 0 1 1.172 8z"/>
|
|
6
|
+
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5M4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0"/>
|
|
7
|
+
</svg>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* setIconSet(bootstrapIconSet);
|
|
11
11
|
*/
|
|
12
12
|
import * as Icons from 'svelte-bootstrap-icons';
|
|
13
|
-
const { ChevronExpand, CaretUpFill, CaretDownFill, Funnel, FunnelFill, Plus, Eye, PencilSquare, Trash3, HouseDoor, Folder, EyeSlash, X, Download, } = Icons;
|
|
13
|
+
const { ChevronExpand, CaretUpFill, CaretDownFill, Funnel, FunnelFill, Plus, Eye, PencilSquare, Trash3, HouseDoor, Folder, EyeSlash, X, Download, GripVertical, } = Icons;
|
|
14
14
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
15
|
function asIcon(c) { return c; }
|
|
16
16
|
export const bootstrapIconSet = {
|
|
@@ -29,6 +29,7 @@ export const bootstrapIconSet = {
|
|
|
29
29
|
passwordShow: asIcon(Eye),
|
|
30
30
|
passwordHide: asIcon(EyeSlash),
|
|
31
31
|
download: asIcon(Download),
|
|
32
|
+
grip: asIcon(GripVertical),
|
|
32
33
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
34
|
getByName: (name) => asIcon(Icons[name]) ?? null,
|
|
34
35
|
};
|
|
@@ -13,6 +13,7 @@ import Folder from '../defaults/Folder.svelte';
|
|
|
13
13
|
import PasswordShow from '../defaults/PasswordShow.svelte';
|
|
14
14
|
import PasswordHide from '../defaults/PasswordHide.svelte';
|
|
15
15
|
import Download from '../defaults/Download.svelte';
|
|
16
|
+
import Grip from '../defaults/Grip.svelte';
|
|
16
17
|
export const defaultIconSet = {
|
|
17
18
|
sortNone: SortNone,
|
|
18
19
|
sortAsc: SortAsc,
|
|
@@ -29,4 +30,5 @@ export const defaultIconSet = {
|
|
|
29
30
|
passwordShow: PasswordShow,
|
|
30
31
|
passwordHide: PasswordHide,
|
|
31
32
|
download: Download,
|
|
33
|
+
grip: Grip,
|
|
32
34
|
};
|
package/dist/icons/types.d.ts
CHANGED
|
@@ -19,5 +19,8 @@ export interface CRUDIconSet {
|
|
|
19
19
|
passwordShow: IconComponent;
|
|
20
20
|
passwordHide: IconComponent;
|
|
21
21
|
download: IconComponent;
|
|
22
|
+
/** Drag handle shown at the start of each row when list reordering is
|
|
23
|
+
* enabled. Optional so existing custom icon sets keep compiling. */
|
|
24
|
+
grip?: IconComponent;
|
|
22
25
|
getByName?: (name: string) => IconComponent | null;
|
|
23
26
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export type { BreadcrumbItem } from './types/breadcrumb.js';
|
|
2
2
|
export { AttributeType } from './types/attribute.js';
|
|
3
3
|
export type { AttributeMetadata, InterfaceMetadata, SelectOption, OptionsResolver, FormatterResolver, EmbeddedItemLabelResolver } from './types/attribute.js';
|
|
4
|
-
export type { CellProps, CellComponent, CellFormatter, SortDirection, IndexedRow, DistinctEntry, PaginatedEnvelope, ServerPagination, FilterSnapshot, TableQuery } from './types/table.js';
|
|
5
|
-
export type { ColumnDefinition, FieldDefinition, ActionConfiguration, CustomAction, BaseCustomBulkAction, ViewBasedCustomBulkAction, EndpointBasedCustomBulkAction, CustomBulkAction, RowAction, SearchConfiguration } from './types/crud.js';
|
|
4
|
+
export type { CellProps, CellComponent, CellFormatter, SortDirection, IndexedRow, DistinctEntry, PaginatedEnvelope, ServerPagination, FilterSnapshot, TableQuery, ReorderOptions } from './types/table.js';
|
|
5
|
+
export type { ColumnDefinition, FieldDefinition, ActionConfiguration, CustomAction, BaseCustomBulkAction, ViewBasedCustomBulkAction, EndpointBasedCustomBulkAction, CustomBulkAction, RowAction, SearchConfiguration, ExportConfiguration, ReorderConfiguration, ListActions, ListConfig } from './types/crud.js';
|
|
6
6
|
export type { RuneforgeConfig } from './config/context.js';
|
|
7
7
|
export { setConfig, getConfig } from './config/context.js';
|
|
8
8
|
export type { CRUDIconSet, IconComponent } from './icons/types.js';
|
|
@@ -31,14 +31,14 @@ export { default as SortHeader } from './components/table/SortHeader.svelte';
|
|
|
31
31
|
export { default as Paginator } from './components/table/Paginator.svelte';
|
|
32
32
|
export { default as ColumnFilter } from './components/table/ColumnFilter.svelte';
|
|
33
33
|
export { SortState, FilterState, snapshotFilter } from './components/table/state.svelte.js';
|
|
34
|
-
export { cellRenderedText, isSortable, isFilterable, compare, distinctEntries } from './components/table/utils.js';
|
|
34
|
+
export { cellRenderedText, isSortable, isFilterable, compare, distinctEntries, moveIndexedRow } from './components/table/utils.js';
|
|
35
35
|
export { default as GenericCRUD } from './components/crud/GenericCRUD.svelte';
|
|
36
36
|
export { default as Field } from './components/crud/Field.svelte';
|
|
37
37
|
export { default as EmbeddedField } from './components/crud/EmbeddedField.svelte';
|
|
38
38
|
export { default as Header } from './components/common/Header.svelte';
|
|
39
39
|
export { default as AvatarCell } from './components/crud/columns/Avatar.svelte';
|
|
40
40
|
export { default as IconCell } from './components/crud/columns/Icon.svelte';
|
|
41
|
-
export { default as CRUDList } from './components/crud/views/List.svelte';
|
|
41
|
+
export { default as CRUDList } from './components/crud/views/list/List.svelte';
|
|
42
42
|
export { default as CRUDCreate } from './components/crud/views/Create.svelte';
|
|
43
43
|
export { default as CRUDRead } from './components/crud/views/Read.svelte';
|
|
44
44
|
export { default as CRUDUpdate } from './components/crud/views/Update.svelte';
|
|
@@ -50,5 +50,6 @@ export { formatBoolean, formatDatetime, formatInstance } from './components/crud
|
|
|
50
50
|
export { groupFields } from './components/crud/utils/grouping.js';
|
|
51
51
|
export type { FieldGroup } from './components/crud/utils/grouping.js';
|
|
52
52
|
export { validateAll } from './components/crud/utils/validation.js';
|
|
53
|
+
export { computeReorderChanges } from './components/crud/utils/reorder.js';
|
|
53
54
|
export { emptyRecord, defaultItemLabel } from './components/crud/utils/embedded.js';
|
|
54
55
|
export { buildChildrenByParent, collectDescendantIds } from './components/crud/utils/tree.js';
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ export { default as SortHeader } from './components/table/SortHeader.svelte';
|
|
|
27
27
|
export { default as Paginator } from './components/table/Paginator.svelte';
|
|
28
28
|
export { default as ColumnFilter } from './components/table/ColumnFilter.svelte';
|
|
29
29
|
export { SortState, FilterState, snapshotFilter } from './components/table/state.svelte.js';
|
|
30
|
-
export { cellRenderedText, isSortable, isFilterable, compare, distinctEntries } from './components/table/utils.js';
|
|
30
|
+
export { cellRenderedText, isSortable, isFilterable, compare, distinctEntries, moveIndexedRow } from './components/table/utils.js';
|
|
31
31
|
// CRUD components
|
|
32
32
|
export { default as GenericCRUD } from './components/crud/GenericCRUD.svelte';
|
|
33
33
|
export { default as Field } from './components/crud/Field.svelte';
|
|
@@ -35,7 +35,7 @@ export { default as EmbeddedField } from './components/crud/EmbeddedField.svelte
|
|
|
35
35
|
export { default as Header } from './components/common/Header.svelte';
|
|
36
36
|
export { default as AvatarCell } from './components/crud/columns/Avatar.svelte';
|
|
37
37
|
export { default as IconCell } from './components/crud/columns/Icon.svelte';
|
|
38
|
-
export { default as CRUDList } from './components/crud/views/List.svelte';
|
|
38
|
+
export { default as CRUDList } from './components/crud/views/list/List.svelte';
|
|
39
39
|
export { default as CRUDCreate } from './components/crud/views/Create.svelte';
|
|
40
40
|
export { default as CRUDRead } from './components/crud/views/Read.svelte';
|
|
41
41
|
export { default as CRUDUpdate } from './components/crud/views/Update.svelte';
|
|
@@ -47,5 +47,6 @@ export { fieldLabel, initials } from './components/crud/utils/misc.js';
|
|
|
47
47
|
export { formatBoolean, formatDatetime, formatInstance } from './components/crud/utils/formatters.js';
|
|
48
48
|
export { groupFields } from './components/crud/utils/grouping.js';
|
|
49
49
|
export { validateAll } from './components/crud/utils/validation.js';
|
|
50
|
+
export { computeReorderChanges } from './components/crud/utils/reorder.js';
|
|
50
51
|
export { emptyRecord, defaultItemLabel } from './components/crud/utils/embedded.js';
|
|
51
52
|
export { buildChildrenByParent, collectDescendantIds } from './components/crud/utils/tree.js';
|
|
@@ -75,6 +75,15 @@ export type AttributeMetadata = {
|
|
|
75
75
|
excludedFromRead?: boolean;
|
|
76
76
|
sortable?: boolean;
|
|
77
77
|
filterable?: boolean;
|
|
78
|
+
/** List column filter only: a static, exhaustive set of choices shown in
|
|
79
|
+
* the column filter's checkbox list, instead of the values sampled off
|
|
80
|
+
* currently loaded rows. For a bounded, known set (e.g. an enum-like text
|
|
81
|
+
* column) that the loaded page might not fully represent — especially
|
|
82
|
+
* under [server-side pagination](#server-side-pagination-sorting--filtering),
|
|
83
|
+
* where the sample is only a handful of values off the current page. `value`
|
|
84
|
+
* is matched against the rendered cell text (and sent server-side as-is);
|
|
85
|
+
* `label` is only what's displayed, falling back to `value`. */
|
|
86
|
+
filterOptions?: SelectOption[];
|
|
78
87
|
groupedAs?: string;
|
|
79
88
|
min?: number;
|
|
80
89
|
max?: number;
|
package/dist/types/crud.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Component } from 'svelte';
|
|
2
2
|
import type { FullAutoFill } from 'svelte/elements';
|
|
3
3
|
import type { AttributeType, SearchResolver, RequiredResolver, SelectOption } from './attribute.js';
|
|
4
|
-
import type { CellComponent, CellFormatter } from './table.js';
|
|
4
|
+
import type { CellComponent, CellFormatter, SortableModule, TableQuery } from './table.js';
|
|
5
|
+
import type { XlsxModule } from '../components/table/export.js';
|
|
5
6
|
export type ColumnDefinition<T extends object = Record<string, unknown>> = {
|
|
6
7
|
[K in keyof T & string]: {
|
|
7
8
|
attribute: K;
|
|
@@ -11,6 +12,8 @@ export type ColumnDefinition<T extends object = Record<string, unknown>> = {
|
|
|
11
12
|
formatter?: CellFormatter<T, T[K]>;
|
|
12
13
|
sortable?: boolean;
|
|
13
14
|
filterable?: boolean;
|
|
15
|
+
/** Static, exhaustive filter choices — see `AttributeMetadata.filterOptions`. */
|
|
16
|
+
filterOptions?: SelectOption[];
|
|
14
17
|
/** Embedded columns only: sub-field definitions for each item, used to
|
|
15
18
|
* render a default cell summary and to expand the column into one
|
|
16
19
|
* sub-column per field on CSV/XLSX export. */
|
|
@@ -182,3 +185,71 @@ export interface SearchConfiguration {
|
|
|
182
185
|
placeholder?: string;
|
|
183
186
|
debounceMs?: number;
|
|
184
187
|
}
|
|
188
|
+
export interface ExportConfiguration<T extends object = Record<string, unknown>> {
|
|
189
|
+
callback?: (query: TableQuery) => Promise<T[]>;
|
|
190
|
+
xlsx?: XlsxModule;
|
|
191
|
+
}
|
|
192
|
+
/** Turns on drag-to-reorder rows in the list view — off by default, enabled
|
|
193
|
+
* by providing this object (`enabled: false` keeps the configuration in
|
|
194
|
+
* place but disables dragging, e.g. temporarily). Not supported alongside
|
|
195
|
+
* [server-side pagination](#server-side-pagination-sorting--filtering): the
|
|
196
|
+
* whole row set needs to be reachable client-side for indices to stay
|
|
197
|
+
* meaningful, so `reorder` is ignored whenever a `PaginatedEnvelope` is used. */
|
|
198
|
+
export interface ReorderConfiguration<T extends object = Record<string, unknown>> {
|
|
199
|
+
enabled?: boolean;
|
|
200
|
+
/** The attribute that stores each row's order index. Establishes the
|
|
201
|
+
* default ascending order (when `compare` is absent) and is written to
|
|
202
|
+
* its new sequential 0-based value on every row whose position changes
|
|
203
|
+
* after a drag. */
|
|
204
|
+
attribute: keyof T & string;
|
|
205
|
+
/** Resolved `sortablejs` default export, e.g. `import Sortable from
|
|
206
|
+
* 'sortablejs'`. Runeforge never bundles `sortablejs` itself — install it
|
|
207
|
+
* separately and pass it in, so the dependency stays fully optional. */
|
|
208
|
+
sortable: SortableModule;
|
|
209
|
+
/** Overrides the plain `attribute`-ascending order for composite orders
|
|
210
|
+
* — e.g. a row's true resting position depends first on a related
|
|
211
|
+
* record's own order, and only then on this row's `attribute`. Takes
|
|
212
|
+
* full ownership of row order while reorder is active (column-header
|
|
213
|
+
* sorting is unavailable, same as the plain `attribute` case). */
|
|
214
|
+
compare?: (a: T, b: T) => number;
|
|
215
|
+
/** POSTed once per drag that settles with at least one changed row — a
|
|
216
|
+
* single request, not one per row — then the list is refreshed. FormData
|
|
217
|
+
* field `changes` carries a JSON-encoded array of `{ id, value }` pairs,
|
|
218
|
+
* one per row whose `attribute` changed (`value` being its new
|
|
219
|
+
* sequential position). Provide this or `callback`. */
|
|
220
|
+
endpoint?: string;
|
|
221
|
+
/** Alternative to `endpoint`: receives the rows whose `attribute` value
|
|
222
|
+
* changed, already updated to their new index. */
|
|
223
|
+
callback?: (items: T[]) => void | Promise<void>;
|
|
224
|
+
/** Drag-handle icon shown at the start of each row. Falls back to the
|
|
225
|
+
* active icon set's `grip` icon. */
|
|
226
|
+
icon?: any;
|
|
227
|
+
/** Lets dragging one row of the current checkbox selection move the
|
|
228
|
+
* whole selection together, via SortableJS's `MultiDrag` plugin (must be
|
|
229
|
+
* mounted on the `sortable` module you pass in). Off by default. */
|
|
230
|
+
multiDrag?: boolean;
|
|
231
|
+
/** While dragging, hovering over the edge zone for this long flips a
|
|
232
|
+
* page instead of requiring one long drag across the whole list.
|
|
233
|
+
* Default `2000`. */
|
|
234
|
+
pageFlipThresholdMs?: number;
|
|
235
|
+
}
|
|
236
|
+
/** Groups the list view's row-level and selection-level custom actions —
|
|
237
|
+
* `custom` replaces the old top-level `actions` prop, `bulk` replaces
|
|
238
|
+
* `customBulkActions`. */
|
|
239
|
+
export interface ListActions<T extends object = Record<string, unknown>> {
|
|
240
|
+
/** Extra per-row actions — see Custom row actions. */
|
|
241
|
+
custom?: CustomAction<T>[];
|
|
242
|
+
/** Extra actions on the current selection — see Custom bulk actions. */
|
|
243
|
+
bulk?: CustomBulkAction<T>[];
|
|
244
|
+
}
|
|
245
|
+
/** Groups the list view's opt-in behaviors. Replaces the old top-level
|
|
246
|
+
* `search`, `enableExport`/`onExport`/`xlsx` props. */
|
|
247
|
+
export interface ListConfig<T extends object = Record<string, unknown>> {
|
|
248
|
+
/** Free-text search box — see Free-text search. */
|
|
249
|
+
search?: SearchConfiguration;
|
|
250
|
+
/** CSV/Excel export. Presence of this object enables the export button —
|
|
251
|
+
* even as an empty `{}` — replacing the old `enableExport` boolean. */
|
|
252
|
+
export?: ExportConfiguration<T>;
|
|
253
|
+
/** Drag-to-reorder rows — see Reordering rows. */
|
|
254
|
+
reorder?: ReorderConfiguration<T>;
|
|
255
|
+
}
|
package/dist/types/table.d.ts
CHANGED
|
@@ -45,3 +45,59 @@ export interface TableQuery {
|
|
|
45
45
|
ordering: string | null;
|
|
46
46
|
filters: FilterSnapshot;
|
|
47
47
|
}
|
|
48
|
+
/** An instance created by `SortableModule.create()` — the only bit of it
|
|
49
|
+
* runeforge ever touches directly. */
|
|
50
|
+
export interface SortableInstance {
|
|
51
|
+
destroy(): void;
|
|
52
|
+
}
|
|
53
|
+
/** Programmatic selection API SortableJS's `MultiDrag` plugin exposes as
|
|
54
|
+
* `Sortable.utils` — used to mirror this table's own row-selection
|
|
55
|
+
* (checkboxes) into the plugin's selection state, so `multiDrag` drags
|
|
56
|
+
* whatever's currently checked instead of relying on its own click/modifier
|
|
57
|
+
* based selection UX. */
|
|
58
|
+
export interface SortableUtils {
|
|
59
|
+
select(element: HTMLElement): void;
|
|
60
|
+
deselect(element: HTMLElement): void;
|
|
61
|
+
}
|
|
62
|
+
/** Minimal duck-typed subset of the `sortablejs` module API used to drive
|
|
63
|
+
* drag-to-reorder. Runeforge never imports `sortablejs` itself — install it
|
|
64
|
+
* separately and pass the resolved default export in via `reorder.sortable`
|
|
65
|
+
* (or `ReorderConfiguration.sortable` on `GenericCRUD`), so the dependency
|
|
66
|
+
* stays fully optional, mirroring `xlsx` for export. Pass `MultiDrag`
|
|
67
|
+
* pre-mounted (`Sortable.mount(new MultiDrag())`) on the module you hand in
|
|
68
|
+
* if you're using `multiDrag`. */
|
|
69
|
+
export interface SortableModule {
|
|
70
|
+
create(element: HTMLElement, options?: Record<string, any>): SortableInstance;
|
|
71
|
+
utils?: SortableUtils;
|
|
72
|
+
}
|
|
73
|
+
/** Enables the drag-to-reorder row layer on `PaginatedTable`/`TableBody`.
|
|
74
|
+
* Presence of this object is what turns dragging on — per-column filtering
|
|
75
|
+
* is suppressed while it's active (dragging needs the full, unfiltered row
|
|
76
|
+
* set reachable), and row order is fully owned by `compare`/`attribute`
|
|
77
|
+
* rather than column-header sorting. Pagination stays on; crossing a page
|
|
78
|
+
* boundary mid-drag is done via the edge hover zones (see
|
|
79
|
+
* `pageFlipThresholdMs`), not by disabling pagination. */
|
|
80
|
+
export interface ReorderOptions<T extends object = Record<string, unknown>> {
|
|
81
|
+
/** The attribute establishing the default ascending order, used when
|
|
82
|
+
* `compare` is not provided. */
|
|
83
|
+
attribute: keyof T & string;
|
|
84
|
+
/** Resolved `sortablejs` module — see the interface doc above. */
|
|
85
|
+
sortable: SortableModule;
|
|
86
|
+
/** Overrides the plain `attribute`-ascending order for cases where the
|
|
87
|
+
* true resting order depends on more than the row's own attribute (e.g.
|
|
88
|
+
* a parent's order first, then this row's own order within it). Takes
|
|
89
|
+
* full ownership of row order while reorder is active. */
|
|
90
|
+
compare?: (a: T, b: T) => number;
|
|
91
|
+
/** Drag-handle icon shown at the start of each row. Falls back to the
|
|
92
|
+
* active icon set's `grip` icon. */
|
|
93
|
+
icon?: any;
|
|
94
|
+
/** Lets dragging one row of the current checkbox selection move the
|
|
95
|
+
* whole selection together, via SortableJS's `MultiDrag` plugin (must be
|
|
96
|
+
* mounted on the `sortable` module you pass in). Off by default. */
|
|
97
|
+
multiDrag?: boolean;
|
|
98
|
+
/** While dragging, hovering the pointer over the narrow zone at either
|
|
99
|
+
* edge of the table for this long flips to the previous/next page —
|
|
100
|
+
* lets a row travel across pages without an unwieldy long drag. Repeated
|
|
101
|
+
* hovering (without leaving the zone) keeps flipping. Default `2000`. */
|
|
102
|
+
pageFlipThresholdMs?: number;
|
|
103
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "runeforge",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.55",
|
|
4
4
|
"description": "SvelteKit toolkit for building metadata-driven CRUD interfaces with tables, forms, and actions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ezequiel Puerta",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
50
50
|
"@tailwindcss/vite": "^4.3.1",
|
|
51
51
|
"@types/node": "^22",
|
|
52
|
+
"@types/sortablejs": "^1.15.9",
|
|
52
53
|
"daisyui": "^5.5.23",
|
|
53
54
|
"eslint": "^10.4.1",
|
|
54
55
|
"eslint-config-prettier": "^10.1.8",
|
|
@@ -57,6 +58,7 @@
|
|
|
57
58
|
"prettier": "^3.8.3",
|
|
58
59
|
"prettier-plugin-svelte": "^4.1.0",
|
|
59
60
|
"publint": "^0.3.21",
|
|
61
|
+
"sortablejs": "^1.15.7",
|
|
60
62
|
"svelte": "^5.56.1",
|
|
61
63
|
"svelte-bootstrap-icons": "^3.3.0",
|
|
62
64
|
"svelte-check": "^4.6.0",
|