vueless 1.3.7-beta.2 → 1.3.7-beta.3

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 (32) hide show
  1. package/components.d.ts +1 -0
  2. package/components.ts +1 -0
  3. package/constants.d.ts +2 -0
  4. package/constants.js +2 -0
  5. package/package.json +2 -2
  6. package/ui.container-col/UCol.vue +0 -1
  7. package/ui.container-collapsible/UCollapsible.vue +190 -0
  8. package/ui.container-collapsible/config.ts +45 -0
  9. package/ui.container-collapsible/constants.ts +1 -0
  10. package/ui.container-collapsible/storybook/docs.mdx +17 -0
  11. package/ui.container-collapsible/storybook/stories.ts +261 -0
  12. package/ui.container-collapsible/tests/UCollapsible.test.ts +571 -0
  13. package/ui.container-collapsible/types.ts +57 -0
  14. package/ui.dropdown/UDropdown.vue +324 -0
  15. package/ui.dropdown/config.ts +27 -0
  16. package/ui.dropdown/constants.ts +1 -0
  17. package/ui.dropdown/storybook/docs.mdx +17 -0
  18. package/ui.dropdown/storybook/stories.ts +286 -0
  19. package/ui.dropdown/tests/UDropdown.test.ts +631 -0
  20. package/ui.dropdown/types.ts +127 -0
  21. package/ui.dropdown-badge/UDropdownBadge.vue +119 -227
  22. package/ui.dropdown-badge/config.ts +18 -15
  23. package/ui.dropdown-badge/tests/UDropdownBadge.test.ts +201 -67
  24. package/ui.dropdown-button/UDropdownButton.vue +121 -226
  25. package/ui.dropdown-button/config.ts +32 -28
  26. package/ui.dropdown-button/tests/UDropdownButton.test.ts +189 -73
  27. package/ui.dropdown-link/UDropdownLink.vue +123 -233
  28. package/ui.dropdown-link/config.ts +15 -18
  29. package/ui.dropdown-link/tests/UDropdownLink.test.ts +190 -71
  30. package/ui.form-listbox/UListbox.vue +2 -3
  31. package/ui.form-listbox/config.ts +2 -2
  32. package/ui.form-select/config.ts +1 -1
@@ -15,10 +15,8 @@ describe("UDropdownBadge.vue", () => {
15
15
  { value: 3, label: "Option 3" },
16
16
  ];
17
17
 
18
- // Props tests
19
18
  describe("Props", () => {
20
- // Label prop
21
- it("renders the correct label text", () => {
19
+ it("Label – renders the correct label text", () => {
22
20
  const label = "Dropdown Badge";
23
21
 
24
22
  const component = mount(UDropdownBadge, {
@@ -31,8 +29,7 @@ describe("UDropdownBadge.vue", () => {
31
29
  expect(component.findComponent(UBadge).props("label")).toBe(label);
32
30
  });
33
31
 
34
- // ModelValue prop
35
- it("selects the correct option based on modelValue", async () => {
32
+ it("ModelValue – selects the correct option based on modelValue", async () => {
36
33
  const modelValue = 2;
37
34
 
38
35
  const component = mount(UDropdownBadge, {
@@ -48,8 +45,7 @@ describe("UDropdownBadge.vue", () => {
48
45
  expect(component.findComponent(UBadge).props("label")).toBe(selectedOption?.label);
49
46
  });
50
47
 
51
- // Multiple prop with modelValue
52
- it("handles multiple selections correctly", async () => {
48
+ it("Multiple handles multiple selections correctly", async () => {
53
49
  const modelValue = [1, 3];
54
50
 
55
51
  const component = mount(UDropdownBadge, {
@@ -67,8 +63,7 @@ describe("UDropdownBadge.vue", () => {
67
63
  expect(component.findComponent(UBadge).props("label")).toBe(expectedLabel);
68
64
  });
69
65
 
70
- // LabelDisplayCount prop
71
- it("limits displayed labels based on labelDisplayCount", async () => {
66
+ it("LabelDisplayCount – limits displayed labels based on labelDisplayCount", async () => {
72
67
  const modelValue = [1, 2, 3];
73
68
  const labelDisplayCount = 1;
74
69
 
@@ -87,8 +82,7 @@ describe("UDropdownBadge.vue", () => {
87
82
  expect(component.findComponent(UBadge).props("label")).toBe(expectedLabel);
88
83
  });
89
84
 
90
- // LabelDisplayCount prop with single value
91
- it("correctly displays label when labelDisplayCount is 1 and only one value is selected", async () => {
85
+ it("LabelDisplayCount displays label correctly with single value", async () => {
92
86
  const modelValue = [1];
93
87
  const labelDisplayCount = 1;
94
88
 
@@ -107,8 +101,7 @@ describe("UDropdownBadge.vue", () => {
107
101
  expect(component.findComponent(UBadge).props("label")).toBe(expectedLabel);
108
102
  });
109
103
 
110
- // Variant prop
111
- it("applies the correct variant class", async () => {
104
+ it("Variant – applies the correct variant class", async () => {
112
105
  const variants = ["solid", "outlined", "subtle", "soft"];
113
106
 
114
107
  variants.forEach((variant) => {
@@ -123,8 +116,7 @@ describe("UDropdownBadge.vue", () => {
123
116
  });
124
117
  });
125
118
 
126
- // Color prop
127
- it("applies the correct color class", async () => {
119
+ it("Color – applies the correct color class", async () => {
128
120
  const colors = [
129
121
  "primary",
130
122
  "secondary",
@@ -149,8 +141,7 @@ describe("UDropdownBadge.vue", () => {
149
141
  });
150
142
  });
151
143
 
152
- // Size prop
153
- it("applies the correct size class", async () => {
144
+ it("Size – applies the correct size class", async () => {
154
145
  const sizes = ["sm", "md", "lg"];
155
146
 
156
147
  sizes.forEach((size) => {
@@ -165,8 +156,7 @@ describe("UDropdownBadge.vue", () => {
165
156
  });
166
157
  });
167
158
 
168
- // Round prop
169
- it("applies round class when round prop is true", () => {
159
+ it("Round – applies round class when round prop is true", () => {
170
160
  const round = true;
171
161
 
172
162
  const component = mount(UDropdownBadge, {
@@ -179,8 +169,7 @@ describe("UDropdownBadge.vue", () => {
179
169
  expect(component.findComponent(UBadge).props("round")).toBe(round);
180
170
  });
181
171
 
182
- // ToggleIcon prop (boolean: true)
183
- it("shows default toggle icon when toggleIcon is true", () => {
172
+ it("ToggleIcon shows default toggle icon when toggleIcon is true", () => {
184
173
  const toggleIcon = true;
185
174
 
186
175
  const component = mount(UDropdownBadge, {
@@ -196,8 +185,7 @@ describe("UDropdownBadge.vue", () => {
196
185
  expect(iconComponent.props("name")).toBe("keyboard_arrow_down");
197
186
  });
198
187
 
199
- // ToggleIcon prop (boolean: false)
200
- it("hides toggle icon when toggleIcon is false", () => {
188
+ it("ToggleIcon hides toggle icon when toggleIcon is false", () => {
201
189
  const toggleIcon = false;
202
190
 
203
191
  const component = mount(UDropdownBadge, {
@@ -212,8 +200,7 @@ describe("UDropdownBadge.vue", () => {
212
200
  expect(iconComponent.exists()).toBe(false);
213
201
  });
214
202
 
215
- // ToggleIcon prop (string)
216
- it("shows custom toggle icon when toggleIcon is a string", () => {
203
+ it("ToggleIcon shows custom toggle icon when toggleIcon is a string", () => {
217
204
  const toggleIcon = "custom_icon";
218
205
 
219
206
  const component = mount(UDropdownBadge, {
@@ -229,8 +216,7 @@ describe("UDropdownBadge.vue", () => {
229
216
  expect(iconComponent.props("name")).toBe(toggleIcon);
230
217
  });
231
218
 
232
- // ID prop
233
- it("applies the correct id attribute", () => {
219
+ it("ID – applies the correct id attribute", () => {
234
220
  const id = "test-dropdown-id";
235
221
 
236
222
  const component = mount(UDropdownBadge, {
@@ -240,11 +226,12 @@ describe("UDropdownBadge.vue", () => {
240
226
  },
241
227
  });
242
228
 
243
- expect(component.findComponent(UBadge).props("id")).toBe(id);
229
+ const dropdown = component.findComponent({ name: "UDropdown" });
230
+
231
+ expect(dropdown.props("id")).toBe(id);
244
232
  });
245
233
 
246
- // DataTest prop
247
- it("applies the correct data-test attribute", () => {
234
+ it("DataTest – applies the correct data-test attribute", () => {
248
235
  const dataTest = "test-dropdown";
249
236
 
250
237
  const component = mount(UDropdownBadge, {
@@ -257,8 +244,7 @@ describe("UDropdownBadge.vue", () => {
257
244
  expect(component.findComponent(UBadge).attributes("data-test")).toBe(dataTest);
258
245
  });
259
246
 
260
- // OptionsLimit prop
261
- it("passes optionsLimit prop to UListbox component", async () => {
247
+ it("OptionsLimit – passes optionsLimit prop to UListbox component", async () => {
262
248
  const optionsLimit = 2;
263
249
 
264
250
  const component = mount(UDropdownBadge, {
@@ -273,8 +259,7 @@ describe("UDropdownBadge.vue", () => {
273
259
  expect(component.findComponent(UListbox).props("optionsLimit")).toBe(optionsLimit);
274
260
  });
275
261
 
276
- // VisibleOptions prop
277
- it("passes visibleOptions prop to UListbox component", async () => {
262
+ it("VisibleOptions – passes visibleOptions prop to UListbox component", async () => {
278
263
  const visibleOptions = 5;
279
264
 
280
265
  const component = mount(UDropdownBadge, {
@@ -289,8 +274,7 @@ describe("UDropdownBadge.vue", () => {
289
274
  expect(component.findComponent(UListbox).props("visibleOptions")).toBe(visibleOptions);
290
275
  });
291
276
 
292
- // GroupLabelKey prop
293
- it("passes groupLabelKey prop to UListbox component", async () => {
277
+ it("GroupLabelKey – passes groupLabelKey prop to UListbox component", async () => {
294
278
  const groupLabelKey = "category";
295
279
  const groupedOptions = [
296
280
  { groupLabel: "Group 1", category: "group1" },
@@ -329,8 +313,7 @@ describe("UDropdownBadge.vue", () => {
329
313
  expect(options[0].text()).toBe("Option 1");
330
314
  });
331
315
 
332
- // CloseOnSelect prop
333
- it("keeps dropdown open when closeOnSelect is false", async () => {
316
+ it("CloseOnSelect – keeps dropdown open when closeOnSelect is false", async () => {
334
317
  const component = mount(UDropdownBadge, {
335
318
  props: {
336
319
  options: defaultOptions,
@@ -351,12 +334,113 @@ describe("UDropdownBadge.vue", () => {
351
334
  // Dropdown should remain open
352
335
  expect(component.findComponent(UListbox).exists()).toBe(true);
353
336
  });
337
+
338
+ it("XPosition – passes xPosition prop to dropdown", () => {
339
+ const component = mount(UDropdownBadge, {
340
+ props: {
341
+ xPosition: "right",
342
+ options: defaultOptions,
343
+ },
344
+ });
345
+
346
+ const dropdown = component.findComponent({ name: "UDropdown" });
347
+
348
+ expect(dropdown.props("xPosition")).toBe("right");
349
+ });
350
+
351
+ it("YPosition – passes yPosition prop to dropdown", () => {
352
+ const component = mount(UDropdownBadge, {
353
+ props: {
354
+ yPosition: "top",
355
+ options: defaultOptions,
356
+ },
357
+ });
358
+
359
+ const dropdown = component.findComponent({ name: "UDropdown" });
360
+
361
+ expect(dropdown.props("yPosition")).toBe("top");
362
+ });
363
+
364
+ it("LabelKey – uses custom label key for options", () => {
365
+ const customOptions = [
366
+ { id: 1, name: "First" },
367
+ { id: 2, name: "Second" },
368
+ ];
369
+
370
+ const component = mount(UDropdownBadge, {
371
+ props: {
372
+ options: customOptions,
373
+ labelKey: "name",
374
+ valueKey: "id",
375
+ },
376
+ });
377
+
378
+ const dropdown = component.findComponent({ name: "UDropdown" });
379
+
380
+ expect(dropdown.props("labelKey")).toBe("name");
381
+ });
382
+
383
+ it("ValueKey – uses custom value key for options", () => {
384
+ const customOptions = [
385
+ { id: 1, name: "First" },
386
+ { id: 2, name: "Second" },
387
+ ];
388
+
389
+ const component = mount(UDropdownBadge, {
390
+ props: {
391
+ options: customOptions,
392
+ labelKey: "name",
393
+ valueKey: "id",
394
+ },
395
+ });
396
+
397
+ const dropdown = component.findComponent({ name: "UDropdown" });
398
+
399
+ expect(dropdown.props("valueKey")).toBe("id");
400
+ });
401
+
402
+ it("GroupValueKey – passes groupValueKey prop to dropdown", () => {
403
+ const component = mount(UDropdownBadge, {
404
+ props: {
405
+ groupValueKey: "items",
406
+ options: defaultOptions,
407
+ },
408
+ });
409
+
410
+ const dropdown = component.findComponent({ name: "UDropdown" });
411
+
412
+ expect(dropdown.props("groupValueKey")).toBe("items");
413
+ });
414
+
415
+ it("Searchable – passes searchable prop to dropdown", () => {
416
+ const component = mount(UDropdownBadge, {
417
+ props: {
418
+ searchable: true,
419
+ options: defaultOptions,
420
+ },
421
+ });
422
+
423
+ const dropdown = component.findComponent({ name: "UDropdown" });
424
+
425
+ expect(dropdown.props("searchable")).toBe(true);
426
+ });
427
+
428
+ it("Disabled – applies disabled state correctly", async () => {
429
+ const component = mount(UDropdownBadge, {
430
+ props: {
431
+ disabled: true,
432
+ options: defaultOptions,
433
+ },
434
+ });
435
+
436
+ const dropdown = component.findComponent({ name: "UDropdown" });
437
+
438
+ expect(dropdown.props("disabled")).toBe(true);
439
+ });
354
440
  });
355
441
 
356
- // Slots tests
357
442
  describe("Slots", () => {
358
- // Default slot
359
- it("renders content from default slot", () => {
443
+ it("Default – renders content from default slot", () => {
360
444
  const slotContent = "Custom Content";
361
445
  const label = "Dropdown Badge";
362
446
 
@@ -373,8 +457,7 @@ describe("UDropdownBadge.vue", () => {
373
457
  expect(component.text()).toContain(slotContent);
374
458
  });
375
459
 
376
- // Left slot
377
- it("renders content from left slot", () => {
460
+ it("Left – renders content from left slot", () => {
378
461
  const label = "Dropdown Badge";
379
462
  const slotText = "Left";
380
463
  const slotClass = "left-content";
@@ -393,8 +476,7 @@ describe("UDropdownBadge.vue", () => {
393
476
  expect(component.find(`.${slotClass}`).text()).toBe(slotText);
394
477
  });
395
478
 
396
- // Toggle slot
397
- it("renders content from toggle slot", () => {
479
+ it("Toggle – renders content from toggle slot", () => {
398
480
  const label = "Dropdown Badge";
399
481
  const slotText = "Toggle";
400
482
  const slotClass = "toggle-content";
@@ -413,8 +495,7 @@ describe("UDropdownBadge.vue", () => {
413
495
  expect(component.find(`.${slotClass}`).text()).toBe(slotText);
414
496
  });
415
497
 
416
- // Before-option slot
417
- it("renders content from before-option slot", async () => {
498
+ it("Before – renders content from before-option slot", async () => {
418
499
  const label = "Dropdown Badge";
419
500
  const slotText = "Before";
420
501
  const slotClass = "before-option-content";
@@ -438,8 +519,7 @@ describe("UDropdownBadge.vue", () => {
438
519
  expect(beforeOptionSlot.text()).toBe(slotText);
439
520
  });
440
521
 
441
- // Option slot
442
- it("renders custom content from option slot", async () => {
522
+ it("Option – renders custom content from option slot", async () => {
443
523
  const label = "Dropdown Badge";
444
524
  const slotClass = "custom-option-content";
445
525
 
@@ -462,8 +542,7 @@ describe("UDropdownBadge.vue", () => {
462
542
  expect(customOptionSlot.text()).toBe("Custom Option 1");
463
543
  });
464
544
 
465
- // After-option slot
466
- it("renders content from after-option slot", async () => {
545
+ it("After – renders content from after-option slot", async () => {
467
546
  const label = "Dropdown Badge";
468
547
  const slotText = "After";
469
548
  const slotClass = "after-option-content";
@@ -487,8 +566,7 @@ describe("UDropdownBadge.vue", () => {
487
566
  expect(afterOptionSlot.text()).toBe(slotText);
488
567
  });
489
568
 
490
- // Empty slot
491
- it("renders custom content from empty slot", async () => {
569
+ it("Empty – renders custom content from empty slot", async () => {
492
570
  const label = "Dropdown Badge";
493
571
  const slotContent = "No options available";
494
572
  const slotClass = "custom-empty";
@@ -513,10 +591,8 @@ describe("UDropdownBadge.vue", () => {
513
591
  });
514
592
  });
515
593
 
516
- // Events tests
517
594
  describe("Events", () => {
518
- // Click event to open dropdown
519
- it("opens dropdown when badge is clicked", async () => {
595
+ it("Click opens dropdown when badge is clicked", async () => {
520
596
  const component = mount(UDropdownBadge, {
521
597
  props: {
522
598
  options: defaultOptions,
@@ -533,8 +609,7 @@ describe("UDropdownBadge.vue", () => {
533
609
  expect(component.findComponent(UListbox).exists()).toBe(true);
534
610
  });
535
611
 
536
- // update:modelValue event
537
- it("emits update:modelValue event when an option is selected", async () => {
612
+ it("update:modelValue – emits update:modelValue event when an option is selected", async () => {
538
613
  const component = mount(UDropdownBadge, {
539
614
  props: {
540
615
  options: defaultOptions,
@@ -555,8 +630,7 @@ describe("UDropdownBadge.vue", () => {
555
630
  expect(component.emitted("update:modelValue")?.[0]).toEqual([2]);
556
631
  });
557
632
 
558
- // clickOption event
559
- it("emits clickOption event when an option is clicked", async () => {
633
+ it("clickOption – emits clickOption event when an option is clicked", async () => {
560
634
  const component = mount(UDropdownBadge, {
561
635
  props: {
562
636
  options: defaultOptions,
@@ -577,8 +651,7 @@ describe("UDropdownBadge.vue", () => {
577
651
  expect(component.emitted("clickOption")?.[0]).toEqual([defaultOptions[1]]);
578
652
  });
579
653
 
580
- // Close dropdown when clicking outside
581
- it("closes dropdown when clicking outside", async () => {
654
+ it("Close – closes dropdown when clicking outside", async () => {
582
655
  const component = mount(UDropdownBadge, {
583
656
  props: {
584
657
  options: defaultOptions,
@@ -589,20 +662,81 @@ describe("UDropdownBadge.vue", () => {
589
662
  await component.findComponent(UBadge).trigger("click");
590
663
  expect(component.findComponent(UListbox).exists()).toBe(true);
591
664
 
592
- // Directly call the hideOptions function
665
+ // Directly call the hide function
593
666
  // This is equivalent to what happens when clicking outside
594
- component.vm.hideOptions();
667
+ component.vm.hide();
595
668
  await component.vm.$nextTick();
596
669
 
597
670
  // Dropdown should be closed
598
671
  expect(component.findComponent(UListbox).exists()).toBe(false);
599
672
  });
673
+
674
+ it("Open – emits open event when dropdown is opened", async () => {
675
+ const component = mount(UDropdownBadge, {
676
+ props: {
677
+ options: defaultOptions,
678
+ },
679
+ });
680
+
681
+ await component.findComponent(UBadge).trigger("click");
682
+
683
+ expect(component.emitted("open")).toBeTruthy();
684
+ });
685
+
686
+ it("Close – emits close event when dropdown is closed", async () => {
687
+ const component = mount(UDropdownBadge, {
688
+ props: {
689
+ options: defaultOptions,
690
+ },
691
+ });
692
+
693
+ await component.findComponent(UBadge).trigger("click");
694
+
695
+ component.vm.hide();
696
+ await component.vm.$nextTick();
697
+
698
+ expect(component.emitted("close")).toBeTruthy();
699
+ });
700
+
701
+ it("SearchChange – emits searchChange event when search value changes", async () => {
702
+ const component = mount(UDropdownBadge, {
703
+ props: {
704
+ searchable: true,
705
+ options: defaultOptions,
706
+ },
707
+ });
708
+
709
+ await component.findComponent(UBadge).trigger("click");
710
+
711
+ const dropdown = component.findComponent({ name: "UDropdown" });
712
+
713
+ dropdown.vm.$emit("searchChange", "test query");
714
+
715
+ expect(component.emitted("searchChange")).toBeTruthy();
716
+ expect(component.emitted("searchChange")?.[0]).toEqual(["test query"]);
717
+ });
718
+
719
+ it("Update:search – emits update:search event when search value updates", async () => {
720
+ const component = mount(UDropdownBadge, {
721
+ props: {
722
+ searchable: true,
723
+ options: defaultOptions,
724
+ },
725
+ });
726
+
727
+ await component.findComponent(UBadge).trigger("click");
728
+
729
+ const dropdown = component.findComponent({ name: "UDropdown" });
730
+
731
+ dropdown.vm.$emit("update:search", "new search");
732
+
733
+ expect(component.emitted("update:search")).toBeTruthy();
734
+ expect(component.emitted("update:search")?.[0]).toEqual(["new search"]);
735
+ });
600
736
  });
601
737
 
602
- // Exposed refs tests
603
738
  describe("Exposed refs", () => {
604
- // wrapperRef
605
- it("exposes wrapperRef", () => {
739
+ it("wrapperRef – exposes wrapperRef", () => {
606
740
  const component = mount(UDropdownBadge, {
607
741
  props: {
608
742
  options: defaultOptions,