vueless 1.4.7-beta.1 → 1.4.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 (78) hide show
  1. package/icons/internal/apps.svg +1 -1
  2. package/icons/internal/calendar_month-fill.svg +1 -1
  3. package/icons/internal/error.svg +1 -1
  4. package/icons/internal/info.svg +1 -1
  5. package/icons/internal/progress_activity.svg +1 -1
  6. package/icons/internal/search.svg +1 -1
  7. package/icons/internal/visibility-fill.svg +1 -1
  8. package/icons/internal/warning.svg +1 -1
  9. package/icons/storybook/account_circle.svg +1 -1
  10. package/icons/storybook/cloud_sync.svg +1 -0
  11. package/icons/storybook/contact_mail.svg +1 -1
  12. package/icons/storybook/date_range.svg +1 -0
  13. package/icons/storybook/delivery_truck_speed.svg +1 -1
  14. package/icons/storybook/directions_bike.svg +1 -1
  15. package/icons/storybook/error.svg +1 -1
  16. package/icons/storybook/event.svg +1 -0
  17. package/icons/storybook/folder.svg +1 -0
  18. package/icons/storybook/format_quote.svg +1 -0
  19. package/icons/storybook/handyman.svg +1 -1
  20. package/icons/storybook/help.svg +1 -1
  21. package/icons/storybook/inbox.svg +1 -1
  22. package/icons/storybook/inbox_customize.svg +1 -1
  23. package/icons/storybook/info.svg +1 -1
  24. package/icons/storybook/key.svg +1 -1
  25. package/icons/storybook/local_shipping.svg +1 -0
  26. package/icons/storybook/location_city.svg +1 -0
  27. package/icons/storybook/lock.svg +1 -1
  28. package/icons/storybook/lock_open.svg +1 -1
  29. package/icons/storybook/mark_email_unread.svg +1 -0
  30. package/icons/storybook/notifications.svg +1 -0
  31. package/icons/storybook/palette.svg +1 -1
  32. package/icons/storybook/person.svg +1 -1
  33. package/icons/storybook/person_search.svg +1 -1
  34. package/icons/storybook/progress_activity.svg +1 -1
  35. package/icons/storybook/rocket_launch.svg +1 -1
  36. package/icons/storybook/sentiment_satisfied.svg +1 -1
  37. package/icons/storybook/shield.svg +1 -0
  38. package/icons/storybook/timer.svg +1 -1
  39. package/icons/storybook/travel_explore.svg +1 -1
  40. package/icons/storybook/workspace_premium.svg +1 -0
  41. package/package.json +32 -31
  42. package/plugin-vite.js +18 -7
  43. package/ui.container-accordion-item/tests/UAccordionItem.test.ts +4 -2
  44. package/ui.container-drawer/tests/UDrawer.test.ts +11 -29
  45. package/ui.container-modal/tests/UModal.test.ts +10 -22
  46. package/ui.data-table/UTableRow.vue +2 -2
  47. package/ui.form-calendar/tests/UCalendar.test.ts +14 -13
  48. package/ui.form-calendar/tests/UCalendarDayView.test.ts +15 -16
  49. package/ui.form-checkbox/UCheckbox.vue +0 -5
  50. package/ui.form-checkbox/storybook/stories.ts +56 -18
  51. package/ui.form-checkbox/tests/UCheckbox.test.ts +0 -17
  52. package/ui.form-checkbox-group/storybook/stories.ts +61 -0
  53. package/ui.form-date-picker/storybook/stories.ts +85 -37
  54. package/ui.form-date-picker-range/storybook/stories.ts +97 -38
  55. package/ui.form-input/storybook/stories.ts +75 -37
  56. package/ui.form-input-file/storybook/stories.ts +44 -5
  57. package/ui.form-input-number/storybook/stories.ts +66 -28
  58. package/ui.form-input-password/storybook/stories.ts +94 -50
  59. package/ui.form-input-search/storybook/stories.ts +40 -4
  60. package/ui.form-label/ULabel.vue +0 -6
  61. package/ui.form-label/storybook/stories.ts +46 -24
  62. package/ui.form-label/tests/ULabel.test.ts +0 -12
  63. package/ui.form-listbox/UListbox.vue +71 -72
  64. package/ui.form-listbox/tests/UListbox.test.ts +3 -1
  65. package/ui.form-radio/URadio.vue +0 -5
  66. package/ui.form-radio/storybook/stories.ts +65 -25
  67. package/ui.form-radio/tests/URadio.test.ts +0 -17
  68. package/ui.form-radio-group/storybook/stories.ts +67 -0
  69. package/ui.form-select/storybook/stories.ts +99 -44
  70. package/ui.form-switch/storybook/stories.ts +35 -11
  71. package/ui.form-textarea/storybook/stories.ts +61 -20
  72. package/ui.loader/tests/ULoader.test.ts +3 -3
  73. package/ui.navigation-progress/tests/UProgress.test.ts +2 -3
  74. package/ui.text-block/tests/UText.test.ts +3 -3
  75. package/ui.text-files/storybook/stories.ts +30 -13
  76. package/ui.text-header/tests/UHeader.test.ts +3 -3
  77. package/ui.text-notify/tests/UNotify.test.ts +14 -18
  78. package/utils/node/helper.js +8 -9
@@ -15,6 +15,7 @@ import ULink from "../../ui.button-link/ULink.vue";
15
15
 
16
16
  import type { Meta, StoryFn } from "@storybook/vue3-vite";
17
17
  import type { Props } from "../types";
18
+ import { ref } from "vue";
18
19
 
19
20
  interface USwitchArgs extends Props {
20
21
  slotTemplate?: string;
@@ -89,15 +90,38 @@ ToggleIcon.args = { toggleIcon: true };
89
90
  export const Disabled = DefaultTemplate.bind({});
90
91
  Disabled.args = { disabled: true };
91
92
 
92
- export const LabelSlot = DefaultTemplate.bind({});
93
- LabelSlot.args = {
94
- label: "Enable Notifications",
95
- slotTemplate: `
96
- <template #label="{ label }">
97
- <URow gap="2xs" align="center">
98
- <UText>I agree to the <ULink label="Privacy Policy" /></UText>
99
- <UIcon name="contract" size="xs" />
100
- </URow>
101
- </template>
93
+ export const Slots: StoryFn<USwitchArgs> = (args) => ({
94
+ components: { USwitch, UCol, UText, URow, ULink, UIcon },
95
+ setup: () => ({ args, labelSlotValue: ref(false), descriptionSlotValue: ref(false) }),
96
+ template: `
97
+ <UCol gap="3xl">
98
+ <USwitch
99
+ v-bind="args"
100
+ v-model="labelSlotValue"
101
+ label="Enable Notifications"
102
+ >
103
+ <template #label="{ label }">
104
+ <URow gap="2xs" align="center">
105
+ <UText :label="label" />
106
+ <UIcon name="notifications" size="xs" />
107
+ </URow>
108
+ </template>
109
+ </USwitch>
110
+
111
+ <USwitch
112
+ v-model="descriptionSlotValue"
113
+ label="Auto-save drafts"
114
+ >
115
+ <template #description>
116
+ <URow align="center" gap="2xs" class="text-neutral">
117
+ <UIcon name="cloud_sync" size="xs" class="mt-0.5" color="primary" />
118
+ <UText size="sm">
119
+ Drafts sync across devices.
120
+ <ULink label="Learn more" underlined size="sm" />.
121
+ </UText>
122
+ </URow>
123
+ </template>
124
+ </USwitch>
125
+ </UCol>
102
126
  `,
103
- };
127
+ });
@@ -12,9 +12,11 @@ import UCol from "../../ui.container-col/UCol.vue";
12
12
  import URow from "../../ui.container-row/URow.vue";
13
13
  import tooltip from "../../v.tooltip/vTooltip";
14
14
  import UText from "../../ui.text-block/UText.vue";
15
+ import ULink from "../../ui.button-link/ULink.vue";
15
16
 
16
17
  import type { Meta, StoryFn } from "@storybook/vue3-vite";
17
18
  import type { Props } from "../types";
19
+ import { ref } from "vue";
18
20
 
19
21
  interface UTextareaArgs extends Props {
20
22
  slotTemplate?: string;
@@ -138,27 +140,66 @@ NoAutocomplete.parameters = {
138
140
  };
139
141
 
140
142
  export const Slots: StoryFn<UTextareaArgs> = (args) => ({
141
- components: { UTextarea, URow, UIcon, UText },
143
+ components: { UTextarea, URow, UCol, UIcon, UText, ULink },
142
144
  directives: { tooltip },
143
- setup: () => ({ args }),
145
+ setup: () => ({
146
+ args,
147
+ descriptionSlotValue: ref(""),
148
+ errorSlotValue: ref(""),
149
+ }),
144
150
  template: `
145
- <URow>
146
- <UTextarea v-bind="args" v-model="args.modelValue" :max-length="300">
147
- <template #left>
148
- <UText :label="args.modelValue?.length + '/300'" variant="lifted" />
149
- </template>
150
- </UTextarea>
151
-
152
- <UTextarea v-bind="args">
153
- <template #right>
154
- <UIcon
155
- name="send"
156
- color="success"
157
- v-tooltip="'Send message'"
158
- interactive
159
- />
160
- </template>
161
- </UTextarea>
162
- </URow>
151
+ <UCol gap="3xl">
152
+ <URow block>
153
+ <UTextarea v-bind="args" v-model="args.modelValue" :max-length="300">
154
+ <template #left>
155
+ <UText :label="args.modelValue?.length + '/300'" variant="lifted" />
156
+ </template>
157
+ </UTextarea>
158
+
159
+ <UTextarea v-bind="args">
160
+ <template #right>
161
+ <UIcon
162
+ name="send"
163
+ color="success"
164
+ v-tooltip="'Send message'"
165
+ interactive
166
+ />
167
+ </template>
168
+ </UTextarea>
169
+ </URow>
170
+
171
+ <URow block>
172
+ <UTextarea v-model="descriptionSlotValue" label="Feedback">
173
+ <template #description>
174
+ <URow align="center" gap="2xs" class="text-neutral">
175
+ <UIcon name="format_quote" size="xs" class="mt-0.5" color="primary" />
176
+ <UText size="sm">
177
+ Markdown is not supported. See
178
+ <ULink label="content guidelines" underlined size="sm" />.
179
+ </UText>
180
+ </URow>
181
+ </template>
182
+ </UTextarea>
183
+
184
+ <UTextarea
185
+ v-model="errorSlotValue"
186
+ label="Message"
187
+ :error="true"
188
+ >
189
+ <template #error>
190
+ <URow align="center" gap="2xs">
191
+ <UIcon name="error" size="xs" color="error" />
192
+ <UText size="sm" color="error">
193
+ <ul>
194
+ <li>Message is too short (minimum 10 characters)</li>
195
+ <li>Remove disallowed characters from your text</li>
196
+ <li>Try again after fixing the issues above</li>
197
+ </ul>
198
+ </UText>
199
+ </URow>
200
+ </template>
201
+ </UTextarea>
202
+ </URow>
203
+ </UCol>
163
204
  `,
164
205
  });
@@ -57,10 +57,10 @@ describe("ULoader.vue", () => {
57
57
  // Check if the ellipses have the correct color class
58
58
  const ellipses = component.findAll("[vl-key='ellipse']");
59
59
 
60
+ const expectedClass = color === "inherit" ? "bg-current" : `bg-${color}`;
61
+
60
62
  ellipses.forEach((ellipse) => {
61
- color === "inherit"
62
- ? expect(ellipse.classes()).toContain("bg-current")
63
- : expect(ellipse.classes()).toContain(`bg-${color}`);
63
+ expect(ellipse.classes()).toContain(expectedClass);
64
64
  });
65
65
  });
66
66
  });
@@ -133,9 +133,8 @@ describe("UProgress.vue", () => {
133
133
  const progressElement = component.find("progress");
134
134
  const stepperElement = component.findComponent(UStepperProgress);
135
135
 
136
- isProgress
137
- ? expect(progressElement.exists()).toBe(isProgress)
138
- : expect(stepperElement.exists()).toBe(!isProgress);
136
+ expect(progressElement.exists()).toBe(isProgress);
137
+ expect(stepperElement.exists()).toBe(!isProgress);
139
138
  });
140
139
  });
141
140
 
@@ -66,9 +66,9 @@ describe("UText.vue", () => {
66
66
  },
67
67
  });
68
68
 
69
- color === "text"
70
- ? expect(component.attributes("class")).toContain("text-default")
71
- : expect(component.attributes("class")).toContain(color);
69
+ const expectedInClass = color === "text" ? "text-default" : color;
70
+
71
+ expect(component.attributes("class")).toContain(expectedInClass);
72
72
  });
73
73
  });
74
74
 
@@ -8,7 +8,10 @@ import {
8
8
 
9
9
  import UFiles from "../../ui.text-files/UFiles.vue";
10
10
  import URow from "../../ui.container-row/URow.vue";
11
+ import UCol from "../../ui.container-col/UCol.vue";
11
12
  import UIcon from "../../ui.image-icon/UIcon.vue";
13
+ import UText from "../../ui.text-block/UText.vue";
14
+ import ULink from "../../ui.button-link/ULink.vue";
12
15
 
13
16
  import type { Meta, StoryFn } from "@storybook/vue3-vite";
14
17
  import type { Props } from "../types";
@@ -80,25 +83,39 @@ export const Sizes = EnumTemplate.bind({});
80
83
  Sizes.args = { enum: "size" };
81
84
 
82
85
  export const Slots: StoryFn<UFilesArgs> = (args) => ({
83
- components: { UFiles, URow, UIcon },
86
+ components: { UFiles, URow, UCol, UIcon, UText, ULink },
84
87
  setup() {
85
88
  return { args };
86
89
  },
87
90
  template: `
88
- <URow>
89
- <UFiles v-bind="args">
90
- <template #before-file="{ index }">
91
- <UIcon v-if="index === 0" name="info" color="warning" size="xs" />
92
- <UIcon v-if="index === 1" name="check_circle" color="success" size="xs" />
93
- </template>
94
- </UFiles>
91
+ <UCol gap="3xl">
92
+ <URow block>
93
+ <UFiles v-bind="args">
94
+ <template #before-file="{ index }">
95
+ <UIcon v-if="index === 0" name="info" color="warning" size="xs" />
96
+ <UIcon v-if="index === 1" name="check_circle" color="success" size="xs" />
97
+ </template>
98
+ </UFiles>
95
99
 
96
- <UFiles v-bind="args">
97
- <template #after-file="{ index }">
98
- <UIcon v-if="index === 0" name="info" color="warning" size="xs" />
99
- <UIcon v-if="index === 1" name="check_circle" color="success" size="xs" />
100
+ <UFiles v-bind="args">
101
+ <template #after-file="{ index }">
102
+ <UIcon v-if="index === 0" name="info" color="warning" size="xs" />
103
+ <UIcon v-if="index === 1" name="check_circle" color="success" size="xs" />
104
+ </template>
105
+ </UFiles>
106
+ </URow>
107
+
108
+ <UFiles v-bind="args" label="Documents">
109
+ <template #description>
110
+ <URow align="center" gap="2xs" class="text-neutral">
111
+ <UIcon name="folder" size="xs" class="mt-0.5" color="primary" />
112
+ <UText size="sm">
113
+ Files are read-only here.
114
+ <ULink label="Manage in storage" underlined size="sm" />.
115
+ </UText>
116
+ </URow>
100
117
  </template>
101
118
  </UFiles>
102
- </URow>
119
+ </UCol>
103
120
  `,
104
121
  });
@@ -49,9 +49,9 @@ describe("UHeader.vue", () => {
49
49
  },
50
50
  });
51
51
 
52
- color === "text"
53
- ? expect(component.attributes("class")).toContain("text-default")
54
- : expect(component.attributes("class")).toContain(color);
52
+ const expectedInClass = color === "text" ? "text-default" : color;
53
+
54
+ expect(component.attributes("class")).toContain(expectedInClass);
55
55
  });
56
56
  });
57
57
 
@@ -48,35 +48,31 @@ describe("UNotify.vue", () => {
48
48
 
49
49
  describe("Props", () => {
50
50
  it("X Position – applies the correct xPosition style", async () => {
51
- const positions = ["left", "center", "right"];
51
+ async function mountAndGetPositionStyles(xPosition: Props["xPosition"]) {
52
+ const component = mountWithLocale({ xPosition });
52
53
 
53
- for (const position of positions) {
54
- const component = mountWithLocale({
55
- xPosition: position as Props["xPosition"],
56
- });
57
-
58
- // Add a notification to ensure the component is rendered
59
54
  dispatchNotifyEvent("notifyStart", mockNotification);
60
55
  await component.vm.$nextTick();
61
56
 
62
- // Manually trigger setPosition since waitForPageElement won't find the elements in tests
63
57
  // @ts-expect-error - Accessing private method for testing
64
58
  component.vm.setPosition();
65
59
  await component.vm.$nextTick();
66
60
 
67
- // Access the internal notifyPositionStyles ref
68
61
  // @ts-expect-error - Accessing private property for testing
69
- const positionStyles = component.vm.notifyPositionStyles;
62
+ return component.vm.notifyPositionStyles as Record<string, string | undefined>;
63
+ }
70
64
 
71
- // For center position, we expect a calculated left value
72
- if (position === "center") {
73
- expect(positionStyles).toHaveProperty("left");
74
- expect(positionStyles.left).toBeDefined();
75
- } else {
76
- expect(positionStyles).toHaveProperty(position);
77
- expect(positionStyles[position]).toBe("0px");
78
- }
65
+ for (const position of ["left", "right"] as const) {
66
+ const positionStyles = await mountAndGetPositionStyles(position);
67
+
68
+ expect(positionStyles).toHaveProperty(position);
69
+ expect(positionStyles[position]).toBe("0px");
79
70
  }
71
+
72
+ const centerStyles = await mountAndGetPositionStyles("center");
73
+
74
+ expect(centerStyles).toHaveProperty("left");
75
+ expect(centerStyles.left).toBeDefined();
80
76
  });
81
77
 
82
78
  it("Y Position – applies the correct yPosition style", async () => {
@@ -1,4 +1,4 @@
1
- import esbuild from "esbuild";
1
+ import { build as rolldownBuild } from "rolldown";
2
2
  import path from "node:path";
3
3
  import { cwd } from "node:process";
4
4
  import { pathToFileURL } from "node:url";
@@ -191,21 +191,20 @@ export async function cacheMergedConfigs({ vuelessSrcDir, basePath } = {}) {
191
191
  }
192
192
 
193
193
  /**
194
- * Builds a TypeScript file into a JavaScript file using esbuild.
194
+ * Bundles a TypeScript component config to ESM `.mjs` via Rolldown (Oxc transform).
195
195
  *
196
196
  * @param {string} entryPath - The path to the TypeScript file to be built.
197
197
  * @param {string} configOutFile - The output path for the resulting JavaScript file.
198
198
  * @return {Promise<void>} A promise that resolves when the build is complete.
199
199
  */
200
200
  export async function buildTSFile(entryPath, configOutFile) {
201
- await esbuild.build({
202
- entryPoints: [entryPath],
203
- outfile: configOutFile,
204
- bundle: true,
201
+ await rolldownBuild({
202
+ input: entryPath,
205
203
  platform: "node",
206
- format: "esm",
207
- target: "ESNext",
208
- loader: { ".ts": "ts" },
204
+ output: {
205
+ file: configOutFile,
206
+ format: "esm",
207
+ },
209
208
  });
210
209
  }
211
210