@warkypublic/svelix 0.1.39 → 0.1.40

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 (46) hide show
  1. package/dist/components/BetterMenu/BetterMenuAsyncButton.svelte +41 -24
  2. package/dist/components/BetterMenu/BetterMenuAsyncButton.svelte.d.ts +1 -1
  3. package/dist/components/BetterMenu/types.d.ts +2 -1
  4. package/dist/components/ContentEditor/subcomponents/AudioPlayer.svelte +2 -3
  5. package/dist/components/ContentEditor/subcomponents/ImageViewer.svelte +2 -3
  6. package/dist/components/ContentEditor/subcomponents/VideoPlayer.svelte +2 -3
  7. package/dist/components/Former/FormerButtonArea.svelte +3 -2
  8. package/dist/components/Former/FormerDrawer.svelte +130 -124
  9. package/dist/components/Former/FormerDrawer.svelte.d.ts +1 -1
  10. package/dist/components/FormerControllers/InlineWrapper.svelte +4 -34
  11. package/dist/components/Gridler/components/GridlerFull.svelte +1 -0
  12. package/dist/components/Gridler/components/GridlerFullWithFormerPreview.svelte +340 -0
  13. package/dist/components/Gridler/components/GridlerFullWithFormerPreview.svelte.d.ts +3 -0
  14. package/dist/components/Gridler/components/GridlerSearch.svelte +2 -4
  15. package/dist/components/Gridler/components/GridlerSearchToggle.svelte +2 -4
  16. package/dist/components/Gridler/types.d.ts +1 -0
  17. package/dist/components/Icons/IconAdd.svelte +8 -0
  18. package/dist/components/Icons/IconAdd.svelte.d.ts +7 -0
  19. package/dist/components/Icons/IconAlertCircle.svelte +9 -0
  20. package/dist/components/Icons/IconAlertCircle.svelte.d.ts +7 -0
  21. package/dist/components/Icons/IconAlertTriangle.svelte +9 -0
  22. package/dist/components/Icons/IconAlertTriangle.svelte.d.ts +7 -0
  23. package/dist/components/Icons/IconCamera.svelte +8 -0
  24. package/dist/components/Icons/IconCamera.svelte.d.ts +7 -0
  25. package/dist/components/Icons/IconClose.svelte +7 -0
  26. package/dist/components/Icons/IconClose.svelte.d.ts +7 -0
  27. package/dist/components/Icons/IconEdit.svelte +8 -0
  28. package/dist/components/Icons/IconEdit.svelte.d.ts +7 -0
  29. package/dist/components/Icons/IconFilter.svelte +7 -0
  30. package/dist/components/Icons/IconFilter.svelte.d.ts +7 -0
  31. package/dist/components/Icons/IconSearch.svelte +8 -0
  32. package/dist/components/Icons/IconSearch.svelte.d.ts +7 -0
  33. package/dist/components/Icons/IconSort.svelte +11 -0
  34. package/dist/components/Icons/IconSort.svelte.d.ts +8 -0
  35. package/dist/components/Icons/IconTrash.svelte +10 -0
  36. package/dist/components/Icons/IconTrash.svelte.d.ts +7 -0
  37. package/dist/components/Icons/index.d.ts +11 -0
  38. package/dist/components/Icons/index.js +11 -0
  39. package/dist/components/Icons/strings.d.ts +11 -0
  40. package/dist/components/Icons/strings.js +15 -0
  41. package/dist/components/Screenshot/Screenshot.svelte +2 -15
  42. package/dist/components/SvarkGrid/components/SvarkHeaderFilterCell.svelte +4 -13
  43. package/dist/components/index.d.ts +1 -0
  44. package/dist/components/index.js +1 -0
  45. package/llm/README.md +93 -0
  46. package/package.json +19 -20
@@ -1,34 +1,51 @@
1
1
  <script lang="ts">
2
- import type { BetterMenuInstanceItem } from './types';
2
+ import type { Snippet } from "svelte";
3
+ import type { BetterMenuInstanceItem } from "./types";
3
4
 
4
- export interface Props {
5
- item: BetterMenuInstanceItem;
6
- onClose: () => void;
7
- }
5
+ export interface Props {
6
+ item: BetterMenuInstanceItem;
7
+ onClose: () => void;
8
+ }
8
9
 
9
- const { item, onClose }: Props = $props();
10
+ const { item, onClose }: Props = $props();
10
11
 
11
- let loading = $state(false);
12
+ let loading = $state(false);
13
+ function isSnippet(value: unknown): value is Snippet {
14
+ return typeof value === "function";
15
+ }
16
+ function isSvg(value: string): boolean {
17
+ return value?.trimStart?.().startsWith?.("<svg");
18
+ }
12
19
 
13
- async function handleClick(e: MouseEvent) {
14
- item.onClick?.(e);
15
- if (item.onClickAsync) {
16
- loading = true;
17
- try {
18
- await item.onClickAsync(e);
19
- } finally {
20
- loading = false;
21
- }
22
- }
23
- onClose();
24
- }
20
+ async function handleClick(e: MouseEvent) {
21
+ item.onClick?.(e);
22
+ if (item.onClickAsync) {
23
+ loading = true;
24
+ try {
25
+ await item.onClickAsync(e);
26
+ } finally {
27
+ loading = false;
28
+ }
29
+ }
30
+ onClose();
31
+ }
25
32
  </script>
26
33
 
27
34
  <button
28
- class="w-full text-left px-4 py-2 text-sm text-slate-700 dark:text-slate-200 hover:bg-slate-100 dark:hover:bg-slate-700 flex items-center gap-2 disabled:opacity-50"
29
- disabled={loading}
30
- onclick={handleClick}
35
+ class="w-full text-left px-4 py-2 text-sm text-slate-700 dark:text-slate-200 hover:bg-slate-100 dark:hover:bg-slate-700 flex items-center gap-2 disabled:opacity-50"
36
+ disabled={loading}
37
+ onclick={handleClick}
31
38
  >
32
- {#if loading}<span class="animate-spin text-xs">⟳</span>{/if}
33
- {item.label}
39
+ {#if loading}<span class="animate-spin text-xs">⟳</span>{/if}
40
+ {#if item.icon}
41
+ {#if isSnippet(item.icon)}
42
+ {@render item.icon()}
43
+ {:else if isSvg(item.icon)}
44
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -->
45
+ <span class="size-4 flex items-center">{@html item.icon}</span>
46
+ {:else}
47
+ {item.icon}
48
+ {/if}
49
+ {/if}
50
+ {item.label}
34
51
  </button>
@@ -1,4 +1,4 @@
1
- import type { BetterMenuInstanceItem } from './types';
1
+ import type { BetterMenuInstanceItem } from "./types";
2
2
  export interface Props {
3
3
  item: BetterMenuInstanceItem;
4
4
  onClose: () => void;
@@ -1,4 +1,4 @@
1
- import type { Snippet } from 'svelte';
1
+ import type { Snippet } from "svelte";
2
2
  export interface BetterMenuInstance {
3
3
  id: string;
4
4
  items?: Array<BetterMenuInstanceItem>;
@@ -11,6 +11,7 @@ export interface BetterMenuInstance {
11
11
  }
12
12
  export interface BetterMenuInstanceItem {
13
13
  id?: string;
14
+ icon?: string | Snippet;
14
15
  isDivider?: boolean;
15
16
  items?: Array<BetterMenuInstanceItem>;
16
17
  label?: string;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { AudioPlayerProps } from '../types.js';
3
+ import IconAlertCircle from '../../Icons/IconAlertCircle.svelte';
3
4
  let { value, filename }: AudioPlayerProps = $props();
4
5
 
5
6
  let src = $state('');
@@ -19,9 +20,7 @@
19
20
  <div class="flex h-full w-full flex-col items-center justify-center gap-4 p-6">
20
21
  {#if err}
21
22
  <div class="flex items-center gap-2 rounded-container-token bg-error-500/10 px-4 py-3 text-sm text-error-700-300">
22
- <svg xmlns="http://www.w3.org/2000/svg" class="size-5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
23
- <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
24
- </svg>
23
+ <IconAlertCircle size={20} class="shrink-0" />
25
24
  {err}
26
25
  </div>
27
26
  {/if}
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { ImageViewerProps } from '../types.js';
3
+ import IconAlertTriangle from '../../Icons/IconAlertTriangle.svelte';
3
4
  let { value, filename }: ImageViewerProps = $props();
4
5
 
5
6
  let src = $state('');
@@ -17,9 +18,7 @@
17
18
  <div class="relative flex h-full w-full items-center justify-center overflow-hidden bg-surface-50-950">
18
19
  {#if err}
19
20
  <div class="flex flex-col items-center gap-2 text-error-500">
20
- <svg xmlns="http://www.w3.org/2000/svg" class="size-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
21
- <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
22
- </svg>
21
+ <IconAlertTriangle size={40} />
23
22
  <span class="text-sm">Failed to load image</span>
24
23
  </div>
25
24
  {:else if src}
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { VideoPlayerProps } from '../types.js';
3
+ import IconAlertCircle from '../../Icons/IconAlertCircle.svelte';
3
4
  let { value, filename }: VideoPlayerProps = $props();
4
5
 
5
6
  let src = $state('');
@@ -19,9 +20,7 @@
19
20
  <div class="flex h-full w-full flex-col items-center justify-center gap-4 bg-black p-4">
20
21
  {#if err}
21
22
  <div class="flex items-center gap-2 rounded-container-token bg-error-500/10 px-4 py-3 text-sm text-error-300">
22
- <svg xmlns="http://www.w3.org/2000/svg" class="size-5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
23
- <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
24
- </svg>
23
+ <IconAlertCircle size={20} class="shrink-0" />
25
24
  {err}
26
25
  </div>
27
26
  {/if}
@@ -69,7 +69,7 @@
69
69
  </script>
70
70
 
71
71
  <div
72
- class="flex items-center justify-center gap-2 p-2 shadow-sm w-full flex-wrap"
72
+ class="flex items-center justify-center gap-2 p-2 shadow-sm w-full flex-wrap pb-4"
73
73
  >
74
74
  {#if typeof onClose === "function"}
75
75
  <button
@@ -101,6 +101,7 @@
101
101
  onclick={handleSave}
102
102
  >
103
103
  {#if saving}<span class="animate-spin mr-1">⟳</span>{/if}
104
- {saveIcon} {effectiveSaveTitle}
104
+ {saveIcon}
105
+ {effectiveSaveTitle}
105
106
  </button>
106
107
  </div>
@@ -1,139 +1,145 @@
1
1
  <script lang="ts">
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- import { Dialog, Portal } from '@skeletonlabs/skeleton-svelte';
4
- import { registerOverlay } from '../OverlayStack';
5
- import Former from './Former.svelte';
6
- import type { FormerProps, FormRequestType } from './types';
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import { Dialog, Portal } from "@skeletonlabs/skeleton-svelte";
4
+ import { registerOverlay } from "../OverlayStack";
5
+ import Former from "./Former.svelte";
6
+ import type { FormerProps, FormRequestType } from "./types";
7
7
 
8
- export interface Props extends FormerProps {
9
- /**
10
- * Override the auto-generated drawer title.
11
- * When omitted the title is derived from the request type and the unique key value:
12
- * insert → "New Record"
13
- * update → "Edit Record — {key}"
14
- * delete → "Delete Record — {key}"
15
- */
16
- title?: string;
17
- /**
18
- * Width of the drawer panel.
19
- * @default '32rem'
20
- */
21
- width?: string;
22
- }
8
+ export interface Props extends FormerProps {
9
+ /**
10
+ * Override the auto-generated drawer title.
11
+ * When omitted the title is derived from the request type and the unique key value:
12
+ * insert → "New Record"
13
+ * update → "Edit Record — {key}"
14
+ * delete → "Delete Record — {key}"
15
+ */
16
+ title?: string;
17
+ /**
18
+ * Width of the drawer panel.
19
+ * @default '32rem'
20
+ */
21
+ width?: string;
22
+ }
23
23
 
24
- let {
25
- afterGet,
26
- afterSave,
27
- beforeSave,
28
- children,
29
- id,
30
- keepOpen = $bindable(false),
31
- layout,
32
- onAPICall,
33
- onChange,
34
- onClose,
35
- onConfirmDelete,
36
- onError,
37
- onOpen,
38
- opened = $bindable(false),
39
- primeData,
40
- request = $bindable<FormRequestType>('insert'),
41
- title,
42
- uniqueKeyField = 'id',
43
- values = $bindable<any>(undefined),
44
- width = '32rem',
45
- }: Props = $props();
24
+ let {
25
+ afterGet,
26
+ afterSave,
27
+ beforeSave,
28
+ children,
29
+ id,
30
+ keepOpen = $bindable(false),
31
+ layout,
32
+ onAPICall,
33
+ onChange,
34
+ onClose,
35
+ onConfirmDelete,
36
+ onError,
37
+ onOpen,
38
+ opened = $bindable(false),
39
+ primeData,
40
+ request = $bindable<FormRequestType>("insert"),
41
+ title,
42
+ uniqueKeyField = "id",
43
+ values = $bindable<any>(undefined),
44
+ width = "32rem",
45
+ }: Props = $props();
46
46
 
47
- const autoTitle = $derived(
48
- title ??
49
- (request === 'delete'
50
- ? `Delete Record${(values as any)?.[uniqueKeyField] ? ` — ${(values as any)[uniqueKeyField]}` : ''}`
51
- : request === 'insert'
52
- ? 'New Record'
53
- : `Edit Record${(values as any)?.[uniqueKeyField] ? ` — ${(values as any)[uniqueKeyField]}` : ''}`)
54
- );
47
+ const autoTitle = $derived(
48
+ title ??
49
+ (request === "delete"
50
+ ? `Delete Record${(values as any)?.[uniqueKeyField] ? ` — ${(values as any)[uniqueKeyField]}` : ""}`
51
+ : request === "insert"
52
+ ? "New Record"
53
+ : `Edit Record${(values as any)?.[uniqueKeyField] ? ` — ${(values as any)[uniqueKeyField]}` : ""}`),
54
+ );
55
55
 
56
- const animBackdrop =
57
- 'transition transition-discrete opacity-0 starting:data-[state=open]:opacity-0 data-[state=open]:opacity-100';
58
- const animContent =
59
- 'transition transition-discrete opacity-0 translate-x-full starting:data-[state=open]:opacity-0 starting:data-[state=open]:translate-x-full data-[state=open]:opacity-100 data-[state=open]:translate-x-0';
56
+ const animBackdrop =
57
+ "transition transition-discrete opacity-0 starting:data-[state=open]:opacity-0 data-[state=open]:opacity-100";
58
+ const animContent =
59
+ "transition transition-discrete opacity-0 translate-x-full starting:data-[state=open]:opacity-0 starting:data-[state=open]:translate-x-full data-[state=open]:opacity-100 data-[state=open]:translate-x-0";
60
60
 
61
- let backdropZ = $state(1000);
62
- let contentZ = $state(1010);
61
+ let backdropZ = $state(1000);
62
+ let contentZ = $state(1010);
63
63
 
64
- $effect(() => {
65
- if (!opened) {
66
- return;
67
- }
64
+ $effect(() => {
65
+ if (!opened) {
66
+ return;
67
+ }
68
68
 
69
- const overlay = registerOverlay({ kind: 'drawer', mount: 'portal' });
70
- backdropZ = overlay.layer.backdrop;
71
- contentZ = overlay.layer.content;
69
+ const overlay = registerOverlay({ kind: "drawer", mount: "portal" });
70
+ backdropZ = overlay.layer.backdrop;
71
+ contentZ = overlay.layer.content;
72
72
 
73
- return () => {
74
- overlay.unregister();
75
- backdropZ = 1000;
76
- contentZ = 1010;
77
- };
78
- });
73
+ return () => {
74
+ overlay.unregister();
75
+ backdropZ = 1000;
76
+ contentZ = 1010;
77
+ };
78
+ });
79
79
  </script>
80
80
 
81
81
  <Dialog
82
- open={opened}
83
- onOpenChange={(e) => {
84
- opened = e.open;
85
- if (!e.open) onClose?.();
86
- }}
87
- closeOnInteractOutside={false}
88
- closeOnEscape={false}
89
- modal
82
+ open={opened}
83
+ onOpenChange={(e) => {
84
+ opened = e.open;
85
+ if (!e.open) onClose?.();
86
+ }}
87
+ closeOnInteractOutside={false}
88
+ closeOnEscape={false}
89
+ modal
90
90
  >
91
- <Portal>
92
- <Dialog.Backdrop
93
- class="fixed inset-0 bg-black/50 backdrop-blur-sm {animBackdrop}"
94
- style={`z-index:${backdropZ};`}
95
- />
96
- <Dialog.Positioner class="fixed inset-0 flex justify-end" style={`z-index:${contentZ};`}>
97
- <Dialog.Content
98
- class="card bg-surface-100-900 shadow-2xl h-full flex flex-col overflow-hidden rounded-none rounded-l-container-token {animContent}"
99
- style="width: {width}"
100
- >
101
- <header
102
- class="flex items-center justify-between px-6 pt-5 pb-4 border-b border-surface-300-600 shrink-0"
103
- >
104
- <Dialog.Title class="text-lg font-semibold">{autoTitle}</Dialog.Title>
105
- <Dialog.CloseTrigger class="btn-icon btn-icon-sm preset-tonal" aria-label="Close drawer">
106
-
107
- </Dialog.CloseTrigger>
108
- </header>
91
+ <Portal>
92
+ <Dialog.Backdrop
93
+ class="fixed inset-0 bg-black/50 backdrop-blur-sm {animBackdrop}"
94
+ style={`z-index:${backdropZ};`}
95
+ />
96
+ <Dialog.Positioner
97
+ class="fixed inset-0 flex justify-end"
98
+ style={`z-index:${contentZ};`}
99
+ >
100
+ <Dialog.Content
101
+ class="card bg-surface-100-900 shadow-2xl h-full flex flex-col overflow-hidden rounded-none rounded-l-container-token {animContent}"
102
+ style="width: {width}"
103
+ >
104
+ <header
105
+ class="flex items-center justify-between px-6 pt-5 pb-4 border-b border-surface-300-600 shrink-0"
106
+ >
107
+ <Dialog.Title class="text-lg font-semibold">{autoTitle}</Dialog.Title>
108
+ <Dialog.CloseTrigger
109
+ class="btn-icon btn-icon-sm preset-tonal"
110
+ aria-label="Close drawer"
111
+ >
112
+
113
+ </Dialog.CloseTrigger>
114
+ </header>
109
115
 
110
- <div class="flex-1 min-h-0 overflow-auto bg-surface-50-950">
111
- <Former
112
- bind:values
113
- bind:opened
114
- bind:request
115
- bind:keepOpen
116
- {afterGet}
117
- {afterSave}
118
- {beforeSave}
119
- {children}
120
- {id}
121
- layout={{ buttonArea: 'bottom', ...layout }}
122
- mounted={opened}
123
- {onAPICall}
124
- {onChange}
125
- {onConfirmDelete}
126
- {onError}
127
- {onOpen}
128
- {primeData}
129
- {uniqueKeyField}
130
- onClose={(data) => {
131
- opened = false;
132
- onClose?.(data);
133
- }}
134
- />
135
- </div>
136
- </Dialog.Content>
137
- </Dialog.Positioner>
138
- </Portal>
116
+ <div class="flex-1 min-h-0 overflow-auto bg-surface-50-950">
117
+ <Former
118
+ bind:values
119
+ bind:opened
120
+ bind:request
121
+ bind:keepOpen
122
+ {afterGet}
123
+ {afterSave}
124
+ {beforeSave}
125
+ {children}
126
+ {id}
127
+ layout={{ buttonArea: "bottom", ...layout }}
128
+ mounted={opened}
129
+ {onAPICall}
130
+ {onChange}
131
+ {onConfirmDelete}
132
+ {onError}
133
+ {onOpen}
134
+ {primeData}
135
+ {uniqueKeyField}
136
+ onClose={(data) => {
137
+ opened = false;
138
+ onClose?.(data);
139
+ }}
140
+ />
141
+ </div>
142
+ </Dialog.Content>
143
+ </Dialog.Positioner>
144
+ </Portal>
139
145
  </Dialog>
@@ -1,4 +1,4 @@
1
- import type { FormerProps } from './types';
1
+ import type { FormerProps } from "./types";
2
2
  export interface Props extends FormerProps {
3
3
  /**
4
4
  * Override the auto-generated drawer title.
@@ -1,5 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
+ import IconAlertCircle from '../Icons/IconAlertCircle.svelte';
4
+ import IconAlertTriangle from '../Icons/IconAlertTriangle.svelte';
3
5
 
4
6
  export interface Props {
5
7
  children?: Snippet;
@@ -52,41 +54,9 @@
52
54
  <span class="inline-flex items-center gap-1.5 text-xs font-medium text-surface-700 dark:text-surface-300">
53
55
  {label}{#if required && isEmpty}<span class="text-error-500">*</span>{/if}
54
56
  {#if showErrorIcon}
55
- <svg
56
- xmlns="http://www.w3.org/2000/svg"
57
- width="14"
58
- height="14"
59
- viewBox="0 0 24 24"
60
- fill="none"
61
- stroke="currentColor"
62
- stroke-width="2"
63
- stroke-linecap="round"
64
- stroke-linejoin="round"
65
- class="text-error-500"
66
- aria-hidden="true"
67
- >
68
- <circle cx="12" cy="12" r="10"></circle>
69
- <line x1="12" y1="8" x2="12" y2="12"></line>
70
- <line x1="12" y1="16" x2="12.01" y2="16"></line>
71
- </svg>
57
+ <IconAlertCircle size={14} class="text-error-500" />
72
58
  {:else if showWarningIcon}
73
- <svg
74
- xmlns="http://www.w3.org/2000/svg"
75
- width="14"
76
- height="14"
77
- viewBox="0 0 24 24"
78
- fill="none"
79
- stroke="currentColor"
80
- stroke-width="2"
81
- stroke-linecap="round"
82
- stroke-linejoin="round"
83
- class="text-warning-500"
84
- aria-hidden="true"
85
- >
86
- <path d="m10.29 3.86-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.71-3.14l-8-14a2 2 0 0 0-3.42 0z"></path>
87
- <line x1="12" y1="9" x2="12" y2="13"></line>
88
- <line x1="12" y1="17" x2="12.01" y2="17"></line>
89
- </svg>
59
+ <IconAlertTriangle size={14} class="text-warning-500" />
90
60
  {/if}
91
61
  </span>
92
62
  {:else if label}
@@ -345,6 +345,7 @@
345
345
  items.push({
346
346
  id: item.id,
347
347
  label: item.label,
348
+ icon: item.icon,
348
349
  onClick: () => {
349
350
  item.onselect?.();
350
351
  onMenuItemSelect?.(item);