@inploi/plugin-chatbot 3.12.7 → 3.13.1

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.
@@ -1,4 +1,4 @@
1
- import { _, g as getHeadOrThrow, i as invariant, A as AbortedError, N, a as getFlowSubmissionsPayload, h as hasProp, k as kbToReadableSize, o as o$1, c as clsx, b as _$1, y, F, s as store, d as a$2, p, e as parse, f as picklist, j as h, l as k, m as isSubmissionOfType, C as Cn, n as parseAsync, V as ValiError, q as object, t as transform, r as maxLength, u as minLength, v as record, w as boolean, x as string, z as email, B as url, D as regex, T, E as cva, G as ERROR_MESSAGES } from "./index-da27a1bf.js";
1
+ import { _, g as getHeadOrThrow, i as invariant, A as AbortedError, N, a as getFlowSubmissionsPayload, k as kbToReadableSize, h, b as _$1, p, F, o as o$1, c as clsx, y, s as store, d as a$2, e as debounce$1, f as k, j as parse, l as picklist, m as isSubmissionOfType, C as Cn, n as parseAsync, V as ValiError, q as object, t as transform, r as maxLength, u as minLength, v as record, w as boolean, x as string, z as email, B as url, D as regex, E as cva, G as ERROR_MESSAGES } from "./index-16ef9a7a.js";
2
2
  import "@inploi/sdk";
3
3
  const followNodes = ({
4
4
  node,
@@ -452,197 +452,39 @@ async function interpretQuestionBooleanNode({
452
452
  }
453
453
  next(node.nextId);
454
454
  }
455
- const dummyDivBecauseGoogleRequiresIt = document.createElement("div");
456
- const keyToAddressComponnents = {
457
- line1: ["street_number", "floor", "room", "premise"],
458
- line2: ["subpremise", "street_address", "route"],
459
- line3: ["sublocality", "neighborhood"],
460
- city: ["locality", "postal_town"],
461
- state: ["administrative_area_level_1"],
462
- postcode: ["postal_code"],
463
- country: ["country"]
464
- };
465
- const fieldMapKeys = Object.keys(keyToAddressComponnents);
466
455
  async function interpretQuestionAddressNode({
467
456
  chat,
468
457
  next,
469
- node,
470
- logger
458
+ node
471
459
  }) {
472
- if (fieldMapKeys.every((key) => node.data.keys[key] === null))
473
- return next(node.nextId);
474
- const {
475
- google
476
- } = window;
477
460
  await chat.sendMessage({
478
461
  author: "bot",
479
462
  type: "text",
480
463
  text: node.data.question
481
464
  });
482
- const askForAddress = async (defaultValues) => {
483
- const addressFields = [{
484
- label: "Postcode",
485
- key: node.data.keys.postcode,
486
- optional: false,
487
- defaultValue: defaultValues.postcode
488
- }, {
489
- label: "Line 1",
490
- key: node.data.keys.line1,
491
- optional: false,
492
- defaultValue: defaultValues.line1
493
- }, {
494
- label: "Line 2",
495
- key: node.data.keys.line2,
496
- optional: true,
497
- defaultValue: defaultValues.line2
498
- }, {
499
- label: "Line 3",
500
- key: node.data.keys.line3,
501
- optional: true,
502
- defaultValue: defaultValues.line3
503
- }, {
504
- label: "City",
505
- key: node.data.keys.city,
506
- optional: false,
507
- defaultValue: defaultValues.city
508
- }, {
509
- label: "State/County/Province",
510
- key: node.data.keys.state,
511
- optional: true,
512
- defaultValue: defaultValues.state
513
- }, {
514
- label: "Country",
515
- key: node.data.keys.country,
516
- optional: false,
517
- defaultValue: defaultValues.country
518
- }];
519
- for (const field of addressFields) {
520
- if (field.key === null)
521
- continue;
522
- await chat.sendMessage({
523
- author: "bot",
524
- type: "text",
525
- text: field.label
526
- });
527
- const {
528
- value
529
- } = await chat.userInput({
530
- type: "text",
531
- key: field.key,
532
- config: {
533
- format: "text",
534
- optional: field.optional,
535
- defaultValue: field.defaultValue
536
- }
537
- });
538
- if (value === null) {
539
- await chat.sendMessage({
540
- type: "system",
541
- variant: "info",
542
- text: "Skipped"
543
- });
544
- } else {
545
- await chat.sendMessage({
546
- author: "user",
547
- type: "text",
548
- text: value
549
- });
550
- }
551
- }
552
- };
553
- if (!hasProp(window, "google") || !hasProp(window.google, "maps") || !hasProp(window.google.maps, "places")) {
554
- logger.warn("Google maps not available, falling back to manual input.");
555
- logger.info("If you’d like to use the address autocomplete, please insert the google maps API snippet in your website and make sure it has access to the *places* library.");
556
- await askForAddress({});
557
- return next(node.nextId);
558
- }
559
- const autocomplete = new google.maps.places.AutocompleteService();
560
- const places = new google.maps.places.PlacesService(dummyDivBecauseGoogleRequiresIt);
561
- const {
562
- value: search
563
- } = await chat.userInput({
564
- type: "text",
565
- key: "_internal-address-search",
566
- config: {
567
- format: "text",
568
- optional: false,
569
- placeholder: "Search for your address"
570
- }
571
- });
572
- if (search === null)
573
- return next(node.id);
574
- await chat.sendMessage({
575
- author: "user",
576
- type: "text",
577
- text: `Search for “${search}”`
578
- });
579
- const {
580
- predictions
581
- } = await autocomplete.getPlacePredictions({
582
- input: search
583
- });
584
- const {
585
- value: [selected]
586
- } = await chat.userInput({
587
- type: "multiple-choice",
588
- key: void 0,
465
+ const response = await chat.userInput({
466
+ type: "address",
467
+ key: node.data.key,
589
468
  config: {
590
- options: predictions.slice(0, 4).map((p2) => ({
591
- label: p2.description,
592
- value: p2.place_id
593
- })).concat({
594
- label: "None of these",
595
- value: "none"
596
- }),
597
- maxSelected: 1,
598
- minSelected: 1
469
+ optional: node.data.optional,
470
+ keys: node.data.keys,
471
+ placeholder: node.data.placeholder
599
472
  }
600
473
  });
601
- if (!selected || selected === "none") {
602
- return next(node.id);
603
- }
604
- const result = await new Promise((resolve, reject) => places.getDetails({
605
- placeId: selected,
606
- fields: ["address_components"]
607
- }, (result2, status) => {
608
- if (status !== google.maps.places.PlacesServiceStatus["OK"])
609
- return reject(status);
610
- if (result2 === null)
611
- return reject("ZERO_RESULTS");
612
- return resolve({
613
- ok: true,
614
- place: result2
615
- });
616
- })).catch(async (e) => {
617
- logger.error("Failed to get address details", e);
618
- return {
619
- ok: false
620
- };
621
- });
622
- if (result.ok === false) {
474
+ if (response.value === null) {
623
475
  await chat.sendMessage({
624
476
  type: "system",
625
- variant: "error",
626
- text: "Failed to get address details"
477
+ variant: "info",
478
+ text: "Skipped"
479
+ });
480
+ } else {
481
+ const addressMessage = Object.values(response.value).filter((line) => line && line.trim().length > 0).join(", ");
482
+ await chat.sendMessage({
483
+ author: "user",
484
+ type: "text",
485
+ text: addressMessage
627
486
  });
628
- await askForAddress({});
629
- return next(node.id);
630
487
  }
631
- const addressComponents = result.place.address_components;
632
- const autoFilledInputs = addressComponents ? fieldMapKeys.reduce((acc, key) => {
633
- const componentTypes = keyToAddressComponnents[key];
634
- const value = addressComponents.filter((component) => component.types.some((type) => componentTypes.includes(type))).map((component) => component.long_name).join(", ");
635
- if (value) {
636
- acc[key] = value;
637
- }
638
- return acc;
639
- }, {}) : {};
640
- await chat.sendMessage({
641
- author: "bot",
642
- type: "text",
643
- text: "Please confirm or adjust your address:"
644
- });
645
- await askForAddress(autoFilledInputs);
646
488
  return next(node.nextId);
647
489
  }
648
490
  async function interpretQuestionFileNode({
@@ -741,7 +583,14 @@ const isIfBlockConditionMet = (ifBlock, submissions) => {
741
583
  answer: {
742
584
  type: "file"
743
585
  }
744
- }, () => false).exhaustive();
586
+ }, () => false).with({
587
+ answer: {
588
+ type: "address",
589
+ value: _.any
590
+ }
591
+ }, () => {
592
+ return false;
593
+ }).exhaustive();
745
594
  };
746
595
  const interpolateString = (str, context) => {
747
596
  const regex2 = /{{\s*([^}]+?)\s*(?:\|\s*([^}]+?)\s*)?}}/g;
@@ -764,6 +613,203 @@ const interpolateString = (str, context) => {
764
613
  }
765
614
  });
766
615
  };
616
+ function getDefaultExportFromCjs(x) {
617
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
618
+ }
619
+ function debounce(func, wait, immediate) {
620
+ var timeout, args, context, timestamp, result;
621
+ if (null == wait)
622
+ wait = 100;
623
+ function later() {
624
+ var last = Date.now() - timestamp;
625
+ if (last < wait && last >= 0) {
626
+ timeout = setTimeout(later, wait - last);
627
+ } else {
628
+ timeout = null;
629
+ if (!immediate) {
630
+ result = func.apply(context, args);
631
+ context = args = null;
632
+ }
633
+ }
634
+ }
635
+ var debounced = function() {
636
+ context = this;
637
+ args = arguments;
638
+ timestamp = Date.now();
639
+ var callNow = immediate && !timeout;
640
+ if (!timeout)
641
+ timeout = setTimeout(later, wait);
642
+ if (callNow) {
643
+ result = func.apply(context, args);
644
+ context = args = null;
645
+ }
646
+ return result;
647
+ };
648
+ debounced.clear = function() {
649
+ if (timeout) {
650
+ clearTimeout(timeout);
651
+ timeout = null;
652
+ }
653
+ };
654
+ debounced.flush = function() {
655
+ if (timeout) {
656
+ result = func.apply(context, args);
657
+ context = args = null;
658
+ clearTimeout(timeout);
659
+ timeout = null;
660
+ }
661
+ };
662
+ return debounced;
663
+ }
664
+ debounce.debounce = debounce;
665
+ var debounce_1 = debounce;
666
+ const createDebounce = /* @__PURE__ */ getDefaultExportFromCjs(debounce_1);
667
+ function useMeasure(_temp) {
668
+ let {
669
+ debounce: debounce2,
670
+ scroll,
671
+ polyfill,
672
+ offsetSize
673
+ } = _temp === void 0 ? {
674
+ debounce: 0,
675
+ scroll: false,
676
+ offsetSize: false
677
+ } : _temp;
678
+ const ResizeObserver = polyfill || (typeof window === "undefined" ? class ResizeObserver {
679
+ } : window.ResizeObserver);
680
+ if (!ResizeObserver) {
681
+ throw new Error("This browser does not support ResizeObserver out of the box. See: https://github.com/react-spring/react-use-measure/#resize-observer-polyfills");
682
+ }
683
+ const [bounds, set2] = h({
684
+ left: 0,
685
+ top: 0,
686
+ width: 0,
687
+ height: 0,
688
+ bottom: 0,
689
+ right: 0,
690
+ x: 0,
691
+ y: 0
692
+ });
693
+ const state = _$1({
694
+ element: null,
695
+ scrollContainers: null,
696
+ resizeObserver: null,
697
+ lastBounds: bounds
698
+ });
699
+ const scrollDebounce = debounce2 ? typeof debounce2 === "number" ? debounce2 : debounce2.scroll : null;
700
+ const resizeDebounce = debounce2 ? typeof debounce2 === "number" ? debounce2 : debounce2.resize : null;
701
+ const mounted = _$1(false);
702
+ p(() => {
703
+ mounted.current = true;
704
+ return () => void (mounted.current = false);
705
+ });
706
+ const [forceRefresh, resizeChange, scrollChange] = F(() => {
707
+ const callback = () => {
708
+ if (!state.current.element)
709
+ return;
710
+ const {
711
+ left,
712
+ top,
713
+ width,
714
+ height,
715
+ bottom,
716
+ right,
717
+ x,
718
+ y: y2
719
+ } = state.current.element.getBoundingClientRect();
720
+ const size = {
721
+ left,
722
+ top,
723
+ width,
724
+ height,
725
+ bottom,
726
+ right,
727
+ x,
728
+ y: y2
729
+ };
730
+ if (state.current.element instanceof HTMLElement && offsetSize) {
731
+ size.height = state.current.element.offsetHeight;
732
+ size.width = state.current.element.offsetWidth;
733
+ }
734
+ Object.freeze(size);
735
+ if (mounted.current && !areBoundsEqual(state.current.lastBounds, size))
736
+ set2(state.current.lastBounds = size);
737
+ };
738
+ return [callback, resizeDebounce ? createDebounce(callback, resizeDebounce) : callback, scrollDebounce ? createDebounce(callback, scrollDebounce) : callback];
739
+ }, [set2, offsetSize, scrollDebounce, resizeDebounce]);
740
+ function removeListeners() {
741
+ if (state.current.scrollContainers) {
742
+ state.current.scrollContainers.forEach((element) => element.removeEventListener("scroll", scrollChange, true));
743
+ state.current.scrollContainers = null;
744
+ }
745
+ if (state.current.resizeObserver) {
746
+ state.current.resizeObserver.disconnect();
747
+ state.current.resizeObserver = null;
748
+ }
749
+ }
750
+ function addListeners() {
751
+ if (!state.current.element)
752
+ return;
753
+ state.current.resizeObserver = new ResizeObserver(scrollChange);
754
+ state.current.resizeObserver.observe(state.current.element);
755
+ if (scroll && state.current.scrollContainers) {
756
+ state.current.scrollContainers.forEach((scrollContainer) => scrollContainer.addEventListener("scroll", scrollChange, {
757
+ capture: true,
758
+ passive: true
759
+ }));
760
+ }
761
+ }
762
+ const ref = (node) => {
763
+ if (!node || node === state.current.element)
764
+ return;
765
+ removeListeners();
766
+ state.current.element = node;
767
+ state.current.scrollContainers = findScrollContainers(node);
768
+ addListeners();
769
+ };
770
+ useOnWindowScroll(scrollChange, Boolean(scroll));
771
+ useOnWindowResize(resizeChange);
772
+ p(() => {
773
+ removeListeners();
774
+ addListeners();
775
+ }, [scroll, scrollChange, resizeChange]);
776
+ p(() => removeListeners, []);
777
+ return [ref, bounds, forceRefresh];
778
+ }
779
+ function useOnWindowResize(onWindowResize) {
780
+ p(() => {
781
+ const cb = onWindowResize;
782
+ window.addEventListener("resize", cb);
783
+ return () => void window.removeEventListener("resize", cb);
784
+ }, [onWindowResize]);
785
+ }
786
+ function useOnWindowScroll(onScroll, enabled) {
787
+ p(() => {
788
+ if (enabled) {
789
+ const cb = onScroll;
790
+ window.addEventListener("scroll", cb, {
791
+ capture: true,
792
+ passive: true
793
+ });
794
+ return () => void window.removeEventListener("scroll", cb, true);
795
+ }
796
+ }, [onScroll, enabled]);
797
+ }
798
+ function findScrollContainers(element) {
799
+ const result = [];
800
+ if (!element || element === document.body)
801
+ return result;
802
+ const {
803
+ overflow,
804
+ overflowX,
805
+ overflowY
806
+ } = window.getComputedStyle(element);
807
+ if ([overflow, overflowX, overflowY].some((prop) => prop === "auto" || prop === "scroll"))
808
+ result.push(element);
809
+ return [...result, ...findScrollContainers(element.parentElement)];
810
+ }
811
+ const keys = ["x", "y", "top", "bottom", "left", "right", "width", "height"];
812
+ const areBoundsEqual = (a2, b) => keys.every((key) => a2[key] === b[key]);
767
813
  const SendButton = ({
768
814
  class: className,
769
815
  ...props
@@ -904,6 +950,344 @@ const SkipButton = ({
904
950
  })]
905
951
  }), "Skip"]
906
952
  });
953
+ const keyToAddressComponents = {
954
+ line1: ["street_number", "floor", "room", "premise"],
955
+ line2: ["subpremise", "street_address", "route"],
956
+ line3: ["sublocality", "neighborhood"],
957
+ city: ["locality", "postal_town"],
958
+ state: ["administrative_area_level_1"],
959
+ postcode: ["postal_code"],
960
+ country: ["country"]
961
+ };
962
+ const fieldMapKeys = Object.keys(keyToAddressComponents);
963
+ const addressComponentsToFields = (addressComponents) => {
964
+ return fieldMapKeys.reduce((acc, key) => {
965
+ const componentTypes = keyToAddressComponents[key];
966
+ const value = addressComponents.filter((component) => component.types.some((type) => componentTypes.includes(type))).map((component) => component.long_name).join(", ");
967
+ if (value) {
968
+ acc[key] = value;
969
+ }
970
+ return acc;
971
+ }, {});
972
+ };
973
+ const dummyDivBecauseGoogleRequiresIt = document.createElement("div");
974
+ const useGooglePlaces = () => {
975
+ return F(() => {
976
+ const {
977
+ google
978
+ } = window;
979
+ if ("google" in window === false || "maps" in google === false || "places" in google.maps === false) {
980
+ return {
981
+ enabled: false
982
+ };
983
+ }
984
+ const autocomplete = new google.maps.places.AutocompleteService();
985
+ const places = new google.maps.places.PlacesService(dummyDivBecauseGoogleRequiresIt);
986
+ return {
987
+ enabled: true,
988
+ getPredictions: async (input) => {
989
+ const {
990
+ predictions
991
+ } = await autocomplete.getPlacePredictions({
992
+ input
993
+ });
994
+ return predictions.map((p2) => ({
995
+ label: p2.description,
996
+ value: p2.place_id
997
+ }));
998
+ },
999
+ getPlaceDetails: async (placeId) => {
1000
+ const result = await new Promise((resolve, reject) => places.getDetails({
1001
+ placeId,
1002
+ fields: ["address_components"]
1003
+ }, (result2, status) => {
1004
+ if (status !== google.maps.places.PlacesServiceStatus["OK"])
1005
+ return reject(status);
1006
+ if (result2 === null)
1007
+ return reject("ZERO_RESULTS");
1008
+ return resolve({
1009
+ ok: true,
1010
+ place: result2
1011
+ });
1012
+ })).catch(async (e) => {
1013
+ console.error("Failed to get address details", e);
1014
+ return {
1015
+ ok: false
1016
+ };
1017
+ });
1018
+ return result;
1019
+ }
1020
+ };
1021
+ }, []);
1022
+ };
1023
+ const BackButton = (props) => {
1024
+ return o$1("button", {
1025
+ type: "button",
1026
+ class: "text-neutral-10 hover:bg-neutral-4 hover:text-neutral-12 hover:border-neutral-5 flex items-center gap-1 rounded-[18px] border border-solid border-transparent px-3 py-1 pl-1.5 text-sm transition-colors",
1027
+ ...props,
1028
+ children: [o$1("svg", {
1029
+ width: "16",
1030
+ height: "16",
1031
+ viewBox: "0 0 16 16",
1032
+ stroke: "currentColor",
1033
+ "stroke-width": "1.5",
1034
+ fill: "none",
1035
+ xmlns: "http://www.w3.org/2000/svg",
1036
+ children: o$1("path", {
1037
+ d: "M10 3L5 8L10 13"
1038
+ })
1039
+ }), o$1("span", {
1040
+ children: "Back"
1041
+ })]
1042
+ });
1043
+ };
1044
+ const optionManual = {
1045
+ label: "Fill in manually",
1046
+ value: ""
1047
+ };
1048
+ const ChatInputAddress = ({
1049
+ input,
1050
+ onSubmitSuccess
1051
+ }) => {
1052
+ const [query, setQuery] = h("");
1053
+ const [addressFields, setAddressFields] = h();
1054
+ const [suggestions, setSuggestions] = h([]);
1055
+ const [placeId, setPlaceId] = h();
1056
+ const {
1057
+ enabled,
1058
+ getPredictions,
1059
+ getPlaceDetails
1060
+ } = useGooglePlaces();
1061
+ const [state, setState] = h(enabled ? "query" : "manual");
1062
+ const debouncedQuery = F(() => debounce$1((query2) => {
1063
+ invariant(enabled, "Query state should not be enabled if Google Places isn't available");
1064
+ setQuery(query2);
1065
+ if (query2 === "") {
1066
+ setSuggestions([]);
1067
+ return;
1068
+ }
1069
+ getPredictions(query2).then((predictions) => {
1070
+ setSuggestions(predictions);
1071
+ });
1072
+ }, 500), [enabled, getPredictions]);
1073
+ p(() => {
1074
+ if (!enabled)
1075
+ return;
1076
+ if (placeId === void 0 || placeId === "")
1077
+ return;
1078
+ getPlaceDetails(placeId).then((result) => {
1079
+ if (!result.ok || !result.place.address_components) {
1080
+ setAddressFields({});
1081
+ return;
1082
+ }
1083
+ const fields = addressComponentsToFields(result.place.address_components);
1084
+ setAddressFields(fields);
1085
+ setState("details");
1086
+ });
1087
+ return () => {
1088
+ setAddressFields(void 0);
1089
+ };
1090
+ }, [placeId, getPlaceDetails, enabled]);
1091
+ switch (state) {
1092
+ case "query": {
1093
+ invariant(enabled, "Query state should not be enabled if Google Places isn't available");
1094
+ return o$1(ChatInputAddressQuery, {
1095
+ input,
1096
+ onSkip: () => onSubmitSuccess(null),
1097
+ onAddressSelect: (e) => {
1098
+ setPlaceId(e);
1099
+ setState("loading");
1100
+ },
1101
+ onInputChange: debouncedQuery,
1102
+ suggestions,
1103
+ query
1104
+ });
1105
+ }
1106
+ case "loading":
1107
+ return o$1(ChatInputAddressDetails, {
1108
+ input,
1109
+ onSubmitSuccess,
1110
+ addressFields: {},
1111
+ actions: o$1(BackButton, {
1112
+ onClick: () => {
1113
+ setPlaceId(void 0);
1114
+ setState("query");
1115
+ }
1116
+ })
1117
+ });
1118
+ case "details":
1119
+ invariant(addressFields !== void 0);
1120
+ return o$1(ChatInputAddressDetails, {
1121
+ input,
1122
+ onSubmitSuccess,
1123
+ addressFields,
1124
+ actions: o$1(BackButton, {
1125
+ onClick: () => {
1126
+ setPlaceId(void 0);
1127
+ setState("query");
1128
+ }
1129
+ })
1130
+ });
1131
+ case "manual":
1132
+ return o$1(ChatInputAddressDetails, {
1133
+ input,
1134
+ onSubmitSuccess,
1135
+ addressFields: {},
1136
+ actions: enabled ? o$1(BackButton, {
1137
+ onClick: () => {
1138
+ setPlaceId(void 0);
1139
+ setState("query");
1140
+ }
1141
+ }) : void 0
1142
+ });
1143
+ }
1144
+ };
1145
+ const ChatInputAddressQuery = ({
1146
+ input,
1147
+ onSkip,
1148
+ suggestions,
1149
+ onAddressSelect,
1150
+ query,
1151
+ onInputChange
1152
+ }) => {
1153
+ const ref = _$1(null);
1154
+ y(() => {
1155
+ if (ref.current) {
1156
+ ref.current.focus();
1157
+ ref.current.select();
1158
+ }
1159
+ }, []);
1160
+ return o$1(k, {
1161
+ children: [o$1("form", {
1162
+ noValidate: true,
1163
+ onSubmit: (e) => {
1164
+ e.preventDefault;
1165
+ },
1166
+ class: "flex flex-col justify-end gap-1 p-2.5",
1167
+ children: [o$1("input", {
1168
+ onChange: (e) => {
1169
+ onInputChange(e.currentTarget.value);
1170
+ },
1171
+ ref,
1172
+ name: "address",
1173
+ id: "chat-address",
1174
+ autocomplete: "on",
1175
+ autoFocus: true,
1176
+ class: "outline-divider ease-expo-out placeholder:text-neutral-10 text-neutral-12 focus-visible:outline-accent-7 caret-accent-9 bg-lowest w-full rounded-full px-3 py-1 text-base outline outline-2 transition-all",
1177
+ placeholder: input.config.placeholder || "Search an address",
1178
+ defaultValue: query
1179
+ }), !input.config.optional && o$1(SkipButton, {
1180
+ class: "absolute right-3",
1181
+ onClick: onSkip
1182
+ })]
1183
+ }), o$1("ul", {
1184
+ children: [suggestions.map((suggestion) => o$1("li", {
1185
+ children: o$1("button", {
1186
+ class: "text-neutral-11 fr hover:bg-neutral-3 hover:text-neutral-12 border-b-neutral-3 flex w-full items-center border border-b border-solid border-transparent px-4 py-3 text-sm transition-colors duration-100",
1187
+ onClick: () => {
1188
+ onAddressSelect(suggestion.value);
1189
+ },
1190
+ children: [o$1("span", {
1191
+ class: "flex-grow",
1192
+ children: suggestion.label
1193
+ }), o$1("svg", {
1194
+ class: "flex-none",
1195
+ width: "16",
1196
+ height: "16",
1197
+ viewBox: "0 0 16 16",
1198
+ stroke: "currentColor",
1199
+ "stroke-width": "1.5",
1200
+ fill: "none",
1201
+ xmlns: "http://www.w3.org/2000/svg",
1202
+ children: o$1("path", {
1203
+ d: "M6 3L11 8L6 13"
1204
+ })
1205
+ })]
1206
+ })
1207
+ }, suggestion.label)), o$1("li", {
1208
+ children: o$1("button", {
1209
+ class: "text-neutral-11 fr hover:bg-neutral-3 hover:text-neutral-12 border-b-neutral-3 flex w-full items-center border border-b border-solid border-transparent px-4 py-3 text-sm transition-colors duration-100",
1210
+ onClick: () => {
1211
+ onAddressSelect(optionManual.value);
1212
+ },
1213
+ children: o$1("span", {
1214
+ class: "flex-grow",
1215
+ children: optionManual.label
1216
+ })
1217
+ })
1218
+ }, optionManual.label)]
1219
+ })]
1220
+ });
1221
+ };
1222
+ const addressKeyToLabel = {
1223
+ line1: "Line 1",
1224
+ line2: "Line 2",
1225
+ line3: "Line 3",
1226
+ city: "City",
1227
+ state: "State",
1228
+ postcode: "Postcode",
1229
+ country: "Country"
1230
+ };
1231
+ const ChatInputAddressDetails = ({
1232
+ addressFields,
1233
+ onSubmitSuccess,
1234
+ actions
1235
+ }) => {
1236
+ const ref = _$1(null);
1237
+ y(() => {
1238
+ if (ref.current) {
1239
+ const firstInput = ref.current.querySelector("input");
1240
+ if (firstInput) {
1241
+ firstInput.focus();
1242
+ firstInput.select();
1243
+ }
1244
+ }
1245
+ }, []);
1246
+ return o$1("form", {
1247
+ class: "bg-neutral-1/90 flex flex-col justify-end gap-2 p-2",
1248
+ onSubmit: (e) => {
1249
+ const formData = new FormData(e.currentTarget);
1250
+ const fields = Object.fromEntries(formData.entries());
1251
+ onSubmitSuccess(fields);
1252
+ },
1253
+ children: [o$1("div", {
1254
+ class: "bg-neutral-3 border-neutral-5 grid items-center gap-1.5 rounded-2xl border pb-2 pl-4 pr-3 pt-3 [grid-template-columns:min-content_1fr]",
1255
+ ref,
1256
+ children: fieldMapKeys.map((key, i2) => {
1257
+ const labelId = `isdk_${key}`;
1258
+ return o$1(k, {
1259
+ children: [o$1("label", {
1260
+ for: labelId,
1261
+ class: "text-neutral-9 [&:has(+*>input:focus)]:text-neutral-11 w-24 pb-2 text-xs uppercase leading-3 tracking-widest transition-colors",
1262
+ children: addressKeyToLabel[key]
1263
+ }), o$1("div", {
1264
+ class: "flex flex-col items-stretch gap-1.5",
1265
+ children: [o$1("input", {
1266
+ autoFocus: i2 === 0 ? true : void 0,
1267
+ class: "text-neutral-12 hover:bg-neutral-4 placeholder:text-neutral-8 focus:bg-neutral-5 flex-1 rounded-lg border-solid bg-transparent px-3 py-1.5 text-base transition-colors focus:outline-none",
1268
+ name: key,
1269
+ id: labelId,
1270
+ defaultValue: addressFields[key],
1271
+ required: true
1272
+ }), i2 !== fieldMapKeys.length - 1 && o$1("hr", {
1273
+ class: "border-b-neutral-5 m-0 w-full border-b border-solid"
1274
+ }), i2 === fieldMapKeys.length - 1 && o$1("hr", {
1275
+ class: "m-0 w-full border-b border-b-transparent"
1276
+ })]
1277
+ })]
1278
+ });
1279
+ })
1280
+ }), o$1("div", {
1281
+ class: "flex w-full flex-1 ",
1282
+ children: [o$1("div", {
1283
+ class: "flex-grow",
1284
+ children: actions
1285
+ }), o$1(SendButton, {
1286
+ class: "flex items-center justify-center"
1287
+ })]
1288
+ })]
1289
+ });
1290
+ };
907
1291
  const useFocusOnMount = () => {
908
1292
  const focusRef = _$1(null);
909
1293
  p(() => {
@@ -917,11 +1301,9 @@ const AnswerSchema = picklist(options);
917
1301
  const FIELD_NAME = "answer";
918
1302
  const ChatInputBoolean = ({
919
1303
  input,
920
- onSubmitSuccess,
921
- onHeightChange
1304
+ onSubmitSuccess
922
1305
  }) => {
923
1306
  const focusRef = useFocusOnMount();
924
- onHeightChange();
925
1307
  return o$1("form", {
926
1308
  noValidate: true,
927
1309
  class: "",
@@ -965,14 +1347,8 @@ const ChatInputBoolean = ({
965
1347
  });
966
1348
  };
967
1349
  const InputError = ({
968
- error,
969
- onAnimationComplete
1350
+ error
970
1351
  }) => {
971
- y(() => {
972
- if (error) {
973
- onAnimationComplete();
974
- }
975
- }, [error, onAnimationComplete]);
976
1352
  if (!error)
977
1353
  return null;
978
1354
  return o$1("div", {
@@ -1074,8 +1450,7 @@ const trimFileName = (fileName, maxLength2) => {
1074
1450
  };
1075
1451
  const ChatInputFile = ({
1076
1452
  input,
1077
- onSubmitSuccess,
1078
- onHeightChange
1453
+ onSubmitSuccess
1079
1454
  }) => {
1080
1455
  var _a;
1081
1456
  const submission = (_a = store.current$.value.flow) == null ? void 0 : _a.data.submissions[input.key];
@@ -1221,7 +1596,6 @@ const ChatInputFile = ({
1221
1596
  })]
1222
1597
  })]
1223
1598
  }), error && o$1(InputError, {
1224
- onAnimationComplete: onHeightChange,
1225
1599
  error
1226
1600
  })]
1227
1601
  });
@@ -1860,7 +2234,7 @@ function createFormControl(props = {}, flushRootRender) {
1860
2234
  const validationModeBeforeSubmit = getValidationModes(_options.mode);
1861
2235
  const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1862
2236
  const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
1863
- const debounce = (callback) => (wait) => {
2237
+ const debounce2 = (callback) => (wait) => {
1864
2238
  clearTimeout(timer);
1865
2239
  timer = setTimeout(callback, wait);
1866
2240
  };
@@ -1954,7 +2328,7 @@ function createFormControl(props = {}, flushRootRender) {
1954
2328
  const previousFieldError = get(_formState.errors, name);
1955
2329
  const shouldUpdateValid = _proxyFormState.isValid && isBoolean(isValid) && _formState.isValid !== isValid;
1956
2330
  if (props.delayError && error) {
1957
- delayErrorCallback = debounce(() => updateErrors(name, error));
2331
+ delayErrorCallback = debounce2(() => updateErrors(name, error));
1958
2332
  delayErrorCallback(props.delayError);
1959
2333
  } else {
1960
2334
  clearTimeout(timer);
@@ -2711,8 +3085,7 @@ const getResolver$1 = (config) => {
2711
3085
  };
2712
3086
  const ChatInputMultipleChoice = ({
2713
3087
  input,
2714
- onSubmitSuccess,
2715
- onHeightChange
3088
+ onSubmitSuccess
2716
3089
  }) => {
2717
3090
  var _a, _b;
2718
3091
  const submission = input.key ? (_a = store.current$.value.flow) == null ? void 0 : _a.data.submissions[input.key] : void 0;
@@ -2788,7 +3161,6 @@ const ChatInputMultipleChoice = ({
2788
3161
  }), o$1("div", {
2789
3162
  class: "px-1",
2790
3163
  children: o$1(InputError, {
2791
- onAnimationComplete: onHeightChange,
2792
3164
  error: (_b = errors2.checked) == null ? void 0 : _b.root
2793
3165
  })
2794
3166
  })]
@@ -2870,8 +3242,7 @@ const getResolver = (config) => {
2870
3242
  };
2871
3243
  const ChatInputText = ({
2872
3244
  input,
2873
- onSubmitSuccess,
2874
- onHeightChange
3245
+ onSubmitSuccess
2875
3246
  }) => {
2876
3247
  var _a;
2877
3248
  const submission = input.key ? (_a = store.current$.value.flow) == null ? void 0 : _a.data.submissions[input.key] : void 0;
@@ -2934,7 +3305,6 @@ const ChatInputText = ({
2934
3305
  })]
2935
3306
  }), o$1(SendButton, {})]
2936
3307
  }), o$1(InputError, {
2937
- onAnimationComplete: onHeightChange,
2938
3308
  error: errors2.text
2939
3309
  })]
2940
3310
  })
@@ -2943,16 +3313,9 @@ const ChatInputText = ({
2943
3313
  const ChatInput = () => {
2944
3314
  var _a;
2945
3315
  const input = (_a = store.current$.value.flow) == null ? void 0 : _a.data.currentInput;
3316
+ const [inputContentRef, bounds] = useMeasure();
2946
3317
  const inputWrapperRef = _$1(null);
2947
- const inputContentRef = _$1(null);
2948
- const updateHeight = T(() => {
2949
- if (inputContentRef.current) {
2950
- store.inputHeight$.value = inputContentRef.current.getBoundingClientRect().height;
2951
- }
2952
- }, []);
2953
- p(() => {
2954
- updateHeight();
2955
- }, [input == null ? void 0 : input.type, updateHeight]);
3318
+ store.inputHeight$.value = bounds.height;
2956
3319
  p(() => {
2957
3320
  const wrapper = inputWrapperRef.current;
2958
3321
  if (!wrapper)
@@ -2972,16 +3335,15 @@ const ChatInput = () => {
2972
3335
  });
2973
3336
  return o$1("div", {
2974
3337
  ref: inputWrapperRef,
3338
+ class: "ease-expo-out absolute bottom-0 w-full overflow-hidden rounded-b-3xl backdrop-blur-xl transition-all duration-700 will-change-[height]",
2975
3339
  style: {
2976
- height: store.inputHeight$.value
3340
+ height: bounds.height
2977
3341
  },
2978
- class: "bg-statusbar ease-expo-out absolute bottom-0 w-full overflow-hidden rounded-b-3xl backdrop-blur-md backdrop-saturate-150 transition-all duration-700",
2979
3342
  children: o$1("div", {
2980
3343
  ref: inputContentRef,
2981
- class: "border-divider border-t",
3344
+ class: "border-divider flex flex-col justify-end border-t",
2982
3345
  children: N({
2983
- input,
2984
- onHeightChange: updateHeight
3346
+ input
2985
3347
  }).with({
2986
3348
  input: _.nullish
2987
3349
  }, () => o$1("div", {
@@ -3031,6 +3393,13 @@ const ChatInput = () => {
3031
3393
  }, (props) => o$1(ChatInputSubmit, {
3032
3394
  onSubmitSuccess: handleSubmitSuccess(props.input.type),
3033
3395
  ...props
3396
+ })).with({
3397
+ input: {
3398
+ type: "address"
3399
+ }
3400
+ }, (props) => o$1(ChatInputAddress, {
3401
+ onSubmitSuccess: handleSubmitSuccess(props.input.type),
3402
+ ...props
3034
3403
  })).exhaustive()
3035
3404
  })
3036
3405
  });