fuma 0.2.3 → 0.3.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.
Files changed (70) hide show
  1. package/dist/api/client.d.ts +3 -0
  2. package/dist/api/client.js +24 -0
  3. package/dist/api/config.d.ts +46 -0
  4. package/dist/api/config.js +7 -0
  5. package/dist/api/index.d.ts +3 -0
  6. package/dist/api/index.js +3 -0
  7. package/dist/api/server.d.ts +11 -0
  8. package/dist/api/server.js +17 -0
  9. package/dist/{Meta.svelte → private/Meta.svelte} +4 -4
  10. package/dist/private/api.d.ts +47 -0
  11. package/dist/private/api.js +9 -0
  12. package/dist/private/model.d.ts +40 -0
  13. package/dist/private/model.js +17 -0
  14. package/dist/server/auth.js +1 -1
  15. package/dist/server/formAction.d.ts +14 -0
  16. package/dist/server/formAction.js +8 -0
  17. package/dist/server/index.d.ts +1 -0
  18. package/dist/server/index.js +1 -0
  19. package/dist/server/parseFormData.d.ts +7 -17
  20. package/dist/server/parseFormData.js +11 -6
  21. package/dist/server/parseQuery.d.ts +1 -10
  22. package/dist/server/parseQuery.js +4 -5
  23. package/dist/server/try.d.ts +5 -2
  24. package/dist/server/try.js +15 -4
  25. package/dist/ui/drawer/Drawer.svelte +19 -11
  26. package/dist/ui/drawer/Drawer.svelte.d.ts +42 -7
  27. package/dist/ui/drawer/layers.d.ts +2 -1
  28. package/dist/ui/drawer/layers.js +5 -5
  29. package/dist/ui/form/Form.svelte +50 -25
  30. package/dist/ui/form/Form.svelte.d.ts +23 -13
  31. package/dist/ui/form/FormInput.svelte +4 -2
  32. package/dist/ui/form/FormInput.svelte.d.ts +116 -0
  33. package/dist/ui/form/form.d.ts +22 -9
  34. package/dist/ui/form/form.js +38 -0
  35. package/dist/ui/form/formInput.d.ts +1 -1
  36. package/dist/ui/input/FormControl.svelte.d.ts +1 -1
  37. package/dist/ui/input/InputBoolean.svelte.d.ts +2 -2
  38. package/dist/ui/input/InputCheckboxs.svelte.d.ts +2 -2
  39. package/dist/ui/input/InputCheckboxsMenu.svelte +5 -5
  40. package/dist/ui/input/InputCheckboxsMenu.svelte.d.ts +2 -2
  41. package/dist/ui/input/InputCombo.svelte.d.ts +2 -2
  42. package/dist/ui/input/InputNumber.svelte.d.ts +1 -1
  43. package/dist/ui/input/InputPassword.svelte.d.ts +2 -2
  44. package/dist/ui/input/InputRadio.svelte.d.ts +2 -2
  45. package/dist/ui/input/InputRelation.svelte +7 -2
  46. package/dist/ui/input/InputRelations.svelte +7 -3
  47. package/dist/ui/input/InputText.svelte.d.ts +2 -2
  48. package/dist/ui/input/RelationAfter.svelte +7 -1
  49. package/dist/ui/input/textRich/InputTextRich.svelte.d.ts +1 -1
  50. package/dist/ui/input/types.d.ts +2 -2
  51. package/dist/ui/login/Login.svelte +7 -3
  52. package/dist/ui/menu/DropDownMenu.svelte +2 -1
  53. package/dist/ui/menu/DropDownMenu.svelte.d.ts +2 -0
  54. package/dist/ui/slot/Slot.svelte +3 -1
  55. package/dist/ui/slot/Slot.svelte.d.ts +22 -0
  56. package/dist/ui/table/field.d.ts +1 -1
  57. package/dist/utils/constant.d.ts +1 -0
  58. package/dist/utils/constant.js +1 -0
  59. package/dist/utils/index.d.ts +1 -0
  60. package/dist/utils/index.js +1 -0
  61. package/dist/utils/jsonParse.d.ts +1 -1
  62. package/dist/utils/jsonParse.js +5 -3
  63. package/dist/validation/form.d.ts +6 -5
  64. package/dist/validation/form.js +8 -8
  65. package/dist/validation/zod.d.ts +79 -19
  66. package/dist/validation/zod.js +16 -18
  67. package/package.json +12 -7
  68. /package/dist/{Meta.svelte.d.ts → private/Meta.svelte.d.ts} +0 -0
  69. /package/dist/{server → private}/prisma.d.ts +0 -0
  70. /package/dist/{server → private}/prisma.js +0 -0
@@ -1,4 +1,4 @@
1
- import { derived, get, writable } from 'svelte/store';
1
+ import { derived, writable } from 'svelte/store';
2
2
  import { page } from '$app/stores';
3
3
  import { browser } from '$app/environment';
4
4
  const layers = writable([]);
@@ -6,14 +6,13 @@ const layersOffset = derived(layers, ($layers) => {
6
6
  const nbDrawer = $layers.length;
7
7
  return $layers.reduce((acc, layer, index) => {
8
8
  const drawerOffset = nbDrawer - index - 1;
9
- console.log({ drawerOffset });
10
9
  return { ...acc, [layer]: drawerOffset };
11
10
  }, {});
12
11
  });
13
- export function subscibeDrawerLayers(key, value) {
12
+ export function subscibeDrawerLayers(key) {
14
13
  const layerId = Math.random().toString().slice(2, 12);
15
14
  let isInitialized = false;
16
- const isActive = derived(page, ({ url }) => url.searchParams.get(key) === value, false);
15
+ const isActive = derived(page, ({ url }) => url.searchParams.has(key), false);
17
16
  const isActiveUnsubscribe = isActive.subscribe(($isActive) => {
18
17
  if ($isActive)
19
18
  addLayer();
@@ -42,7 +41,8 @@ export function subscibeDrawerLayers(key, value) {
42
41
  }
43
42
  return {
44
43
  isActive,
45
- offset: derived(layersOffset, (drawers) => drawers[layerId]),
44
+ index: derived(layers, ($layers) => $layers.indexOf(layerId)),
45
+ offset: derived(layersOffset, (offsets) => offsets[layerId]),
46
46
  destroy() {
47
47
  removeLayer();
48
48
  isActiveUnsubscribe();
@@ -1,44 +1,72 @@
1
- <script>import { contextContainer } from "../context.js";
2
- import { createEventDispatcher, onMount } from "svelte";
1
+ <script context="module"></script>
2
+
3
+ <script
4
+
5
+ generics="Shape extends z.ZodRawShape, Data extends FormDataInput<Shape> = FormDataInput<Shape>"
6
+ >import { createEventDispatcher, onMount } from "svelte";
3
7
  import { fade } from "svelte/transition";
4
8
  import { page } from "$app/stores";
9
+ import { contextContainer } from "../context.js";
5
10
  import {
6
11
  initData,
7
- getFieldType
12
+ getFieldType,
13
+ useHandleInput
8
14
  } from "./form.js";
15
+ import ButtonDelete from "../button/ButtonDelete.svelte";
9
16
  import { useForm } from "../../validation/form.js";
10
- import Input from "./FormInput.svelte";
17
+ import FormInput from "./FormInput.svelte";
11
18
  import FormSection from "./FormSection.svelte";
12
19
  let klass = "";
13
20
  export { klass as class };
14
21
  export let classSection = "";
15
22
  export let classAction = "";
23
+ export let model = void 0;
16
24
  export let fields = [];
17
25
  export let sections = [{}];
18
- export let data = initData(fields);
19
26
  export let action = "";
20
- export let actionDelete = "";
21
- export let actionPrefix = "";
27
+ export let actionCreate = "_create";
28
+ export let actionDelete = "_delete";
29
+ export let actionUpdate = "_update";
22
30
  export let options = {};
31
+ let dataInput = initData(fields);
32
+ export { dataInput as data };
33
+ let data = dataInput;
34
+ $:
35
+ $isDirty ? dataInput = data : data = dataInput;
23
36
  export function set(key, value) {
37
+ isDirty.set(true);
24
38
  data[key] = value;
25
39
  }
40
+ export function update(updater) {
41
+ isDirty.set(true);
42
+ data = updater(data);
43
+ }
26
44
  const dispatch = createEventDispatcher();
27
- const { enhance } = useForm({
45
+ const { enhance, setError } = useForm({
28
46
  ...options,
29
- onSuccess(action2, data2) {
30
- dispatch("success", { action: action2, data: data2 });
47
+ async onSuccess(url, data2) {
31
48
  if (options.onSuccess)
32
- options.onSuccess(action2, data2);
49
+ await options.onSuccess(url, data2);
50
+ dispatch("success", { action: url, data: data2 });
51
+ const actionPath = url.pathname + url.search;
52
+ if (actionPath.includes(action + actionDelete))
53
+ dispatch("deleted");
54
+ if (!data2)
55
+ return;
56
+ if (actionPath.includes(action + actionCreate))
57
+ dispatch("created", data2);
58
+ if (actionPath.includes(action + actionUpdate))
59
+ dispatch("updated", data2);
33
60
  }
34
61
  });
62
+ const { handleInput, isDirty } = useHandleInput({ model, setError });
35
63
  onMount(lookupValueFromParams);
36
64
  function lookupValueFromParams() {
37
65
  fields.flat().forEach(({ key }) => {
38
66
  if (data[key])
39
67
  return;
40
68
  const value = $page.url.searchParams.get(key);
41
- if (value)
69
+ if (value && key in data)
42
70
  data[key] = value;
43
71
  });
44
72
  }
@@ -56,11 +84,14 @@ const getBoolean = (bool) => (_data) => typeof bool === "boolean" || bool === vo
56
84
 
57
85
  <form
58
86
  method="post"
59
- action="{actionPrefix}{action}"
87
+ action="{action}{data.id ? actionUpdate : actionCreate}"
60
88
  enctype="multipart/form-data"
61
89
  class="{klass} flex flex-col gap-4"
62
90
  use:enhance
91
+ on:input={handleInput}
63
92
  >
93
+ <slot />
94
+
64
95
  {#if data.id}
65
96
  <input type="hidden" name="id" value={data.id} />
66
97
  {/if}
@@ -78,7 +109,7 @@ const getBoolean = (bool) => (_data) => typeof bool === "boolean" || bool === vo
78
109
  style={`grid-column: span ${field.colSpan || 2};`}
79
110
  in:fade|local={{ duration: 200 }}
80
111
  >
81
- <Input
112
+ <FormInput
82
113
  key={field.key}
83
114
  type={inputType}
84
115
  bind:value={data[field.key]}
@@ -96,19 +127,13 @@ const getBoolean = (bool) => (_data) => typeof bool === "boolean" || bool === vo
96
127
  <div
97
128
  class="
98
129
  {classAction} {actionPadding}
99
- sticky bottom-0 col-span-full mt-2 flex gap-2 border-t py-4 backdrop-blur-sm
130
+ sticky bottom-0 col-span-full mt-2 flex flex-row-reverse gap-2 border-t py-4 backdrop-blur-sm
100
131
  "
101
132
  >
102
- {#if actionDelete}
103
- <button
104
- class="btn-ghos btn text-error"
105
- type="button"
106
- formaction="{actionPrefix}{actionDelete}"
107
- >
108
- Supprimer
109
- </button>
110
- {/if}
111
- <div class="grow" />
112
133
  <button class="btn btn-primary"> Valider </button>
134
+ <div class="grow" />
135
+ {#if data.id && actionDelete}
136
+ <ButtonDelete formaction="{action}{actionDelete}">Supprimer</ButtonDelete>
137
+ {/if}
113
138
  </div>
114
139
  </form>
@@ -1,35 +1,45 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import type { z } from 'zod';
3
- import { type FormField, type FormSectionProps } from './form.js';
3
+ import type { FormDataInput } from './form.js';
4
+ import { type FormField, type FormSectionProps, type Nullable } from './form.js';
4
5
  import { type UseFormOptions } from '../../validation/form.js';
5
- declare class __sveltets_Render<Shape extends z.ZodRawShape> {
6
+ declare class __sveltets_Render<Shape extends z.ZodRawShape, Data extends FormDataInput<Shape> = FormDataInput<Shape>> {
6
7
  props(): {
7
8
  class?: string | undefined;
8
9
  classSection?: string | undefined;
9
10
  classAction?: string | undefined;
11
+ model?: Shape | undefined;
10
12
  fields?: FormField<Shape>[][] | undefined;
11
13
  sections?: FormSectionProps<Shape>[] | undefined;
12
- data?: Partial<z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]> extends infer T ? { [k in keyof T]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]>[k]; } : never> | undefined;
13
14
  action?: string | undefined;
15
+ actionCreate?: string | undefined;
14
16
  actionDelete?: string | undefined;
15
- actionPrefix?: string | undefined;
16
- options?: UseFormOptions<Partial<z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]> extends infer T ? { [k in keyof T]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]>[k]; } : never>> | undefined;
17
- set?: (<K extends keyof Shape>(key: K, value: Partial<z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]> extends infer T_1 ? { [k in keyof T_1]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]>[k]; } : never>[K]) => void) | undefined;
17
+ actionUpdate?: string | undefined;
18
+ options?: UseFormOptions<Data> | undefined;
19
+ data?: Nullable<Data> | undefined;
20
+ set?: (<K extends keyof Shape>(key: K, value: Nullable<Data>[K]) => void) | undefined;
21
+ update?: ((updater: (currentData: Nullable<Data>) => Nullable<Data>) => void) | undefined;
18
22
  };
19
23
  events(): {
20
24
  success: CustomEvent<{
21
25
  action: URL;
22
- data?: Partial<z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]> extends infer T ? { [k in keyof T]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]>[k]; } : never> | undefined;
26
+ data?: Data | undefined;
23
27
  }>;
28
+ created: CustomEvent<Data>;
29
+ updated: CustomEvent<Data>;
30
+ deleted: CustomEvent<void>;
24
31
  } & {
25
32
  [evt: string]: CustomEvent<any>;
26
33
  };
27
- slots(): {};
34
+ slots(): {
35
+ default: {};
36
+ };
28
37
  }
29
- export type FormProps<Shape extends z.ZodRawShape> = ReturnType<__sveltets_Render<Shape>['props']>;
30
- export type FormEvents<Shape extends z.ZodRawShape> = ReturnType<__sveltets_Render<Shape>['events']>;
31
- export type FormSlots<Shape extends z.ZodRawShape> = ReturnType<__sveltets_Render<Shape>['slots']>;
32
- export default class Form<Shape extends z.ZodRawShape> extends SvelteComponent<FormProps<Shape>, FormEvents<Shape>, FormSlots<Shape>> {
33
- get set(): <K extends keyof Shape>(key: K, value: Partial<z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]> extends infer T ? { [k in keyof T]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]>[k]; } : never>[K]) => void;
38
+ export type FormProps<Shape extends z.ZodRawShape, Data extends FormDataInput<Shape> = FormDataInput<Shape>> = ReturnType<__sveltets_Render<Shape, Data>['props']>;
39
+ export type FormEvents<Shape extends z.ZodRawShape, Data extends FormDataInput<Shape> = FormDataInput<Shape>> = ReturnType<__sveltets_Render<Shape, Data>['events']>;
40
+ export type FormSlots<Shape extends z.ZodRawShape, Data extends FormDataInput<Shape> = FormDataInput<Shape>> = ReturnType<__sveltets_Render<Shape, Data>['slots']>;
41
+ export default class Form<Shape extends z.ZodRawShape, Data extends FormDataInput<Shape> = FormDataInput<Shape>> extends SvelteComponent<FormProps<Shape, Data>, FormEvents<Shape, Data>, FormSlots<Shape, Data>> {
42
+ get set(): <K extends keyof Shape>(key: K, value: Nullable<Data>[K]) => void;
43
+ get update(): (updater: (currentData: Nullable<Data>) => Nullable<Data>) => void;
34
44
  }
35
45
  export {};
@@ -1,7 +1,9 @@
1
- <script>import { formInputs } from "./formInput.js";
1
+ <script generics="InputType extends FormInputsType">import { formInputs } from "./formInput.js";
2
2
  let inputType;
3
3
  export { inputType as type };
4
4
  export let value;
5
+ $:
6
+ component = formInputs[inputType];
5
7
  </script>
6
8
 
7
- <svelte:component this={formInputs[inputType]} bind:value {...$$restProps} />
9
+ <svelte:component this={component} bind:value {...$$restProps} />
@@ -0,0 +1,116 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type FormInputsType } from './formInput.js';
3
+ declare class __sveltets_Render<InputType extends FormInputsType> {
4
+ props(): import("svelte").ComponentProps<InstanceType<{
5
+ readonly text: typeof import("../index.js").InputText;
6
+ readonly textarea: typeof import("../index.js").InputTextarea;
7
+ readonly textrich: typeof import("../index.js").InputTextRich;
8
+ readonly boolean: typeof import("../index.js").InputBoolean;
9
+ readonly date: typeof import("../index.js").InputDate;
10
+ readonly datetime: typeof import("../index.js").InputDatetime;
11
+ readonly number: typeof import("../index.js").InputNumber;
12
+ readonly password: typeof import("../index.js").InputPassword;
13
+ readonly select: typeof import("../index.js").InputSelect;
14
+ readonly radio: typeof import("../index.js").InputRadio;
15
+ readonly relation: {
16
+ new (options: import("svelte").ComponentConstructorOptions<{
17
+ key?: string | undefined;
18
+ label?: string | undefined;
19
+ search: (q: string) => Promise<any[]>;
20
+ createUrl?: string | undefined;
21
+ createTitle?: string | undefined;
22
+ createIcon?: string | undefined;
23
+ value?: any;
24
+ error?: string | undefined;
25
+ placeholder?: string | undefined;
26
+ tippyProps?: Partial<import("tippy.js").Props> | undefined;
27
+ flatMode?: boolean | undefined;
28
+ slotItem?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
29
+ slotSuggestion?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
30
+ class?: string | undefined;
31
+ classList?: string | undefined;
32
+ clear?: (() => Promise<void>) | undefined;
33
+ }>): import("../index.js").InputRelation<any>;
34
+ };
35
+ readonly relations: {
36
+ new (options: import("svelte").ComponentConstructorOptions<{
37
+ key?: string | undefined;
38
+ label?: string | undefined;
39
+ search: (q: string) => Promise<any[]>;
40
+ createUrl?: string | undefined;
41
+ createTitle?: string | undefined;
42
+ createIcon?: string | undefined;
43
+ error?: string | undefined;
44
+ placeholder?: string | undefined;
45
+ flatMode?: boolean | undefined;
46
+ slotItem?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
47
+ slotSuggestion?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
48
+ class?: string | undefined;
49
+ classList?: string | undefined;
50
+ value?: any[] | null | undefined;
51
+ }>): import("../index.js").InputRelations<any>;
52
+ };
53
+ }[InputType]>> & {
54
+ type: InputType;
55
+ value: import("svelte").ComponentProps<InstanceType<{
56
+ readonly text: typeof import("../index.js").InputText;
57
+ readonly textarea: typeof import("../index.js").InputTextarea;
58
+ readonly textrich: typeof import("../index.js").InputTextRich;
59
+ readonly boolean: typeof import("../index.js").InputBoolean;
60
+ readonly date: typeof import("../index.js").InputDate;
61
+ readonly datetime: typeof import("../index.js").InputDatetime;
62
+ readonly number: typeof import("../index.js").InputNumber;
63
+ readonly password: typeof import("../index.js").InputPassword;
64
+ readonly select: typeof import("../index.js").InputSelect;
65
+ readonly radio: typeof import("../index.js").InputRadio;
66
+ readonly relation: {
67
+ new (options: import("svelte").ComponentConstructorOptions<{
68
+ key?: string | undefined;
69
+ label?: string | undefined;
70
+ search: (q: string) => Promise<any[]>;
71
+ createUrl?: string | undefined;
72
+ createTitle?: string | undefined;
73
+ createIcon?: string | undefined;
74
+ value?: any;
75
+ error?: string | undefined;
76
+ placeholder?: string | undefined;
77
+ tippyProps?: Partial<import("tippy.js").Props> | undefined;
78
+ flatMode?: boolean | undefined;
79
+ slotItem?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
80
+ slotSuggestion?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
81
+ class?: string | undefined;
82
+ classList?: string | undefined;
83
+ clear?: (() => Promise<void>) | undefined;
84
+ }>): import("../index.js").InputRelation<any>;
85
+ };
86
+ readonly relations: {
87
+ new (options: import("svelte").ComponentConstructorOptions<{
88
+ key?: string | undefined;
89
+ label?: string | undefined;
90
+ search: (q: string) => Promise<any[]>;
91
+ createUrl?: string | undefined;
92
+ createTitle?: string | undefined;
93
+ createIcon?: string | undefined;
94
+ error?: string | undefined;
95
+ placeholder?: string | undefined;
96
+ flatMode?: boolean | undefined;
97
+ slotItem?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
98
+ slotSuggestion?: ((item: any) => string | import("../../index.js").ComponentAndProps) | null | undefined;
99
+ class?: string | undefined;
100
+ classList?: string | undefined;
101
+ value?: any[] | null | undefined;
102
+ }>): import("../index.js").InputRelations<any>;
103
+ };
104
+ }[InputType]>>["value"];
105
+ };
106
+ events(): {} & {
107
+ [evt: string]: CustomEvent<any>;
108
+ };
109
+ slots(): {};
110
+ }
111
+ export type FormInputProps_<InputType extends FormInputsType> = ReturnType<__sveltets_Render<InputType>['props']>;
112
+ export type FormInputEvents<InputType extends FormInputsType> = ReturnType<__sveltets_Render<InputType>['events']>;
113
+ export type FormInputSlots<InputType extends FormInputsType> = ReturnType<__sveltets_Render<InputType>['slots']>;
114
+ export default class FormInput<InputType extends FormInputsType> extends SvelteComponent<FormInputProps_<InputType>, FormInputEvents<InputType>, FormInputSlots<InputType>> {
115
+ }
116
+ export {};
@@ -1,24 +1,37 @@
1
1
  import type { z } from 'zod';
2
2
  import type { ComponentProps } from 'svelte';
3
+ import { type Writable } from 'svelte/store';
4
+ import type { FormEventHandler } from 'svelte/elements';
3
5
  import { type FormInputsProps, type FormInputsType } from './formInput.js';
4
6
  import type FormSection from './FormSection.svelte';
5
7
  type Shape = z.ZodRawShape;
6
8
  type PickOne<T> = {
7
9
  [P in keyof T]: Record<P, T[P]> & Partial<Record<Exclude<keyof T, P>, undefined>>;
8
10
  }[keyof T];
9
- export type BoolOrFunction<M extends Shape> = boolean | ((data: FormData<M>) => unknown);
10
- export type FormData<M extends Shape> = Partial<z.infer<z.ZodObject<M>>>;
11
- export type FormField<M extends Shape> = {
12
- key: string & keyof M;
11
+ export type Nullable<T> = {
12
+ [P in keyof T]?: T[P] | null;
13
+ };
14
+ export type BoolOrFunction<S extends Shape> = boolean | ((data: Nullable<FormDataInput<S>>) => unknown);
15
+ export type FormDataInput<S extends Shape> = z.ZodObject<S>['_input'];
16
+ export type FormField<S extends Shape> = {
17
+ key: string & keyof S;
13
18
  /** number col used by field */
14
19
  colSpan?: number;
15
20
  /** hide field if true */
16
- hide?: BoolOrFunction<M>;
21
+ hide?: BoolOrFunction<S>;
17
22
  } & PickOne<FormInputsProps>;
18
- export type FormSectionProps<M extends Shape> = ComponentProps<FormSection> & {
23
+ export type FormSectionProps<S extends Shape> = ComponentProps<FormSection> & {
19
24
  /** hide group if true */
20
- hide?: BoolOrFunction<M>;
25
+ hide?: BoolOrFunction<S>;
26
+ };
27
+ export declare function initData<S extends Shape, Data extends FormDataInput<S> = FormDataInput<S>>(fields: FormField<S>[][]): Data;
28
+ export declare function getFieldType<S extends Shape>(field: FormField<S>): FormInputsType;
29
+ type HandleInputOptions<S extends Shape> = {
30
+ model?: S;
31
+ setError: (key: string, value: string) => void;
32
+ };
33
+ export declare function useHandleInput<S extends Shape>({ model, setError }: HandleInputOptions<S>): {
34
+ isDirty: Writable<boolean>;
35
+ handleInput: FormEventHandler<HTMLFormElement>;
21
36
  };
22
- export declare function initData<M extends Shape>(fields: FormField<M>[][]): FormData<M>;
23
- export declare function getFieldType<M extends Shape>(field: FormField<M>): FormInputsType;
24
37
  export {};
@@ -1,3 +1,5 @@
1
+ import debounce from 'debounce';
2
+ import { writable } from 'svelte/store';
1
3
  import { formInputsType } from './formInput.js';
2
4
  export function initData(fields) {
3
5
  // @ts-ignore
@@ -13,3 +15,39 @@ export function getFieldType(field) {
13
15
  return 'text';
14
16
  return inputType;
15
17
  }
18
+ export function useHandleInput({ model, setError }) {
19
+ const isDirty = writable(false);
20
+ const setErrorDebounced = debounce(setError, 1500);
21
+ return {
22
+ isDirty,
23
+ handleInput: ({ target }) => {
24
+ if (!target)
25
+ return;
26
+ isDirty.set(true);
27
+ if (!model)
28
+ return;
29
+ const { name, type, value, valueAsNumber, valueAsDate, checked } = target;
30
+ const typeMapValue = {
31
+ number: valueAsNumber,
32
+ date: valueAsDate,
33
+ text: value,
34
+ checkbox: checked
35
+ };
36
+ const v = typeMapValue[type] ?? value;
37
+ if (v === undefined || name === undefined)
38
+ return;
39
+ if (name === undefined)
40
+ return;
41
+ if (!model[name])
42
+ return;
43
+ const res = model[name].safeParse(v);
44
+ if (res.success) {
45
+ setErrorDebounced.clear();
46
+ setError(name, '');
47
+ }
48
+ else {
49
+ setErrorDebounced(name, res.error.issues[0].message);
50
+ }
51
+ }
52
+ };
53
+ }
@@ -31,7 +31,7 @@ export type FormInputProps<T extends FormInputsType> = ComponentProps<InstanceTy
31
31
  export type FormInputsProps = {
32
32
  [T in FormInputsType]: FormInputProps<T>;
33
33
  };
34
- export declare const formInputsType: ("number" | "boolean" | "select" | "textarea" | "date" | "text" | "password" | "radio" | "textrich" | "datetime" | "relation" | "relations")[];
34
+ export declare const formInputsType: ("number" | "boolean" | "select" | "date" | "textarea" | "text" | "password" | "radio" | "textrich" | "datetime" | "relation" | "relations")[];
35
35
  export declare function relationProps<Item extends {
36
36
  id: string;
37
37
  }>(props: ComponentProps<InstanceType<typeof InputRelation<Item>>>): {
@@ -12,7 +12,7 @@ declare const __propDef: {
12
12
  prefix?: string | number | undefined;
13
13
  prefixFor?: string | number | undefined;
14
14
  enhanceDisabled?: boolean | undefined;
15
- labelPosition?: ("top" | "right" | "left") | undefined;
15
+ labelPosition?: ("top" | "left" | "right") | undefined;
16
16
  };
17
17
  events: {
18
18
  [evt: string]: CustomEvent<any>;
@@ -11,12 +11,12 @@ declare const __propDef: {
11
11
  prefix?: string | number | undefined;
12
12
  prefixFor?: string | number | undefined;
13
13
  enhanceDisabled?: boolean | undefined;
14
- labelPosition?: ("top" | "right" | "left") | undefined;
14
+ labelPosition?: ("top" | "left" | "right") | undefined;
15
15
  } & {
16
16
  input?: HTMLInputAttributes | undefined;
17
17
  inputElement?: HTMLInputElement | undefined;
18
18
  wrapperClass?: string | undefined;
19
- value?: boolean | undefined;
19
+ value?: boolean | null | undefined;
20
20
  bindWithParams?: boolean | undefined;
21
21
  } & {
22
22
  isRow?: boolean | undefined;
@@ -11,12 +11,12 @@ declare const __propDef: {
11
11
  prefix?: string | number | undefined;
12
12
  prefixFor?: string | number | undefined;
13
13
  enhanceDisabled?: boolean | undefined;
14
- labelPosition?: ("top" | "right" | "left") | undefined;
14
+ labelPosition?: ("top" | "left" | "right") | undefined;
15
15
  } & {
16
16
  input?: import("svelte/elements.js").HTMLInputAttributes | undefined;
17
17
  inputElement?: HTMLInputElement | undefined;
18
18
  wrapperClass?: string | undefined;
19
- value?: string[] | undefined;
19
+ value?: string[] | null | undefined;
20
20
  bindWithParams?: boolean | undefined;
21
21
  } & {
22
22
  options: Options;
@@ -27,7 +27,7 @@ $:
27
27
  function handleSubmit() {
28
28
  if (!dropdown)
29
29
  return;
30
- if (!value.length) {
30
+ if (!value?.length) {
31
31
  goto($urlParam.without(key), { replaceState: true, noScroll: true });
32
32
  return;
33
33
  }
@@ -43,23 +43,23 @@ function handleReset() {
43
43
  <input type="hidden" name={key} value={JSON.stringify(value)} />
44
44
 
45
45
  <DropDown bind:this={dropdown} tippyProps={{ onHide: handleSubmit }} wrapperClass="mb-[-2px]">
46
- <div class="join" class:ml-2={value.length} slot="activator">
46
+ <div class="join" class:ml-2={value?.length} slot="activator">
47
47
  <button class="btn indicator join-item btn-sm {btnClass || ''}">
48
48
  <slot name="label">
49
49
  <span>{label}</span>
50
50
  </slot>
51
- {#if value.length > 0}
51
+ {#if !!value?.length}
52
52
  <span
53
53
  class="
54
54
  badge indicator-item badge-sm indicator-start
55
55
  {badgePrimary ? 'badge-primary' : 'badge-outline bg-base-100'}
56
56
  "
57
57
  >
58
- {value.length}
58
+ {value?.length}
59
59
  </span>
60
60
  {/if}
61
61
  </button>
62
- {#if value.length}
62
+ {#if !!value?.length}
63
63
  <button class="btn btn-square join-item btn-sm" on:click={handleReset}>
64
64
  <Icon path={mdiClose} class="fill-base-content" />
65
65
  </button>
@@ -11,12 +11,12 @@ declare const __propDef: {
11
11
  prefix?: string | number | undefined;
12
12
  prefixFor?: string | number | undefined;
13
13
  enhanceDisabled?: boolean | undefined;
14
- labelPosition?: ("top" | "right" | "left") | undefined;
14
+ labelPosition?: ("top" | "left" | "right") | undefined;
15
15
  } & {
16
16
  input?: import("svelte/elements.js").HTMLInputAttributes | undefined;
17
17
  inputElement?: HTMLInputElement | undefined;
18
18
  wrapperClass?: string | undefined;
19
- value?: string[] | undefined;
19
+ value?: string[] | null | undefined;
20
20
  bindWithParams?: boolean | undefined;
21
21
  } & {
22
22
  key: string;
@@ -14,12 +14,12 @@ declare const __propDef: {
14
14
  prefix?: string | number | undefined;
15
15
  prefixFor?: string | number | undefined;
16
16
  enhanceDisabled?: boolean | undefined;
17
- labelPosition?: ("top" | "right" | "left") | undefined;
17
+ labelPosition?: ("top" | "left" | "right") | undefined;
18
18
  } & {
19
19
  input?: import("svelte/elements").HTMLInputAttributes | undefined;
20
20
  inputElement?: HTMLInputElement | undefined;
21
21
  wrapperClass?: string | undefined;
22
- value?: string | undefined;
22
+ value?: string | null | undefined;
23
23
  bindWithParams?: boolean | undefined;
24
24
  } & {
25
25
  options: Options;
@@ -1,7 +1,7 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import { type InputProps } from './index.js';
3
3
  declare const __propDef: {
4
- props: InputProps;
4
+ props: InputProps<string | number>;
5
5
  events: {
6
6
  input: Event;
7
7
  focus: FocusEvent;
@@ -10,12 +10,12 @@ declare const __propDef: {
10
10
  prefix?: string | number | undefined;
11
11
  prefixFor?: string | number | undefined;
12
12
  enhanceDisabled?: boolean | undefined;
13
- labelPosition?: ("top" | "right" | "left") | undefined;
13
+ labelPosition?: ("top" | "left" | "right") | undefined;
14
14
  } & {
15
15
  input?: import("svelte/elements.js").HTMLInputAttributes | undefined;
16
16
  inputElement?: HTMLInputElement | undefined;
17
17
  wrapperClass?: string | undefined;
18
- value?: string | undefined;
18
+ value?: string | null | undefined;
19
19
  bindWithParams?: boolean | undefined;
20
20
  } & {
21
21
  autocomplete?: string | undefined;
@@ -11,12 +11,12 @@ declare const __propDef: {
11
11
  prefix?: string | number | undefined;
12
12
  prefixFor?: string | number | undefined;
13
13
  enhanceDisabled?: boolean | undefined;
14
- labelPosition?: ("top" | "right" | "left") | undefined;
14
+ labelPosition?: ("top" | "left" | "right") | undefined;
15
15
  } & {
16
16
  input?: import("svelte/elements.js").HTMLInputAttributes | undefined;
17
17
  inputElement?: HTMLInputElement | undefined;
18
18
  wrapperClass?: string | undefined;
19
- value?: string | undefined;
19
+ value?: string | null | undefined;
20
20
  bindWithParams?: boolean | undefined;
21
21
  } & {
22
22
  options: Options;
@@ -2,6 +2,7 @@
2
2
  import debounce from "debounce";
3
3
  import { toast } from "svelte-sonner";
4
4
  import { mdiClose } from "@mdi/js";
5
+ import { USE_JSON_PARSER } from "../../utils/constant.js";
5
6
  import { Icon } from "../icon/index.js";
6
7
  import { Slot } from "../slot/index.js";
7
8
  import { DropDown } from "../menu/index.js";
@@ -101,7 +102,11 @@ async function handleBlur() {
101
102
  <Icon path={mdiClose} />
102
103
  </button>
103
104
  </div>
104
- <input type="hidden" name={key} value={item.id} />
105
+ <input
106
+ type="hidden"
107
+ name={key}
108
+ value="{USE_JSON_PARSER}{JSON.stringify({ id: item.id })}"
109
+ />
105
110
  {/if}
106
111
  </FormControl>
107
112
  </div>
@@ -113,7 +118,7 @@ async function handleBlur() {
113
118
  {isLoading}
114
119
  {focusIndex}
115
120
  let:index
116
- class="w-full {classList}"
121
+ class="w-full min-w-40 {classList}"
117
122
  on:select={({ detail }) => select(detail)}
118
123
  >
119
124
  <slot name="suggestion" item={proposedItems[index]}>