svelte-comp 1.2.7 → 1.3.5

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 (139) hide show
  1. package/README.md +12 -11
  2. package/dist/App.svelte +497 -2
  3. package/dist/app.css +2 -3
  4. package/dist/app.d.ts +10 -0
  5. package/dist/lang.d.ts +3 -3
  6. package/dist/lang.js +3 -3
  7. package/dist/lib/Accordion.svelte +14 -14
  8. package/dist/lib/Badge.svelte +44 -0
  9. package/dist/lib/Badge.svelte.d.ts +10 -0
  10. package/dist/lib/Button.svelte +23 -8
  11. package/dist/lib/Calendar.svelte +384 -377
  12. package/dist/lib/Card.svelte +6 -6
  13. package/dist/lib/Carousel.svelte +16 -16
  14. package/dist/lib/Carousel.svelte.d.ts +1 -1
  15. package/dist/lib/CheckBox.svelte +2 -2
  16. package/dist/lib/CodeView.svelte +6 -5
  17. package/dist/lib/ColorPicker.svelte +6 -6
  18. package/dist/lib/ContextMenu.svelte +328 -0
  19. package/dist/lib/ContextMenu.svelte.d.ts +14 -0
  20. package/dist/lib/DatePicker.svelte +161 -161
  21. package/dist/lib/Dialog.svelte +10 -10
  22. package/dist/lib/Field.svelte +1 -1
  23. package/dist/lib/FilePicker.svelte +127 -74
  24. package/dist/lib/FilePicker.svelte.d.ts +6 -3
  25. package/dist/lib/Hamburger.svelte +27 -21
  26. package/dist/lib/InstallPWA.svelte +94 -0
  27. package/dist/lib/InstallPWA.svelte.d.ts +8 -0
  28. package/dist/lib/Menu.svelte +18 -18
  29. package/dist/lib/NoticeBase.svelte +140 -0
  30. package/dist/lib/NoticeBase.svelte.d.ts +43 -0
  31. package/dist/lib/PrimaryColorSelect.svelte +6 -6
  32. package/dist/lib/ProgressCircle.svelte +7 -9
  33. package/dist/lib/ProgressCircle.svelte.d.ts +7 -9
  34. package/dist/lib/SearchInput.svelte +6 -6
  35. package/dist/lib/Select.svelte +2 -2
  36. package/dist/lib/Slider.svelte +1 -1
  37. package/dist/lib/Splitter.svelte +15 -6
  38. package/dist/lib/Switch.svelte +5 -4
  39. package/dist/lib/Tabs.svelte +6 -6
  40. package/dist/lib/ThemeToggle.svelte +1 -0
  41. package/dist/lib/TimePicker.svelte +103 -95
  42. package/dist/lib/TimePickerNew.svelte +634 -0
  43. package/dist/lib/TimePickerNew.svelte.d.ts +49 -0
  44. package/dist/lib/Toast.svelte +17 -120
  45. package/dist/lib/Tooltip.svelte +7 -7
  46. package/dist/lib/Topbar.svelte +112 -0
  47. package/dist/lib/Topbar.svelte.d.ts +44 -0
  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 +5 -0
  133. package/dist/lib/index.js +5 -0
  134. package/dist/lib/lang.d.ts +64 -0
  135. package/dist/lib/lang.js +64 -0
  136. package/dist/lib/types/index.d.ts +1 -0
  137. package/dist/styles.css +2 -0
  138. package/dist/utils/index.js +15 -4
  139. package/package.json +12 -12
@@ -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 {};