@nucleux/questionnaire 0.0.0-stage → 0.6.0
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/LICENSE +21 -0
- package/README.md +68 -2
- package/dist/index.cjs +863 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +203 -0
- package/dist/index.d.ts +203 -0
- package/dist/index.js +827 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,863 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var lucideReact = require('lucide-react');
|
|
6
|
+
var utils = require('@nucleux/utils');
|
|
7
|
+
var button = require('@nucleux/button');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
|
|
10
|
+
function _interopNamespace(e) {
|
|
11
|
+
if (e && e.__esModule) return e;
|
|
12
|
+
var n = Object.create(null);
|
|
13
|
+
if (e) {
|
|
14
|
+
Object.keys(e).forEach(function (k) {
|
|
15
|
+
if (k !== 'default') {
|
|
16
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
17
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return e[k]; }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
n.default = e;
|
|
25
|
+
return Object.freeze(n);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
29
|
+
|
|
30
|
+
// src/index.tsx
|
|
31
|
+
var useIsoLayoutEffect = typeof window !== "undefined" ? React__namespace.useLayoutEffect : React__namespace.useEffect;
|
|
32
|
+
function mergeRefs(...refs) {
|
|
33
|
+
return (node) => {
|
|
34
|
+
for (const ref of refs) {
|
|
35
|
+
if (typeof ref === "function") ref(node);
|
|
36
|
+
else if (ref) ref.current = node;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function renderPart(tag, props, state, render) {
|
|
41
|
+
if (typeof render === "function") return render(props, state);
|
|
42
|
+
if (React__namespace.isValidElement(render)) {
|
|
43
|
+
const element = render;
|
|
44
|
+
const theirs = element.props;
|
|
45
|
+
const merged = { ...props, ...theirs };
|
|
46
|
+
for (const key of Object.keys(props)) {
|
|
47
|
+
const ours = props[key];
|
|
48
|
+
const other = theirs[key];
|
|
49
|
+
if (/^on[A-Z]/.test(key) && typeof ours === "function" && typeof other === "function") {
|
|
50
|
+
merged[key] = (...args) => {
|
|
51
|
+
other(...args);
|
|
52
|
+
ours(...args);
|
|
53
|
+
};
|
|
54
|
+
} else if (key === "className") {
|
|
55
|
+
merged.className = utils.cn(ours, other);
|
|
56
|
+
} else if (key === "children" && other === void 0) {
|
|
57
|
+
merged.children = ours;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return React__namespace.cloneElement(element, merged);
|
|
61
|
+
}
|
|
62
|
+
return React__namespace.createElement(tag, props);
|
|
63
|
+
}
|
|
64
|
+
var flag = (on) => on ? "" : void 0;
|
|
65
|
+
var CONTROL = "input[data-questionnaire-control]";
|
|
66
|
+
function readAnswer(fieldset) {
|
|
67
|
+
const checked = [];
|
|
68
|
+
let text = "";
|
|
69
|
+
fieldset.querySelectorAll(CONTROL).forEach((input) => {
|
|
70
|
+
if (input.matches(":disabled")) return;
|
|
71
|
+
if (input.type === "radio" || input.type === "checkbox") {
|
|
72
|
+
if (input.checked) checked.push(input.value);
|
|
73
|
+
} else if (!text && input.value.trim() !== "") {
|
|
74
|
+
text = input.value;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return { checked, text };
|
|
78
|
+
}
|
|
79
|
+
var sameAnswer = (a, b) => !!a && a.text === b.text && a.checked.length === b.checked.length && a.checked.every((v, i) => v === b.checked[i]);
|
|
80
|
+
var hasAnswer = (a) => !!a && (a.checked.length > 0 || a.text.trim() !== "");
|
|
81
|
+
function shortcutLabel(scheme, index) {
|
|
82
|
+
if (!scheme || index < 0) return void 0;
|
|
83
|
+
if (scheme === "letters") return index < 26 ? String.fromCharCode(65 + index) : void 0;
|
|
84
|
+
return index < 9 ? String(index + 1) : void 0;
|
|
85
|
+
}
|
|
86
|
+
var RootContext = React__namespace.createContext(null);
|
|
87
|
+
function useRoot(part) {
|
|
88
|
+
const ctx = React__namespace.useContext(RootContext);
|
|
89
|
+
if (!ctx) throw new Error(`<${part}> must be used inside <Questionnaire>.`);
|
|
90
|
+
return ctx;
|
|
91
|
+
}
|
|
92
|
+
var ItemContext = React__namespace.createContext(null);
|
|
93
|
+
function useItem(part) {
|
|
94
|
+
const ctx = React__namespace.useContext(ItemContext);
|
|
95
|
+
if (!ctx) throw new Error(`<${part}> must be used inside <QuestionnaireItem>.`);
|
|
96
|
+
return ctx;
|
|
97
|
+
}
|
|
98
|
+
var Questionnaire = React__namespace.forwardRef(
|
|
99
|
+
({
|
|
100
|
+
item: itemProp,
|
|
101
|
+
defaultItem,
|
|
102
|
+
items,
|
|
103
|
+
onItemChange,
|
|
104
|
+
shortcuts,
|
|
105
|
+
noValidate = true,
|
|
106
|
+
onSubmit,
|
|
107
|
+
onReset,
|
|
108
|
+
onKeyDown,
|
|
109
|
+
className,
|
|
110
|
+
children,
|
|
111
|
+
...props
|
|
112
|
+
}, ref) => {
|
|
113
|
+
const formRef = React__namespace.useRef(null);
|
|
114
|
+
const elements = React__namespace.useRef(/* @__PURE__ */ new Map());
|
|
115
|
+
const initialItem = React__namespace.useRef(defaultItem);
|
|
116
|
+
const pendingFocus = React__namespace.useRef(null);
|
|
117
|
+
const [metas, setMetas] = React__namespace.useState({});
|
|
118
|
+
const [internalItem, setInternalItem] = React__namespace.useState(defaultItem);
|
|
119
|
+
const [answers, setAnswers] = React__namespace.useState({});
|
|
120
|
+
const [skipped, setSkipped] = React__namespace.useState({});
|
|
121
|
+
const [invalid, setInvalid] = React__namespace.useState({});
|
|
122
|
+
const [, setTick] = React__namespace.useState(0);
|
|
123
|
+
const definitions = React__namespace.useMemo(
|
|
124
|
+
() => new Map((items ?? []).map((d) => [d.name, d])),
|
|
125
|
+
[items]
|
|
126
|
+
);
|
|
127
|
+
const metaOf = (name) => {
|
|
128
|
+
const def = definitions.get(name);
|
|
129
|
+
return metas[name] ?? {
|
|
130
|
+
required: def?.required ?? false,
|
|
131
|
+
multiple: def?.multiple ?? false,
|
|
132
|
+
disabled: def?.disabled ?? false
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
const domOrder = Object.keys(metas).sort((a, b) => {
|
|
136
|
+
const ea = elements.current.get(a);
|
|
137
|
+
const eb = elements.current.get(b);
|
|
138
|
+
if (!ea || !eb) return 0;
|
|
139
|
+
return ea.compareDocumentPosition(eb) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
|
|
140
|
+
});
|
|
141
|
+
const order = items ? [...items.map((d) => d.name), ...domOrder.filter((n) => !definitions.has(n))] : domOrder;
|
|
142
|
+
const enabled = order.filter((n) => !metaOf(n).disabled);
|
|
143
|
+
const requested = itemProp !== void 0 ? itemProp : internalItem;
|
|
144
|
+
const active = requested !== void 0 && enabled.includes(requested) ? requested : enabled[0];
|
|
145
|
+
const index = active !== void 0 ? enabled.indexOf(active) : -1;
|
|
146
|
+
const isLast = index === enabled.length - 1;
|
|
147
|
+
const answered = (name) => hasAnswer(answers[name]);
|
|
148
|
+
const statusOf = (name) => answered(name) ? "answered" : skipped[name] ? "skipped" : "unanswered";
|
|
149
|
+
const isValid = (name) => answered(name) || !metaOf(name).required && !!skipped[name];
|
|
150
|
+
const goTo = (name, target) => {
|
|
151
|
+
pendingFocus.current = { name, target };
|
|
152
|
+
if (name !== active) {
|
|
153
|
+
if (itemProp === void 0) setInternalItem(name);
|
|
154
|
+
onItemChange?.(name);
|
|
155
|
+
}
|
|
156
|
+
setTick((t) => t + 1);
|
|
157
|
+
};
|
|
158
|
+
const markInvalid = (names) => setInvalid((prev) => {
|
|
159
|
+
const nextState = { ...prev };
|
|
160
|
+
for (const n of names) nextState[n] = true;
|
|
161
|
+
return nextState;
|
|
162
|
+
});
|
|
163
|
+
const clearFlag = (setter, name) => setter((prev) => {
|
|
164
|
+
if (!prev[name]) return prev;
|
|
165
|
+
const nextState = { ...prev };
|
|
166
|
+
delete nextState[name];
|
|
167
|
+
return nextState;
|
|
168
|
+
});
|
|
169
|
+
const next = () => {
|
|
170
|
+
if (active === void 0) return;
|
|
171
|
+
if (!isValid(active)) {
|
|
172
|
+
markInvalid([active]);
|
|
173
|
+
goTo(active, "control");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
clearFlag(setInvalid, active);
|
|
177
|
+
const target = enabled[index + 1];
|
|
178
|
+
if (target !== void 0) goTo(target, "item");
|
|
179
|
+
};
|
|
180
|
+
const previous = () => {
|
|
181
|
+
const target = enabled[index - 1];
|
|
182
|
+
if (index > 0 && target !== void 0) goTo(target, "item");
|
|
183
|
+
};
|
|
184
|
+
const skip = () => {
|
|
185
|
+
if (active === void 0 || metaOf(active).required) return;
|
|
186
|
+
const el = elements.current.get(active);
|
|
187
|
+
el?.querySelectorAll(CONTROL).forEach((input) => {
|
|
188
|
+
if (input.type === "radio" || input.type === "checkbox") input.checked = false;
|
|
189
|
+
else input.value = "";
|
|
190
|
+
});
|
|
191
|
+
setAnswers((prev) => ({ ...prev, [active]: { checked: [], text: "" } }));
|
|
192
|
+
setSkipped((prev) => ({ ...prev, [active]: true }));
|
|
193
|
+
clearFlag(setInvalid, active);
|
|
194
|
+
const target = enabled[index + 1];
|
|
195
|
+
if (target !== void 0) goTo(target, "item");
|
|
196
|
+
};
|
|
197
|
+
const continueFlow = () => {
|
|
198
|
+
if (active === void 0) return;
|
|
199
|
+
if (!isLast) {
|
|
200
|
+
next();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const form = formRef.current;
|
|
204
|
+
if (!form) return;
|
|
205
|
+
if (typeof form.requestSubmit === "function") form.requestSubmit();
|
|
206
|
+
else form.dispatchEvent(new Event("submit", { bubbles: true, cancelable: true }));
|
|
207
|
+
};
|
|
208
|
+
React__namespace.useEffect(() => {
|
|
209
|
+
const pending = pendingFocus.current;
|
|
210
|
+
if (!pending || pending.name !== active) return;
|
|
211
|
+
const el = elements.current.get(pending.name);
|
|
212
|
+
if (!el || el.hidden) return;
|
|
213
|
+
pendingFocus.current = null;
|
|
214
|
+
if (pending.target === "control") {
|
|
215
|
+
const control = Array.from(el.querySelectorAll(CONTROL)).find(
|
|
216
|
+
(c) => !c.matches(":disabled")
|
|
217
|
+
);
|
|
218
|
+
(control ?? el).focus();
|
|
219
|
+
} else {
|
|
220
|
+
el.focus();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
const handleSubmit = (event) => {
|
|
224
|
+
const failing = enabled.filter((n) => !isValid(n));
|
|
225
|
+
if (failing.length > 0) {
|
|
226
|
+
event.preventDefault();
|
|
227
|
+
markInvalid(failing);
|
|
228
|
+
goTo(failing[0], "control");
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
onSubmit?.(event);
|
|
232
|
+
};
|
|
233
|
+
const handleReset = (event) => {
|
|
234
|
+
onReset?.(event);
|
|
235
|
+
if (event.defaultPrevented) return;
|
|
236
|
+
setSkipped({});
|
|
237
|
+
setInvalid({});
|
|
238
|
+
if (itemProp === void 0) setInternalItem(initialItem.current);
|
|
239
|
+
else if (initialItem.current !== void 0) onItemChange?.(initialItem.current);
|
|
240
|
+
setTimeout(() => setTick((t) => t + 1), 0);
|
|
241
|
+
};
|
|
242
|
+
const handleKeyDown = (event) => {
|
|
243
|
+
onKeyDown?.(event);
|
|
244
|
+
if (event.defaultPrevented) return;
|
|
245
|
+
const target = event.target;
|
|
246
|
+
const fieldset = active !== void 0 ? elements.current.get(active) : void 0;
|
|
247
|
+
const input = target instanceof HTMLInputElement ? target : null;
|
|
248
|
+
const isChoiceInput = !!input && (input.type === "radio" || input.type === "checkbox");
|
|
249
|
+
const isTextEntry = !!input && !isChoiceInput && !["button", "submit", "reset"].includes(input.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement || target.isContentEditable;
|
|
250
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
251
|
+
event.preventDefault();
|
|
252
|
+
continueFlow();
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (event.key === "Enter") {
|
|
256
|
+
if (input && (isChoiceInput || isTextEntry)) {
|
|
257
|
+
event.preventDefault();
|
|
258
|
+
if (active !== void 0 && answered(active)) continueFlow();
|
|
259
|
+
}
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (event.altKey || event.ctrlKey || event.metaKey) return;
|
|
263
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
264
|
+
if (!fieldset || !fieldset.contains(target)) return;
|
|
265
|
+
if (isTextEntry && !(input && input.value === "")) return;
|
|
266
|
+
const controls = Array.from(fieldset.querySelectorAll(CONTROL)).filter(
|
|
267
|
+
(c) => !c.matches(":disabled")
|
|
268
|
+
);
|
|
269
|
+
if (controls.length === 0) return;
|
|
270
|
+
event.preventDefault();
|
|
271
|
+
const i = input ? controls.indexOf(input) : -1;
|
|
272
|
+
const n = controls.length;
|
|
273
|
+
const nextIndex = event.key === "ArrowDown" ? i < 0 ? 0 : (i + 1) % n : i < 0 ? n - 1 : (i - 1 + n) % n;
|
|
274
|
+
const control = controls[nextIndex];
|
|
275
|
+
control.focus();
|
|
276
|
+
if (control.type === "radio" && !control.checked) control.click();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
280
|
+
if (isTextEntry || input && input.type === "radio") return;
|
|
281
|
+
if (event.key === "ArrowLeft") {
|
|
282
|
+
if (index > 0) {
|
|
283
|
+
event.preventDefault();
|
|
284
|
+
previous();
|
|
285
|
+
}
|
|
286
|
+
} else if (active !== void 0 && !isLast && statusOf(active) !== "unanswered") {
|
|
287
|
+
event.preventDefault();
|
|
288
|
+
next();
|
|
289
|
+
}
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (shortcuts && fieldset && !isTextEntry && event.key.length === 1) {
|
|
293
|
+
const key = shortcuts === "letters" ? event.key.toUpperCase() : event.key;
|
|
294
|
+
if (!(shortcuts === "letters" ? /^[A-Z]$/ : /^[1-9]$/).test(key)) return;
|
|
295
|
+
const choice = fieldset.querySelector(`[data-shortcut="${key}"]`);
|
|
296
|
+
const control = choice?.querySelector(CONTROL);
|
|
297
|
+
if (control && !control.matches(":disabled")) {
|
|
298
|
+
event.preventDefault();
|
|
299
|
+
control.focus();
|
|
300
|
+
control.click();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const register = React__namespace.useCallback((name, meta) => {
|
|
305
|
+
setMetas((prev) => {
|
|
306
|
+
const old = prev[name];
|
|
307
|
+
if (old && old.required === meta.required && old.multiple === meta.multiple && old.disabled === meta.disabled)
|
|
308
|
+
return prev;
|
|
309
|
+
return { ...prev, [name]: meta };
|
|
310
|
+
});
|
|
311
|
+
}, []);
|
|
312
|
+
const unregister = React__namespace.useCallback((name) => {
|
|
313
|
+
setMetas((prev) => {
|
|
314
|
+
if (!(name in prev)) return prev;
|
|
315
|
+
const nextState = { ...prev };
|
|
316
|
+
delete nextState[name];
|
|
317
|
+
return nextState;
|
|
318
|
+
});
|
|
319
|
+
}, []);
|
|
320
|
+
const setElement = React__namespace.useCallback((name, el) => {
|
|
321
|
+
if (el) elements.current.set(name, el);
|
|
322
|
+
else elements.current.delete(name);
|
|
323
|
+
}, []);
|
|
324
|
+
const setAnswer = React__namespace.useCallback((name, answer) => {
|
|
325
|
+
setAnswers((prev) => sameAnswer(prev[name], answer) ? prev : { ...prev, [name]: answer });
|
|
326
|
+
if (hasAnswer(answer)) {
|
|
327
|
+
const drop = (prev) => {
|
|
328
|
+
if (!prev[name]) return prev;
|
|
329
|
+
const nextState = { ...prev };
|
|
330
|
+
delete nextState[name];
|
|
331
|
+
return nextState;
|
|
332
|
+
};
|
|
333
|
+
setSkipped(drop);
|
|
334
|
+
setInvalid(drop);
|
|
335
|
+
}
|
|
336
|
+
}, []);
|
|
337
|
+
const context = {
|
|
338
|
+
shortcuts,
|
|
339
|
+
definitions,
|
|
340
|
+
active,
|
|
341
|
+
index,
|
|
342
|
+
total: enabled.length,
|
|
343
|
+
answers,
|
|
344
|
+
invalid,
|
|
345
|
+
register,
|
|
346
|
+
unregister,
|
|
347
|
+
setElement,
|
|
348
|
+
setAnswer,
|
|
349
|
+
statusOf,
|
|
350
|
+
isRequired: (name) => metaOf(name).required,
|
|
351
|
+
next,
|
|
352
|
+
previous,
|
|
353
|
+
skip
|
|
354
|
+
};
|
|
355
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RootContext.Provider, { value: context, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
356
|
+
"form",
|
|
357
|
+
{
|
|
358
|
+
ref: mergeRefs(ref, formRef),
|
|
359
|
+
noValidate,
|
|
360
|
+
"data-slot": "questionnaire",
|
|
361
|
+
"data-current": index + 1,
|
|
362
|
+
"data-total": enabled.length,
|
|
363
|
+
"data-first": flag(index === 0),
|
|
364
|
+
"data-last": flag(enabled.length > 0 && isLast),
|
|
365
|
+
"data-shortcuts": shortcuts,
|
|
366
|
+
className: utils.cn("flex w-full min-w-0 flex-col gap-4", className),
|
|
367
|
+
onSubmit: handleSubmit,
|
|
368
|
+
onReset: handleReset,
|
|
369
|
+
onKeyDown: handleKeyDown,
|
|
370
|
+
...props,
|
|
371
|
+
children
|
|
372
|
+
}
|
|
373
|
+
) });
|
|
374
|
+
}
|
|
375
|
+
);
|
|
376
|
+
Questionnaire.displayName = "Questionnaire";
|
|
377
|
+
var QuestionnaireProgress = React__namespace.forwardRef(
|
|
378
|
+
({ className, render, children, ...props }, ref) => {
|
|
379
|
+
const root = useRoot("QuestionnaireProgress");
|
|
380
|
+
const current = root.index + 1;
|
|
381
|
+
const total = root.total;
|
|
382
|
+
const state = {
|
|
383
|
+
current,
|
|
384
|
+
total,
|
|
385
|
+
first: root.index === 0,
|
|
386
|
+
last: total > 0 && current === total
|
|
387
|
+
};
|
|
388
|
+
const text = `Question ${current} of ${total}`;
|
|
389
|
+
return renderPart(
|
|
390
|
+
"div",
|
|
391
|
+
{
|
|
392
|
+
ref,
|
|
393
|
+
role: "progressbar",
|
|
394
|
+
"aria-label": "Questionnaire progress",
|
|
395
|
+
"aria-valuemin": 0,
|
|
396
|
+
"aria-valuemax": total,
|
|
397
|
+
"aria-valuenow": current,
|
|
398
|
+
"aria-valuetext": text,
|
|
399
|
+
"data-slot": "questionnaire-progress",
|
|
400
|
+
"data-current": current,
|
|
401
|
+
"data-total": total,
|
|
402
|
+
"data-first": flag(state.first),
|
|
403
|
+
"data-last": flag(state.last),
|
|
404
|
+
className: utils.cn(
|
|
405
|
+
"min-h-[1lh] w-fit min-w-[14ch] text-xs font-medium tabular-nums text-muted-foreground",
|
|
406
|
+
className
|
|
407
|
+
),
|
|
408
|
+
...props,
|
|
409
|
+
children: children ?? text
|
|
410
|
+
},
|
|
411
|
+
state,
|
|
412
|
+
render
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
);
|
|
416
|
+
QuestionnaireProgress.displayName = "QuestionnaireProgress";
|
|
417
|
+
var QuestionnaireItem = React__namespace.forwardRef(
|
|
418
|
+
({
|
|
419
|
+
name,
|
|
420
|
+
required = false,
|
|
421
|
+
multiple = false,
|
|
422
|
+
disabled = false,
|
|
423
|
+
invalid: invalidProp = false,
|
|
424
|
+
onStatusChange,
|
|
425
|
+
onChange,
|
|
426
|
+
className,
|
|
427
|
+
children,
|
|
428
|
+
"aria-describedby": describedByProp,
|
|
429
|
+
...props
|
|
430
|
+
}, ref) => {
|
|
431
|
+
const root = useRoot("QuestionnaireItem");
|
|
432
|
+
const elRef = React__namespace.useRef(null);
|
|
433
|
+
const baseId = React__namespace.useId();
|
|
434
|
+
const [hasDescription, setHasDescription] = React__namespace.useState(false);
|
|
435
|
+
const [hasError, setHasError] = React__namespace.useState(false);
|
|
436
|
+
const [domChoices, setDomChoices] = React__namespace.useState([]);
|
|
437
|
+
const { register, unregister, setElement, setAnswer } = root;
|
|
438
|
+
useIsoLayoutEffect(() => {
|
|
439
|
+
register(name, { required, multiple, disabled });
|
|
440
|
+
}, [register, name, required, multiple, disabled]);
|
|
441
|
+
useIsoLayoutEffect(() => () => unregister(name), [unregister, name]);
|
|
442
|
+
useIsoLayoutEffect(() => {
|
|
443
|
+
const el = elRef.current;
|
|
444
|
+
if (!el) return;
|
|
445
|
+
setAnswer(name, readAnswer(el));
|
|
446
|
+
const values = Array.from(el.querySelectorAll("[data-questionnaire-choice-value]")).filter((c) => !c.hasAttribute("data-disabled")).map((c) => c.getAttribute("data-questionnaire-choice-value") ?? "");
|
|
447
|
+
setDomChoices(
|
|
448
|
+
(prev) => prev.length === values.length && prev.every((v, i) => v === values[i]) ? prev : values
|
|
449
|
+
);
|
|
450
|
+
});
|
|
451
|
+
const active = root.active === name && !disabled;
|
|
452
|
+
const status = root.statusOf(name);
|
|
453
|
+
const invalid = invalidProp || !!root.invalid[name];
|
|
454
|
+
const lastStatus = React__namespace.useRef(status);
|
|
455
|
+
React__namespace.useEffect(() => {
|
|
456
|
+
if (lastStatus.current !== status) {
|
|
457
|
+
lastStatus.current = status;
|
|
458
|
+
onStatusChange?.(status);
|
|
459
|
+
}
|
|
460
|
+
}, [status, onStatusChange]);
|
|
461
|
+
const definedChoices = root.definitions.get(name)?.choices;
|
|
462
|
+
const choiceOrder = definedChoices ? definedChoices.filter((c) => !c.disabled).map((c) => c.value) : domChoices;
|
|
463
|
+
const answer = root.answers[name];
|
|
464
|
+
const descriptionId = `${baseId}-description`;
|
|
465
|
+
const errorId = `${baseId}-error`;
|
|
466
|
+
const describedBy = [describedByProp, hasDescription && descriptionId, invalid && hasError && errorId].filter(Boolean).join(" ") || void 0;
|
|
467
|
+
const handleChange = (event) => {
|
|
468
|
+
onChange?.(event);
|
|
469
|
+
const el = elRef.current;
|
|
470
|
+
const target = event.target;
|
|
471
|
+
if (!el || !target.matches?.(CONTROL)) return;
|
|
472
|
+
if (!multiple) {
|
|
473
|
+
if (target.type === "radio" && target.checked) {
|
|
474
|
+
el.querySelectorAll(`${CONTROL}[data-questionnaire-control="input"]`).forEach((i) => {
|
|
475
|
+
i.value = "";
|
|
476
|
+
});
|
|
477
|
+
} else if (target.getAttribute("data-questionnaire-control") === "input" && target.value.trim() !== "") {
|
|
478
|
+
el.querySelectorAll(`${CONTROL}[type="radio"]`).forEach((i) => {
|
|
479
|
+
i.checked = false;
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
setAnswer(name, readAnswer(el));
|
|
484
|
+
};
|
|
485
|
+
const itemContext = {
|
|
486
|
+
name,
|
|
487
|
+
multiple,
|
|
488
|
+
required,
|
|
489
|
+
disabled,
|
|
490
|
+
invalid,
|
|
491
|
+
measured: answer !== void 0,
|
|
492
|
+
checked: answer?.checked ?? [],
|
|
493
|
+
text: answer?.text ?? "",
|
|
494
|
+
descriptionId,
|
|
495
|
+
errorId,
|
|
496
|
+
setHasDescription,
|
|
497
|
+
setHasError,
|
|
498
|
+
shortcutFor: (value) => shortcutLabel(root.shortcuts, choiceOrder.indexOf(value))
|
|
499
|
+
};
|
|
500
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ItemContext.Provider, { value: itemContext, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
501
|
+
"fieldset",
|
|
502
|
+
{
|
|
503
|
+
ref: mergeRefs(ref, elRef, (el) => setElement(name, el)),
|
|
504
|
+
tabIndex: -1,
|
|
505
|
+
disabled,
|
|
506
|
+
hidden: !active,
|
|
507
|
+
"aria-describedby": describedBy,
|
|
508
|
+
"aria-invalid": invalid || void 0,
|
|
509
|
+
"data-slot": "questionnaire-item",
|
|
510
|
+
"data-active": flag(active),
|
|
511
|
+
"data-status": status,
|
|
512
|
+
"data-required": flag(required),
|
|
513
|
+
"data-multiple": flag(multiple),
|
|
514
|
+
"data-disabled": flag(disabled),
|
|
515
|
+
"data-invalid": flag(invalid),
|
|
516
|
+
className: utils.cn(
|
|
517
|
+
"m-0 flex min-w-0 flex-col gap-4 border-0 p-0 outline-none [&[hidden]]:hidden",
|
|
518
|
+
className
|
|
519
|
+
),
|
|
520
|
+
onChange: handleChange,
|
|
521
|
+
...props,
|
|
522
|
+
children
|
|
523
|
+
}
|
|
524
|
+
) });
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
QuestionnaireItem.displayName = "QuestionnaireItem";
|
|
528
|
+
var QuestionnaireTitle = React__namespace.forwardRef(
|
|
529
|
+
({ className, render, ...props }, ref) => renderPart(
|
|
530
|
+
"legend",
|
|
531
|
+
{
|
|
532
|
+
ref,
|
|
533
|
+
"data-slot": "questionnaire-title",
|
|
534
|
+
className: utils.cn(
|
|
535
|
+
"text-pretty text-base font-medium leading-snug [&:not(:has(~[data-slot=questionnaire-description]))]:mb-4",
|
|
536
|
+
className
|
|
537
|
+
),
|
|
538
|
+
...props
|
|
539
|
+
},
|
|
540
|
+
{},
|
|
541
|
+
render
|
|
542
|
+
)
|
|
543
|
+
);
|
|
544
|
+
QuestionnaireTitle.displayName = "QuestionnaireTitle";
|
|
545
|
+
var QuestionnaireDescription = React__namespace.forwardRef(
|
|
546
|
+
({ className, render, id, ...props }, ref) => {
|
|
547
|
+
const item = useItem("QuestionnaireDescription");
|
|
548
|
+
const { setHasDescription } = item;
|
|
549
|
+
React__namespace.useEffect(() => {
|
|
550
|
+
setHasDescription(true);
|
|
551
|
+
return () => setHasDescription(false);
|
|
552
|
+
}, [setHasDescription]);
|
|
553
|
+
return renderPart(
|
|
554
|
+
"p",
|
|
555
|
+
{
|
|
556
|
+
ref,
|
|
557
|
+
id: id ?? item.descriptionId,
|
|
558
|
+
"data-slot": "questionnaire-description",
|
|
559
|
+
className: utils.cn("text-pretty text-sm text-muted-foreground", className),
|
|
560
|
+
...props
|
|
561
|
+
},
|
|
562
|
+
{},
|
|
563
|
+
render
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
);
|
|
567
|
+
QuestionnaireDescription.displayName = "QuestionnaireDescription";
|
|
568
|
+
var QuestionnaireChoices = React__namespace.forwardRef(
|
|
569
|
+
({ className, render, ...props }, ref) => {
|
|
570
|
+
const root = useRoot("QuestionnaireChoices");
|
|
571
|
+
return renderPart(
|
|
572
|
+
"div",
|
|
573
|
+
{
|
|
574
|
+
ref,
|
|
575
|
+
"data-slot": "questionnaire-choices",
|
|
576
|
+
"data-shortcuts": root.shortcuts,
|
|
577
|
+
className: utils.cn("group/questionnaire-choices grid min-w-0 gap-2", className),
|
|
578
|
+
...props
|
|
579
|
+
},
|
|
580
|
+
{ shortcuts: root.shortcuts },
|
|
581
|
+
render
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
);
|
|
585
|
+
QuestionnaireChoices.displayName = "QuestionnaireChoices";
|
|
586
|
+
var QuestionnaireChoice = React__namespace.forwardRef(
|
|
587
|
+
({ value, checked, defaultChecked, disabled = false, onChange, className, children, ...props }, ref) => {
|
|
588
|
+
const item = useItem("QuestionnaireChoice");
|
|
589
|
+
const type = item.multiple ? "checkbox" : "radio";
|
|
590
|
+
const isChecked = checked ?? (item.measured ? item.checked.includes(value) : !!defaultChecked);
|
|
591
|
+
const isDisabled = disabled || item.disabled;
|
|
592
|
+
const shortcut = disabled ? void 0 : item.shortcutFor(value);
|
|
593
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
594
|
+
"label",
|
|
595
|
+
{
|
|
596
|
+
ref,
|
|
597
|
+
"data-slot": "questionnaire-choice",
|
|
598
|
+
"data-questionnaire-choice-value": value,
|
|
599
|
+
"data-type": type,
|
|
600
|
+
"data-checked": flag(isChecked),
|
|
601
|
+
"data-unchecked": flag(!isChecked),
|
|
602
|
+
"data-disabled": flag(isDisabled),
|
|
603
|
+
"data-invalid": flag(item.invalid),
|
|
604
|
+
"data-shortcut": shortcut,
|
|
605
|
+
className: utils.cn(
|
|
606
|
+
"group/questionnaire-choice relative flex min-h-11 cursor-pointer select-none items-start gap-2.5 rounded-lg border border-input bg-transparent px-3 py-2.5 text-start text-sm outline-none transition-colors hover:bg-muted/50 has-[>input:focus-visible]:border-ring has-[>input:focus-visible]:ring-2 has-[>input:focus-visible]:ring-ring/50 data-[invalid]:border-destructive data-[checked]:border-primary/40 data-[checked]:bg-muted",
|
|
607
|
+
"data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
|
|
608
|
+
className
|
|
609
|
+
),
|
|
610
|
+
...props,
|
|
611
|
+
children: [
|
|
612
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
613
|
+
"input",
|
|
614
|
+
{
|
|
615
|
+
type,
|
|
616
|
+
name: item.name,
|
|
617
|
+
value,
|
|
618
|
+
checked,
|
|
619
|
+
defaultChecked: checked === void 0 ? defaultChecked : void 0,
|
|
620
|
+
disabled,
|
|
621
|
+
onChange,
|
|
622
|
+
"aria-invalid": item.invalid || void 0,
|
|
623
|
+
"aria-keyshortcuts": shortcut,
|
|
624
|
+
"data-questionnaire-control": "choice",
|
|
625
|
+
"data-slot": "questionnaire-choice-input",
|
|
626
|
+
className: "absolute inset-0 z-10 size-full cursor-pointer opacity-0"
|
|
627
|
+
}
|
|
628
|
+
),
|
|
629
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
630
|
+
"span",
|
|
631
|
+
{
|
|
632
|
+
"aria-hidden": "true",
|
|
633
|
+
"data-slot": "questionnaire-choice-indicator",
|
|
634
|
+
className: utils.cn(
|
|
635
|
+
"pointer-events-none relative flex size-4 shrink-0 translate-y-[0.1125rem] items-center justify-center rounded-[4px] border border-input group-has-[[data-slot=questionnaire-choice-description]]/questionnaire-choice:translate-y-0.5 group-data-[checked]/questionnaire-choice:border-primary group-data-[checked]/questionnaire-choice:bg-primary group-data-[checked]/questionnaire-choice:text-primary-foreground",
|
|
636
|
+
type === "radio" && "rounded-full"
|
|
637
|
+
),
|
|
638
|
+
children: type === "radio" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
639
|
+
"span",
|
|
640
|
+
{
|
|
641
|
+
"data-slot": "questionnaire-choice-indicator-dot",
|
|
642
|
+
className: "hidden size-2 rounded-full bg-primary-foreground group-data-[checked]/questionnaire-choice:block"
|
|
643
|
+
}
|
|
644
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
645
|
+
lucideReact.Check,
|
|
646
|
+
{
|
|
647
|
+
"data-slot": "questionnaire-choice-indicator-check",
|
|
648
|
+
className: "hidden size-3.5 group-data-[checked]/questionnaire-choice:block"
|
|
649
|
+
}
|
|
650
|
+
)
|
|
651
|
+
}
|
|
652
|
+
),
|
|
653
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-slot": "questionnaire-choice-label", className: "flex min-w-0 flex-1 flex-col gap-0.5 leading-snug", children }),
|
|
654
|
+
shortcut ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
655
|
+
"span",
|
|
656
|
+
{
|
|
657
|
+
"aria-hidden": "true",
|
|
658
|
+
"data-slot": "questionnaire-choice-shortcut",
|
|
659
|
+
className: "pointer-events-none ms-auto inline-flex size-5 shrink-0 translate-y-[0.1125rem] items-center justify-center rounded-md border border-input bg-background font-mono text-[0.625rem] font-medium leading-none text-muted-foreground group-has-[[data-slot=questionnaire-choice-description]]/questionnaire-choice:translate-y-0.5",
|
|
660
|
+
children: shortcut
|
|
661
|
+
}
|
|
662
|
+
) : null
|
|
663
|
+
]
|
|
664
|
+
}
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
);
|
|
668
|
+
QuestionnaireChoice.displayName = "QuestionnaireChoice";
|
|
669
|
+
var QuestionnaireChoiceDescription = React__namespace.forwardRef(
|
|
670
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
671
|
+
"span",
|
|
672
|
+
{
|
|
673
|
+
ref,
|
|
674
|
+
"data-slot": "questionnaire-choice-description",
|
|
675
|
+
className: utils.cn("text-muted-foreground", className),
|
|
676
|
+
...props
|
|
677
|
+
}
|
|
678
|
+
)
|
|
679
|
+
);
|
|
680
|
+
QuestionnaireChoiceDescription.displayName = "QuestionnaireChoiceDescription";
|
|
681
|
+
var QuestionnaireInput = React__namespace.forwardRef(
|
|
682
|
+
({ className, type = "text", disabled = false, render, ...props }, ref) => {
|
|
683
|
+
const item = useItem("QuestionnaireInput");
|
|
684
|
+
const initial = String(props.value ?? props.defaultValue ?? "");
|
|
685
|
+
const filled = item.measured ? item.text.trim() !== "" : initial.trim() !== "";
|
|
686
|
+
const isDisabled = disabled || item.disabled;
|
|
687
|
+
const state = { disabled: isDisabled, filled, invalid: item.invalid };
|
|
688
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "questionnaire-input-wrapper", className: "group/questionnaire-input relative w-full min-w-0", children: renderPart(
|
|
689
|
+
"input",
|
|
690
|
+
{
|
|
691
|
+
ref,
|
|
692
|
+
type,
|
|
693
|
+
name: filled ? item.name : void 0,
|
|
694
|
+
disabled,
|
|
695
|
+
"aria-invalid": item.invalid || void 0,
|
|
696
|
+
"data-questionnaire-control": "input",
|
|
697
|
+
"data-slot": "questionnaire-input",
|
|
698
|
+
"data-filled": flag(filled),
|
|
699
|
+
"data-empty": flag(!filled),
|
|
700
|
+
"data-disabled": flag(isDisabled),
|
|
701
|
+
"data-invalid": flag(item.invalid),
|
|
702
|
+
className: utils.cn(
|
|
703
|
+
"h-8 min-h-11 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base outline-none transition-[color,box-shadow,background-color] focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-destructive/20 sm:min-h-0 md:text-sm",
|
|
704
|
+
"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground",
|
|
705
|
+
className
|
|
706
|
+
),
|
|
707
|
+
...props
|
|
708
|
+
},
|
|
709
|
+
state,
|
|
710
|
+
render
|
|
711
|
+
) });
|
|
712
|
+
}
|
|
713
|
+
);
|
|
714
|
+
QuestionnaireInput.displayName = "QuestionnaireInput";
|
|
715
|
+
var QuestionnaireError = React__namespace.forwardRef(
|
|
716
|
+
({ className, render, children, id, ...props }, ref) => {
|
|
717
|
+
const item = useItem("QuestionnaireError");
|
|
718
|
+
const { setHasError } = item;
|
|
719
|
+
React__namespace.useEffect(() => {
|
|
720
|
+
setHasError(true);
|
|
721
|
+
return () => setHasError(false);
|
|
722
|
+
}, [setHasError]);
|
|
723
|
+
const message = children ?? (item.required ? "Choose an answer to continue." : "Choose an answer or skip this question.");
|
|
724
|
+
return renderPart(
|
|
725
|
+
"p",
|
|
726
|
+
{
|
|
727
|
+
ref,
|
|
728
|
+
id: id ?? item.errorId,
|
|
729
|
+
role: item.invalid ? "alert" : void 0,
|
|
730
|
+
hidden: !item.invalid || void 0,
|
|
731
|
+
"data-slot": "questionnaire-error",
|
|
732
|
+
"data-invalid": flag(item.invalid),
|
|
733
|
+
className: utils.cn("mt-2 text-sm text-destructive [&[hidden]]:hidden", className),
|
|
734
|
+
...props,
|
|
735
|
+
children: item.invalid ? message : null
|
|
736
|
+
},
|
|
737
|
+
{ invalid: item.invalid },
|
|
738
|
+
render
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
);
|
|
742
|
+
QuestionnaireError.displayName = "QuestionnaireError";
|
|
743
|
+
var QuestionnaireActions = React__namespace.forwardRef(
|
|
744
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
745
|
+
"div",
|
|
746
|
+
{
|
|
747
|
+
ref,
|
|
748
|
+
"data-slot": "questionnaire-actions",
|
|
749
|
+
className: utils.cn(
|
|
750
|
+
"grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-2 sm:min-h-8",
|
|
751
|
+
className
|
|
752
|
+
),
|
|
753
|
+
...props
|
|
754
|
+
}
|
|
755
|
+
)
|
|
756
|
+
);
|
|
757
|
+
QuestionnaireActions.displayName = "QuestionnaireActions";
|
|
758
|
+
var variantMap = {
|
|
759
|
+
default: "primary",
|
|
760
|
+
outline: "secondary",
|
|
761
|
+
primary: "primary",
|
|
762
|
+
cta: "cta",
|
|
763
|
+
secondary: "secondary",
|
|
764
|
+
ghost: "ghost",
|
|
765
|
+
destructive: "destructive",
|
|
766
|
+
link: "link"
|
|
767
|
+
};
|
|
768
|
+
var sizeMap = {
|
|
769
|
+
default: "md",
|
|
770
|
+
xs: "sm",
|
|
771
|
+
sm: "sm",
|
|
772
|
+
md: "md",
|
|
773
|
+
lg: "lg",
|
|
774
|
+
icon: "icon",
|
|
775
|
+
"icon-sm": "icon-sm",
|
|
776
|
+
"icon-lg": "icon-lg"
|
|
777
|
+
};
|
|
778
|
+
var actionLayout = {
|
|
779
|
+
previous: "col-start-1 row-start-1 justify-self-start",
|
|
780
|
+
skip: "col-start-2 row-start-1 justify-self-end",
|
|
781
|
+
next: "col-start-3 row-start-1 justify-self-end",
|
|
782
|
+
submit: "col-start-3 row-start-1 justify-self-end"
|
|
783
|
+
};
|
|
784
|
+
var actionLabel = {
|
|
785
|
+
previous: "Previous",
|
|
786
|
+
skip: "Skip",
|
|
787
|
+
next: "Next",
|
|
788
|
+
submit: "Submit"
|
|
789
|
+
};
|
|
790
|
+
function useAction(kind, { variant, size, render, disabled, onClick, className, children, ...props }, ref) {
|
|
791
|
+
const root = useRoot(`Questionnaire${actionLabel[kind]}`);
|
|
792
|
+
const last = root.total > 0 && root.index === root.total - 1;
|
|
793
|
+
const visible = root.active !== void 0 && (kind === "previous" ? root.index > 0 : kind === "skip" ? !root.isRequired(root.active) : kind === "next" ? !last : last);
|
|
794
|
+
const status = root.active !== void 0 ? root.statusOf(root.active) : "unanswered";
|
|
795
|
+
const shortcut = (kind === "next" || kind === "submit") && visible && !disabled ? "Enter" : void 0;
|
|
796
|
+
const state = { visible, disabled: !!disabled, shortcut, status };
|
|
797
|
+
const nucleuxVariant = variantMap[variant ?? (kind === "next" || kind === "submit" ? "default" : "outline")];
|
|
798
|
+
const nucleuxSize = sizeMap[size ?? "default"];
|
|
799
|
+
return renderPart(
|
|
800
|
+
"button",
|
|
801
|
+
{
|
|
802
|
+
ref,
|
|
803
|
+
type: kind === "submit" ? "submit" : "button",
|
|
804
|
+
disabled,
|
|
805
|
+
hidden: !visible || void 0,
|
|
806
|
+
"aria-keyshortcuts": shortcut ? "Control+Enter Meta+Enter" : void 0,
|
|
807
|
+
"data-slot": `questionnaire-${kind}`,
|
|
808
|
+
"data-size": size ?? "default",
|
|
809
|
+
"data-variant": variant ?? (kind === "next" || kind === "submit" ? "default" : "outline"),
|
|
810
|
+
"data-visible": flag(visible),
|
|
811
|
+
"data-hidden": flag(!visible),
|
|
812
|
+
"data-disabled": flag(disabled),
|
|
813
|
+
"data-shortcut": shortcut,
|
|
814
|
+
"data-status": status,
|
|
815
|
+
className: utils.cn(actionLayout[kind], "min-h-11 sm:min-h-0 data-[hidden]:hidden", className),
|
|
816
|
+
onClick: (event) => {
|
|
817
|
+
onClick?.(event);
|
|
818
|
+
if (event.defaultPrevented) return;
|
|
819
|
+
if (kind === "previous") root.previous();
|
|
820
|
+
else if (kind === "skip") root.skip();
|
|
821
|
+
else if (kind === "next") root.next();
|
|
822
|
+
},
|
|
823
|
+
...props,
|
|
824
|
+
children: children ?? actionLabel[kind]
|
|
825
|
+
},
|
|
826
|
+
state,
|
|
827
|
+
render ?? /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: nucleuxVariant, size: nucleuxSize })
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
var QuestionnairePrevious = React__namespace.forwardRef(
|
|
831
|
+
(props, ref) => useAction("previous", props, ref)
|
|
832
|
+
);
|
|
833
|
+
QuestionnairePrevious.displayName = "QuestionnairePrevious";
|
|
834
|
+
var QuestionnaireSkip = React__namespace.forwardRef(
|
|
835
|
+
(props, ref) => useAction("skip", props, ref)
|
|
836
|
+
);
|
|
837
|
+
QuestionnaireSkip.displayName = "QuestionnaireSkip";
|
|
838
|
+
var QuestionnaireNext = React__namespace.forwardRef(
|
|
839
|
+
(props, ref) => useAction("next", props, ref)
|
|
840
|
+
);
|
|
841
|
+
QuestionnaireNext.displayName = "QuestionnaireNext";
|
|
842
|
+
var QuestionnaireSubmit = React__namespace.forwardRef(
|
|
843
|
+
(props, ref) => useAction("submit", props, ref)
|
|
844
|
+
);
|
|
845
|
+
QuestionnaireSubmit.displayName = "QuestionnaireSubmit";
|
|
846
|
+
|
|
847
|
+
exports.Questionnaire = Questionnaire;
|
|
848
|
+
exports.QuestionnaireActions = QuestionnaireActions;
|
|
849
|
+
exports.QuestionnaireChoice = QuestionnaireChoice;
|
|
850
|
+
exports.QuestionnaireChoiceDescription = QuestionnaireChoiceDescription;
|
|
851
|
+
exports.QuestionnaireChoices = QuestionnaireChoices;
|
|
852
|
+
exports.QuestionnaireDescription = QuestionnaireDescription;
|
|
853
|
+
exports.QuestionnaireError = QuestionnaireError;
|
|
854
|
+
exports.QuestionnaireInput = QuestionnaireInput;
|
|
855
|
+
exports.QuestionnaireItem = QuestionnaireItem;
|
|
856
|
+
exports.QuestionnaireNext = QuestionnaireNext;
|
|
857
|
+
exports.QuestionnairePrevious = QuestionnairePrevious;
|
|
858
|
+
exports.QuestionnaireProgress = QuestionnaireProgress;
|
|
859
|
+
exports.QuestionnaireSkip = QuestionnaireSkip;
|
|
860
|
+
exports.QuestionnaireSubmit = QuestionnaireSubmit;
|
|
861
|
+
exports.QuestionnaireTitle = QuestionnaireTitle;
|
|
862
|
+
//# sourceMappingURL=index.cjs.map
|
|
863
|
+
//# sourceMappingURL=index.cjs.map
|