fuma 2.1.1 → 2.1.4

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 (82) hide show
  1. package/dist/_doc/DocExample.svelte +122 -0
  2. package/dist/_doc/DocExample.svelte.d.ts +10 -0
  3. package/dist/_doc/DocProps.svelte +61 -0
  4. package/dist/_doc/DocProps.svelte.d.ts +13 -0
  5. package/dist/_doc/DocSection.svelte +22 -0
  6. package/dist/_doc/DocSection.svelte.d.ts +9 -0
  7. package/dist/_doc/highlight.d.ts +2 -0
  8. package/dist/_doc/highlight.js +18 -0
  9. package/dist/_doc/index.d.ts +4 -0
  10. package/dist/_doc/index.js +3 -0
  11. package/dist/_doc/parse-props.d.ts +2 -0
  12. package/dist/_doc/parse-props.js +253 -0
  13. package/dist/command/command.svelte.d.ts +4 -2
  14. package/dist/command/command.svelte.js +29 -2
  15. package/dist/command/index.d.ts +1 -1
  16. package/dist/command/index.js +1 -1
  17. package/dist/index.d.ts +11 -5
  18. package/dist/index.js +11 -5
  19. package/dist/input/InputBoolean.svelte +4 -7
  20. package/dist/input/InputBoolean.svelte.d.ts +1 -1
  21. package/dist/input/InputNumber.svelte +1 -1
  22. package/dist/input/InputNumber.svelte.d.ts +1 -1
  23. package/dist/input/InputRadio.svelte +2 -2
  24. package/dist/input/InputRadio.svelte.d.ts +1 -1
  25. package/dist/input/InputRange.svelte +1 -1
  26. package/dist/input/InputRange.svelte.d.ts +1 -1
  27. package/dist/input/InputRelation.svelte +133 -52
  28. package/dist/input/InputRelation.svelte.d.ts +60 -4
  29. package/dist/input/InputSelect.svelte +2 -2
  30. package/dist/input/InputSelectNative.svelte +3 -3
  31. package/dist/input/InputSelectNative.svelte.d.ts +2 -2
  32. package/dist/input/InputString.svelte +1 -1
  33. package/dist/input/InputString.svelte.d.ts +1 -1
  34. package/dist/input/InputTextarea.svelte +2 -3
  35. package/dist/input/InputTextarea.svelte.d.ts +1 -1
  36. package/dist/input/Issues.svelte +3 -4
  37. package/dist/input/Issues.svelte.d.ts +2 -2
  38. package/dist/input/index.d.ts +1 -1
  39. package/dist/loading/Loading.svelte +43 -0
  40. package/dist/loading/Loading.svelte.d.ts +11 -0
  41. package/dist/loading/index.d.ts +1 -0
  42. package/dist/loading/index.js +1 -0
  43. package/dist/popover/Popover.svelte +1 -1
  44. package/dist/popover/index.d.ts +1 -1
  45. package/dist/popover/index.js +1 -1
  46. package/dist/popover/popover.svelte.d.ts +4 -1
  47. package/dist/popover/popover.svelte.js +14 -9
  48. package/dist/remote/index.d.ts +1 -0
  49. package/dist/remote/index.js +1 -0
  50. package/dist/remote/useForm.d.ts +10 -0
  51. package/dist/remote/useForm.js +23 -3
  52. package/dist/search/Spans.svelte +3 -2
  53. package/dist/search/Spans.svelte.d.ts +1 -1
  54. package/dist/search/index.d.ts +1 -1
  55. package/dist/search/index.js +1 -1
  56. package/dist/search/search.d.ts +38 -0
  57. package/dist/search/search.js +15 -2
  58. package/dist/ui/copy/ButtonCopy.svelte +1 -1
  59. package/dist/ui/copy/ButtonCopy.svelte.d.ts +1 -1
  60. package/dist/ui/copy/index.d.ts +1 -1
  61. package/dist/ui/copy/index.js +1 -1
  62. package/dist/ui/drawer/Drawer.svelte +1 -1
  63. package/dist/ui/drawer/drawerFly.js +1 -1
  64. package/dist/ui/menu/DropDownMenu.svelte +3 -17
  65. package/dist/ui/menu/DropDownMenu.svelte.d.ts +0 -3
  66. package/dist/ui/pagination/Pagination.svelte +1 -1
  67. package/dist/ui/range/RangePicker.svelte +1 -2
  68. package/dist/ui/range/RangePickerButton.svelte +1 -1
  69. package/dist/ui/table/Table.svelte +1 -3
  70. package/dist/ui/table/Table.svelte.d.ts +0 -1
  71. package/dist/ui/table/TableFieldsEdition.svelte +4 -3
  72. package/dist/ui/table/TableViewSelect.svelte +3 -12
  73. package/dist/ui/table/TableViewSelect.svelte.d.ts +0 -5
  74. package/dist/ui/table/head/TableHeadDate.svelte +2 -2
  75. package/dist/ui/table/head/TableHeadNumber.svelte +1 -1
  76. package/dist/ui/table/head/TableHeadSelect.svelte +3 -3
  77. package/dist/utils/options.d.ts +1 -1
  78. package/dist/utils/options.js +1 -1
  79. package/dist/validation/zod.js +2 -1
  80. package/package.json +3 -24
  81. /package/dist/{data.d.ts → _doc/data.d.ts} +0 -0
  82. /package/dist/{data.js → _doc/data.js} +0 -0
@@ -10,8 +10,11 @@ export type PopoverOptions = {
10
10
  listenHover?: boolean;
11
11
  /** Only when listenHover={true} */
12
12
  hideDelay?: number;
13
+ onShow?: () => void;
14
+ onHide?: () => void;
15
+ hotKey?: string;
13
16
  };
14
- export declare function usePopover({ mode, placement, listenClick, listenFocus, listenHover, hideDelay }?: PopoverOptions): {
17
+ export declare function usePopover({ mode, placement, listenClick, listenFocus, listenHover, hideDelay, onShow, onHide, hotKey }?: PopoverOptions): {
15
18
  show: () => void;
16
19
  hide: () => void;
17
20
  readonly isOpen: boolean;
@@ -16,7 +16,7 @@ const placements = {
16
16
  'right-start': 'right span-bottom'
17
17
  };
18
18
  let popoverInstanceCount = 0;
19
- export function usePopover({ mode = 'auto', placement = 'bottom-start', listenClick = true, listenFocus = true, listenHover = false, hideDelay = 400 } = {}) {
19
+ export function usePopover({ mode = 'auto', placement = 'bottom-start', listenClick = true, listenFocus = true, listenHover = false, hideDelay = 400, onShow, onHide, hotKey } = {}) {
20
20
  const uid = popoverInstanceCount++;
21
21
  const anchorName = `--anchor-${uid}`;
22
22
  let popover = $state();
@@ -24,9 +24,11 @@ export function usePopover({ mode = 'auto', placement = 'bottom-start', listenCl
24
24
  const hideDebounced = debounce(hide, hideDelay);
25
25
  function show() {
26
26
  popover?.showPopover();
27
+ onShow?.();
27
28
  }
28
29
  function hide() {
29
30
  popover?.hidePopover();
31
+ onHide?.();
30
32
  }
31
33
  function onMouseEnter() {
32
34
  hideDebounced.clear();
@@ -48,6 +50,9 @@ export function usePopover({ mode = 'auto', placement = 'bottom-start', listenCl
48
50
  cleanups.push(on(activator, 'mouseenter', onMouseEnter));
49
51
  cleanups.push(on(activator, 'mouseleave', hideDebounced));
50
52
  }
53
+ if (hotKey) {
54
+ cleanups.push(on(window, 'keydown', handleHotKey));
55
+ }
51
56
  return () => {
52
57
  for (const cleanup of cleanups)
53
58
  cleanup();
@@ -65,6 +70,14 @@ export function usePopover({ mode = 'auto', placement = 'bottom-start', listenCl
65
70
  cleanup();
66
71
  };
67
72
  }
73
+ async function handleHotKey(event) {
74
+ const { metaKey, ctrlKey, key } = event;
75
+ if ((metaKey || ctrlKey) && key === hotKey) {
76
+ event.preventDefault();
77
+ show();
78
+ return;
79
+ }
80
+ }
68
81
  return {
69
82
  show,
70
83
  hide,
@@ -75,15 +88,9 @@ export function usePopover({ mode = 'auto', placement = 'bottom-start', listenCl
75
88
  popover: mode,
76
89
  [createAttachmentKey()]: (node) => {
77
90
  popover = node;
78
- // biome-ignore lint/suspicious/noTsIgnore: await for a svelte-check update
79
- // @ts-ignore
80
91
  popover.style.positionAnchor = anchorName;
81
- // biome-ignore lint/suspicious/noTsIgnore: await for a svelte-check update
82
- // @ts-ignore
83
92
  popover.style.positionArea = placements[placement];
84
93
  popover.style.inset = 'auto';
85
- // biome-ignore lint/suspicious/noTsIgnore: await for a svelte-check update
86
- // @ts-ignore
87
94
  popover.style.positionTry = 'flip-x, flip-y';
88
95
  popover.style.position = 'relative';
89
96
  return attachPopoverListeners(node);
@@ -91,8 +98,6 @@ export function usePopover({ mode = 'auto', placement = 'bottom-start', listenCl
91
98
  },
92
99
  trigger: {
93
100
  [createAttachmentKey()]: (node) => {
94
- // biome-ignore lint/suspicious/noTsIgnore: await for a svelte-check update
95
- // @ts-ignore
96
101
  node.style.anchorName = anchorName;
97
102
  return attachTriggerListeners(node);
98
103
  }
@@ -0,0 +1 @@
1
+ export * from './useForm.js';
@@ -0,0 +1 @@
1
+ export * from './useForm.js';
@@ -1,6 +1,16 @@
1
1
  import type { RemoteForm, RemoteFormInput } from '@sveltejs/kit';
2
2
  import type { StandardSchemaV1 } from 'runed/kit';
3
+ import { type Attachment } from 'svelte/attachments';
3
4
  /**
4
5
  * Enable preflight and run validation on input
6
+ * @deprecated
5
7
  */
6
8
  export declare function useForm<Input extends RemoteFormInput | undefined, Output>(remoteForm: RemoteForm<Input, Output>, schema: StandardSchemaV1<Input>, debounceMs?: number): RemoteForm<Input, Output>;
9
+ export declare function validationOnInput<Input extends RemoteFormInput | undefined, Output>(remoteForm: RemoteForm<Input, Output>, debounceMs?: number): Attachment<HTMLFormElement>;
10
+ type UseEnhanceCallbackOptions<Input extends RemoteFormInput | void> = {
11
+ onSuccess?: (data: Input, form: HTMLFormElement) => void;
12
+ onError?: (err: unknown) => void;
13
+ };
14
+ type EnhanceCallback<Input extends RemoteFormInput | void> = Parameters<RemoteForm<Input, unknown>['enhance']>[0];
15
+ export declare function useEnhanceCallback<Input extends RemoteFormInput | void>({ onSuccess, onError }: UseEnhanceCallbackOptions<Input>): EnhanceCallback<Input>;
16
+ export {};
@@ -3,8 +3,14 @@ import { createAttachmentKey } from 'svelte/attachments';
3
3
  import { on } from 'svelte/events';
4
4
  /**
5
5
  * Enable preflight and run validation on input
6
+ * @deprecated
6
7
  */
7
8
  export function useForm(remoteForm, schema, debounceMs = 1000) {
9
+ const validation = validationOnInput(remoteForm, debounceMs);
10
+ Object.assign(remoteForm, { [createAttachmentKey()]: validation });
11
+ return remoteForm.preflight(schema);
12
+ }
13
+ export function validationOnInput(remoteForm, debounceMs = 1000) {
8
14
  const validation = (formElement) => {
9
15
  const debouncedValidate = debounce(() => remoteForm.validate(), debounceMs);
10
16
  return on(formElement, 'input', ({ target }) => {
@@ -13,10 +19,24 @@ export function useForm(remoteForm, schema, debounceMs = 1000) {
13
19
  target.type === 'checkbox' ||
14
20
  target.type === 'radio' ||
15
21
  target.tagName === 'SELECT';
16
- instantValidation ? remoteForm.validate() : debouncedValidate();
22
+ if (instantValidation)
23
+ remoteForm.validate();
24
+ else
25
+ debouncedValidate();
17
26
  }
18
27
  });
19
28
  };
20
- Object.assign(remoteForm, { [createAttachmentKey()]: validation });
21
- return remoteForm.preflight(schema);
29
+ return validation;
30
+ }
31
+ export function useEnhanceCallback({ onSuccess, onError }) {
32
+ return ({ submit, data, form }) => {
33
+ submit()
34
+ .then(() => {
35
+ onSuccess?.(data, form);
36
+ })
37
+ .catch((err) => {
38
+ console.error(err);
39
+ onError?.(err);
40
+ });
41
+ };
22
42
  }
@@ -1,10 +1,11 @@
1
1
  <script lang="ts">
2
- import type { SearchQueryResultSpan } from './search.ts'
2
+ import type { SearchQueryResultSpan } from './search.js'
3
3
 
4
4
  let { spans }: { spans: SearchQueryResultSpan[] } = $props()
5
5
  </script>
6
6
 
7
- {#each spans as { value, isMatch }}
7
+ {#each spans as span (span)}
8
+ {@const { isMatch, value } = span}
8
9
  <span
9
10
  class={isMatch ? 'rounded-xs text-secondary' : ''}
10
11
  class:ml-px={value.startsWith(' ')}
@@ -1,4 +1,4 @@
1
- import type { SearchQueryResultSpan } from './search.ts';
1
+ import type { SearchQueryResultSpan } from './search.js';
2
2
  type $$ComponentProps = {
3
3
  spans: SearchQueryResultSpan[];
4
4
  };
@@ -1,2 +1,2 @@
1
1
  export { default as Spans } from './Spans.svelte';
2
- export * from './search.ts';
2
+ export * from './search.js';
@@ -1,2 +1,2 @@
1
1
  export { default as Spans } from './Spans.svelte';
2
- export * from './search.ts';
2
+ export * from './search.js';
@@ -0,0 +1,38 @@
1
+ import type { FuseResultMatch, IFuseOptions } from 'fuse.js';
2
+ import Fuse from 'fuse.js';
3
+ export type CombinedFuseResult<T> = {
4
+ item: T;
5
+ score: number;
6
+ matches: FuseResultMatch[];
7
+ };
8
+ type Keys<Item> = Partial<Record<keyof Item, Partial<{
9
+ weight: number;
10
+ getFn: (item: Item) => string;
11
+ }>>>;
12
+ export type SearchOptions<Item, K extends Keys<Item> = Keys<Item>> = {
13
+ items?: Item[];
14
+ keys: K;
15
+ } & Omit<IFuseOptions<Item>, 'includeMatches' | 'keys'>;
16
+ export type SearchQueryOptions = {
17
+ tokensSeparator?: string;
18
+ tokensMaxCount?: number;
19
+ };
20
+ export type SearchQueryResult<Item, K extends Keys<Item> = Keys<Item>> = {
21
+ item: Item;
22
+ spans: Record<keyof K, SearchQueryResultSpan[]>;
23
+ score: number;
24
+ };
25
+ export type SearchQueryResultSpan = {
26
+ value: string;
27
+ isMatch: boolean;
28
+ };
29
+ export declare function useSearch<Item extends object, K extends Keys<Item>>({ items, keys, ...fuseOptions }: SearchOptions<Item, K>): {
30
+ fuse: Fuse<Item>;
31
+ query: (value: string, { tokensSeparator, tokensMaxCount }?: SearchQueryOptions) => SearchQueryResult<Item, K>[];
32
+ prismaWhereTokens: (value: string, { tokensSeparator, tokensMaxCount }?: SearchQueryOptions) => {
33
+ OR: { [P in keyof K]?: {
34
+ contains: string;
35
+ } | undefined; }[];
36
+ }[];
37
+ };
38
+ export {};
@@ -3,6 +3,8 @@ import { mergeRanges } from 'perod';
3
3
  export function useSearch({ items = [], keys, ...fuseOptions }) {
4
4
  const fuse = new Fuse(items, {
5
5
  includeMatches: true,
6
+ ignoreLocation: true,
7
+ ignoreDiacritics: true,
6
8
  keys: Object.entries(keys).map(([name, param]) => ({
7
9
  name,
8
10
  ...(param || {})
@@ -28,9 +30,20 @@ export function useSearch({ items = [], keys, ...fuseOptions }) {
28
30
  }
29
31
  return queryResults;
30
32
  }
33
+ function prismaWhereTokens(value, { tokensSeparator = ' ', tokensMaxCount = 4 } = {}) {
34
+ const tokens = value.split(tokensSeparator).slice(0, tokensMaxCount);
35
+ const whereTokens = [];
36
+ for (const token of tokens) {
37
+ whereTokens.push({
38
+ OR: Object.keys(keys).map((k) => ({ [k]: { contains: token } }))
39
+ });
40
+ }
41
+ return whereTokens;
42
+ }
31
43
  return {
32
- ...fuse,
33
- query
44
+ fuse,
45
+ query,
46
+ prismaWhereTokens
34
47
  };
35
48
  }
36
49
  function getSpans(key, matches) {
@@ -3,7 +3,7 @@
3
3
  import type { Component } from 'svelte'
4
4
  import type { ClassValue } from 'svelte/elements'
5
5
  import { tip } from '../../action/tip.js'
6
- import { type UseCopyOptions, useCopy } from './useCopy.svelte.ts'
6
+ import { type UseCopyOptions, useCopy } from './useCopy.svelte.js'
7
7
 
8
8
  let {
9
9
  title = '',
@@ -1,7 +1,7 @@
1
1
  import { type IconProps } from '@lucide/svelte';
2
2
  import type { Component } from 'svelte';
3
3
  import type { ClassValue } from 'svelte/elements';
4
- import { type UseCopyOptions } from './useCopy.svelte.ts';
4
+ import { type UseCopyOptions } from './useCopy.svelte.js';
5
5
  type $$ComponentProps = {
6
6
  /** Tooltip text */
7
7
  title?: string;
@@ -1,2 +1,2 @@
1
1
  export { default as ButtonCopy } from './ButtonCopy.svelte';
2
- export * from './useCopy.svelte.ts';
2
+ export * from './useCopy.svelte.js';
@@ -1,2 +1,2 @@
1
1
  export { default as ButtonCopy } from './ButtonCopy.svelte';
2
- export * from './useCopy.svelte.ts';
2
+ export * from './useCopy.svelte.js';
@@ -8,7 +8,7 @@
8
8
  import { XIcon } from '@lucide/svelte'
9
9
 
10
10
  import { goto } from '$app/navigation'
11
- import { urlParam } from '../../state/param.svelte.ts'
11
+ import { urlParam } from '../../state/param.svelte.js'
12
12
  import { drawerFly } from './drawerFly.js'
13
13
  import { writable } from 'svelte/store'
14
14
  import { useLayer } from './useLayer.svelte.js'
@@ -13,7 +13,7 @@ export function drawerFly(node, { delay = 0, duration = 400, easing = cubicOut,
13
13
  css: (t, u) => `
14
14
  transform: ${transform} translate(${(1 - t) * xValue}${xUnit}, ${(1 - t) * yValue}${yUnit});
15
15
  opacity: ${target_opacity - od * u}`,
16
- tick: (t, _u) => {
16
+ tick: (t) => {
17
17
  onTransition({ x: t * xValue, y: t * yValue });
18
18
  }
19
19
  };
@@ -2,32 +2,20 @@
2
2
  import { ChevronsUpDownIcon } from '@lucide/svelte'
3
3
  import type { Snippet } from 'svelte'
4
4
  import { DropDown } from './index.js'
5
- import { type Options, parseOptions } from '../../utils/options.js'
6
5
  import type { TippyProps } from '../../utils/tippy.js'
7
6
 
8
7
  let {
9
- options: optionsProp,
10
8
  tippyProps = {},
11
- onSelect,
12
9
  children: childrenProp
13
10
  }: {
14
- options: Options
15
11
  tippyProps?: Partial<TippyProps>
16
- onSelect?: (value: string) => void
17
12
  children?: Snippet
18
13
  } = $props()
19
-
20
- let options = $derived(parseOptions(optionsProp))
21
- let trigger = $state<HTMLElement>()
22
14
  </script>
23
15
 
24
16
  <DropDown {tippyProps}>
25
17
  {#snippet activator()}
26
- <button
27
- bind:this={trigger}
28
- type="button"
29
- class="flex h-12 items-center gap-2 rounded-lg border pr-2 pl-4"
30
- >
18
+ <button type="button" class="flex h-12 items-center gap-2 rounded-lg border pr-2 pl-4">
31
19
  {#if childrenProp}
32
20
  {@render childrenProp()}
33
21
  {:else}
@@ -37,10 +25,9 @@
37
25
  </button>
38
26
  {/snippet}
39
27
 
40
- {#snippet children({ hide })}
41
- <span>TODO: use Command or REMOVE THIS COMPONENT</span>
28
+ <span>TODO: use Command or REMOVE THIS COMPONENT</span>
42
29
 
43
- <!-- <SelectorList
30
+ <!-- <SelectorList
44
31
  {trigger}
45
32
  items={options.map((opt) => ({ id: opt.value, ...opt }))}
46
33
  onSelect={(index) => {
@@ -56,5 +43,4 @@
56
43
  <span class="pr-4 whitespace-nowrap">{item.label}</span>
57
44
  {/snippet}
58
45
  </SelectorList> -->
59
- {/snippet}
60
46
  </DropDown>
@@ -1,10 +1,7 @@
1
1
  import type { Snippet } from 'svelte';
2
- import { type Options } from '../../utils/options.js';
3
2
  import type { TippyProps } from '../../utils/tippy.js';
4
3
  type $$ComponentProps = {
5
- options: Options;
6
4
  tippyProps?: Partial<TippyProps>;
7
- onSelect?: (value: string) => void;
8
5
  children?: Snippet;
9
6
  };
10
7
  declare const DropDownMenu: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { ChevronLeftIcon, ChevronRightIcon } from '@lucide/svelte'
3
3
  import { tip } from '../../action/tip.js'
4
- import { param, urlParam } from '../../state/index.ts'
4
+ import { param, urlParam } from '../../state/index.js'
5
5
 
6
6
  let { take = 20 }: { take?: number } = $props()
7
7
 
@@ -49,8 +49,7 @@
49
49
  startDate: range?.start ? dayjs(range.start).toDate() : undefined,
50
50
  endDate: range?.end ? dayjs(range.end).toDate() : undefined,
51
51
  setup: (picker: Litepicker) => {
52
- // biome-ignore lint/suspicious/noExplicitAny: Litepicker external type
53
- picker.on('selected', (date1: any, date2: any) => {
52
+ picker.on('selected', (date1: { dateInstance: Date }, date2: { dateInstance: Date }) => {
54
53
  range = {
55
54
  start: new Date(
56
55
  `${getAbsoluteDate(date1.dateInstance)}T${getAbsoluteTime(range?.start)}`
@@ -2,7 +2,7 @@
2
2
  import { CalendarRangeIcon } from '@lucide/svelte'
3
3
  import { slide } from 'svelte/transition'
4
4
  import { goto } from '$app/navigation'
5
- import { param, urlParam } from '../../state/param.svelte.ts'
5
+ import { param, urlParam } from '../../state/param.svelte.js'
6
6
  import { DropDown } from '../menu/index.js'
7
7
  import { formatRangeShort } from './format.js'
8
8
  import { type RangeAsDate, RangePicker } from './index.js'
@@ -21,8 +21,7 @@
21
21
  classRow,
22
22
  hideBody = false,
23
23
  onCreateField,
24
- onclick,
25
- screenPadding
24
+ onclick
26
25
  }: {
27
26
  key?: string
28
27
  fields: TableField<Item>[]
@@ -34,7 +33,6 @@
34
33
  hideBody?: boolean
35
34
  onCreateField?: () => void
36
35
  onclick?: (item?: Item) => void
37
- screenPadding?: number
38
36
  } = $props()
39
37
 
40
38
  $effect(() => {
@@ -12,7 +12,6 @@ declare function $$render<Item extends ItemBase>(): {
12
12
  hideBody?: boolean;
13
13
  onCreateField?: () => void;
14
14
  onclick?: (item?: Item) => void;
15
- screenPadding?: number;
16
15
  };
17
16
  exports: {};
18
17
  bindings: "";
@@ -11,11 +11,12 @@
11
11
  import { page } from '$app/state'
12
12
  import { listEditable } from '../../action/list/index.js'
13
13
  import { tip } from '../../action/tip.js'
14
- import { param, urlParam } from '../../state/param.svelte.ts'
14
+ import { param, urlParam } from '../../state/param.svelte.js'
15
15
  import { DropDown } from '../menu/index.js'
16
16
  import { context } from './context.js'
17
17
  import type { ItemBase, TableField } from './index.js'
18
18
  import { jsonParse } from '../../utils/jsonParse.js'
19
+ import type { ResolvedPathname } from '$app/types'
19
20
 
20
21
  let {
21
22
  fields,
@@ -30,14 +31,14 @@
30
31
  let { KEY_FIELDS_VISIBLE, KEY_FIELDS_HIDDEN, KEY_FIELDS_ORDER } = $derived(context.get(key))
31
32
 
32
33
  function getFieldHref(field: TableField<Item>) {
33
- if (field.locked) return
34
+ if (field.locked) return '' as ResolvedPathname
34
35
  const url = toggleParam(field.visible ? KEY_FIELDS_HIDDEN : KEY_FIELDS_VISIBLE, field.key)
35
36
  if (url.searchParams.has(field.key)) {
36
37
  url.searchParams.delete(field.key)
37
38
  url.searchParams.delete('skip')
38
39
  url.searchParams.delete('take')
39
40
  }
40
- return url.pathname + url.search
41
+ return (url.pathname + url.search) as ResolvedPathname
41
42
  }
42
43
 
43
44
  function toggleParam(paramKey: string, fieldKey: string): URL {
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { Dialog } from '../dialog/index.js'
6
6
  import { DropDown } from '../menu/index.js'
7
+ import { SvelteURLSearchParams } from 'svelte/reactivity'
7
8
 
8
9
  // import { InputText } from '../input/index.js';
9
10
  // import { useForm } from '../../validation/form.jss';
@@ -15,19 +16,9 @@
15
16
  }
16
17
 
17
18
  let {
18
- key,
19
- views,
20
- action = '',
21
- actionCreate = '?/view_create',
22
- actionUpdate = '?/view_update',
23
- actionDelete = '?/view_delete'
19
+ views
24
20
  }: {
25
- key: string
26
21
  views: View[]
27
- action?: string
28
- actionCreate?: string
29
- actionUpdate?: string
30
- actionDelete?: string
31
22
  } = $props()
32
23
 
33
24
  let dialog = $state<HTMLDialogElement>()
@@ -38,7 +29,7 @@
38
29
  // });
39
30
 
40
31
  let query = $derived.by(() => {
41
- const searchParam = new URLSearchParams(page.url.searchParams)
32
+ const searchParam = new SvelteURLSearchParams(page.url.searchParams)
42
33
  searchParam.delete('skip')
43
34
  searchParam.delete('take')
44
35
  return searchParam.toString()
@@ -4,12 +4,7 @@ type View = {
4
4
  query: string;
5
5
  };
6
6
  type $$ComponentProps = {
7
- key: string;
8
7
  views: View[];
9
- action?: string;
10
- actionCreate?: string;
11
- actionUpdate?: string;
12
- actionDelete?: string;
13
8
  };
14
9
  declare const TableViewSelect: import("svelte").Component<$$ComponentProps, {}, "">;
15
10
  type TableViewSelect = ReturnType<typeof TableViewSelect>;
@@ -2,7 +2,7 @@
2
2
  import { CalendarArrowDownIcon, CalendarArrowUpIcon, CalendarSearchIcon } from '@lucide/svelte'
3
3
  import { goto } from '$app/navigation'
4
4
  import { page } from '$app/state'
5
- import { urlParam } from '../../../state/param.svelte.ts'
5
+ import { urlParam } from '../../../state/param.svelte.js'
6
6
  import { DropDown } from '../../menu/index.js'
7
7
  import { formatRange } from '../../range/format.js'
8
8
  import { type RangeAsDate, RangePicker } from '../../range/index.js'
@@ -19,7 +19,7 @@
19
19
  start?: string
20
20
  end?: string
21
21
  order?: 'asc' | 'desc'
22
- }>(page.url.searchParams.get(field.key), {})
22
+ }>(page.url.searchParams.get((() => field.key)()), {})
23
23
 
24
24
  let range: RangeAsDate = $state({
25
25
  start: initialValue.start ? new Date(initialValue.start) : null,
@@ -4,7 +4,7 @@
4
4
  import z from 'zod'
5
5
  import { goto } from '$app/navigation'
6
6
  import { page } from '$app/state'
7
- import { urlParam } from '../../../state/param.svelte.ts'
7
+ import { urlParam } from '../../../state/param.svelte.js'
8
8
  import { DropDown } from '../../menu/index.js'
9
9
  import { zodCoerceJsonRecord } from '../../../validation/zod.js'
10
10
  import type { ItemBase, TableField } from '../field.js'
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" generics="Item extends ItemBase">
2
2
  import { ListFilterIcon } from '@lucide/svelte'
3
3
  import { page } from '$app/state'
4
- import { param, urlParam } from '../../../state/param.svelte.ts'
4
+ import { param, urlParam } from '../../../state/param.svelte.js'
5
5
  import { DropDown } from '../../menu/index.js'
6
6
  import type { ItemBase, TableField } from '../index.js'
7
7
  import { jsonParse } from '../../../utils/jsonParse.js'
@@ -61,7 +61,7 @@
61
61
 
62
62
  {#if optionsActive.length}
63
63
  <div class="flex flex-wrap gap-1">
64
- {#each optionsActive as option}
64
+ {#each optionsActive as option (option.value)}
65
65
  <span class="badge badge-xs text-[0.7rem] font-normal text-white badge-primary">
66
66
  {#if option.icon}
67
67
  <option.icon size={10} class="-translate-x-1 fill-white/80" />
@@ -75,7 +75,7 @@
75
75
  {/snippet}
76
76
 
77
77
  <div class="flex flex-col gap-1">
78
- {#each options as { isActive, icon: Icon, label, value }}
78
+ {#each options as { isActive, icon: Icon, label, value } (value)}
79
79
  <a
80
80
  href={getHref(value)}
81
81
  class="menu-item px-3 py-2"
@@ -1,6 +1,6 @@
1
1
  import type { IconProps } from '@lucide/svelte';
2
2
  import type { Component } from 'svelte';
3
- import type { InputProps } from '../input/type.ts';
3
+ import type { InputProps } from '../input/type.js';
4
4
  export type Option = {
5
5
  value: string;
6
6
  label: string;
@@ -1,5 +1,5 @@
1
1
  import z from 'zod';
2
- import { zodCoerceJsonValue } from '../validation/zod.ts';
2
+ import { zodCoerceJsonValue } from '../validation/zod.js';
3
3
  export function parseOptions(options) {
4
4
  if (typeof options === 'string') {
5
5
  options = zodCoerceJsonValue.pipe(z.array(z.string())).default([]).parse(options);
@@ -15,7 +15,8 @@ export const zodCoerceJson = z.string().transform((str, ctx) => {
15
15
  try {
16
16
  return JSON.parse(str);
17
17
  }
18
- catch (_err) {
18
+ catch (e) {
19
+ console.error(e);
19
20
  ctx.addIssue({ code: 'custom', message: 'Invalid JSON' });
20
21
  return z.NEVER;
21
22
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fuma",
3
- "version": "2.1.1",
3
+ "version": "2.1.4",
4
4
  "description": "My fullstack material build with sveltekit, daisyui, zod, prisma, lucia",
5
5
  "author": {
6
6
  "name": "Jonas Voisard",
@@ -8,10 +8,10 @@
8
8
  },
9
9
  "scripts": {
10
10
  "dev": "vite dev --host",
11
- "build": "vite build && npm run package",
11
+ "build": "vite build && bun run package",
12
12
  "preview": "vite preview --host",
13
13
  "package": "svelte-kit sync && svelte-package && publint",
14
- "prepublishOnly": "npm run package",
14
+ "prepublishOnly": "bun run package",
15
15
  "sync": "svelte-kit sync",
16
16
  "svelte-check": "svelte-check --tsconfig ./tsconfig.json",
17
17
  "check": "run-p sync svelte-check lint",
@@ -33,27 +33,6 @@
33
33
  "svelte": "./dist/index.js",
34
34
  "default": "./dist/index.js"
35
35
  },
36
- "./ui": {
37
- "types": "./dist/ui/index.d.ts",
38
- "svelte": "./dist/ui/index.js",
39
- "default": "./dist/ui/index.js"
40
- },
41
- "./utils": {
42
- "types": "./dist/utils/index.d.ts",
43
- "default": "./dist/utils/index.js"
44
- },
45
- "./state": {
46
- "types": "./dist/state/index.d.ts",
47
- "default": "./dist/state/index.js"
48
- },
49
- "./validation": {
50
- "types": "./dist/validation/index.d.ts",
51
- "default": "./dist/validation/index.js"
52
- },
53
- "./action": {
54
- "types": "./dist/action/index.d.ts",
55
- "default": "./dist/action/index.js"
56
- },
57
36
  "./server": {
58
37
  "types": "./dist/server/index.d.ts",
59
38
  "default": "./dist/server/index.js"
File without changes
File without changes