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.
Files changed (78) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1342 -1222
  3. package/dist/components/Avatar.svelte +31 -31
  4. package/dist/components/IconRenderer.svelte +22 -22
  5. package/dist/components/Modal.svelte +75 -75
  6. package/dist/components/common/Header.svelte +40 -40
  7. package/dist/components/crud/EmbeddedField.svelte +175 -175
  8. package/dist/components/crud/Field.svelte +376 -376
  9. package/dist/components/crud/GenericCRUD.svelte +426 -435
  10. package/dist/components/crud/GenericCRUD.svelte.d.ts +6 -9
  11. package/dist/components/crud/SearchInput.svelte +53 -53
  12. package/dist/components/crud/columns/Avatar.svelte +15 -15
  13. package/dist/components/crud/columns/Icon.svelte +8 -8
  14. package/dist/components/crud/utils/reorder.d.ts +4 -0
  15. package/dist/components/crud/utils/reorder.js +13 -0
  16. package/dist/components/crud/views/Create.svelte +232 -232
  17. package/dist/components/crud/views/Read.svelte +124 -124
  18. package/dist/components/crud/views/Update.svelte +208 -208
  19. package/dist/components/crud/views/list/List.svelte +291 -0
  20. package/dist/components/crud/views/{List.svelte.d.ts → list/List.svelte.d.ts} +4 -14
  21. package/dist/components/crud/views/list/Modals.svelte +56 -0
  22. package/dist/components/crud/views/list/Modals.svelte.d.ts +36 -0
  23. package/dist/components/crud/views/list/Table.svelte +176 -0
  24. package/dist/components/crud/views/list/Table.svelte.d.ts +59 -0
  25. package/dist/components/crud/views/list/Toolbar.svelte +341 -0
  26. package/dist/components/crud/views/list/Toolbar.svelte.d.ts +46 -0
  27. package/dist/components/form/Button.svelte +27 -27
  28. package/dist/components/form/Label.svelte +37 -37
  29. package/dist/components/form/MultiSelect.svelte +248 -248
  30. package/dist/components/form/PasswordInput.svelte +68 -68
  31. package/dist/components/form/Required.svelte +1 -1
  32. package/dist/components/form/Select.svelte +209 -209
  33. package/dist/components/form/Tree.svelte +62 -62
  34. package/dist/components/form/TreeNode.svelte +66 -66
  35. package/dist/components/navigation/Breadcrumbs.svelte +111 -111
  36. package/dist/components/table/ColumnFilter.svelte +168 -168
  37. package/dist/components/table/PaginatedTable.svelte +536 -215
  38. package/dist/components/table/PaginatedTable.svelte.d.ts +11 -2
  39. package/dist/components/table/Paginator.svelte +113 -113
  40. package/dist/components/table/SortHeader.svelte +43 -43
  41. package/dist/components/table/TableBody.svelte +150 -70
  42. package/dist/components/table/TableBody.svelte.d.ts +14 -1
  43. package/dist/components/table/TableHeader.svelte +88 -83
  44. package/dist/components/table/TableHeader.svelte.d.ts +1 -0
  45. package/dist/components/table/sortable.d.ts +27 -0
  46. package/dist/components/table/sortable.js +55 -0
  47. package/dist/components/table/utils.d.ts +28 -1
  48. package/dist/components/table/utils.js +75 -0
  49. package/dist/i18n/en.js +2 -0
  50. package/dist/i18n/es.js +2 -0
  51. package/dist/i18n/types.d.ts +2 -0
  52. package/dist/icons/defaults/Clear.svelte +6 -6
  53. package/dist/icons/defaults/Create.svelte +6 -6
  54. package/dist/icons/defaults/Delete.svelte +6 -6
  55. package/dist/icons/defaults/Download.svelte +7 -7
  56. package/dist/icons/defaults/Edit.svelte +7 -7
  57. package/dist/icons/defaults/Filter.svelte +6 -6
  58. package/dist/icons/defaults/FilterActive.svelte +6 -6
  59. package/dist/icons/defaults/Folder.svelte +6 -6
  60. package/dist/icons/defaults/Grip.svelte +7 -0
  61. package/dist/icons/defaults/Grip.svelte.d.ts +7 -0
  62. package/dist/icons/defaults/Home.svelte +6 -6
  63. package/dist/icons/defaults/PasswordHide.svelte +9 -9
  64. package/dist/icons/defaults/PasswordShow.svelte +7 -7
  65. package/dist/icons/defaults/SortAsc.svelte +6 -6
  66. package/dist/icons/defaults/SortDesc.svelte +6 -6
  67. package/dist/icons/defaults/SortNone.svelte +6 -6
  68. package/dist/icons/defaults/View.svelte +7 -7
  69. package/dist/icons/sets/bootstrap.js +2 -1
  70. package/dist/icons/sets/default.js +2 -0
  71. package/dist/icons/types.d.ts +3 -0
  72. package/dist/index.d.ts +5 -4
  73. package/dist/index.js +3 -2
  74. package/dist/types/attribute.d.ts +9 -0
  75. package/dist/types/crud.d.ts +72 -1
  76. package/dist/types/table.d.ts +56 -0
  77. package/package.json +3 -1
  78. package/dist/components/crud/views/List.svelte +0 -584
@@ -1,7 +1,5 @@
1
- import type { XlsxModule } from '../table/export.js';
2
1
  import type { AttributeMetadata } from '../../types/attribute.js';
3
- import type { ActionConfiguration, ColumnDefinition, CustomAction, CustomBulkAction, FieldDefinition, SearchConfiguration } from '../../types/crud.js';
4
- import type { TableQuery } from '../../types/table.js';
2
+ import type { ActionConfiguration, ColumnDefinition, FieldDefinition, ListActions, ListConfig } from '../../types/crud.js';
5
3
  declare function $$render<T extends object = Record<string, unknown>>(): {
6
4
  props: {
7
5
  data?: Record<string, unknown>;
@@ -15,18 +13,17 @@ declare function $$render<T extends object = Record<string, unknown>>(): {
15
13
  update?: ActionConfiguration<T>;
16
14
  read?: ActionConfiguration<T>;
17
15
  deletion?: ActionConfiguration<T>;
18
- actions?: CustomAction<T>[];
19
- customBulkActions?: CustomBulkAction<T>[];
20
- search?: SearchConfiguration;
16
+ /** Extra per-row (`custom`) and per-selection (`bulk`) actions. */
17
+ actions?: ListActions<T>;
18
+ /** Opt-in list behaviors: free-text search, CSV/Excel export, and
19
+ * drag-to-reorder. */
20
+ config?: ListConfig<T>;
21
21
  columns?: ColumnDefinition<T>[];
22
22
  fields?: FieldDefinition<T>[];
23
23
  meta?: Partial<Record<string, AttributeMetadata>>;
24
24
  form?: {
25
25
  error?: string;
26
26
  } | null;
27
- enableExport?: boolean;
28
- onExport?: (query: TableQuery) => Promise<T[]>;
29
- xlsx?: XlsxModule;
30
27
  };
31
28
  exports: {};
32
29
  bindings: "";
@@ -1,53 +1,53 @@
1
- <script lang="ts">
2
- import { page } from '$app/state';
3
- import { goto } from '$app/navigation';
4
- import { getStrings } from '../../i18n/context.js';
5
- import type { SearchConfiguration } from '../../types/crud.js';
6
-
7
- const strings = getStrings();
8
-
9
- let {
10
- config = {} as SearchConfiguration
11
- }: {
12
- config?: SearchConfiguration;
13
- } = $props();
14
-
15
- const param = $derived(config.param ?? 'search');
16
- const debounceMs = $derived(config.debounceMs ?? 300);
17
-
18
- // Intentional one-time hydration of local state from the initial `param`
19
- // value (not a live binding) - svelte-check's state_referenced_locally
20
- // warning is a false positive here, same as PaginatedTable's initialSort
21
- // etc. After mount this is the source of truth for what the user is
22
- // typing, so it doesn't fight with the URL updates this component itself
23
- // triggers on every keystroke.
24
- let value = $state(page.url.searchParams.get(param) ?? '');
25
- let debounceTimer: ReturnType<typeof setTimeout>;
26
-
27
- function onInput() {
28
- clearTimeout(debounceTimer);
29
- debounceTimer = setTimeout(() => {
30
- // eslint-disable-next-line svelte/prefer-svelte-reactivity
31
- const params = new URLSearchParams(page.url.searchParams);
32
- const trimmed = value.trim();
33
- if (trimmed) params.set(param, trimmed);
34
- else params.delete(param);
35
- // A new search term can leave the current page past the end of the
36
- // narrowed result set, and any open create/read/edit view stops
37
- // making sense once the underlying list changes - drop both.
38
- params.delete('page');
39
- params.delete('view');
40
- params.delete('id');
41
- const qs = params.toString();
42
- goto(qs ? `?${qs}` : '?', { keepFocus: true, noScroll: true, replaceState: true });
43
- }, debounceMs);
44
- }
45
- </script>
46
-
47
- <input
48
- type="search"
49
- bind:value
50
- oninput={onInput}
51
- placeholder={config.placeholder ?? strings.searchPlaceholder}
52
- class="input input-bordered w-64 shrink-0"
53
- />
1
+ <script lang="ts">
2
+ import { page } from '$app/state';
3
+ import { goto } from '$app/navigation';
4
+ import { getStrings } from '../../i18n/context.js';
5
+ import type { SearchConfiguration } from '../../types/crud.js';
6
+
7
+ const strings = getStrings();
8
+
9
+ let {
10
+ config = {} as SearchConfiguration
11
+ }: {
12
+ config?: SearchConfiguration;
13
+ } = $props();
14
+
15
+ const param = $derived(config.param ?? 'search');
16
+ const debounceMs = $derived(config.debounceMs ?? 300);
17
+
18
+ // Intentional one-time hydration of local state from the initial `param`
19
+ // value (not a live binding) - svelte-check's state_referenced_locally
20
+ // warning is a false positive here, same as PaginatedTable's initialSort
21
+ // etc. After mount this is the source of truth for what the user is
22
+ // typing, so it doesn't fight with the URL updates this component itself
23
+ // triggers on every keystroke.
24
+ let value = $state(page.url.searchParams.get(param) ?? '');
25
+ let debounceTimer: ReturnType<typeof setTimeout>;
26
+
27
+ function onInput() {
28
+ clearTimeout(debounceTimer);
29
+ debounceTimer = setTimeout(() => {
30
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
31
+ const params = new URLSearchParams(page.url.searchParams);
32
+ const trimmed = value.trim();
33
+ if (trimmed) params.set(param, trimmed);
34
+ else params.delete(param);
35
+ // A new search term can leave the current page past the end of the
36
+ // narrowed result set, and any open create/read/edit view stops
37
+ // making sense once the underlying list changes - drop both.
38
+ params.delete('page');
39
+ params.delete('view');
40
+ params.delete('id');
41
+ const qs = params.toString();
42
+ goto(qs ? `?${qs}` : '?', { keepFocus: true, noScroll: true, replaceState: true });
43
+ }, debounceMs);
44
+ }
45
+ </script>
46
+
47
+ <input
48
+ type="search"
49
+ bind:value
50
+ oninput={onInput}
51
+ placeholder={config.placeholder ?? strings.searchPlaceholder}
52
+ class="input input-bordered w-64 shrink-0"
53
+ />
@@ -1,15 +1,15 @@
1
- <script lang="ts">
2
- import AvatarComponent from '../../Avatar.svelte';
3
- import { initials } from '../utils/misc.js';
4
- import type { CellProps } from '../../../types/table.js';
5
-
6
- type AvatarRow = { firstName?: string; lastName?: string; email?: string };
7
-
8
- let { value, row }: CellProps<AvatarRow, string | null | undefined> = $props();
9
- </script>
10
-
11
- <AvatarComponent
12
- src={value ?? null}
13
- text={initials(row.firstName, row.lastName)}
14
- alt={row.email ?? ''}
15
- />
1
+ <script lang="ts">
2
+ import AvatarComponent from '../../Avatar.svelte';
3
+ import { initials } from '../utils/misc.js';
4
+ import type { CellProps } from '../../../types/table.js';
5
+
6
+ type AvatarRow = { firstName?: string; lastName?: string; email?: string };
7
+
8
+ let { value, row }: CellProps<AvatarRow, string | null | undefined> = $props();
9
+ </script>
10
+
11
+ <AvatarComponent
12
+ src={value ?? null}
13
+ text={initials(row.firstName, row.lastName)}
14
+ alt={row.email ?? ''}
15
+ />
@@ -1,8 +1,8 @@
1
- <script lang="ts">
2
- import IconRenderer from '../../IconRenderer.svelte';
3
- import type { CellProps } from '../../../types/table.js';
4
-
5
- let { value }: CellProps<Record<string, unknown>, string> = $props();
6
- </script>
7
-
8
- <IconRenderer name={String(value ?? '')} />
1
+ <script lang="ts">
2
+ import IconRenderer from '../../IconRenderer.svelte';
3
+ import type { CellProps } from '../../../types/table.js';
4
+
5
+ let { value }: CellProps<Record<string, unknown>, string> = $props();
6
+ </script>
7
+
8
+ <IconRenderer name={String(value ?? '')} />
@@ -0,0 +1,4 @@
1
+ /** Given the full row list in its new (post-drag) order, returns copies of
2
+ * only the rows whose `attribute` no longer matches their new sequential
3
+ * (0-based) position — the minimal set worth persisting. */
4
+ export declare function computeReorderChanges<T extends object>(rows: T[], attribute: keyof T & string): T[];
@@ -0,0 +1,13 @@
1
+ /** Given the full row list in its new (post-drag) order, returns copies of
2
+ * only the rows whose `attribute` no longer matches their new sequential
3
+ * (0-based) position — the minimal set worth persisting. */
4
+ export function computeReorderChanges(rows, attribute) {
5
+ const changed = [];
6
+ rows.forEach((row, index) => {
7
+ const current = Number(row[attribute]);
8
+ if (current !== index) {
9
+ changed.push({ ...row, [attribute]: index });
10
+ }
11
+ });
12
+ return changed;
13
+ }