runeforge 0.0.19 → 0.0.20

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.
@@ -43,6 +43,16 @@
43
43
  const preview = $derived(filePreview ?? (typeof saved === 'string' && saved ? saved : null));
44
44
  const avatarInitials = $derived(initials(record.firstName as string, record.lastName as string));
45
45
  const displayValue = $derived(saved == null ? '' : String(saved));
46
+ const selectOptions = $derived(field.dependentOptions ? field.dependentOptions(record) : (field.options ?? []));
47
+ const selectDisabled = $derived(field.disabled ? field.disabled(record) : false);
48
+
49
+ $effect(() => {
50
+ if (!field.dependentOptions) return;
51
+ const current = record[field.attribute];
52
+ if (current && !selectOptions.some((o) => o.value === String(current))) {
53
+ record[field.attribute] = '';
54
+ }
55
+ });
46
56
  </script>
47
57
 
48
58
  <div class="flex flex-col gap-1">
@@ -86,15 +96,16 @@
86
96
  type="text"
87
97
  id={field.attribute}
88
98
  class="input input-bordered w-full"
89
- value={field.options?.find((o) => o.value === String(saved))?.label ?? displayValue}
99
+ value={selectOptions.find((o) => o.value === String(saved))?.label ?? displayValue}
90
100
  disabled
91
101
  />
92
102
  {:else}
93
103
  <Select
94
104
  name={field.attribute}
95
105
  bind:value={record[field.attribute] as string}
96
- options={field.options ?? []}
106
+ options={selectOptions}
97
107
  placeholder={field.placeholder}
108
+ disabled={selectDisabled}
98
109
  {error}
99
110
  />
100
111
  {/if}
@@ -72,13 +72,8 @@
72
72
  fields?: FieldDefinition<T>[];
73
73
  meta?: Partial<Record<string, AttributeMetadata>>;
74
74
  form?: { error?: string } | null;
75
- /** Shows an icon-only export button (CSV, and Excel if `xlsx` is provided). */
76
75
  enableExport?: boolean;
77
- /** Server-pagination mode only: fetch all rows matching the current query
78
- * (unpaginated) for export. Without it, export falls back to the loaded page. */
79
76
  onExport?: (query: TableQuery) => Promise<T[]>;
80
- /** Resolved `xlsx` (SheetJS) module, e.g. `import * as xlsx from 'xlsx'`.
81
- * Enables the "Export as Excel" option; omit to only offer CSV. */
82
77
  xlsx?: XlsxModule;
83
78
  } = $props();
84
79
 
@@ -241,7 +236,12 @@
241
236
  autocomplete: m.autocomplete,
242
237
  placeholder: m.placeholder,
243
238
  default: m.default,
244
- options: resolveOptions(m, data)
239
+ options: resolveOptions(m, data),
240
+ dependentOptions: m.dependentOptions
241
+ ? (record: Record<string, unknown>) => m.dependentOptions!(data, record)
242
+ : undefined,
243
+ disabled: m.disabled,
244
+ seed: m.seed
245
245
  }))
246
246
  : entityData.length > 0
247
247
  ? (Object.entries(entityData[0]) as [string, unknown][])
@@ -263,7 +263,12 @@
263
263
  autocomplete: m.autocomplete,
264
264
  placeholder: m.placeholder,
265
265
  default: m.default,
266
- options: resolveOptions(m, data)
266
+ options: resolveOptions(m, data),
267
+ dependentOptions: m.dependentOptions
268
+ ? (record: Record<string, unknown>) => m.dependentOptions!(data, record)
269
+ : undefined,
270
+ disabled: m.disabled,
271
+ seed: m.seed
267
272
  }))
268
273
  : entityData.length > 0
269
274
  ? (Object.entries(entityData[0]) as [string, unknown][])
@@ -285,7 +290,12 @@
285
290
  autocomplete: m.autocomplete,
286
291
  placeholder: m.placeholder,
287
292
  default: m.default,
288
- options: resolveOptions(m, data)
293
+ options: resolveOptions(m, data),
294
+ dependentOptions: m.dependentOptions
295
+ ? (record: Record<string, unknown>) => m.dependentOptions!(data, record)
296
+ : undefined,
297
+ disabled: m.disabled,
298
+ seed: m.seed
289
299
  }))
290
300
  : entityData.length > 0
291
301
  ? (Object.entries(entityData[0]) as [string, unknown][])
@@ -24,13 +24,8 @@ declare function $$render<T extends object = Record<string, unknown>>(): {
24
24
  form?: {
25
25
  error?: string;
26
26
  } | null;
27
- /** Shows an icon-only export button (CSV, and Excel if `xlsx` is provided). */
28
27
  enableExport?: boolean;
29
- /** Server-pagination mode only: fetch all rows matching the current query
30
- * (unpaginated) for export. Without it, export falls back to the loaded page. */
31
28
  onExport?: (query: TableQuery) => Promise<T[]>;
32
- /** Resolved `xlsx` (SheetJS) module, e.g. `import * as xlsx from 'xlsx'`.
33
- * Enables the "Export as Excel" option; omit to only offer CSV. */
34
29
  xlsx?: XlsxModule;
35
30
  };
36
31
  exports: {};
@@ -47,7 +47,8 @@
47
47
  const seeded: Record<string, unknown> = { ...inst };
48
48
  for (const f of fields) {
49
49
  if (f.type !== 'boolean' && f.type !== 'file') {
50
- seeded[f.attribute] = String(inst[f.attribute] ?? '');
50
+ const raw = f.seed ? f.seed(inst) : inst[f.attribute];
51
+ seeded[f.attribute] = String(raw ?? '');
51
52
  }
52
53
  }
53
54
  return seeded;
@@ -19,10 +19,16 @@ export type SelectOption = {
19
19
  };
20
20
  export type OptionsResolver = SelectOption[] | ((data: any) => SelectOption[]);
21
21
  export type FormatterResolver = (data?: any) => CellFormatter<any, any>;
22
+ export type DependentOptionsResolver = (data: any, record: Record<string, unknown>) => SelectOption[];
23
+ export type DisabledResolver = (record: Record<string, unknown>) => boolean;
24
+ export type SeedResolver = (instance: any) => unknown;
22
25
  export type AttributeMetadata = {
23
26
  label?: string;
24
27
  type?: AttributeType;
25
28
  options?: OptionsResolver;
29
+ dependentOptions?: DependentOptionsResolver;
30
+ disabled?: DisabledResolver;
31
+ seed?: SeedResolver;
26
32
  component?: CellComponent<any, any>;
27
33
  formatter?: FormatterResolver;
28
34
  required?: boolean;
@@ -25,6 +25,12 @@ export interface FieldDefinition<T extends object = Record<string, unknown>> {
25
25
  value: string;
26
26
  label: string;
27
27
  }[];
28
+ dependentOptions?: (record: Record<string, unknown>) => {
29
+ value: string;
30
+ label: string;
31
+ }[];
32
+ disabled?: (record: Record<string, unknown>) => boolean;
33
+ seed?: (instance: any) => unknown;
28
34
  }
29
35
  export interface ActionConfiguration<T extends object = Record<string, unknown>> {
30
36
  enabled?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runeforge",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
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",