@bookinglab/booking-ui-react 1.7.1 → 1.9.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/README.md CHANGED
@@ -72,6 +72,7 @@ interface Question {
72
72
  name: string;
73
73
  detail_type: 'heading' | 'text_field' | 'text_area' | 'select' | 'date' | 'number' | 'check';
74
74
  required?: boolean;
75
+ disabled?: boolean;
75
76
  help_text?: string;
76
77
  options?: QuestionOption[]; // For select type
77
78
  settings?: QuestionSettings;
package/dist/index.d.cts CHANGED
@@ -230,6 +230,8 @@ interface ContactDetailsFormProps {
230
230
  classNames?: ContactDetailsFormClassNames;
231
231
  /** Per-field settings for the default contact fields (required, disabled) */
232
232
  fieldSettings?: ContactDetailsFieldSettings;
233
+ /** When true, the submit button is hidden and form values are emitted via `onChange` on every change */
234
+ hideSubmitButton?: boolean;
233
235
  }
234
236
  /**
235
237
  * Imperative handle methods exposed via ref
@@ -326,6 +328,8 @@ interface Question {
326
328
  price_per_booking?: boolean;
327
329
  outcome?: boolean;
328
330
  hide_on_customer_journey?: boolean;
331
+ /** Whether the question field is disabled */
332
+ disabled?: boolean;
329
333
  }
330
334
  type FormValues = Record<number, string | number | boolean>;
331
335
  type FormErrors = Record<number, string>;
package/dist/index.d.ts CHANGED
@@ -230,6 +230,8 @@ interface ContactDetailsFormProps {
230
230
  classNames?: ContactDetailsFormClassNames;
231
231
  /** Per-field settings for the default contact fields (required, disabled) */
232
232
  fieldSettings?: ContactDetailsFieldSettings;
233
+ /** When true, the submit button is hidden and form values are emitted via `onChange` on every change */
234
+ hideSubmitButton?: boolean;
233
235
  }
234
236
  /**
235
237
  * Imperative handle methods exposed via ref
@@ -326,6 +328,8 @@ interface Question {
326
328
  price_per_booking?: boolean;
327
329
  outcome?: boolean;
328
330
  hide_on_customer_journey?: boolean;
331
+ /** Whether the question field is disabled */
332
+ disabled?: boolean;
329
333
  }
330
334
  type FormValues = Record<number, string | number | boolean>;
331
335
  type FormErrors = Record<number, string>;
package/dist/index.js CHANGED
@@ -788,7 +788,8 @@ var ContactDetailsForm = react.forwardRef(
788
788
  submitLabel = "Submit",
789
789
  className = "",
790
790
  classNames = {},
791
- fieldSettings = {}
791
+ fieldSettings = {},
792
+ hideSubmitButton = false
792
793
  }, ref) => {
793
794
  const formId = react.useId();
794
795
  const [firstName, setFirstName] = react.useState(initialValues?.firstName || "");
@@ -829,6 +830,7 @@ var ContactDetailsForm = react.forwardRef(
829
830
  }, [fieldSettings]);
830
831
  const validateQuestionField = react.useCallback((question, value) => {
831
832
  if (question.detail_type === "heading") return null;
833
+ if (question.disabled) return null;
832
834
  if (question.required) {
833
835
  if (value === void 0 || value === "" || value === null) {
834
836
  return `${question.name} is required`;
@@ -1039,6 +1041,7 @@ var ContactDetailsForm = react.forwardRef(
1039
1041
  const value = questionValues[question.id];
1040
1042
  const error = questionTouched[question.id] ? questionErrors[question.id] : void 0;
1041
1043
  const hasError = !!error;
1044
+ const isDisabled = !!question.disabled;
1042
1045
  const ariaProps = {
1043
1046
  "aria-invalid": hasError ? true : void 0,
1044
1047
  "aria-describedby": hasError ? errorId : void 0,
@@ -1059,10 +1062,11 @@ var ContactDetailsForm = react.forwardRef(
1059
1062
  id: fieldId,
1060
1063
  type: "text",
1061
1064
  value: value || "",
1065
+ disabled: isDisabled,
1062
1066
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1063
1067
  onBlur: () => handleQuestionBlur(question.id),
1064
1068
  placeholder: question.settings?.placeholder,
1065
- className: inputClasses(hasError),
1069
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1066
1070
  ...ariaProps
1067
1071
  }
1068
1072
  ),
@@ -1080,11 +1084,12 @@ var ContactDetailsForm = react.forwardRef(
1080
1084
  {
1081
1085
  id: fieldId,
1082
1086
  value: value || "",
1087
+ disabled: isDisabled,
1083
1088
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1084
1089
  onBlur: () => handleQuestionBlur(question.id),
1085
1090
  placeholder: question.settings?.placeholder,
1086
1091
  rows: 4,
1087
- className: inputClasses(hasError),
1092
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1088
1093
  ...ariaProps
1089
1094
  }
1090
1095
  ),
@@ -1102,9 +1107,10 @@ var ContactDetailsForm = react.forwardRef(
1102
1107
  {
1103
1108
  id: fieldId,
1104
1109
  value: value ?? "",
1110
+ disabled: isDisabled,
1105
1111
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1106
1112
  onBlur: () => handleQuestionBlur(question.id),
1107
- className: inputClasses(hasError),
1113
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1108
1114
  ...ariaProps,
1109
1115
  children: [
1110
1116
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select an option" }),
@@ -1127,12 +1133,13 @@ var ContactDetailsForm = react.forwardRef(
1127
1133
  id: fieldId,
1128
1134
  type: "number",
1129
1135
  value: value ?? "",
1136
+ disabled: isDisabled,
1130
1137
  onChange: (e) => handleQuestionChange(question.id, e.target.value ? Number(e.target.value) : ""),
1131
1138
  onBlur: () => handleQuestionBlur(question.id),
1132
1139
  min: question.settings?.min,
1133
1140
  max: question.settings?.max,
1134
1141
  placeholder: question.settings?.placeholder,
1135
- className: inputClasses(hasError),
1142
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1136
1143
  ...ariaProps
1137
1144
  }
1138
1145
  ),
@@ -1151,9 +1158,10 @@ var ContactDetailsForm = react.forwardRef(
1151
1158
  id: fieldId,
1152
1159
  type: "date",
1153
1160
  value: value || "",
1161
+ disabled: isDisabled,
1154
1162
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1155
1163
  onBlur: () => handleQuestionBlur(question.id),
1156
- className: inputClasses(hasError),
1164
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1157
1165
  ...ariaProps
1158
1166
  }
1159
1167
  ),
@@ -1169,9 +1177,10 @@ var ContactDetailsForm = react.forwardRef(
1169
1177
  id: fieldId,
1170
1178
  type: "checkbox",
1171
1179
  checked: !!value,
1180
+ disabled: isDisabled,
1172
1181
  onChange: (e) => handleQuestionChange(question.id, e.target.checked),
1173
1182
  onBlur: () => handleQuestionBlur(question.id),
1174
- className: styles.checkbox,
1183
+ className: cx2(styles.checkbox, isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1175
1184
  ...ariaProps
1176
1185
  }
1177
1186
  ),
@@ -1187,12 +1196,24 @@ var ContactDetailsForm = react.forwardRef(
1187
1196
  return null;
1188
1197
  }
1189
1198
  };
1199
+ react.useEffect(() => {
1200
+ if (hideSubmitButton && _onChange) {
1201
+ const contactValid = !contactFields.some((f) => {
1202
+ if (getFieldDisabled(f.name)) return false;
1203
+ return !!validateContactField(f.name, f.value);
1204
+ });
1205
+ const questionsValid = !questions.some(
1206
+ (q) => !!validateQuestionField(q, questionValues[q.id])
1207
+ );
1208
+ _onChange(buildOutput(), contactValid && questionsValid);
1209
+ }
1210
+ }, [hideSubmitButton, firstName, lastName, emailValue, questionValues]);
1190
1211
  return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className, noValidate: true, children: [
1191
1212
  renderContactField("firstName", "First name", firstName),
1192
1213
  renderContactField("lastName", "Last name", lastName),
1193
1214
  renderContactField("email", "Email", emailValue, "email"),
1194
1215
  questions.map(renderQuestionField),
1195
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", className: styles.button, children: submitLabel })
1216
+ !hideSubmitButton && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", className: styles.button, children: submitLabel })
1196
1217
  ] });
1197
1218
  }
1198
1219
  );