@bookinglab/booking-ui-react 1.8.0 → 1.10.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
@@ -232,6 +232,8 @@ interface ContactDetailsFormProps {
232
232
  fieldSettings?: ContactDetailsFieldSettings;
233
233
  /** When true, the submit button is hidden and form values are emitted via `onChange` on every change */
234
234
  hideSubmitButton?: boolean;
235
+ /** When true, all validation errors are shown immediately (useful for external submit triggers) */
236
+ isSubmitted?: boolean;
235
237
  }
236
238
  /**
237
239
  * Imperative handle methods exposed via ref
@@ -328,6 +330,8 @@ interface Question {
328
330
  price_per_booking?: boolean;
329
331
  outcome?: boolean;
330
332
  hide_on_customer_journey?: boolean;
333
+ /** Whether the question field is disabled */
334
+ disabled?: boolean;
331
335
  }
332
336
  type FormValues = Record<number, string | number | boolean>;
333
337
  type FormErrors = Record<number, string>;
package/dist/index.d.ts CHANGED
@@ -232,6 +232,8 @@ interface ContactDetailsFormProps {
232
232
  fieldSettings?: ContactDetailsFieldSettings;
233
233
  /** When true, the submit button is hidden and form values are emitted via `onChange` on every change */
234
234
  hideSubmitButton?: boolean;
235
+ /** When true, all validation errors are shown immediately (useful for external submit triggers) */
236
+ isSubmitted?: boolean;
235
237
  }
236
238
  /**
237
239
  * Imperative handle methods exposed via ref
@@ -328,6 +330,8 @@ interface Question {
328
330
  price_per_booking?: boolean;
329
331
  outcome?: boolean;
330
332
  hide_on_customer_journey?: boolean;
333
+ /** Whether the question field is disabled */
334
+ disabled?: boolean;
331
335
  }
332
336
  type FormValues = Record<number, string | number | boolean>;
333
337
  type FormErrors = Record<number, string>;
package/dist/index.js CHANGED
@@ -789,7 +789,8 @@ var ContactDetailsForm = react.forwardRef(
789
789
  className = "",
790
790
  classNames = {},
791
791
  fieldSettings = {},
792
- hideSubmitButton = false
792
+ hideSubmitButton = false,
793
+ isSubmitted = false
793
794
  }, ref) => {
794
795
  const formId = react.useId();
795
796
  const [firstName, setFirstName] = react.useState(initialValues?.firstName || "");
@@ -830,6 +831,7 @@ var ContactDetailsForm = react.forwardRef(
830
831
  }, [fieldSettings]);
831
832
  const validateQuestionField = react.useCallback((question, value) => {
832
833
  if (question.detail_type === "heading") return null;
834
+ if (question.disabled) return null;
833
835
  if (question.required) {
834
836
  if (value === void 0 || value === "" || value === null) {
835
837
  return `${question.name} is required`;
@@ -1008,7 +1010,7 @@ var ContactDetailsForm = react.forwardRef(
1008
1010
  const errorId = `${fieldId}-error`;
1009
1011
  const isDisabled = getFieldDisabled(name);
1010
1012
  const isRequired = getFieldRequired(name);
1011
- const error = contactTouched[name] ? contactErrors[name] : void 0;
1013
+ const error = contactTouched[name] || isSubmitted ? contactErrors[name] : void 0;
1012
1014
  const hasError = !!error;
1013
1015
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.fieldWrapper, children: [
1014
1016
  /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: fieldId, className: styles.label, children: [
@@ -1038,8 +1040,9 @@ var ContactDetailsForm = react.forwardRef(
1038
1040
  const fieldId = `${formId}-q-${question.id}`;
1039
1041
  const errorId = `${fieldId}-error`;
1040
1042
  const value = questionValues[question.id];
1041
- const error = questionTouched[question.id] ? questionErrors[question.id] : void 0;
1043
+ const error = questionTouched[question.id] || isSubmitted ? questionErrors[question.id] : void 0;
1042
1044
  const hasError = !!error;
1045
+ const isDisabled = !!question.disabled;
1043
1046
  const ariaProps = {
1044
1047
  "aria-invalid": hasError ? true : void 0,
1045
1048
  "aria-describedby": hasError ? errorId : void 0,
@@ -1060,10 +1063,11 @@ var ContactDetailsForm = react.forwardRef(
1060
1063
  id: fieldId,
1061
1064
  type: "text",
1062
1065
  value: value || "",
1066
+ disabled: isDisabled,
1063
1067
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1064
1068
  onBlur: () => handleQuestionBlur(question.id),
1065
1069
  placeholder: question.settings?.placeholder,
1066
- className: inputClasses(hasError),
1070
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1067
1071
  ...ariaProps
1068
1072
  }
1069
1073
  ),
@@ -1081,11 +1085,12 @@ var ContactDetailsForm = react.forwardRef(
1081
1085
  {
1082
1086
  id: fieldId,
1083
1087
  value: value || "",
1088
+ disabled: isDisabled,
1084
1089
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1085
1090
  onBlur: () => handleQuestionBlur(question.id),
1086
1091
  placeholder: question.settings?.placeholder,
1087
1092
  rows: 4,
1088
- className: inputClasses(hasError),
1093
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1089
1094
  ...ariaProps
1090
1095
  }
1091
1096
  ),
@@ -1103,9 +1108,10 @@ var ContactDetailsForm = react.forwardRef(
1103
1108
  {
1104
1109
  id: fieldId,
1105
1110
  value: value ?? "",
1111
+ disabled: isDisabled,
1106
1112
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1107
1113
  onBlur: () => handleQuestionBlur(question.id),
1108
- className: inputClasses(hasError),
1114
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1109
1115
  ...ariaProps,
1110
1116
  children: [
1111
1117
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select an option" }),
@@ -1128,12 +1134,13 @@ var ContactDetailsForm = react.forwardRef(
1128
1134
  id: fieldId,
1129
1135
  type: "number",
1130
1136
  value: value ?? "",
1137
+ disabled: isDisabled,
1131
1138
  onChange: (e) => handleQuestionChange(question.id, e.target.value ? Number(e.target.value) : ""),
1132
1139
  onBlur: () => handleQuestionBlur(question.id),
1133
1140
  min: question.settings?.min,
1134
1141
  max: question.settings?.max,
1135
1142
  placeholder: question.settings?.placeholder,
1136
- className: inputClasses(hasError),
1143
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1137
1144
  ...ariaProps
1138
1145
  }
1139
1146
  ),
@@ -1152,9 +1159,10 @@ var ContactDetailsForm = react.forwardRef(
1152
1159
  id: fieldId,
1153
1160
  type: "date",
1154
1161
  value: value || "",
1162
+ disabled: isDisabled,
1155
1163
  onChange: (e) => handleQuestionChange(question.id, e.target.value),
1156
1164
  onBlur: () => handleQuestionBlur(question.id),
1157
- className: inputClasses(hasError),
1165
+ className: cx2(inputClasses(hasError), isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1158
1166
  ...ariaProps
1159
1167
  }
1160
1168
  ),
@@ -1170,9 +1178,10 @@ var ContactDetailsForm = react.forwardRef(
1170
1178
  id: fieldId,
1171
1179
  type: "checkbox",
1172
1180
  checked: !!value,
1181
+ disabled: isDisabled,
1173
1182
  onChange: (e) => handleQuestionChange(question.id, e.target.checked),
1174
1183
  onBlur: () => handleQuestionBlur(question.id),
1175
- className: styles.checkbox,
1184
+ className: cx2(styles.checkbox, isDisabled ? "opacity-50 cursor-not-allowed" : ""),
1176
1185
  ...ariaProps
1177
1186
  }
1178
1187
  ),
@@ -1188,6 +1197,12 @@ var ContactDetailsForm = react.forwardRef(
1188
1197
  return null;
1189
1198
  }
1190
1199
  };
1200
+ react.useEffect(() => {
1201
+ if (isSubmitted) {
1202
+ validateAllContacts();
1203
+ validateAllQuestions();
1204
+ }
1205
+ }, [isSubmitted]);
1191
1206
  react.useEffect(() => {
1192
1207
  if (hideSubmitButton && _onChange) {
1193
1208
  const contactValid = !contactFields.some((f) => {