@warkypublic/svelix 0.1.46 → 0.2.1

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 (129) hide show
  1. package/README.md +93 -33
  2. package/dist/components/BetterMenu/BetterMenu.svelte +21 -37
  3. package/dist/components/BetterMenu/BetterMenuAsyncButton.svelte +21 -31
  4. package/dist/components/BetterMenu/BetterMenuPreview.svelte +27 -29
  5. package/dist/components/BetterMenu/MenuRenderer.svelte +40 -51
  6. package/dist/components/Boxer/Boxer.svelte +492 -602
  7. package/dist/components/Boxer/BoxerTarget.svelte +6 -46
  8. package/dist/components/Boxer/BoxerTarget.svelte.d.ts +1 -0
  9. package/dist/components/Boxer/types.d.ts +0 -1
  10. package/dist/components/Button.svelte +19 -43
  11. package/dist/components/ButtonPreview.svelte +2 -11
  12. package/dist/components/CardGrid/CardGrid.svelte +489 -614
  13. package/dist/components/CardGrid/CardGrid.svelte.d.ts +4 -0
  14. package/dist/components/CardGrid/CardGridFilterPanel.svelte +111 -90
  15. package/dist/components/CardGrid/DefaultCard.svelte +86 -97
  16. package/dist/components/CardGrid/DefaultCard.svelte.d.ts +1 -0
  17. package/dist/components/CardGrid/ImageCardStory.svelte +87 -36
  18. package/dist/components/CardGrid/cardGrid.d.ts +24 -0
  19. package/dist/components/CardGrid/cardGrid.js +20 -0
  20. package/dist/components/ContentEditor/CollaboraInsertTextDemo.svelte +5 -10
  21. package/dist/components/ContentEditor/ContentEditor.svelte +24 -50
  22. package/dist/components/ContentEditor/subcomponents/AudioPlayer.svelte +17 -17
  23. package/dist/components/ContentEditor/subcomponents/CollaboraEditor.svelte +244 -309
  24. package/dist/components/ContentEditor/subcomponents/EmailViewer.svelte +2 -3
  25. package/dist/components/ContentEditor/subcomponents/ImageViewer.svelte +14 -15
  26. package/dist/components/ContentEditor/subcomponents/MarkdownViewer.svelte +74 -90
  27. package/dist/components/ContentEditor/subcomponents/MonacoEditor.svelte +75 -103
  28. package/dist/components/ContentEditor/subcomponents/Office365Editor.svelte +234 -297
  29. package/dist/components/ContentEditor/subcomponents/PdfViewer.svelte +14 -20
  30. package/dist/components/ContentEditor/subcomponents/TextEditor.svelte +122 -150
  31. package/dist/components/ContentEditor/subcomponents/UnknownFile.svelte +105 -126
  32. package/dist/components/ContentEditor/subcomponents/VideoPlayer.svelte +17 -17
  33. package/dist/components/ContentEditor/subcomponents/ZipViewer.svelte +2 -3
  34. package/dist/components/ErrorBoundary/ErrorBoundary.svelte +41 -58
  35. package/dist/components/ErrorBoundary/ErrorBoundaryPreview.svelte +8 -16
  36. package/dist/components/Former/Former.svelte +306 -424
  37. package/dist/components/Former/FormerButtonArea.svelte +17 -68
  38. package/dist/components/Former/FormerDrawer.svelte +16 -80
  39. package/dist/components/Former/FormerDrawerPreview.svelte +99 -89
  40. package/dist/components/Former/FormerModal.svelte +16 -74
  41. package/dist/components/Former/FormerModalPreview.svelte +99 -89
  42. package/dist/components/Former/FormerPreview.svelte +76 -78
  43. package/dist/components/Former/FormerRestApiPreview.svelte +55 -48
  44. package/dist/components/Former/formerOverlayHelpers.svelte.d.ts +11 -0
  45. package/dist/components/Former/formerOverlayHelpers.svelte.js +38 -0
  46. package/dist/components/Former/index.d.ts +1 -0
  47. package/dist/components/Former/index.js +1 -0
  48. package/dist/components/FormerControllers/ButtonCtrl.svelte +13 -49
  49. package/dist/components/FormerControllers/CtrlFieldShell.svelte +15 -0
  50. package/dist/components/FormerControllers/CtrlFieldShell.svelte.d.ts +12 -0
  51. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrl.svelte +285 -457
  52. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlCalendar.svelte +95 -136
  53. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlPickerPanel.svelte +3 -62
  54. package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlTimeFields.svelte +143 -217
  55. package/dist/components/FormerControllers/IconButtonCtrl.svelte +13 -47
  56. package/dist/components/FormerControllers/InlineWrapper.svelte +12 -41
  57. package/dist/components/FormerControllers/InlineWrapperPreview.svelte +4 -26
  58. package/dist/components/FormerControllers/NativeSelectCtrl.svelte +7 -39
  59. package/dist/components/FormerControllers/NumberInputCtrl.svelte +21 -43
  60. package/dist/components/FormerControllers/PasswordInputCtrl.svelte +8 -33
  61. package/dist/components/FormerControllers/SwitchCtrl.svelte +4 -20
  62. package/dist/components/FormerControllers/TextAreaCtrl.svelte +7 -34
  63. package/dist/components/FormerControllers/TextInputCtrl.svelte +7 -34
  64. package/dist/components/FormerControllers/ctrlLoading.svelte.d.ts +8 -0
  65. package/dist/components/FormerControllers/ctrlLoading.svelte.js +43 -0
  66. package/dist/components/FormerControllers/index.d.ts +2 -0
  67. package/dist/components/FormerControllers/index.js +2 -0
  68. package/dist/components/FormerControllers/utils.d.ts +1 -0
  69. package/dist/components/FormerControllers/utils.js +3 -0
  70. package/dist/components/GlobalStateStore/GlobalStateStoreProvider.svelte +73 -120
  71. package/dist/components/Gridler/components/Gridler.svelte +344 -442
  72. package/dist/components/Gridler/components/GridlerCanvas.svelte +720 -1115
  73. package/dist/components/Gridler/components/GridlerEditor.svelte +2 -15
  74. package/dist/components/Gridler/components/GridlerFull.svelte +521 -841
  75. package/dist/components/Gridler/components/GridlerFull.svelte.d.ts +1 -1
  76. package/dist/components/Gridler/components/GridlerFullWithFormerPreview.svelte +194 -147
  77. package/dist/components/Gridler/components/GridlerSearch.svelte +7 -16
  78. package/dist/components/Gridler/components/GridlerSearchToggle.svelte +7 -19
  79. package/dist/components/Gridler/types.d.ts +1 -1
  80. package/dist/components/Gridler/utils/serverPaging.d.ts +1 -0
  81. package/dist/components/Gridler/utils/serverPaging.js +7 -0
  82. package/dist/components/Icons/IconAdd.svelte +1 -3
  83. package/dist/components/Icons/IconAlertCircle.svelte +1 -3
  84. package/dist/components/Icons/IconAlertTriangle.svelte +1 -3
  85. package/dist/components/Icons/IconCamera.svelte +1 -3
  86. package/dist/components/Icons/IconClose.svelte +1 -3
  87. package/dist/components/Icons/IconEdit.svelte +1 -3
  88. package/dist/components/Icons/IconFilter.svelte +1 -3
  89. package/dist/components/Icons/IconSearch.svelte +1 -3
  90. package/dist/components/Icons/IconSort.svelte +1 -3
  91. package/dist/components/Icons/IconTrash.svelte +1 -3
  92. package/dist/components/Portal/Portal.svelte +14 -38
  93. package/dist/components/Screenshot/Screenshot.svelte +7 -13
  94. package/dist/components/Svark/Svark.svelte +680 -852
  95. package/dist/components/Svark/SvarkContextMenu.svelte +44 -63
  96. package/dist/components/Svark/SvarkInfiniteLoader.svelte +2 -6
  97. package/dist/components/Svark/SvarkPager.svelte +2 -28
  98. package/dist/components/Svark/SvarkSelectionDemo.svelte +4 -8
  99. package/dist/components/Svark/SvarkTopBar.svelte +9 -74
  100. package/dist/components/SvarkGrid/SvarkGrid.svelte +877 -1123
  101. package/dist/components/SvarkGrid/components/SvarkColumnFilterForm.svelte +45 -58
  102. package/dist/components/SvarkGrid/components/SvarkContextMenu.svelte +44 -63
  103. package/dist/components/SvarkGrid/components/SvarkHeaderFilterCell.svelte +41 -75
  104. package/dist/components/SvarkGrid/components/SvarkInfiniteLoader.svelte +2 -6
  105. package/dist/components/SvarkGrid/components/SvarkPager.svelte +2 -28
  106. package/dist/components/SvarkGrid/components/SvarkSearchPopover.svelte +8 -16
  107. package/dist/components/SvarkGrid/components/SvarkTopBar.svelte +6 -62
  108. package/dist/components/SvarkGrid/internal/SvarkGridView.svelte +345 -507
  109. package/dist/components/VTree/VTree.svelte +454 -431
  110. package/dist/components/VTree/VTree.utils.d.ts +23 -0
  111. package/dist/components/VTree/VTree.utils.js +73 -0
  112. package/dist/components/VTree/VTreeContextMenu.svelte +21 -33
  113. package/dist/components/VTree/VTreeControlledSelectionDemo.svelte +20 -0
  114. package/dist/components/VTree/VTreeControlledSelectionDemo.svelte.d.ts +18 -0
  115. package/dist/components/VTree/VTreeCustomizationDemo.svelte +23 -0
  116. package/dist/components/VTree/VTreeCustomizationDemo.svelte.d.ts +18 -0
  117. package/dist/components/VTree/VTreeEventsDemo.svelte +48 -58
  118. package/dist/components/VTree/VTreeInteractionDemo.svelte +29 -0
  119. package/dist/components/VTree/VTreeInteractionDemo.svelte.d.ts +18 -0
  120. package/dist/components/VTree/VTreeMultiSelectDemo.svelte +27 -0
  121. package/dist/components/VTree/VTreeMultiSelectDemo.svelte.d.ts +18 -0
  122. package/dist/components/VTree/VTreeRow.svelte +77 -115
  123. package/dist/components/VTree/VTreeRow.svelte.d.ts +34 -18
  124. package/dist/components/VTree/VTreeSearch.svelte +6 -13
  125. package/dist/components/VTree/VTreeVirtualViewport.svelte +54 -143
  126. package/dist/components/VTree/VTreeVirtualViewport.svelte.d.ts +35 -18
  127. package/dist/components/VTree/types.d.ts +39 -1
  128. package/llm/COMPONENT_GUIDE.md +25 -0
  129. package/package.json +51 -50
@@ -1,93 +1,104 @@
1
- <script lang="ts">
2
-
3
- import FormerModal from './FormerModal.svelte';
4
- import type { FormRequestType } from './types';
5
- import TextInputCtrl from '../FormerControllers/TextInputCtrl.svelte';
6
- import PasswordInputCtrl from '../FormerControllers/PasswordInputCtrl.svelte';
7
- import NumberInputCtrl from '../FormerControllers/NumberInputCtrl.svelte';
8
- import NativeSelectCtrl from '../FormerControllers/NativeSelectCtrl.svelte';
9
- import TextAreaCtrl from '../FormerControllers/TextAreaCtrl.svelte';
10
- import SwitchCtrl from '../FormerControllers/SwitchCtrl.svelte';
11
- import Boxer from '../Boxer/Boxer.svelte';
12
-
13
- interface UserForm {
14
- id?: number;
15
- firstName: string;
16
- lastName: string;
17
- email: string;
18
- password: string;
19
- age?: number;
20
- role: string;
21
- department: string;
22
- skills: string[];
23
- bio: string;
24
- website: string;
25
- emailNotifications: boolean;
26
- active: boolean;
1
+ <script lang="ts">import FormerModal from "./FormerModal.svelte";
2
+ import TextInputCtrl from "../FormerControllers/TextInputCtrl.svelte";
3
+ import PasswordInputCtrl from "../FormerControllers/PasswordInputCtrl.svelte";
4
+ import NumberInputCtrl from "../FormerControllers/NumberInputCtrl.svelte";
5
+ import NativeSelectCtrl from "../FormerControllers/NativeSelectCtrl.svelte";
6
+ import TextAreaCtrl from "../FormerControllers/TextAreaCtrl.svelte";
7
+ import SwitchCtrl from "../FormerControllers/SwitchCtrl.svelte";
8
+ import Boxer from "../Boxer/Boxer.svelte";
9
+ const { request = "insert" } = $props();
10
+ const emptyUser = {
11
+ firstName: "",
12
+ lastName: "",
13
+ email: "",
14
+ password: "",
15
+ age: undefined,
16
+ role: "",
17
+ department: "",
18
+ skills: [],
19
+ bio: "",
20
+ website: "",
21
+ emailNotifications: true,
22
+ active: true
23
+ };
24
+ const filledUser = {
25
+ id: 1,
26
+ firstName: "Jane",
27
+ lastName: "Smith",
28
+ email: "jane.smith@example.com",
29
+ password: "",
30
+ age: 32,
31
+ role: "admin",
32
+ department: "engineering",
33
+ skills: ["typescript", "svelte"],
34
+ bio: "Senior software engineer with 10 years of experience building scalable systems.",
35
+ website: "https://janesmith.dev",
36
+ emailNotifications: true,
37
+ active: true
38
+ };
39
+ const roleOptions = [
40
+ {
41
+ label: "Admin",
42
+ value: "admin"
43
+ },
44
+ {
45
+ label: "Editor",
46
+ value: "editor"
47
+ },
48
+ {
49
+ label: "Viewer",
50
+ value: "viewer"
27
51
  }
28
-
29
- export interface Props {
30
- request?: FormRequestType;
52
+ ];
53
+ const departmentOptions = [
54
+ {
55
+ label: "Engineering",
56
+ value: "engineering"
57
+ },
58
+ {
59
+ label: "Product",
60
+ value: "product"
61
+ },
62
+ {
63
+ label: "Design",
64
+ value: "design"
65
+ },
66
+ {
67
+ label: "Marketing",
68
+ value: "marketing"
69
+ },
70
+ {
71
+ label: "Operations",
72
+ value: "operations"
31
73
  }
32
-
33
- const { request = 'insert' }: Props = $props();
34
-
35
- const emptyUser: UserForm = {
36
- firstName: '',
37
- lastName: '',
38
- email: '',
39
- password: '',
40
- age: undefined,
41
- role: '',
42
- department: '',
43
- skills: [],
44
- bio: '',
45
- website: '',
46
- emailNotifications: true,
47
- active: true,
48
- };
49
-
50
- const filledUser: UserForm = {
51
- id: 1,
52
- firstName: 'Jane',
53
- lastName: 'Smith',
54
- email: 'jane.smith@example.com',
55
- password: '',
56
- age: 32,
57
- role: 'admin',
58
- department: 'engineering',
59
- skills: ['typescript', 'svelte'],
60
- bio: 'Senior software engineer with 10 years of experience building scalable systems.',
61
- website: 'https://janesmith.dev',
62
- emailNotifications: true,
63
- active: true,
64
- };
65
-
66
- const roleOptions = [
67
- { label: 'Admin', value: 'admin' },
68
- { label: 'Editor', value: 'editor' },
69
- { label: 'Viewer', value: 'viewer' },
70
- ];
71
-
72
- const departmentOptions = [
73
- { label: 'Engineering', value: 'engineering' },
74
- { label: 'Product', value: 'product' },
75
- { label: 'Design', value: 'design' },
76
- { label: 'Marketing', value: 'marketing' },
77
- { label: 'Operations', value: 'operations' },
78
- ];
79
-
80
- const skillOptions = [
81
- { label: 'Svelte', value: 'svelte' },
82
- { label: 'TypeScript', value: 'typescript' },
83
- { label: 'Node.js', value: 'nodejs' },
84
- { label: 'Testing', value: 'testing' },
85
- { label: 'UX', value: 'ux' },
86
- ];
87
-
88
- let values = $state<UserForm>(request === 'insert' ? { ...emptyUser } : { ...filledUser });
89
- let lastSaved = $state<UserForm | undefined>(undefined);
90
- let opened = $state(false);
74
+ ];
75
+ const skillOptions = [
76
+ {
77
+ label: "Svelte",
78
+ value: "svelte"
79
+ },
80
+ {
81
+ label: "TypeScript",
82
+ value: "typescript"
83
+ },
84
+ {
85
+ label: "Node.js",
86
+ value: "nodejs"
87
+ },
88
+ {
89
+ label: "Testing",
90
+ value: "testing"
91
+ },
92
+ {
93
+ label: "UX",
94
+ value: "ux"
95
+ }
96
+ ];
97
+ // eslint-disable-next-line svelte/no-unused-svelte-ignore
98
+ // svelte-ignore state_referenced_locally -- initial value is intentional (sets up form state once)
99
+ let values = $state(request === "insert" ? { ...emptyUser } : { ...filledUser });
100
+ let lastSaved = $state(undefined);
101
+ let opened = $state(false);
91
102
  </script>
92
103
 
93
104
  <div class="p-8 space-y-6">
@@ -212,7 +223,6 @@
212
223
  data={skillOptions}
213
224
  dataSource="local"
214
225
  multiSelect
215
- searchable
216
226
  clearable
217
227
  placeholder="Search skills..."
218
228
  disabled={isReadonly}
@@ -1,81 +1,79 @@
1
- <script lang="ts">
2
- import Former from './Former.svelte';
3
- import type { FormRequestType } from './types';
4
- import TextInputCtrl from '../FormerControllers/TextInputCtrl.svelte';
5
- import PasswordInputCtrl from '../FormerControllers/PasswordInputCtrl.svelte';
6
- import NumberInputCtrl from '../FormerControllers/NumberInputCtrl.svelte';
7
- import NativeSelectCtrl from '../FormerControllers/NativeSelectCtrl.svelte';
8
- import TextAreaCtrl from '../FormerControllers/TextAreaCtrl.svelte';
9
- import SwitchCtrl from '../FormerControllers/SwitchCtrl.svelte';
10
-
11
- interface UserForm {
12
- id?: number;
13
- firstName: string;
14
- lastName: string;
15
- email: string;
16
- password: string;
17
- age?: number;
18
- role: string;
19
- department: string;
20
- bio: string;
21
- website: string;
22
- emailNotifications: boolean;
23
- active: boolean;
24
- }
25
-
26
- export interface Props {
27
- request?: FormRequestType;
28
- showKeepOpenSwitch?: boolean;
29
- }
30
-
31
- const { request = 'insert', showKeepOpenSwitch = false }: Props = $props();
32
-
33
- const emptyUser: UserForm = {
34
- firstName: '',
35
- lastName: '',
36
- email: '',
37
- password: '',
38
- age: undefined,
39
- role: '',
40
- department: '',
41
- bio: '',
42
- website: '',
43
- emailNotifications: true,
44
- active: true,
45
- };
46
-
47
- const filledUser: UserForm = {
48
- id: 1,
49
- firstName: 'Jane',
50
- lastName: 'Smith',
51
- email: 'jane.smith@example.com',
52
- password: '',
53
- age: 32,
54
- role: 'admin',
55
- department: 'engineering',
56
- bio: 'Senior software engineer with 10 years of experience building scalable systems.',
57
- website: 'https://janesmith.dev',
58
- emailNotifications: true,
59
- active: true,
60
- };
61
-
62
- let values = $state<UserForm>(request === 'insert' ? { ...emptyUser } : { ...filledUser });
63
- let lastSaved = $state<UserForm | undefined>(undefined);
64
- let opened = $state(true);
65
-
66
- const roleOptions = [
67
- { label: 'Admin', value: 'admin' },
68
- { label: 'Editor', value: 'editor' },
69
- { label: 'Viewer', value: 'viewer' },
70
- ];
71
-
72
- const departmentOptions = [
73
- { label: 'Engineering', value: 'engineering' },
74
- { label: 'Product', value: 'product' },
75
- { label: 'Design', value: 'design' },
76
- { label: 'Marketing', value: 'marketing' },
77
- { label: 'Operations', value: 'operations' },
78
- ];
1
+ <script lang="ts">import Former from "./Former.svelte";
2
+ import TextInputCtrl from "../FormerControllers/TextInputCtrl.svelte";
3
+ import PasswordInputCtrl from "../FormerControllers/PasswordInputCtrl.svelte";
4
+ import NumberInputCtrl from "../FormerControllers/NumberInputCtrl.svelte";
5
+ import NativeSelectCtrl from "../FormerControllers/NativeSelectCtrl.svelte";
6
+ import TextAreaCtrl from "../FormerControllers/TextAreaCtrl.svelte";
7
+ import SwitchCtrl from "../FormerControllers/SwitchCtrl.svelte";
8
+ const { request = "insert", showKeepOpenSwitch = false } = $props();
9
+ const emptyUser = {
10
+ firstName: "",
11
+ lastName: "",
12
+ email: "",
13
+ password: "",
14
+ age: undefined,
15
+ role: "",
16
+ department: "",
17
+ bio: "",
18
+ website: "",
19
+ emailNotifications: true,
20
+ active: true
21
+ };
22
+ const filledUser = {
23
+ id: 1,
24
+ firstName: "Jane",
25
+ lastName: "Smith",
26
+ email: "jane.smith@example.com",
27
+ password: "",
28
+ age: 32,
29
+ role: "admin",
30
+ department: "engineering",
31
+ bio: "Senior software engineer with 10 years of experience building scalable systems.",
32
+ website: "https://janesmith.dev",
33
+ emailNotifications: true,
34
+ active: true
35
+ };
36
+ // eslint-disable-next-line svelte/no-unused-svelte-ignore
37
+ // svelte-ignore state_referenced_locally -- initial value is intentional (sets up form state once)
38
+ let values = $state(request === "insert" ? { ...emptyUser } : { ...filledUser });
39
+ let lastSaved = $state(undefined);
40
+ let opened = $state(true);
41
+ const roleOptions = [
42
+ {
43
+ label: "Admin",
44
+ value: "admin"
45
+ },
46
+ {
47
+ label: "Editor",
48
+ value: "editor"
49
+ },
50
+ {
51
+ label: "Viewer",
52
+ value: "viewer"
53
+ }
54
+ ];
55
+ const departmentOptions = [
56
+ {
57
+ label: "Engineering",
58
+ value: "engineering"
59
+ },
60
+ {
61
+ label: "Product",
62
+ value: "product"
63
+ },
64
+ {
65
+ label: "Design",
66
+ value: "design"
67
+ },
68
+ {
69
+ label: "Marketing",
70
+ value: "marketing"
71
+ },
72
+ {
73
+ label: "Operations",
74
+ value: "operations"
75
+ }
76
+ ];
79
77
  </script>
80
78
 
81
79
  <div class="p-6 space-y-6">
@@ -1,51 +1,58 @@
1
- <script lang="ts">
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- import FormerModal from "./FormerModal.svelte";
4
- import { FormerRestHeadSpecAPI } from "./FormerRestHeadSpecAPI";
5
- import type { FormRequestType } from "./types";
6
- import TextInputCtrl from "../FormerControllers/TextInputCtrl.svelte";
7
- import TextAreaCtrl from "../FormerControllers/TextAreaCtrl.svelte";
8
- import NativeSelectCtrl from "../FormerControllers/NativeSelectCtrl.svelte";
9
-
10
- // ── Config state ────────────────────────────────────────────────────────────
11
- let apiUrl = $state("https://www.postb.in/b/1771846908265-6770497136749");
12
- let authToken = $state("");
13
- let showToken = $state(false);
14
- let recordId = $state("1");
15
- let request = $state<FormRequestType>("insert");
16
-
17
- // ── Modal state ─────────────────────────────────────────────────────────────
18
- let opened = $state(false);
19
- let values = $state<Record<string, any>>({});
20
- let lastResponse = $state<Record<string, any> | undefined>(undefined);
21
- let lastError = $state<string | undefined>(undefined);
22
-
23
- // Re-create the API adapter whenever the URL or token changes.
24
- // $derived is correct here — FormerRestHeadSpecAPI is a pure factory function.
25
- const onAPICall = $derived(
26
- FormerRestHeadSpecAPI({
27
- authToken,
28
- url: apiUrl,
29
- }),
30
- );
31
-
32
- const requestOptions = [
33
- { label: "Insert (POST)", value: "insert" },
34
- { label: "Update (PUT)", value: "update" },
35
- { label: "Delete (DELETE)", value: "delete" },
36
- { label: "View (GET)", value: "view" },
37
- ];
38
-
39
- function openForm() {
40
- lastError = undefined;
41
- if (request === "insert") {
42
- values = { title: "", body: "", userId: 1 };
43
- } else {
44
- // For non-insert modes prime the key so Former knows which record to load.
45
- values = { id: Number(recordId) || 1 };
46
- }
47
- opened = true;
48
- }
1
+ <script lang="ts">/* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import FormerModal from "./FormerModal.svelte";
3
+ import { FormerRestHeadSpecAPI } from "./FormerRestHeadSpecAPI";
4
+ import TextInputCtrl from "../FormerControllers/TextInputCtrl.svelte";
5
+ import TextAreaCtrl from "../FormerControllers/TextAreaCtrl.svelte";
6
+ import NativeSelectCtrl from "../FormerControllers/NativeSelectCtrl.svelte";
7
+ // ── Config state ────────────────────────────────────────────────────────────
8
+ let apiUrl = $state("https://www.postb.in/b/1771846908265-6770497136749");
9
+ let authToken = $state("");
10
+ let showToken = $state(false);
11
+ let recordId = $state("1");
12
+ let request = $state("insert");
13
+ // ── Modal state ─────────────────────────────────────────────────────────────
14
+ let opened = $state(false);
15
+ let values = $state({});
16
+ let lastResponse = $state(undefined);
17
+ let lastError = $state(undefined);
18
+ // Re-create the API adapter whenever the URL or token changes.
19
+ // $derived is correct here — FormerRestHeadSpecAPI is a pure factory function.
20
+ const onAPICall = $derived(FormerRestHeadSpecAPI({
21
+ authToken,
22
+ url: apiUrl
23
+ }));
24
+ const requestOptions = [
25
+ {
26
+ label: "Insert (POST)",
27
+ value: "insert"
28
+ },
29
+ {
30
+ label: "Update (PUT)",
31
+ value: "update"
32
+ },
33
+ {
34
+ label: "Delete (DELETE)",
35
+ value: "delete"
36
+ },
37
+ {
38
+ label: "View (GET)",
39
+ value: "view"
40
+ }
41
+ ];
42
+ function openForm() {
43
+ lastError = undefined;
44
+ if (request === "insert") {
45
+ values = {
46
+ title: "",
47
+ body: "",
48
+ userId: 1
49
+ };
50
+ } else {
51
+ // For non-insert modes prime the key so Former knows which record to load.
52
+ values = { id: Number(recordId) || 1 };
53
+ }
54
+ opened = true;
55
+ }
49
56
  </script>
50
57
 
51
58
  <div class="p-6 space-y-6">
@@ -0,0 +1,11 @@
1
+ import type { FormRequestType } from './types';
2
+ export declare function deriveAutoTitle(params: {
3
+ request?: FormRequestType;
4
+ title?: string;
5
+ uniqueKeyField: string;
6
+ values?: unknown;
7
+ }): string;
8
+ export declare function createOverlayZIndex(kind: 'dialog' | 'drawer', getOpened: () => boolean): {
9
+ readonly backdropZ: number;
10
+ readonly contentZ: number;
11
+ };
@@ -0,0 +1,38 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { registerOverlay } from '../OverlayStack';
3
+ export function deriveAutoTitle(params) {
4
+ const { request, title, uniqueKeyField, values } = params;
5
+ if (title)
6
+ return title;
7
+ const keyValue = values?.[uniqueKeyField];
8
+ if (request === 'delete')
9
+ return `Delete Record${keyValue ? ` — ${keyValue}` : ''}`;
10
+ if (request === 'insert')
11
+ return 'New Record';
12
+ return `Edit Record${keyValue ? ` — ${keyValue}` : ''}`;
13
+ }
14
+ export function createOverlayZIndex(kind, getOpened) {
15
+ let backdropZ = $state(1000);
16
+ let contentZ = $state(1010);
17
+ $effect(() => {
18
+ if (!getOpened()) {
19
+ return;
20
+ }
21
+ const overlay = registerOverlay({ kind, mount: 'portal' });
22
+ backdropZ = overlay.layer.backdrop;
23
+ contentZ = overlay.layer.content;
24
+ return () => {
25
+ overlay.unregister();
26
+ backdropZ = 1000;
27
+ contentZ = 1010;
28
+ };
29
+ });
30
+ return {
31
+ get backdropZ() {
32
+ return backdropZ;
33
+ },
34
+ get contentZ() {
35
+ return contentZ;
36
+ },
37
+ };
38
+ }
@@ -3,6 +3,7 @@ export { default as FormerButtonArea } from './FormerButtonArea.svelte';
3
3
  export { default as FormerDrawer } from './FormerDrawer.svelte';
4
4
  export { default as FormerModal } from './FormerModal.svelte';
5
5
  export { createFormerState } from './formerState.svelte';
6
+ export { createOverlayZIndex, deriveAutoTitle } from './formerOverlayHelpers.svelte';
6
7
  export { FormerResolveSpecAPI } from './FormerResolveSpecAPI';
7
8
  export { FormerRestHeadSpecAPI } from './FormerRestHeadSpecAPI';
8
9
  export * from './types';
@@ -3,6 +3,7 @@ export { default as FormerButtonArea } from './FormerButtonArea.svelte';
3
3
  export { default as FormerDrawer } from './FormerDrawer.svelte';
4
4
  export { default as FormerModal } from './FormerModal.svelte';
5
5
  export { createFormerState } from './formerState.svelte';
6
+ export { createOverlayZIndex, deriveAutoTitle } from './formerOverlayHelpers.svelte';
6
7
  export { FormerResolveSpecAPI } from './FormerResolveSpecAPI';
7
8
  export { FormerRestHeadSpecAPI } from './FormerRestHeadSpecAPI';
8
9
  export * from './types';
@@ -1,60 +1,24 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- export interface Props {
5
- children?: Snippet;
6
- disabled?: boolean;
7
- loading?: boolean;
8
- onclick?: () => Promise<void>;
9
- sid?: string;
10
- title?: string;
11
- tooltip?: string;
12
- variant?: 'filled' | 'ghost' | 'outlined';
13
- }
14
-
15
- const {
16
- children,
17
- disabled,
18
- loading: externalLoading = false,
19
- onclick,
20
- sid,
21
- title,
22
- tooltip,
23
- variant = 'filled',
24
- }: Props = $props();
25
-
26
- let internalLoading = $state(false);
27
- const isLoading = $derived(internalLoading || externalLoading);
28
-
29
- const variantClass = $derived(
30
- variant === 'outlined'
31
- ? 'preset-outlined-primary-500'
32
- : variant === 'ghost'
33
- ? 'preset-tonal-primary'
34
- : 'preset-filled-primary-500'
35
- );
36
-
37
- async function handleClick() {
38
- if (onclick && !isLoading) {
39
- internalLoading = true;
40
- try {
41
- await onclick();
42
- } finally {
43
- internalLoading = false;
44
- }
45
- }
46
- }
1
+ <script lang="ts">import { createClickLoading, createClickPulse } from "./ctrlLoading.svelte";
2
+ const { children, disabled, loading: externalLoading = false, onclick, sid, title, tooltip, variant = "filled" } = $props();
3
+ const clickLoading = createClickLoading(() => externalLoading);
4
+ const variantClass = $derived(variant === "outlined" ? "preset-outlined-primary-500" : variant === "ghost" ? "preset-tonal-primary" : "preset-filled-primary-500");
5
+ const clickPulse = createClickPulse();
6
+ function handleClick() {
7
+ clickPulse.trigger();
8
+ clickLoading.run(onclick);
9
+ }
47
10
  </script>
48
11
 
49
12
  <button
50
- class="btn {variantClass}"
13
+ class="btn {variantClass} transition-transform duration-150"
14
+ class:scale-90={clickPulse.pressed}
51
15
  data-sid={sid}
52
- disabled={disabled || isLoading}
16
+ disabled={disabled || clickLoading.isLoading}
53
17
  title={tooltip}
54
18
  type="button"
55
19
  onclick={handleClick}
56
20
  >
57
- {#if isLoading}
21
+ {#if clickLoading.isLoading}
58
22
  <span class="animate-spin mr-1">⟳</span>
59
23
  {/if}
60
24
  {#if children}
@@ -0,0 +1,15 @@
1
+ <script lang="ts">const { children, error, id, label, required, tooltip } = $props();
2
+ export {};
3
+ </script>
4
+
5
+ <div class="flex flex-col gap-1" title={tooltip}>
6
+ {#if label}
7
+ <label class="label text-sm font-medium" for={id}>
8
+ {label}{#if required}<span class="text-error-500">*</span>{/if}
9
+ </label>
10
+ {/if}
11
+ {@render children()}
12
+ {#if error}
13
+ <p class="text-error-500 text-xs">{error}</p>
14
+ {/if}
15
+ </div>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ export interface Props {
3
+ children: Snippet;
4
+ error?: string;
5
+ id?: string;
6
+ label?: string;
7
+ required?: boolean;
8
+ tooltip?: string;
9
+ }
10
+ declare const CtrlFieldShell: import("svelte").Component<Props, {}, "">;
11
+ type CtrlFieldShell = ReturnType<typeof CtrlFieldShell>;
12
+ export default CtrlFieldShell;