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