@queuezero/vue 0.1.7 → 0.1.8

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.
package/dist/index.d.mts CHANGED
@@ -56,6 +56,12 @@ interface WaitlistFormProps {
56
56
  showLabel?: boolean;
57
57
  /** Label text */
58
58
  labelText?: string;
59
+ /** Display mode: 'inline' renders form directly, 'modal' renders trigger button */
60
+ displayMode?: 'inline' | 'modal';
61
+ /** Text for modal trigger button (only used when displayMode is 'modal') */
62
+ triggerText?: string;
63
+ /** Modal size (only used when displayMode is 'modal') */
64
+ modalSize?: 'sm' | 'md' | 'lg';
59
65
  }
60
66
  /**
61
67
  * Props for WaitlistStatus component
@@ -200,6 +206,18 @@ declare const WaitlistForm: vue.DefineComponent<vue.ExtractPropTypes<{
200
206
  type: StringConstructor;
201
207
  default: string;
202
208
  };
209
+ displayMode: {
210
+ type: PropType<"inline" | "modal">;
211
+ default: string;
212
+ };
213
+ triggerText: {
214
+ type: StringConstructor;
215
+ default: string;
216
+ };
217
+ modalSize: {
218
+ type: PropType<"sm" | "md" | "lg">;
219
+ default: string;
220
+ };
203
221
  }>, () => VNode<vue.RendererNode, vue.RendererElement, {
204
222
  [key: string]: any;
205
223
  }> | VNode<vue.RendererNode, vue.RendererElement, {
@@ -236,6 +254,18 @@ declare const WaitlistForm: vue.DefineComponent<vue.ExtractPropTypes<{
236
254
  type: StringConstructor;
237
255
  default: string;
238
256
  };
257
+ displayMode: {
258
+ type: PropType<"inline" | "modal">;
259
+ default: string;
260
+ };
261
+ triggerText: {
262
+ type: StringConstructor;
263
+ default: string;
264
+ };
265
+ modalSize: {
266
+ type: PropType<"sm" | "md" | "lg">;
267
+ default: string;
268
+ };
239
269
  }>> & Readonly<{
240
270
  onSuccess?: ((response: SubmitResponse) => any) | undefined;
241
271
  onError?: ((error: Error) => any) | undefined;
@@ -247,6 +277,9 @@ declare const WaitlistForm: vue.DefineComponent<vue.ExtractPropTypes<{
247
277
  loadingText: string;
248
278
  showLabel: boolean;
249
279
  labelText: string;
280
+ displayMode: "inline" | "modal";
281
+ triggerText: string;
282
+ modalSize: "sm" | "md" | "lg";
250
283
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
251
284
 
252
285
  /**
package/dist/index.d.ts CHANGED
@@ -56,6 +56,12 @@ interface WaitlistFormProps {
56
56
  showLabel?: boolean;
57
57
  /** Label text */
58
58
  labelText?: string;
59
+ /** Display mode: 'inline' renders form directly, 'modal' renders trigger button */
60
+ displayMode?: 'inline' | 'modal';
61
+ /** Text for modal trigger button (only used when displayMode is 'modal') */
62
+ triggerText?: string;
63
+ /** Modal size (only used when displayMode is 'modal') */
64
+ modalSize?: 'sm' | 'md' | 'lg';
59
65
  }
60
66
  /**
61
67
  * Props for WaitlistStatus component
@@ -200,6 +206,18 @@ declare const WaitlistForm: vue.DefineComponent<vue.ExtractPropTypes<{
200
206
  type: StringConstructor;
201
207
  default: string;
202
208
  };
209
+ displayMode: {
210
+ type: PropType<"inline" | "modal">;
211
+ default: string;
212
+ };
213
+ triggerText: {
214
+ type: StringConstructor;
215
+ default: string;
216
+ };
217
+ modalSize: {
218
+ type: PropType<"sm" | "md" | "lg">;
219
+ default: string;
220
+ };
203
221
  }>, () => VNode<vue.RendererNode, vue.RendererElement, {
204
222
  [key: string]: any;
205
223
  }> | VNode<vue.RendererNode, vue.RendererElement, {
@@ -236,6 +254,18 @@ declare const WaitlistForm: vue.DefineComponent<vue.ExtractPropTypes<{
236
254
  type: StringConstructor;
237
255
  default: string;
238
256
  };
257
+ displayMode: {
258
+ type: PropType<"inline" | "modal">;
259
+ default: string;
260
+ };
261
+ triggerText: {
262
+ type: StringConstructor;
263
+ default: string;
264
+ };
265
+ modalSize: {
266
+ type: PropType<"sm" | "md" | "lg">;
267
+ default: string;
268
+ };
239
269
  }>> & Readonly<{
240
270
  onSuccess?: ((response: SubmitResponse) => any) | undefined;
241
271
  onError?: ((error: Error) => any) | undefined;
@@ -247,6 +277,9 @@ declare const WaitlistForm: vue.DefineComponent<vue.ExtractPropTypes<{
247
277
  loadingText: string;
248
278
  showLabel: boolean;
249
279
  labelText: string;
280
+ displayMode: "inline" | "modal";
281
+ triggerText: string;
282
+ modalSize: "sm" | "md" | "lg";
250
283
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
251
284
 
252
285
  /**
package/dist/index.js CHANGED
@@ -135,6 +135,18 @@ var WaitlistForm = (0, import_vue2.defineComponent)({
135
135
  labelText: {
136
136
  type: String,
137
137
  default: "Email"
138
+ },
139
+ displayMode: {
140
+ type: String,
141
+ default: "inline"
142
+ },
143
+ triggerText: {
144
+ type: String,
145
+ default: "Join Waitlist"
146
+ },
147
+ modalSize: {
148
+ type: String,
149
+ default: "md"
138
150
  }
139
151
  },
140
152
  emits: {
@@ -145,8 +157,12 @@ var WaitlistForm = (0, import_vue2.defineComponent)({
145
157
  const { join, loading, error: contextError, isJoined, publicConfig } = useWaitlistContext();
146
158
  const email = (0, import_vue2.ref)("");
147
159
  const localError = (0, import_vue2.ref)(null);
160
+ const isModalOpen = (0, import_vue2.ref)(false);
148
161
  const formData = (0, import_vue2.reactive)({});
149
162
  const displayError = (0, import_vue2.computed)(() => localError.value || contextError.value);
163
+ const branding = (0, import_vue2.computed)(() => publicConfig.value?.branding || {});
164
+ const themeColor = (0, import_vue2.computed)(() => branding.value.themeColor || "#10B981");
165
+ const sizeClasses = { sm: "qz-modal-sm", md: "qz-modal-md", lg: "qz-modal-lg" };
150
166
  const formFields = (0, import_vue2.computed)(() => {
151
167
  return publicConfig.value?.formFields?.filter((f) => f.enabled) ?? [];
152
168
  });
@@ -298,7 +314,7 @@ var WaitlistForm = (0, import_vue2.defineComponent)({
298
314
  formFields.value.forEach((field) => {
299
315
  fieldNodes.push(renderField(field));
300
316
  });
301
- return (0, import_vue2.h)(
317
+ const formContent = (0, import_vue2.h)(
302
318
  "form",
303
319
  {
304
320
  class: "qz-form",
@@ -324,6 +340,61 @@ var WaitlistForm = (0, import_vue2.defineComponent)({
324
340
  )
325
341
  ]
326
342
  );
343
+ if (props.displayMode === "inline") {
344
+ return formContent;
345
+ }
346
+ return (0, import_vue2.h)("div", { class: "qz-waitlist-modal-wrapper" }, [
347
+ // Trigger button
348
+ (0, import_vue2.h)(
349
+ "button",
350
+ {
351
+ type: "button",
352
+ class: "qz-modal-trigger",
353
+ style: { "--qz-theme-color": themeColor.value },
354
+ onClick: () => {
355
+ isModalOpen.value = true;
356
+ }
357
+ },
358
+ props.triggerText
359
+ ),
360
+ // Modal overlay (only when open)
361
+ isModalOpen.value && (0, import_vue2.h)(
362
+ "div",
363
+ {
364
+ class: "qz-modal-overlay",
365
+ onClick: (e) => {
366
+ if (e.target === e.currentTarget) isModalOpen.value = false;
367
+ }
368
+ },
369
+ [
370
+ (0, import_vue2.h)("div", { class: `qz-modal ${sizeClasses[props.modalSize]}`, style: { "--qz-theme-color": themeColor.value } }, [
371
+ // Header
372
+ (0, import_vue2.h)("div", { class: "qz-modal-header" }, [
373
+ branding.value.logoUrl ? (0, import_vue2.h)("img", { src: branding.value.logoUrl, alt: "Logo", class: "qz-modal-logo" }) : (0, import_vue2.h)("span"),
374
+ (0, import_vue2.h)("button", {
375
+ type: "button",
376
+ class: "qz-modal-close",
377
+ "aria-label": "Close",
378
+ onClick: () => {
379
+ isModalOpen.value = false;
380
+ }
381
+ }, [
382
+ (0, import_vue2.h)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, [
383
+ (0, import_vue2.h)("path", { d: "M18 6L6 18M6 6l12 12" })
384
+ ])
385
+ ])
386
+ ]),
387
+ // Cover image
388
+ branding.value.coverImageUrl && (0, import_vue2.h)("img", { src: branding.value.coverImageUrl, alt: "", class: "qz-modal-cover" }),
389
+ // Body
390
+ (0, import_vue2.h)("div", { class: "qz-modal-body" }, [
391
+ (0, import_vue2.h)("h2", { class: "qz-modal-title" }, publicConfig.value?.name || "Join Waitlist"),
392
+ formContent
393
+ ])
394
+ ])
395
+ ]
396
+ )
397
+ ]);
327
398
  };
328
399
  }
329
400
  });
package/dist/index.mjs CHANGED
@@ -99,6 +99,18 @@ var WaitlistForm = defineComponent({
99
99
  labelText: {
100
100
  type: String,
101
101
  default: "Email"
102
+ },
103
+ displayMode: {
104
+ type: String,
105
+ default: "inline"
106
+ },
107
+ triggerText: {
108
+ type: String,
109
+ default: "Join Waitlist"
110
+ },
111
+ modalSize: {
112
+ type: String,
113
+ default: "md"
102
114
  }
103
115
  },
104
116
  emits: {
@@ -109,8 +121,12 @@ var WaitlistForm = defineComponent({
109
121
  const { join, loading, error: contextError, isJoined, publicConfig } = useWaitlistContext();
110
122
  const email = ref2("");
111
123
  const localError = ref2(null);
124
+ const isModalOpen = ref2(false);
112
125
  const formData = reactive({});
113
126
  const displayError = computed2(() => localError.value || contextError.value);
127
+ const branding = computed2(() => publicConfig.value?.branding || {});
128
+ const themeColor = computed2(() => branding.value.themeColor || "#10B981");
129
+ const sizeClasses = { sm: "qz-modal-sm", md: "qz-modal-md", lg: "qz-modal-lg" };
114
130
  const formFields = computed2(() => {
115
131
  return publicConfig.value?.formFields?.filter((f) => f.enabled) ?? [];
116
132
  });
@@ -262,7 +278,7 @@ var WaitlistForm = defineComponent({
262
278
  formFields.value.forEach((field) => {
263
279
  fieldNodes.push(renderField(field));
264
280
  });
265
- return h(
281
+ const formContent = h(
266
282
  "form",
267
283
  {
268
284
  class: "qz-form",
@@ -288,6 +304,61 @@ var WaitlistForm = defineComponent({
288
304
  )
289
305
  ]
290
306
  );
307
+ if (props.displayMode === "inline") {
308
+ return formContent;
309
+ }
310
+ return h("div", { class: "qz-waitlist-modal-wrapper" }, [
311
+ // Trigger button
312
+ h(
313
+ "button",
314
+ {
315
+ type: "button",
316
+ class: "qz-modal-trigger",
317
+ style: { "--qz-theme-color": themeColor.value },
318
+ onClick: () => {
319
+ isModalOpen.value = true;
320
+ }
321
+ },
322
+ props.triggerText
323
+ ),
324
+ // Modal overlay (only when open)
325
+ isModalOpen.value && h(
326
+ "div",
327
+ {
328
+ class: "qz-modal-overlay",
329
+ onClick: (e) => {
330
+ if (e.target === e.currentTarget) isModalOpen.value = false;
331
+ }
332
+ },
333
+ [
334
+ h("div", { class: `qz-modal ${sizeClasses[props.modalSize]}`, style: { "--qz-theme-color": themeColor.value } }, [
335
+ // Header
336
+ h("div", { class: "qz-modal-header" }, [
337
+ branding.value.logoUrl ? h("img", { src: branding.value.logoUrl, alt: "Logo", class: "qz-modal-logo" }) : h("span"),
338
+ h("button", {
339
+ type: "button",
340
+ class: "qz-modal-close",
341
+ "aria-label": "Close",
342
+ onClick: () => {
343
+ isModalOpen.value = false;
344
+ }
345
+ }, [
346
+ h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, [
347
+ h("path", { d: "M18 6L6 18M6 6l12 12" })
348
+ ])
349
+ ])
350
+ ]),
351
+ // Cover image
352
+ branding.value.coverImageUrl && h("img", { src: branding.value.coverImageUrl, alt: "", class: "qz-modal-cover" }),
353
+ // Body
354
+ h("div", { class: "qz-modal-body" }, [
355
+ h("h2", { class: "qz-modal-title" }, publicConfig.value?.name || "Join Waitlist"),
356
+ formContent
357
+ ])
358
+ ])
359
+ ]
360
+ )
361
+ ]);
291
362
  };
292
363
  }
293
364
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@queuezero/vue",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Vue components and composables for QueueZero viral waitlists",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -34,7 +34,7 @@
34
34
  "vue": ">=3.3.0"
35
35
  },
36
36
  "dependencies": {
37
- "queuezero": "^0.1.5"
37
+ "queuezero": "^0.1.6"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.13.11",