svelte-comp 1.3.3 → 1.3.6

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 (138) hide show
  1. package/LICENSE.md +21 -21
  2. package/README.md +101 -100
  3. package/dist/App.svelte +507 -507
  4. package/dist/Container.svelte +59 -59
  5. package/dist/app.css +234 -235
  6. package/dist/app.d.ts +10 -0
  7. package/dist/lib/Accordion.svelte +155 -155
  8. package/dist/lib/Badge.svelte +44 -44
  9. package/dist/lib/Button.svelte +185 -170
  10. package/dist/lib/Calendar.svelte +384 -384
  11. package/dist/lib/Card.svelte +103 -103
  12. package/dist/lib/Carousel.svelte +293 -293
  13. package/dist/lib/Carousel.svelte.d.ts +1 -1
  14. package/dist/lib/CheckBox.svelte +210 -210
  15. package/dist/lib/CodeView.svelte +308 -307
  16. package/dist/lib/ColorPicker.svelte +159 -159
  17. package/dist/lib/ContextMenu.svelte +328 -322
  18. package/dist/lib/DatePicker.svelte +246 -246
  19. package/dist/lib/Dialog.svelte +233 -233
  20. package/dist/lib/Field.svelte +299 -299
  21. package/dist/lib/FilePicker.svelte +295 -240
  22. package/dist/lib/FilePicker.svelte.d.ts +6 -1
  23. package/dist/lib/Form.svelte +438 -438
  24. package/dist/lib/Hamburger.svelte +217 -217
  25. package/dist/lib/InstallPWA.svelte +94 -94
  26. package/dist/lib/Menu.svelte +623 -623
  27. package/dist/lib/NoticeBase.svelte +140 -140
  28. package/dist/lib/PaginatedCard.svelte +73 -73
  29. package/dist/lib/Pagination.svelte +119 -119
  30. package/dist/lib/PrimaryColorSelect.svelte +111 -111
  31. package/dist/lib/ProgressBar.svelte +141 -141
  32. package/dist/lib/ProgressCircle.svelte +190 -190
  33. package/dist/lib/Radio.svelte +189 -189
  34. package/dist/lib/SearchInput.svelte +104 -104
  35. package/dist/lib/Select.svelte +524 -524
  36. package/dist/lib/Slider.svelte +253 -253
  37. package/dist/lib/Splitter.svelte +159 -150
  38. package/dist/lib/Switch.svelte +168 -167
  39. package/dist/lib/Table.svelte +299 -299
  40. package/dist/lib/Tabs.svelte +213 -213
  41. package/dist/lib/ThemeToggle.svelte +128 -127
  42. package/dist/lib/TimePicker.svelte +312 -312
  43. package/dist/lib/TimePickerNew.svelte +634 -0
  44. package/dist/lib/TimePickerNew.svelte.d.ts +49 -0
  45. package/dist/lib/Toast.svelte +123 -123
  46. package/dist/lib/Tooltip.svelte +110 -110
  47. package/dist/lib/Topbar.svelte +107 -107
  48. package/dist/lib/__tests__/Accordion.test.d.ts +1 -0
  49. package/dist/lib/__tests__/Accordion.test.js +171 -0
  50. package/dist/lib/__tests__/Badge.test.d.ts +1 -0
  51. package/dist/lib/__tests__/Badge.test.js +41 -0
  52. package/dist/lib/__tests__/Button.test.d.ts +1 -0
  53. package/dist/lib/__tests__/Button.test.js +269 -0
  54. package/dist/lib/__tests__/Calendar.test.d.ts +1 -0
  55. package/dist/lib/__tests__/Calendar.test.js +171 -0
  56. package/dist/lib/__tests__/Card.test.d.ts +1 -0
  57. package/dist/lib/__tests__/Card.test.js +148 -0
  58. package/dist/lib/__tests__/Carousel.test.d.ts +1 -0
  59. package/dist/lib/__tests__/Carousel.test.js +439 -0
  60. package/dist/lib/__tests__/CheckBox.test.d.ts +1 -0
  61. package/dist/lib/__tests__/CheckBox.test.js +152 -0
  62. package/dist/lib/__tests__/CodeView.test.d.ts +1 -0
  63. package/dist/lib/__tests__/CodeView.test.js +157 -0
  64. package/dist/lib/__tests__/ColorPicker.test.d.ts +1 -0
  65. package/dist/lib/__tests__/ColorPicker.test.js +93 -0
  66. package/dist/lib/__tests__/ContextMenu.test.d.ts +1 -0
  67. package/dist/lib/__tests__/ContextMenu.test.js +67 -0
  68. package/dist/lib/__tests__/DatePicker.test.d.ts +1 -0
  69. package/dist/lib/__tests__/DatePicker.test.js +108 -0
  70. package/dist/lib/__tests__/Dialog.test.d.ts +1 -0
  71. package/dist/lib/__tests__/Dialog.test.js +183 -0
  72. package/dist/lib/__tests__/Field.test.d.ts +1 -0
  73. package/dist/lib/__tests__/Field.test.js +190 -0
  74. package/dist/lib/__tests__/FilePicker.test.d.ts +1 -0
  75. package/dist/lib/__tests__/FilePicker.test.js +179 -0
  76. package/dist/lib/__tests__/Form.integration.test.d.ts +1 -0
  77. package/dist/lib/__tests__/Form.integration.test.js +158 -0
  78. package/dist/lib/__tests__/Form.test.d.ts +1 -0
  79. package/dist/lib/__tests__/Form.test.js +463 -0
  80. package/dist/lib/__tests__/Hamburger.test.d.ts +1 -0
  81. package/dist/lib/__tests__/Hamburger.test.js +161 -0
  82. package/dist/lib/__tests__/InstallPWA.test.d.ts +1 -0
  83. package/dist/lib/__tests__/InstallPWA.test.js +15 -0
  84. package/dist/lib/__tests__/Menu.test.d.ts +1 -0
  85. package/dist/lib/__tests__/Menu.test.js +285 -0
  86. package/dist/lib/__tests__/NoticeBase.test.d.ts +1 -0
  87. package/dist/lib/__tests__/NoticeBase.test.js +60 -0
  88. package/dist/lib/__tests__/PaginatedCard.test.d.ts +1 -0
  89. package/dist/lib/__tests__/PaginatedCard.test.js +89 -0
  90. package/dist/lib/__tests__/Pagination.test.d.ts +1 -0
  91. package/dist/lib/__tests__/Pagination.test.js +168 -0
  92. package/dist/lib/__tests__/PrimaryColorSelect.test.d.ts +1 -0
  93. package/dist/lib/__tests__/PrimaryColorSelect.test.js +92 -0
  94. package/dist/lib/__tests__/ProgressBar.test.d.ts +1 -0
  95. package/dist/lib/__tests__/ProgressBar.test.js +69 -0
  96. package/dist/lib/__tests__/ProgressCircle.test.d.ts +1 -0
  97. package/dist/lib/__tests__/ProgressCircle.test.js +71 -0
  98. package/dist/lib/__tests__/Radio.test.d.ts +1 -0
  99. package/dist/lib/__tests__/Radio.test.js +127 -0
  100. package/dist/lib/__tests__/SearchInput.test.d.ts +1 -0
  101. package/dist/lib/__tests__/SearchInput.test.js +80 -0
  102. package/dist/lib/__tests__/Select.test.d.ts +1 -0
  103. package/dist/lib/__tests__/Select.test.js +408 -0
  104. package/dist/lib/__tests__/Slider.test.d.ts +1 -0
  105. package/dist/lib/__tests__/Slider.test.js +213 -0
  106. package/dist/lib/__tests__/Splitter.test.d.ts +1 -0
  107. package/dist/lib/__tests__/Splitter.test.js +87 -0
  108. package/dist/lib/__tests__/Switch.test.d.ts +1 -0
  109. package/dist/lib/__tests__/Switch.test.js +97 -0
  110. package/dist/lib/__tests__/Table.test.d.ts +1 -0
  111. package/dist/lib/__tests__/Table.test.js +349 -0
  112. package/dist/lib/__tests__/Tabs.test.d.ts +1 -0
  113. package/dist/lib/__tests__/Tabs.test.js +262 -0
  114. package/dist/lib/__tests__/ThemeToggle.test.d.ts +1 -0
  115. package/dist/lib/__tests__/ThemeToggle.test.js +84 -0
  116. package/dist/lib/__tests__/TimePicker.test.d.ts +1 -0
  117. package/dist/lib/__tests__/TimePicker.test.js +146 -0
  118. package/dist/lib/__tests__/TimePickerNew.test.d.ts +1 -0
  119. package/dist/lib/__tests__/TimePickerNew.test.js +322 -0
  120. package/dist/lib/__tests__/Toast.test.d.ts +1 -0
  121. package/dist/lib/__tests__/Toast.test.js +135 -0
  122. package/dist/lib/__tests__/Tooltip.test.d.ts +1 -0
  123. package/dist/lib/__tests__/Tooltip.test.js +171 -0
  124. package/dist/lib/__tests__/Topbar.test.d.ts +1 -0
  125. package/dist/lib/__tests__/Topbar.test.js +25 -0
  126. package/dist/lib/__tests__/setupLangContext.d.ts +1 -0
  127. package/dist/lib/__tests__/setupLangContext.js +65 -0
  128. package/dist/lib/__tests__/storage.test.d.ts +1 -0
  129. package/dist/lib/__tests__/storage.test.js +124 -0
  130. package/dist/lib/__tests__/utils.test.d.ts +1 -0
  131. package/dist/lib/__tests__/utils.test.js +11 -0
  132. package/dist/lib/index.d.ts +1 -0
  133. package/dist/lib/index.js +1 -0
  134. package/dist/lib/lang.d.ts +4 -0
  135. package/dist/lib/lang.js +4 -0
  136. package/dist/styles.css +234 -232
  137. package/dist/utils/index.js +15 -4
  138. package/package.json +52 -52
@@ -0,0 +1,463 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ // $lib/__tests__/Form.test.ts
38
+ import { render, fireEvent } from "@testing-library/svelte";
39
+ import { describe, it, expect, vi } from "vitest";
40
+ import Form from "../Form.svelte";
41
+ describe("Form", function () {
42
+ var basicSchema = [
43
+ {
44
+ name: "email",
45
+ type: "email",
46
+ label: "Email",
47
+ required: true,
48
+ },
49
+ {
50
+ name: "password",
51
+ type: "password",
52
+ label: "Password",
53
+ required: true,
54
+ },
55
+ {
56
+ name: "newsletter",
57
+ type: "checkbox",
58
+ label: "Subscribe to newsletter",
59
+ },
60
+ ];
61
+ it("renders form with all field types", function () {
62
+ var getByText = render(Form, {
63
+ props: { schema: basicSchema },
64
+ }).getByText;
65
+ expect(getByText("Email")).toBeTruthy();
66
+ expect(getByText("Password")).toBeTruthy();
67
+ expect(getByText("Subscribe to newsletter")).toBeTruthy();
68
+ });
69
+ it("initializes form with default values", function () {
70
+ var container = render(Form, {
71
+ props: {
72
+ schema: basicSchema,
73
+ value: { email: "test@example.com" },
74
+ },
75
+ }).container;
76
+ var emailInput = container.querySelector('input[type="email"]');
77
+ expect(emailInput.value).toBe("test@example.com");
78
+ });
79
+ it("updates form values on input", function () { return __awaiter(void 0, void 0, void 0, function () {
80
+ var mockOnChange, container, emailInput;
81
+ return __generator(this, function (_a) {
82
+ switch (_a.label) {
83
+ case 0:
84
+ mockOnChange = vi.fn();
85
+ container = render(Form, {
86
+ props: {
87
+ schema: basicSchema,
88
+ onChange: mockOnChange,
89
+ },
90
+ }).container;
91
+ emailInput = container.querySelector('input[type="email"]');
92
+ return [4 /*yield*/, fireEvent.input(emailInput, { target: { value: "new@example.com" } })];
93
+ case 1:
94
+ _a.sent();
95
+ expect(mockOnChange).toHaveBeenCalledWith({
96
+ email: "new@example.com",
97
+ password: "",
98
+ newsletter: false,
99
+ });
100
+ return [2 /*return*/];
101
+ }
102
+ });
103
+ }); });
104
+ it("validates required fields on blur", function () { return __awaiter(void 0, void 0, void 0, function () {
105
+ var _a, container, findByText, emailInput, error;
106
+ return __generator(this, function (_b) {
107
+ switch (_b.label) {
108
+ case 0:
109
+ _a = render(Form, {
110
+ props: {
111
+ schema: basicSchema,
112
+ validateOn: "blur",
113
+ },
114
+ }), container = _a.container, findByText = _a.findByText;
115
+ emailInput = container.querySelector('input[type="email"]');
116
+ return [4 /*yield*/, fireEvent.blur(emailInput)];
117
+ case 1:
118
+ _b.sent();
119
+ return [4 /*yield*/, findByText("Required")];
120
+ case 2:
121
+ error = _b.sent();
122
+ expect(error).toBeTruthy();
123
+ return [2 /*return*/];
124
+ }
125
+ });
126
+ }); });
127
+ it("submits form when valid", function () { return __awaiter(void 0, void 0, void 0, function () {
128
+ var mockOnSubmit, container, emailInput, passwordInput, form;
129
+ return __generator(this, function (_a) {
130
+ switch (_a.label) {
131
+ case 0:
132
+ mockOnSubmit = vi.fn();
133
+ container = render(Form, {
134
+ props: {
135
+ schema: basicSchema,
136
+ onSubmit: mockOnSubmit,
137
+ },
138
+ }).container;
139
+ emailInput = container.querySelector('input[type="email"]');
140
+ passwordInput = container.querySelector('input[type="password"]');
141
+ return [4 /*yield*/, fireEvent.input(emailInput, {
142
+ target: { value: "test@example.com" },
143
+ })];
144
+ case 1:
145
+ _a.sent();
146
+ return [4 /*yield*/, fireEvent.input(passwordInput, { target: { value: "password123" } })];
147
+ case 2:
148
+ _a.sent();
149
+ form = container.querySelector("form");
150
+ return [4 /*yield*/, fireEvent.submit(form)];
151
+ case 3:
152
+ _a.sent();
153
+ expect(mockOnSubmit).toHaveBeenCalledWith({
154
+ email: "test@example.com",
155
+ password: "password123",
156
+ newsletter: false,
157
+ }, expect.objectContaining({
158
+ reset: expect.any(Function),
159
+ }));
160
+ return [2 /*return*/];
161
+ }
162
+ });
163
+ }); });
164
+ it("shows validation errors on submit when validateOn='submit'", function () { return __awaiter(void 0, void 0, void 0, function () {
165
+ var mockOnSubmit, formApi, container, isValid, form;
166
+ return __generator(this, function (_a) {
167
+ switch (_a.label) {
168
+ case 0:
169
+ mockOnSubmit = vi.fn();
170
+ container = render(Form, {
171
+ props: {
172
+ schema: basicSchema,
173
+ validateOn: "submit",
174
+ onSubmit: mockOnSubmit,
175
+ expose: function (api) {
176
+ formApi = api;
177
+ },
178
+ },
179
+ }).container;
180
+ return [4 /*yield*/, formApi.validate()];
181
+ case 1:
182
+ isValid = _a.sent();
183
+ expect(isValid).toBe(false);
184
+ form = container.querySelector("form");
185
+ return [4 /*yield*/, fireEvent.submit(form)];
186
+ case 2:
187
+ _a.sent();
188
+ expect(mockOnSubmit).not.toHaveBeenCalled();
189
+ return [2 /*return*/];
190
+ }
191
+ });
192
+ }); });
193
+ it("handles conditional fields with when function", function () { return __awaiter(void 0, void 0, void 0, function () {
194
+ var conditionalSchema, _a, container, queryByText, checkbox;
195
+ return __generator(this, function (_b) {
196
+ switch (_b.label) {
197
+ case 0:
198
+ conditionalSchema = [
199
+ {
200
+ name: "show_extra",
201
+ type: "checkbox",
202
+ label: "Show extra field",
203
+ },
204
+ {
205
+ name: "extra_field",
206
+ type: "text",
207
+ label: "Extra Field",
208
+ when: function (form) { return form.show_extra === true; },
209
+ },
210
+ ];
211
+ _a = render(Form, {
212
+ props: { schema: conditionalSchema },
213
+ }), container = _a.container, queryByText = _a.queryByText;
214
+ expect(queryByText("Extra Field")).toBeNull();
215
+ checkbox = container.querySelector('input[type="checkbox"]');
216
+ return [4 /*yield*/, fireEvent.click(checkbox)];
217
+ case 1:
218
+ _b.sent();
219
+ expect(queryByText("Extra Field")).toBeTruthy();
220
+ return [2 /*return*/];
221
+ }
222
+ });
223
+ }); });
224
+ it("resets form values using expose API", function () { return __awaiter(void 0, void 0, void 0, function () {
225
+ var formApi, container, emailInput;
226
+ return __generator(this, function (_a) {
227
+ switch (_a.label) {
228
+ case 0:
229
+ container = render(Form, {
230
+ props: {
231
+ schema: basicSchema,
232
+ expose: function (api) {
233
+ formApi = api;
234
+ },
235
+ },
236
+ }).container;
237
+ emailInput = container.querySelector('input[type="email"]');
238
+ return [4 /*yield*/, fireEvent.input(emailInput, {
239
+ target: { value: "test@example.com" },
240
+ })];
241
+ case 1:
242
+ _a.sent();
243
+ expect(emailInput.value).toBe("test@example.com");
244
+ formApi.reset();
245
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 0); })];
246
+ case 2:
247
+ _a.sent();
248
+ expect(emailInput.value).toBe("");
249
+ return [2 /*return*/];
250
+ }
251
+ });
252
+ }); });
253
+ it("handles select field type", function () { return __awaiter(void 0, void 0, void 0, function () {
254
+ var schemaWithSelect, getByText;
255
+ return __generator(this, function (_a) {
256
+ schemaWithSelect = [
257
+ {
258
+ name: "country",
259
+ type: "select",
260
+ label: "Country",
261
+ options: [
262
+ { value: "us", label: "USA" },
263
+ { value: "ca", label: "Canada" },
264
+ ],
265
+ },
266
+ ];
267
+ getByText = render(Form, {
268
+ props: { schema: schemaWithSelect },
269
+ }).getByText;
270
+ expect(getByText("Country")).toBeTruthy();
271
+ return [2 /*return*/];
272
+ });
273
+ }); });
274
+ it("applies compact mode styles", function () {
275
+ var container = render(Form, {
276
+ props: {
277
+ schema: basicSchema,
278
+ compact: true,
279
+ },
280
+ }).container;
281
+ var form = container.querySelector("form");
282
+ expect(form === null || form === void 0 ? void 0 : form.className).toContain("justify-items-center");
283
+ });
284
+ it("handles custom validators", function () { return __awaiter(void 0, void 0, void 0, function () {
285
+ var customValidator, schemaWithValidator, _a, container, findByText, usernameInput, error;
286
+ return __generator(this, function (_b) {
287
+ switch (_b.label) {
288
+ case 0:
289
+ customValidator = vi.fn(function (value) {
290
+ return typeof value === "string" && value.length < 3
291
+ ? "Must be at least 3 characters"
292
+ : null;
293
+ });
294
+ schemaWithValidator = [
295
+ {
296
+ name: "username",
297
+ type: "text",
298
+ label: "Username",
299
+ validators: [customValidator],
300
+ },
301
+ ];
302
+ _a = render(Form, {
303
+ props: {
304
+ schema: schemaWithValidator,
305
+ validateOn: "blur",
306
+ },
307
+ }), container = _a.container, findByText = _a.findByText;
308
+ usernameInput = container.querySelector('input[type="text"]');
309
+ return [4 /*yield*/, fireEvent.input(usernameInput, { target: { value: "ab" } })];
310
+ case 1:
311
+ _b.sent();
312
+ return [4 /*yield*/, fireEvent.blur(usernameInput)];
313
+ case 2:
314
+ _b.sent();
315
+ return [4 /*yield*/, findByText("Must be at least 3 characters")];
316
+ case 3:
317
+ error = _b.sent();
318
+ expect(error).toBeTruthy();
319
+ expect(customValidator).toHaveBeenCalledWith("ab", expect.any(Object));
320
+ return [2 /*return*/];
321
+ }
322
+ });
323
+ }); });
324
+ it("handles number field type with parsing", function () { return __awaiter(void 0, void 0, void 0, function () {
325
+ var numberSchema, mockOnChange, container, ageInput;
326
+ return __generator(this, function (_a) {
327
+ switch (_a.label) {
328
+ case 0:
329
+ numberSchema = [
330
+ {
331
+ name: "age",
332
+ type: "number",
333
+ label: "Age",
334
+ },
335
+ ];
336
+ mockOnChange = vi.fn();
337
+ container = render(Form, {
338
+ props: {
339
+ schema: numberSchema,
340
+ onChange: mockOnChange,
341
+ },
342
+ }).container;
343
+ ageInput = container.querySelector('input[type="number"]');
344
+ return [4 /*yield*/, fireEvent.input(ageInput, { target: { value: "25" } })];
345
+ case 1:
346
+ _a.sent();
347
+ expect(mockOnChange).toHaveBeenCalledWith({
348
+ age: 25,
349
+ });
350
+ return [2 /*return*/];
351
+ }
352
+ });
353
+ }); });
354
+ it("applies custom label alignment", function () {
355
+ var container = render(Form, {
356
+ props: {
357
+ schema: basicSchema,
358
+ labelAlign: "center",
359
+ },
360
+ }).container;
361
+ var labels = container.querySelectorAll('[class*="text-center"]');
362
+ expect(labels.length).toBeGreaterThan(0);
363
+ });
364
+ it("generates deterministic form ids", function () {
365
+ var container1 = render(Form, {
366
+ props: { schema: basicSchema },
367
+ }).container;
368
+ var container2 = render(Form, {
369
+ props: { schema: basicSchema },
370
+ }).container;
371
+ var form1 = container1.querySelector("form");
372
+ var form2 = container2.querySelector("form");
373
+ expect(form1 === null || form1 === void 0 ? void 0 : form1.id).toMatch(/^form-/);
374
+ expect(form2 === null || form2 === void 0 ? void 0 : form2.id).toMatch(/^form-/);
375
+ });
376
+ it("submits form programmatically via expose API", function () { return __awaiter(void 0, void 0, void 0, function () {
377
+ var mockOnSubmit, formApi, container, emailInput, passwordInput;
378
+ return __generator(this, function (_a) {
379
+ switch (_a.label) {
380
+ case 0:
381
+ mockOnSubmit = vi.fn();
382
+ container = render(Form, {
383
+ props: {
384
+ schema: basicSchema,
385
+ onSubmit: mockOnSubmit,
386
+ expose: function (api) {
387
+ formApi = api;
388
+ },
389
+ },
390
+ }).container;
391
+ emailInput = container.querySelector('input[type="email"]');
392
+ passwordInput = container.querySelector('input[type="password"]');
393
+ return [4 /*yield*/, fireEvent.input(emailInput, {
394
+ target: { value: "test@example.com" },
395
+ })];
396
+ case 1:
397
+ _a.sent();
398
+ return [4 /*yield*/, fireEvent.input(passwordInput, { target: { value: "password123" } })];
399
+ case 2:
400
+ _a.sent();
401
+ return [4 /*yield*/, formApi.submit()];
402
+ case 3:
403
+ _a.sent();
404
+ expect(mockOnSubmit).toHaveBeenCalledWith({
405
+ email: "test@example.com",
406
+ password: "password123",
407
+ newsletter: false,
408
+ }, expect.any(Object));
409
+ return [2 /*return*/];
410
+ }
411
+ });
412
+ }); });
413
+ it("validates form programmatically via expose API", function () { return __awaiter(void 0, void 0, void 0, function () {
414
+ var formApi, isValid;
415
+ return __generator(this, function (_a) {
416
+ switch (_a.label) {
417
+ case 0:
418
+ render(Form, {
419
+ props: {
420
+ schema: basicSchema,
421
+ expose: function (api) {
422
+ formApi = api;
423
+ },
424
+ },
425
+ });
426
+ return [4 /*yield*/, formApi.validate()];
427
+ case 1:
428
+ isValid = _a.sent();
429
+ expect(isValid).toBe(false);
430
+ return [2 /*return*/];
431
+ }
432
+ });
433
+ }); });
434
+ it("gets form data via expose API", function () { return __awaiter(void 0, void 0, void 0, function () {
435
+ var formApi, container, emailInput, formData;
436
+ return __generator(this, function (_a) {
437
+ switch (_a.label) {
438
+ case 0:
439
+ container = render(Form, {
440
+ props: {
441
+ schema: basicSchema,
442
+ expose: function (api) {
443
+ formApi = api;
444
+ },
445
+ },
446
+ }).container;
447
+ emailInput = container.querySelector('input[type="email"]');
448
+ return [4 /*yield*/, fireEvent.input(emailInput, {
449
+ target: { value: "test@example.com" },
450
+ })];
451
+ case 1:
452
+ _a.sent();
453
+ formData = formApi.getData();
454
+ expect(formData).toEqual({
455
+ email: "test@example.com",
456
+ password: "",
457
+ newsletter: false,
458
+ });
459
+ return [2 /*return*/];
460
+ }
461
+ });
462
+ }); });
463
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,161 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { render, fireEvent } from "@testing-library/svelte";
38
+ import { describe, it, expect, vi } from "vitest";
39
+ import Hamburger from "../Hamburger.svelte";
40
+ var items = [
41
+ { id: "home", label: "Home" },
42
+ { id: "settings", label: "Settings" },
43
+ ];
44
+ describe("Hamburger", function () {
45
+ it("renders trigger and opens dialog on click", function () { return __awaiter(void 0, void 0, void 0, function () {
46
+ var _a, getByRole, queryByRole, trigger;
47
+ return __generator(this, function (_b) {
48
+ switch (_b.label) {
49
+ case 0:
50
+ _a = render(Hamburger, {
51
+ props: { menuItems: items },
52
+ }), getByRole = _a.getByRole, queryByRole = _a.queryByRole;
53
+ expect(queryByRole("dialog")).toBeNull();
54
+ trigger = getByRole("button", { name: "Toggle navigation" });
55
+ return [4 /*yield*/, fireEvent.click(trigger)];
56
+ case 1:
57
+ _b.sent();
58
+ expect(getByRole("dialog")).toBeTruthy();
59
+ return [2 /*return*/];
60
+ }
61
+ });
62
+ }); });
63
+ it("renders menu items when open", function () { return __awaiter(void 0, void 0, void 0, function () {
64
+ var _a, getByRole, getByText;
65
+ return __generator(this, function (_b) {
66
+ switch (_b.label) {
67
+ case 0:
68
+ _a = render(Hamburger, {
69
+ props: { menuItems: items },
70
+ }), getByRole = _a.getByRole, getByText = _a.getByText;
71
+ return [4 /*yield*/, fireEvent.click(getByRole("button", { name: "Toggle navigation" }))];
72
+ case 1:
73
+ _b.sent();
74
+ expect(getByText("Home")).toBeTruthy();
75
+ expect(getByText("Settings")).toBeTruthy();
76
+ return [2 /*return*/];
77
+ }
78
+ });
79
+ }); });
80
+ it("calls onSelect and closes when closeOnSelect is true", function () { return __awaiter(void 0, void 0, void 0, function () {
81
+ var onSelect, _a, getByRole, getByText, queryByRole;
82
+ return __generator(this, function (_b) {
83
+ switch (_b.label) {
84
+ case 0:
85
+ onSelect = vi.fn();
86
+ _a = render(Hamburger, {
87
+ props: { menuItems: items, onSelect: onSelect, closeOnSelect: true },
88
+ }), getByRole = _a.getByRole, getByText = _a.getByText, queryByRole = _a.queryByRole;
89
+ return [4 /*yield*/, fireEvent.click(getByRole("button", { name: "Toggle navigation" }))];
90
+ case 1:
91
+ _b.sent();
92
+ return [4 /*yield*/, fireEvent.click(getByText("Home"))];
93
+ case 2:
94
+ _b.sent();
95
+ expect(onSelect).toHaveBeenCalledWith("home");
96
+ expect(queryByRole("dialog")).toBeNull();
97
+ return [2 /*return*/];
98
+ }
99
+ });
100
+ }); });
101
+ it("keeps open when closeOnSelect is false", function () { return __awaiter(void 0, void 0, void 0, function () {
102
+ var onSelect, _a, getByRole, getByText;
103
+ return __generator(this, function (_b) {
104
+ switch (_b.label) {
105
+ case 0:
106
+ onSelect = vi.fn();
107
+ _a = render(Hamburger, {
108
+ props: { menuItems: items, onSelect: onSelect, closeOnSelect: false },
109
+ }), getByRole = _a.getByRole, getByText = _a.getByText;
110
+ return [4 /*yield*/, fireEvent.click(getByRole("button", { name: "Toggle navigation" }))];
111
+ case 1:
112
+ _b.sent();
113
+ return [4 /*yield*/, fireEvent.click(getByText("Settings"))];
114
+ case 2:
115
+ _b.sent();
116
+ expect(onSelect).toHaveBeenCalledWith("settings");
117
+ expect(getByRole("dialog")).toBeTruthy();
118
+ return [2 /*return*/];
119
+ }
120
+ });
121
+ }); });
122
+ it("closes on overlay click", function () { return __awaiter(void 0, void 0, void 0, function () {
123
+ var _a, getByRole, container, queryByRole, overlay;
124
+ return __generator(this, function (_b) {
125
+ switch (_b.label) {
126
+ case 0:
127
+ _a = render(Hamburger, {
128
+ props: { menuItems: items },
129
+ }), getByRole = _a.getByRole, container = _a.container, queryByRole = _a.queryByRole;
130
+ return [4 /*yield*/, fireEvent.click(getByRole("button", { name: "Toggle navigation" }))];
131
+ case 1:
132
+ _b.sent();
133
+ overlay = container.querySelector('button[aria-hidden="true"]');
134
+ return [4 /*yield*/, fireEvent.click(overlay)];
135
+ case 2:
136
+ _b.sent();
137
+ expect(queryByRole("dialog")).toBeNull();
138
+ return [2 /*return*/];
139
+ }
140
+ });
141
+ }); });
142
+ it("closes on Escape key", function () { return __awaiter(void 0, void 0, void 0, function () {
143
+ var _a, getByRole, queryByRole;
144
+ return __generator(this, function (_b) {
145
+ switch (_b.label) {
146
+ case 0:
147
+ _a = render(Hamburger, {
148
+ props: { menuItems: items },
149
+ }), getByRole = _a.getByRole, queryByRole = _a.queryByRole;
150
+ return [4 /*yield*/, fireEvent.click(getByRole("button", { name: "Toggle navigation" }))];
151
+ case 1:
152
+ _b.sent();
153
+ return [4 /*yield*/, fireEvent.keyDown(document, { key: "Escape" })];
154
+ case 2:
155
+ _b.sent();
156
+ expect(queryByRole("dialog")).toBeNull();
157
+ return [2 /*return*/];
158
+ }
159
+ });
160
+ }); });
161
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { render } from "@testing-library/svelte";
3
+ import InstallPWA from "../InstallPWA.svelte";
4
+ describe("InstallPWA", function () {
5
+ it("renders button when alwaysShow is true", function () {
6
+ var getByText = render(InstallPWA, {
7
+ props: { alwaysShow: true },
8
+ }).getByText;
9
+ expect(getByText("Install App")).toBeTruthy();
10
+ });
11
+ it("does not render button by default", function () {
12
+ var queryByText = render(InstallPWA).queryByText;
13
+ expect(queryByText("Install App")).toBeNull();
14
+ });
15
+ });
@@ -0,0 +1 @@
1
+ export {};