@queuezero/vue 0.1.6 → 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 +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +86 -1
- package/dist/index.mjs +86 -1
- package/package.json +2 -2
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
|
});
|
|
@@ -230,6 +246,20 @@ var WaitlistForm = (0, import_vue2.defineComponent)({
|
|
|
230
246
|
}
|
|
231
247
|
});
|
|
232
248
|
break;
|
|
249
|
+
case "textarea":
|
|
250
|
+
inputNode = (0, import_vue2.h)("textarea", {
|
|
251
|
+
id: fieldId,
|
|
252
|
+
class: "qz-form-textarea",
|
|
253
|
+
value: fieldValue,
|
|
254
|
+
placeholder: field.placeholder || "",
|
|
255
|
+
disabled: loading.value,
|
|
256
|
+
required: field.required,
|
|
257
|
+
rows: 3,
|
|
258
|
+
onInput: (e) => {
|
|
259
|
+
formData[field.key] = e.target.value;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
break;
|
|
233
263
|
default:
|
|
234
264
|
inputNode = (0, import_vue2.h)("input", {
|
|
235
265
|
id: fieldId,
|
|
@@ -284,7 +314,7 @@ var WaitlistForm = (0, import_vue2.defineComponent)({
|
|
|
284
314
|
formFields.value.forEach((field) => {
|
|
285
315
|
fieldNodes.push(renderField(field));
|
|
286
316
|
});
|
|
287
|
-
|
|
317
|
+
const formContent = (0, import_vue2.h)(
|
|
288
318
|
"form",
|
|
289
319
|
{
|
|
290
320
|
class: "qz-form",
|
|
@@ -310,6 +340,61 @@ var WaitlistForm = (0, import_vue2.defineComponent)({
|
|
|
310
340
|
)
|
|
311
341
|
]
|
|
312
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
|
+
]);
|
|
313
398
|
};
|
|
314
399
|
}
|
|
315
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
|
});
|
|
@@ -194,6 +210,20 @@ var WaitlistForm = defineComponent({
|
|
|
194
210
|
}
|
|
195
211
|
});
|
|
196
212
|
break;
|
|
213
|
+
case "textarea":
|
|
214
|
+
inputNode = h("textarea", {
|
|
215
|
+
id: fieldId,
|
|
216
|
+
class: "qz-form-textarea",
|
|
217
|
+
value: fieldValue,
|
|
218
|
+
placeholder: field.placeholder || "",
|
|
219
|
+
disabled: loading.value,
|
|
220
|
+
required: field.required,
|
|
221
|
+
rows: 3,
|
|
222
|
+
onInput: (e) => {
|
|
223
|
+
formData[field.key] = e.target.value;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
break;
|
|
197
227
|
default:
|
|
198
228
|
inputNode = h("input", {
|
|
199
229
|
id: fieldId,
|
|
@@ -248,7 +278,7 @@ var WaitlistForm = defineComponent({
|
|
|
248
278
|
formFields.value.forEach((field) => {
|
|
249
279
|
fieldNodes.push(renderField(field));
|
|
250
280
|
});
|
|
251
|
-
|
|
281
|
+
const formContent = h(
|
|
252
282
|
"form",
|
|
253
283
|
{
|
|
254
284
|
class: "qz-form",
|
|
@@ -274,6 +304,61 @@ var WaitlistForm = defineComponent({
|
|
|
274
304
|
)
|
|
275
305
|
]
|
|
276
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
|
+
]);
|
|
277
362
|
};
|
|
278
363
|
}
|
|
279
364
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@queuezero/vue",
|
|
3
|
-
"version": "0.1.
|
|
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.
|
|
37
|
+
"queuezero": "^0.1.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.13.11",
|