udp-stencil-component-library 26.9.0-beta.0 → 26.9.0-beta.2

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.
Files changed (111) hide show
  1. package/dist/cjs/{base-map_4.cjs.entry.js → base-map_3.cjs.entry.js} +0 -59
  2. package/dist/cjs/{codecs-CzM31cMq.js → codecs-ClSB_OaD.js} +156 -63
  3. package/dist/cjs/form-metadata-display_2.cjs.entry.js +105 -0
  4. package/dist/cjs/{form-metadata-display_9.cjs.entry.js → image-upload_8.cjs.entry.js} +68 -62
  5. package/dist/cjs/index-CZB9dMeB.js +22 -46
  6. package/dist/cjs/loader.cjs.js +1 -1
  7. package/dist/cjs/slot-index-Dzl7Zum5.js +77 -0
  8. package/dist/cjs/stencil-library.cjs.js +1 -1
  9. package/dist/cjs/{udp-container-query_2.cjs.entry.js → udp-container-query-grid.cjs.entry.js} +0 -33
  10. package/dist/cjs/udp-container-query.cjs.entry.js +37 -0
  11. package/dist/cjs/udp-detail-list_9.cjs.entry.js +2286 -0
  12. package/dist/cjs/udp-fluent-inline-edit_5.cjs.entry.js +299 -77
  13. package/dist/cjs/udp-question-form-builder.cjs.entry.js +1 -1
  14. package/dist/collection/components/forms/udp-question-form/core/slot-index.js +32 -0
  15. package/dist/collection/components/forms/udp-question-form/renderer/runtime/codecs.js +140 -64
  16. package/dist/collection/components/forms/udp-question-form/renderer/runtime/parse.js +14 -2
  17. package/dist/collection/components/forms/udp-question-form/renderer/runtime/types.js +17 -0
  18. package/dist/collection/components/forms/udp-question-form/renderer/udp-question-form-renderer.js +259 -23
  19. package/dist/collection/components/forms/udp-question-form/renderer/ui/adapters/udp-question-tally-adapter.js +3 -3
  20. package/dist/collection/components/forms/udp-question-form/renderer/ui/form-shell.js +3 -2
  21. package/dist/collection/components/forms/udp-question-form/renderer/ui/question-renderer.js +17 -4
  22. package/dist/collection/components/forms/udp-question-form/renderer/ui/question-view-renderer.js +6 -1
  23. package/dist/collection/components/forms/udp-question-form/renderer/ui/section-card.js +4 -2
  24. package/dist/collection/components/inputs/location-input/build-static-map-url.js +19 -0
  25. package/dist/collection/components/inputs/location-input/location-input.js +19 -20
  26. package/dist/collection/components/inputs/location-input/resolve-display-location.js +29 -0
  27. package/dist/components/location-input2.js +1 -1
  28. package/dist/components/udp-detail-list-item.js +1 -1
  29. package/dist/components/udp-detail-list-item2.js +1 -0
  30. package/dist/components/udp-detail-list.js +1 -1
  31. package/dist/components/udp-detail-list2.js +1 -0
  32. package/dist/components/udp-fluent-file-input.js +1 -1
  33. package/dist/components/udp-fluent-file-input2.js +1 -0
  34. package/dist/components/udp-fluent-image.js +1 -1
  35. package/dist/components/udp-fluent-image2.js +1 -0
  36. package/dist/components/udp-fluent-list-input.js +1 -1
  37. package/dist/components/udp-fluent-list-input2.js +1 -0
  38. package/dist/components/udp-fluent-location-input.js +1 -1
  39. package/dist/components/udp-fluent-location-input2.js +1 -0
  40. package/dist/components/udp-fluent-signature-input.js +1 -1
  41. package/dist/components/udp-fluent-signature-input2.js +1 -0
  42. package/dist/components/udp-fluent-table-input.js +1 -1
  43. package/dist/components/udp-fluent-table-input2.js +1 -0
  44. package/dist/components/udp-question-form-builder.js +1 -1
  45. package/dist/components/udp-question-form-renderer2.js +1 -1
  46. package/dist/components/udp-question-tally-adapter.js +1 -1
  47. package/dist/components/udp-question-tally-adapter2.js +1 -0
  48. package/dist/docs.json +657 -43
  49. package/dist/esm/{base-map_4.entry.js → base-map_3.entry.js} +1 -59
  50. package/dist/esm/{codecs-bR6Ih0TV.js → codecs-CI_fHfY1.js} +156 -63
  51. package/dist/esm/form-metadata-display_2.entry.js +102 -0
  52. package/dist/esm/{form-metadata-display_9.entry.js → image-upload_8.entry.js} +70 -63
  53. package/dist/esm/index-15aY63VA.js +22 -46
  54. package/dist/esm/loader.js +1 -1
  55. package/dist/esm/slot-index-aYrr8BJl.js +74 -0
  56. package/dist/esm/stencil-library.js +1 -1
  57. package/dist/esm/{udp-container-query_2.entry.js → udp-container-query-grid.entry.js} +1 -33
  58. package/dist/esm/udp-container-query.entry.js +35 -0
  59. package/dist/esm/udp-detail-list_9.entry.js +2269 -0
  60. package/dist/esm/udp-fluent-inline-edit_5.entry.js +298 -76
  61. package/dist/esm/udp-question-form-builder.entry.js +1 -1
  62. package/dist/stencil-library/{base-map_4.entry.js → base-map_3.entry.js} +1 -1
  63. package/dist/stencil-library/codecs-CI_fHfY1.js +1 -0
  64. package/dist/stencil-library/form-metadata-display_2.entry.js +1 -0
  65. package/dist/stencil-library/image-upload_8.entry.js +1 -0
  66. package/dist/stencil-library/slot-index-aYrr8BJl.js +1 -0
  67. package/dist/stencil-library/stencil-library.esm.js +1 -1
  68. package/dist/stencil-library/udp-container-query-grid.entry.js +1 -0
  69. package/dist/stencil-library/udp-container-query.entry.js +1 -0
  70. package/dist/stencil-library/udp-detail-list_9.entry.js +1 -0
  71. package/dist/stencil-library/udp-fluent-inline-edit_5.entry.js +1 -1
  72. package/dist/stencil-library/udp-question-form-builder.entry.js +1 -1
  73. package/dist/types/components/forms/udp-question-form/core/slot-index.d.ts +19 -6
  74. package/dist/types/components/forms/udp-question-form/renderer/runtime/codecs.d.ts +11 -7
  75. package/dist/types/components/forms/udp-question-form/renderer/runtime/types.d.ts +19 -3
  76. package/dist/types/components/forms/udp-question-form/renderer/udp-question-form-renderer.d.ts +99 -7
  77. package/dist/types/components/forms/udp-question-form/renderer/ui/form-shell.d.ts +13 -0
  78. package/dist/types/components/forms/udp-question-form/renderer/ui/question-renderer.d.ts +8 -0
  79. package/dist/types/components/inputs/location-input/build-static-map-url.d.ts +20 -0
  80. package/dist/types/components/inputs/location-input/resolve-display-location.d.ts +15 -0
  81. package/package.json +1 -1
  82. package/dist/cjs/udp-detail-list-item.cjs.entry.js +0 -41
  83. package/dist/cjs/udp-detail-list.cjs.entry.js +0 -152
  84. package/dist/cjs/udp-fluent-file-input.cjs.entry.js +0 -632
  85. package/dist/cjs/udp-fluent-image.cjs.entry.js +0 -27
  86. package/dist/cjs/udp-fluent-list-input.cjs.entry.js +0 -46
  87. package/dist/cjs/udp-fluent-location-input.cjs.entry.js +0 -558
  88. package/dist/cjs/udp-fluent-signature-input.cjs.entry.js +0 -385
  89. package/dist/cjs/udp-fluent-table-input.cjs.entry.js +0 -347
  90. package/dist/cjs/udp-question-tally-adapter.cjs.entry.js +0 -138
  91. package/dist/esm/udp-detail-list-item.entry.js +0 -39
  92. package/dist/esm/udp-detail-list.entry.js +0 -150
  93. package/dist/esm/udp-fluent-file-input.entry.js +0 -630
  94. package/dist/esm/udp-fluent-image.entry.js +0 -25
  95. package/dist/esm/udp-fluent-list-input.entry.js +0 -44
  96. package/dist/esm/udp-fluent-location-input.entry.js +0 -550
  97. package/dist/esm/udp-fluent-signature-input.entry.js +0 -379
  98. package/dist/esm/udp-fluent-table-input.entry.js +0 -345
  99. package/dist/esm/udp-question-tally-adapter.entry.js +0 -136
  100. package/dist/stencil-library/codecs-bR6Ih0TV.js +0 -1
  101. package/dist/stencil-library/form-metadata-display_9.entry.js +0 -1
  102. package/dist/stencil-library/udp-container-query_2.entry.js +0 -1
  103. package/dist/stencil-library/udp-detail-list-item.entry.js +0 -1
  104. package/dist/stencil-library/udp-detail-list.entry.js +0 -1
  105. package/dist/stencil-library/udp-fluent-file-input.entry.js +0 -1
  106. package/dist/stencil-library/udp-fluent-image.entry.js +0 -1
  107. package/dist/stencil-library/udp-fluent-list-input.entry.js +0 -1
  108. package/dist/stencil-library/udp-fluent-location-input.entry.js +0 -1
  109. package/dist/stencil-library/udp-fluent-signature-input.entry.js +0 -1
  110. package/dist/stencil-library/udp-fluent-table-input.entry.js +0 -1
  111. package/dist/stencil-library/udp-question-tally-adapter.entry.js +0 -1
@@ -683,65 +683,6 @@ const StencilField = class {
683
683
  get el() { return index.getElement(this); }
684
684
  };
685
685
 
686
- const tallyCss = () => `:host{display:block;width:100%}.tally-container{display:flex;flex-direction:column;gap:var(--spacing-02, 8px)}.tally-label{font-weight:600;margin-bottom:var(--spacing-02, 8px)}.tally-loading{display:flex;align-items:center;justify-content:center;padding:var(--spacing-04, 16px);color:var(--text-secondary, #6b7280)}.tally-content{display:flex;flex-direction:column;gap:var(--spacing-03, 12px)}.tally-stats{display:flex;gap:var(--spacing-04, 16px);flex-wrap:wrap}.tally-item{display:flex;flex-direction:column;align-items:center;padding:var(--spacing-03, 12px) var(--spacing-04, 16px);border-radius:var(--border-radius-01, 4px);border:1px solid var(--border-subtle, #e5e7eb);background-color:var(--layer-01, #ffffff);min-width:80px;flex:1;max-width:120px}.tally-item.tally-yes{border-color:var(--support-success, #42be65);background-color:var(--support-success-hover, #f6f8ff)}.tally-item.tally-no{border-color:var(--support-error, #da1e28);background-color:var(--support-error-hover, #fff1f1)}.tally-item.tally-unanswered{border-color:var(--support-warning, #f1c21b);background-color:var(--support-warning-hover, #fcf4d6)}.tally-count{font-weight:700;line-height:1.2;margin-bottom:var(--spacing-01, 4px)}.tally-yes .tally-count{color:var(--support-success, #42be65)}.tally-no .tally-count{color:var(--support-error, #da1e28)}.tally-unanswered .tally-count{color:var(--support-warning, #f1c21b)}.tally-item .tally-label{margin:0;font-weight:500;text-transform:uppercase;font-size:0.75rem;letter-spacing:0.02em}.tally-summary{padding:var(--spacing-02, 8px) 0;border-top:1px solid var(--border-subtle, #e5e7eb);text-align:center}.error-message{margin-top:var(--spacing-02, 8px);padding:var(--spacing-02, 8px);border-radius:var(--border-radius-01, 4px);background-color:var(--support-error-hover, #fff1f1);border:1px solid var(--support-error, #da1e28)}:host(.udp-input--size-small) .tally-item{padding:var(--spacing-02, 8px) var(--spacing-03, 12px);min-width:60px;max-width:90px}:host(.udp-input--size-small) .tally-count{font-size:1.25rem}:host(.udp-input--size-large) .tally-item{padding:var(--spacing-04, 16px) var(--spacing-05, 20px);min-width:100px;max-width:150px}:host(.udp-input--size-large) .tally-count{font-size:2rem}:host(.udp-input--margin-none) .tally-container{gap:0}:host(.udp-input--margin-dense) .tally-container{gap:var(--spacing-01, 4px)}:host(.udp-input--margin-comfortable) .tally-container{gap:var(--spacing-04, 16px)}:host(.udp-input--disabled) .tally-item{opacity:0.5;pointer-events:none}:host(.udp-input--readonly) .tally-item{background-color:var(--field-01, #f4f4f4)}@media (max-width: 480px){.tally-stats{flex-direction:column}.tally-item{max-width:none;flex:none}}`;
687
-
688
- const TallyDisplay = class {
689
- constructor(hostRef) {
690
- index.registerInstance(this, hostRef);
691
- /**
692
- * Label for the tally display.
693
- */
694
- this.label = 'Response Tally';
695
- /**
696
- * Number of Yes responses.
697
- */
698
- this.yesCount = 0;
699
- /**
700
- * Number of No responses.
701
- */
702
- this.noCount = 0;
703
- /**
704
- * Number of Not Applicable responses.
705
- */
706
- this.naCount = 0;
707
- /**
708
- * Total number of fields being tallied.
709
- */
710
- this.totalFields = 0;
711
- /**
712
- * Whether the component is disabled.
713
- */
714
- this.disabled = false;
715
- /**
716
- * Whether the component is read-only.
717
- */
718
- this.readonly = false;
719
- /**
720
- * Size variant for the tally display.
721
- */
722
- this.size = 'normal';
723
- /**
724
- * Margin variant for the component spacing.
725
- */
726
- this.margin = 'normal';
727
- }
728
- render() {
729
- const isError = !!this.error;
730
- const answeredCount = this.yesCount + this.noCount + this.naCount;
731
- const unansweredCount = this.totalFields - answeredCount;
732
- return (index.h(index.Host, { key: '4e1b03c99dbe1d333b6144a232dc386b15f6053f', class: {
733
- 'udp-input': true,
734
- 'udp-input--error': isError,
735
- 'udp-input--disabled': this.disabled,
736
- 'udp-input--readonly': this.readonly,
737
- [`udp-input--size-${this.size}`]: true,
738
- [`udp-input--margin-${this.margin}`]: true,
739
- } }, index.h("div", { key: '55d69a511e24a845ae28c3ffb05a6b564f1fbbdf', class: "tally-container" }, this.label && (index.h("unity-typography", { key: '30439676a573ad086d2280974106be9f683bc808', variant: "caption-text" }, index.h("label", { key: '7e39f59eb0fcdd5e0f35f0de36b80bae4d199e8c', htmlFor: this.id, class: "tally-label" }, this.label))), index.h("div", { key: '40ecef47645a053be156a17c50f0ed4a3e2c2d2e', class: "tally-content", id: this.id }, index.h("div", { key: '34808d7cd994a1888bd0b825fae1634ad730ebb8', class: "tally-stats" }, index.h("div", { key: '0e49084939f51ff2dd72221d0f89987b80bc5399', class: "tally-item tally-yes" }, index.h("unity-typography", { key: '81bb681a92294513faf31275cd4e569ffa8a15fa', variant: "h4", class: "tally-count" }, this.yesCount), index.h("unity-typography", { key: '9440146b8adcc4cf9da3c2e3eea229703e0284dc', variant: "caption-text", class: "tally-label" }, "Yes")), index.h("div", { key: '453033c26001d2683181a91e0ebec682ad5d4d38', class: "tally-item tally-no" }, index.h("unity-typography", { key: 'c840b3783bdc163242f4e18c784e0b489fd4c301', variant: "h4", class: "tally-count" }, this.noCount), index.h("unity-typography", { key: '0af346f74b0e574e99efa717f111b18375bd15dd', variant: "caption-text", class: "tally-label" }, "No")), index.h("div", { key: '8a9355d09c683110350f62dd24af0aa404b23c87', class: "tally-item tally-na" }, index.h("unity-typography", { key: '9bb906130f240bf423c6c4920c75b8f9890647b1', variant: "h4", class: "tally-count" }, this.naCount), index.h("unity-typography", { key: '7c51faeeb2c29a7c2e936efaec66677ab50d67b0', variant: "caption-text", class: "tally-label" }, "Not Applicable")), unansweredCount > 0 && (index.h("div", { key: '225d3f0d49da9f15eeae6c3829d7105d0d80c560', class: "tally-item tally-unanswered" }, index.h("unity-typography", { key: 'f167b42959297823e1ffa199be60b558a520d922', variant: "h4", class: "tally-count" }, unansweredCount), index.h("unity-typography", { key: 'de96f235c61bbdd1eb4a4a102a2c80513c543dba', variant: "caption-text", class: "tally-label" }, "Unanswered")))), index.h("div", { key: 'f2abf82180e67933ed34e1d102581c036c7d2614', class: "tally-summary" }, index.h("unity-typography", { key: '7becceb75df4182f6d477b2aa14e8e5464e4534e', variant: "caption-text" }, "Total Questions: ", this.totalFields))), isError && (index.h("div", { key: '56f57a775f1cde86c97e55d1bd4eeb7c2b0b0db7', class: "error-message" }, index.h("unity-typography", { key: 'ef3370bdd1d122fdc9df92fcd990e064989da81e', variant: "caption-text", color: "error" }, this.error))))));
740
- }
741
- };
742
- TallyDisplay.style = tallyCss();
743
-
744
686
  exports.base_map = BaseMap;
745
687
  exports.selectable_list = SelectableList;
746
688
  exports.stencil_field = StencilField;
747
- exports.tally_display = TallyDisplay;
@@ -1940,6 +1940,23 @@ function getDriveFileId(file) {
1940
1940
  const id = file.driveFileId;
1941
1941
  return typeof id === 'string' && id.length > 0 ? id : null;
1942
1942
  }
1943
+ /**
1944
+ * Tag a legacy (pre-v2, non-JSON) Location wire value onto a decoded value so
1945
+ * an unedited re-save can round-trip it byte-for-byte — same trick as
1946
+ * `driveFileId` above, an extra runtime-only property rather than a field on
1947
+ * the component's public `FluentLocationValue` type. Cleared automatically
1948
+ * the moment the user picks a new location, since `udp-fluent-location-input`
1949
+ * always emits a fresh plain object with only the canonical value keys.
1950
+ */
1951
+ function tagLegacyLocationToken(value, token) {
1952
+ value.legacyValueToken = token;
1953
+ return value;
1954
+ }
1955
+ /** Reads the tag set by `tagLegacyLocationToken`. */
1956
+ function getLegacyLocationToken(value) {
1957
+ const token = value === null || value === void 0 ? void 0 : value.legacyValueToken;
1958
+ return typeof token === 'string' && token.length > 0 ? token : null;
1959
+ }
1943
1960
  exports.SubmissionStatus = void 0;
1944
1961
  (function (SubmissionStatus) {
1945
1962
  SubmissionStatus[SubmissionStatus["InProgress"] = 1] = "InProgress";
@@ -1991,48 +2008,64 @@ const multiSelectCodec = {
1991
2008
  },
1992
2009
  encode: value => (value == null || value.length === 0 ? '' : value.join(',')),
1993
2010
  };
2011
+ function buildAddressDetailFromFlat(flat) {
2012
+ var _a, _b, _c, _d, _e, _f, _g;
2013
+ const freeform = (_a = flat.address) !== null && _a !== void 0 ? _a : '';
2014
+ const hasAddress = freeform.length > 0 ||
2015
+ flat.streetNumber != null ||
2016
+ flat.streetName != null ||
2017
+ flat.municipality != null ||
2018
+ flat.countrySubdivisionName != null ||
2019
+ flat.postalCode != null ||
2020
+ flat.country != null;
2021
+ if (!hasAddress)
2022
+ return null;
2023
+ return {
2024
+ freeformAddress: freeform,
2025
+ streetNumber: (_b = flat.streetNumber) !== null && _b !== void 0 ? _b : undefined,
2026
+ streetName: (_c = flat.streetName) !== null && _c !== void 0 ? _c : undefined,
2027
+ municipality: (_d = flat.municipality) !== null && _d !== void 0 ? _d : undefined,
2028
+ countrySubdivisionName: (_e = flat.countrySubdivisionName) !== null && _e !== void 0 ? _e : undefined,
2029
+ postalCode: (_f = flat.postalCode) !== null && _f !== void 0 ? _f : undefined,
2030
+ country: (_g = flat.country) !== null && _g !== void 0 ? _g : undefined,
2031
+ };
2032
+ }
1994
2033
  const locationCodec = {
1995
2034
  decode: wire => {
1996
- var _a, _b, _c, _d;
2035
+ var _a, _b, _c;
1997
2036
  if (wire == null || wire === '')
1998
2037
  return null;
1999
2038
  let parsed;
2000
2039
  try {
2001
2040
  parsed = JSON.parse(wire);
2002
2041
  }
2003
- catch (_e) {
2004
- return null;
2042
+ catch (_d) {
2043
+ // Not v2 JSON — a v1 map-screenshot file token. Tag it so `encode` can
2044
+ // round-trip it byte-for-byte if the user never edits this field;
2045
+ // `hydrateValueWithMetadata()` fills in real lat/lng/address from
2046
+ // `metadata.location`.
2047
+ const shell = {
2048
+ latitude: null,
2049
+ longitude: null,
2050
+ address: null,
2051
+ timestamp: null,
2052
+ };
2053
+ return tagLegacyLocationToken(shell, wire);
2005
2054
  }
2006
- const freeform = (_a = parsed.address) !== null && _a !== void 0 ? _a : '';
2007
- const hasAddress = freeform.length > 0 ||
2008
- parsed.streetNumber != null ||
2009
- parsed.streetName != null ||
2010
- parsed.municipality != null ||
2011
- parsed.countrySubdivisionName != null ||
2012
- parsed.postalCode != null ||
2013
- parsed.country != null;
2014
- const address = hasAddress
2015
- ? {
2016
- freeformAddress: freeform,
2017
- streetNumber: parsed.streetNumber,
2018
- streetName: parsed.streetName,
2019
- municipality: parsed.municipality,
2020
- countrySubdivisionName: parsed.countrySubdivisionName,
2021
- postalCode: parsed.postalCode,
2022
- country: parsed.country,
2023
- }
2024
- : null;
2025
2055
  return {
2026
- latitude: (_b = parsed.latitude) !== null && _b !== void 0 ? _b : null,
2027
- longitude: (_c = parsed.longitude) !== null && _c !== void 0 ? _c : null,
2028
- address,
2029
- timestamp: (_d = parsed.timestamp) !== null && _d !== void 0 ? _d : null,
2056
+ latitude: (_a = parsed.latitude) !== null && _a !== void 0 ? _a : null,
2057
+ longitude: (_b = parsed.longitude) !== null && _b !== void 0 ? _b : null,
2058
+ address: buildAddressDetailFromFlat(parsed),
2059
+ timestamp: (_c = parsed.timestamp) !== null && _c !== void 0 ? _c : null,
2030
2060
  };
2031
2061
  },
2032
2062
  encode: value => {
2033
2063
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
2034
2064
  if (value == null)
2035
2065
  return '';
2066
+ const legacyToken = getLegacyLocationToken(value);
2067
+ if (legacyToken != null)
2068
+ return legacyToken;
2036
2069
  if (value.latitude == null && value.longitude == null && !value.address)
2037
2070
  return '';
2038
2071
  const wire = {
@@ -2283,31 +2316,55 @@ function isPassOneFieldType(fieldTypeId) {
2283
2316
  }
2284
2317
  /**
2285
2318
  * Merge metadata-sidecar fields onto the decoded value for types where the
2286
- * "value" string alone isn't the full user-visible state. Today only
2287
- * `Signature` needs this — `metadata.signature` carries `fullName` and the
2288
- * lat/lng/timestamp captured at stroke-end. Returns the value untouched for
2289
- * every other type.
2319
+ * "value" string alone isn't the full user-visible state:
2320
+ * - `Signature` — `metadata.signature` carries `fullName` and the
2321
+ * lat/lng/timestamp captured at stroke-end.
2322
+ * - `Location` — a legacy (v1) answer's real lat/lng/address live in
2323
+ * `metadata.location`, not `.value` (see `locationCodec`'s doc comment).
2324
+ * Returns the value untouched for every other type.
2290
2325
  */
2291
2326
  function hydrateValueWithMetadata(fieldTypeId, decoded, metadata) {
2292
- var _a, _b, _c, _d, _e, _f, _g, _h;
2293
- if (fieldTypeId !== types.FieldTypeId.Signature)
2327
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
2328
+ if (fieldTypeId === types.FieldTypeId.Signature) {
2329
+ const sig = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.signature) !== null && _a !== void 0 ? _a : null;
2330
+ const baseValue = (decoded !== null && decoded !== void 0 ? decoded : null);
2331
+ if (!sig && !baseValue)
2332
+ return null;
2333
+ const next = {
2334
+ file: (_b = baseValue === null || baseValue === void 0 ? void 0 : baseValue.file) !== null && _b !== void 0 ? _b : null,
2335
+ fullName: (_d = (_c = sig === null || sig === void 0 ? void 0 : sig.fullName) !== null && _c !== void 0 ? _c : baseValue === null || baseValue === void 0 ? void 0 : baseValue.fullName) !== null && _d !== void 0 ? _d : null,
2336
+ metadata: sig != null
2337
+ ? {
2338
+ timestamp: (_e = sig.timestamp) !== null && _e !== void 0 ? _e : null,
2339
+ latitude: (_f = sig.latitude) !== null && _f !== void 0 ? _f : null,
2340
+ longitude: (_g = sig.longitude) !== null && _g !== void 0 ? _g : null,
2341
+ }
2342
+ : (_h = baseValue === null || baseValue === void 0 ? void 0 : baseValue.metadata) !== null && _h !== void 0 ? _h : null,
2343
+ };
2344
+ return next;
2345
+ }
2346
+ if (fieldTypeId === types.FieldTypeId.Location) {
2347
+ return hydrateLocationWithMetadata(decoded, (_j = metadata === null || metadata === void 0 ? void 0 : metadata.location) !== null && _j !== void 0 ? _j : null);
2348
+ }
2349
+ return decoded;
2350
+ }
2351
+ function hydrateLocationWithMetadata(decoded, loc) {
2352
+ var _a, _b, _c;
2353
+ // A genuine v2-native decode already has real coordinates/address —
2354
+ // `metadata.location` in that case is legacy server-side noise, ignore it.
2355
+ if (decoded && (decoded.latitude != null || decoded.longitude != null || decoded.address != null)) {
2294
2356
  return decoded;
2295
- const sig = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.signature) !== null && _a !== void 0 ? _a : null;
2296
- const baseValue = (decoded !== null && decoded !== void 0 ? decoded : null);
2297
- if (!sig && !baseValue)
2298
- return null;
2299
- const next = {
2300
- file: (_b = baseValue === null || baseValue === void 0 ? void 0 : baseValue.file) !== null && _b !== void 0 ? _b : null,
2301
- fullName: (_d = (_c = sig === null || sig === void 0 ? void 0 : sig.fullName) !== null && _c !== void 0 ? _c : baseValue === null || baseValue === void 0 ? void 0 : baseValue.fullName) !== null && _d !== void 0 ? _d : null,
2302
- metadata: sig != null
2303
- ? {
2304
- timestamp: (_e = sig.timestamp) !== null && _e !== void 0 ? _e : null,
2305
- latitude: (_f = sig.latitude) !== null && _f !== void 0 ? _f : null,
2306
- longitude: (_g = sig.longitude) !== null && _g !== void 0 ? _g : null,
2307
- }
2308
- : (_h = baseValue === null || baseValue === void 0 ? void 0 : baseValue.metadata) !== null && _h !== void 0 ? _h : null,
2357
+ }
2358
+ if (!loc)
2359
+ return decoded;
2360
+ const merged = {
2361
+ latitude: (_a = loc.latitude) !== null && _a !== void 0 ? _a : null,
2362
+ longitude: (_b = loc.longitude) !== null && _b !== void 0 ? _b : null,
2363
+ address: buildAddressDetailFromFlat(loc),
2364
+ timestamp: (_c = loc.timestamp) !== null && _c !== void 0 ? _c : null,
2309
2365
  };
2310
- return next;
2366
+ const legacyToken = getLegacyLocationToken(decoded);
2367
+ return legacyToken != null ? tagLegacyLocationToken(merged, legacyToken) : merged;
2311
2368
  }
2312
2369
  /**
2313
2370
  * Walk a per-question-instance iterator and the values map to collect every
@@ -2374,29 +2431,65 @@ function extractFilesFromValues(loadedForm, values) {
2374
2431
  /**
2375
2432
  * Produce the metadata blob to write into the envelope for a given question.
2376
2433
  * For `Signature`, derives `metadata.signature` from the decoded value
2377
- * (fullName + lat/lng/timestamp); for every other type, passes through the
2378
- * existing metadata untouched. Returns `undefined` when nothing should be
2379
- * written.
2434
+ * (fullName + lat/lng/timestamp). For `Location`, derives `metadata.location`
2435
+ * so the legacy (v1) renderer can still hydrate its map/address on load — see
2436
+ * `locationCodec`'s doc comment — while leaving an unedited legacy answer's
2437
+ * metadata byte-identical. For every other type, passes through the existing
2438
+ * metadata untouched. Returns `undefined` when nothing should be written.
2380
2439
  */
2381
2440
  function buildResponseMetadata(fieldTypeId, decodedValue, existingMetadata) {
2382
2441
  var _a, _b, _c, _d, _e;
2383
- if (fieldTypeId !== types.FieldTypeId.Signature)
2384
- return existingMetadata;
2385
- const sv = decodedValue;
2386
- const hasFile = (sv === null || sv === void 0 ? void 0 : sv.file) instanceof File;
2387
- const fullName = (_a = sv === null || sv === void 0 ? void 0 : sv.fullName) !== null && _a !== void 0 ? _a : null;
2388
- const meta = (_b = sv === null || sv === void 0 ? void 0 : sv.metadata) !== null && _b !== void 0 ? _b : null;
2389
- const hasAny = hasFile || (fullName != null && fullName !== '') || meta != null;
2390
- if (!hasAny)
2442
+ if (fieldTypeId === types.FieldTypeId.Signature) {
2443
+ const sv = decodedValue;
2444
+ const hasFile = (sv === null || sv === void 0 ? void 0 : sv.file) instanceof File;
2445
+ const fullName = (_a = sv === null || sv === void 0 ? void 0 : sv.fullName) !== null && _a !== void 0 ? _a : null;
2446
+ const meta = (_b = sv === null || sv === void 0 ? void 0 : sv.metadata) !== null && _b !== void 0 ? _b : null;
2447
+ const hasAny = hasFile || (fullName != null && fullName !== '') || meta != null;
2448
+ if (!hasAny)
2449
+ return existingMetadata;
2450
+ const base = existingMetadata != null && typeof existingMetadata === 'object'
2451
+ ? existingMetadata
2452
+ : {};
2453
+ return Object.assign(Object.assign({}, base), { signature: {
2454
+ latitude: (_c = meta === null || meta === void 0 ? void 0 : meta.latitude) !== null && _c !== void 0 ? _c : null,
2455
+ longitude: (_d = meta === null || meta === void 0 ? void 0 : meta.longitude) !== null && _d !== void 0 ? _d : null,
2456
+ timestamp: (_e = meta === null || meta === void 0 ? void 0 : meta.timestamp) !== null && _e !== void 0 ? _e : null,
2457
+ fullName,
2458
+ } });
2459
+ }
2460
+ if (fieldTypeId === types.FieldTypeId.Location) {
2461
+ return buildLocationResponseMetadata(decodedValue, existingMetadata);
2462
+ }
2463
+ return existingMetadata;
2464
+ }
2465
+ function buildLocationResponseMetadata(value, existingMetadata) {
2466
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
2467
+ // Untouched legacy answer — leave metadata exactly as loaded so re-saving
2468
+ // an unedited v1-captured Location doesn't disturb its stored data.
2469
+ if (getLegacyLocationToken(value) != null)
2391
2470
  return existingMetadata;
2392
2471
  const base = existingMetadata != null && typeof existingMetadata === 'object'
2393
2472
  ? existingMetadata
2394
2473
  : {};
2395
- return Object.assign(Object.assign({}, base), { signature: {
2396
- latitude: (_c = meta === null || meta === void 0 ? void 0 : meta.latitude) !== null && _c !== void 0 ? _c : null,
2397
- longitude: (_d = meta === null || meta === void 0 ? void 0 : meta.longitude) !== null && _d !== void 0 ? _d : null,
2398
- timestamp: (_e = meta === null || meta === void 0 ? void 0 : meta.timestamp) !== null && _e !== void 0 ? _e : null,
2399
- fullName,
2474
+ const hasData = value != null && (value.latitude != null || value.longitude != null || value.address != null);
2475
+ if (!hasData) {
2476
+ // Nothing to clear if there was never a location recorded — don't
2477
+ // fabricate a metadata object where none existed.
2478
+ if (base.location == null)
2479
+ return existingMetadata;
2480
+ return Object.assign(Object.assign({}, base), { location: null });
2481
+ }
2482
+ return Object.assign(Object.assign({}, base), { location: {
2483
+ latitude: (_a = value.latitude) !== null && _a !== void 0 ? _a : null,
2484
+ longitude: (_b = value.longitude) !== null && _b !== void 0 ? _b : null,
2485
+ timestamp: (_c = value.timestamp) !== null && _c !== void 0 ? _c : null,
2486
+ address: (_e = (_d = value.address) === null || _d === void 0 ? void 0 : _d.freeformAddress) !== null && _e !== void 0 ? _e : null,
2487
+ streetNumber: (_g = (_f = value.address) === null || _f === void 0 ? void 0 : _f.streetNumber) !== null && _g !== void 0 ? _g : null,
2488
+ streetName: (_j = (_h = value.address) === null || _h === void 0 ? void 0 : _h.streetName) !== null && _j !== void 0 ? _j : null,
2489
+ municipality: (_l = (_k = value.address) === null || _k === void 0 ? void 0 : _k.municipality) !== null && _l !== void 0 ? _l : null,
2490
+ countrySubdivisionName: (_o = (_m = value.address) === null || _m === void 0 ? void 0 : _m.countrySubdivisionName) !== null && _o !== void 0 ? _o : null,
2491
+ country: (_q = (_p = value.address) === null || _p === void 0 ? void 0 : _p.country) !== null && _q !== void 0 ? _q : null,
2492
+ postalCode: (_s = (_r = value.address) === null || _r === void 0 ? void 0 : _r.postalCode) !== null && _s !== void 0 ? _s : null,
2400
2493
  } });
2401
2494
  }
2402
2495
 
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-CZB9dMeB.js');
4
+ var utils = require('./utils-Bp02BX38.js');
5
+
6
+ const formMetadataDisplayCss = () => `:host{display:block}.container{display:grid;gap:10px;padding:12px 14px;background:var(--unity-color-surface, #fff)}.row{display:grid;grid-template-columns:130px 1fr;align-items:baseline;column-gap:12px}.label{font-size:12px;line-height:1.2;letter-spacing:0.02em;text-transform:uppercase;color:var(--unity-color-text-secondary, rgba(0, 0, 0, 0.65))}.value{color:var(--unity-color-text, rgba(0, 0, 0, 0.9));overflow-wrap:anywhere}@media (max-width: 420px){.row{grid-template-columns:1fr;row-gap:4px}}`;
7
+
8
+ const FormMetadataDisplay = class {
9
+ constructor(hostRef) {
10
+ index.registerInstance(this, hostRef);
11
+ /**
12
+ * Toggles rendering of the "Name" row.
13
+ * Defaults to true.
14
+ */
15
+ this.displayOwnerFullName = true;
16
+ /**
17
+ * Toggles rendering of the "Email" row.
18
+ * Defaults to true.
19
+ */
20
+ this.displayOwnerEmail = true;
21
+ /**
22
+ * Toggles rendering of the "Submitted on" row.
23
+ * Defaults to true.
24
+ */
25
+ this.displaySubmissionDate = true;
26
+ }
27
+ /**
28
+ * Renders a single metadata row using a standard label/value layout.
29
+ * @internal
30
+ */
31
+ renderRow(label, value) {
32
+ return (index.h("div", { class: "row" }, index.h("span", { class: "label" }, label), index.h("unity-typography", { class: "value", variant: "h4" }, value)));
33
+ }
34
+ /**
35
+ * Renders the metadata container. Rows are conditionally included based on flags + data presence.
36
+ * @internal
37
+ */
38
+ render() {
39
+ return (
40
+ // role/aria-label provide a lightweight accessible grouping for screen readers
41
+ index.h("div", { key: 'e76c4a74661c13b2962c090efec64c8d0b1134cc', class: "container", role: "group", "aria-label": "Form metadata" }, this.displayOwnerFullName && this.userDisplayName && this.renderRow('Name', this.userDisplayName), this.displayOwnerEmail && this.userEmail && this.renderRow('Email', this.userEmail), this.displaySubmissionDate && this.submittedOn && this.renderRow('Submitted on', utils.dateFormatter(this.submittedOn, 'long'))));
42
+ }
43
+ };
44
+ FormMetadataDisplay.style = formMetadataDisplayCss();
45
+
46
+ const tallyCss = () => `:host{display:block;width:100%}.tally-container{display:flex;flex-direction:column;gap:var(--spacing-02, 8px)}.tally-label{font-weight:600;margin-bottom:var(--spacing-02, 8px)}.tally-loading{display:flex;align-items:center;justify-content:center;padding:var(--spacing-04, 16px);color:var(--text-secondary, #6b7280)}.tally-content{display:flex;flex-direction:column;gap:var(--spacing-03, 12px)}.tally-stats{display:flex;gap:var(--spacing-04, 16px);flex-wrap:wrap}.tally-item{display:flex;flex-direction:column;align-items:center;padding:var(--spacing-03, 12px) var(--spacing-04, 16px);border-radius:var(--border-radius-01, 4px);border:1px solid var(--border-subtle, #e5e7eb);background-color:var(--layer-01, #ffffff);min-width:80px;flex:1;max-width:120px}.tally-item.tally-yes{border-color:var(--support-success, #42be65);background-color:var(--support-success-hover, #f6f8ff)}.tally-item.tally-no{border-color:var(--support-error, #da1e28);background-color:var(--support-error-hover, #fff1f1)}.tally-item.tally-unanswered{border-color:var(--support-warning, #f1c21b);background-color:var(--support-warning-hover, #fcf4d6)}.tally-count{font-weight:700;line-height:1.2;margin-bottom:var(--spacing-01, 4px)}.tally-yes .tally-count{color:var(--support-success, #42be65)}.tally-no .tally-count{color:var(--support-error, #da1e28)}.tally-unanswered .tally-count{color:var(--support-warning, #f1c21b)}.tally-item .tally-label{margin:0;font-weight:500;text-transform:uppercase;font-size:0.75rem;letter-spacing:0.02em}.tally-summary{padding:var(--spacing-02, 8px) 0;border-top:1px solid var(--border-subtle, #e5e7eb);text-align:center}.error-message{margin-top:var(--spacing-02, 8px);padding:var(--spacing-02, 8px);border-radius:var(--border-radius-01, 4px);background-color:var(--support-error-hover, #fff1f1);border:1px solid var(--support-error, #da1e28)}:host(.udp-input--size-small) .tally-item{padding:var(--spacing-02, 8px) var(--spacing-03, 12px);min-width:60px;max-width:90px}:host(.udp-input--size-small) .tally-count{font-size:1.25rem}:host(.udp-input--size-large) .tally-item{padding:var(--spacing-04, 16px) var(--spacing-05, 20px);min-width:100px;max-width:150px}:host(.udp-input--size-large) .tally-count{font-size:2rem}:host(.udp-input--margin-none) .tally-container{gap:0}:host(.udp-input--margin-dense) .tally-container{gap:var(--spacing-01, 4px)}:host(.udp-input--margin-comfortable) .tally-container{gap:var(--spacing-04, 16px)}:host(.udp-input--disabled) .tally-item{opacity:0.5;pointer-events:none}:host(.udp-input--readonly) .tally-item{background-color:var(--field-01, #f4f4f4)}@media (max-width: 480px){.tally-stats{flex-direction:column}.tally-item{max-width:none;flex:none}}`;
47
+
48
+ const TallyDisplay = class {
49
+ constructor(hostRef) {
50
+ index.registerInstance(this, hostRef);
51
+ /**
52
+ * Label for the tally display.
53
+ */
54
+ this.label = 'Response Tally';
55
+ /**
56
+ * Number of Yes responses.
57
+ */
58
+ this.yesCount = 0;
59
+ /**
60
+ * Number of No responses.
61
+ */
62
+ this.noCount = 0;
63
+ /**
64
+ * Number of Not Applicable responses.
65
+ */
66
+ this.naCount = 0;
67
+ /**
68
+ * Total number of fields being tallied.
69
+ */
70
+ this.totalFields = 0;
71
+ /**
72
+ * Whether the component is disabled.
73
+ */
74
+ this.disabled = false;
75
+ /**
76
+ * Whether the component is read-only.
77
+ */
78
+ this.readonly = false;
79
+ /**
80
+ * Size variant for the tally display.
81
+ */
82
+ this.size = 'normal';
83
+ /**
84
+ * Margin variant for the component spacing.
85
+ */
86
+ this.margin = 'normal';
87
+ }
88
+ render() {
89
+ const isError = !!this.error;
90
+ const answeredCount = this.yesCount + this.noCount + this.naCount;
91
+ const unansweredCount = this.totalFields - answeredCount;
92
+ return (index.h(index.Host, { key: '4e1b03c99dbe1d333b6144a232dc386b15f6053f', class: {
93
+ 'udp-input': true,
94
+ 'udp-input--error': isError,
95
+ 'udp-input--disabled': this.disabled,
96
+ 'udp-input--readonly': this.readonly,
97
+ [`udp-input--size-${this.size}`]: true,
98
+ [`udp-input--margin-${this.margin}`]: true,
99
+ } }, index.h("div", { key: '55d69a511e24a845ae28c3ffb05a6b564f1fbbdf', class: "tally-container" }, this.label && (index.h("unity-typography", { key: '30439676a573ad086d2280974106be9f683bc808', variant: "caption-text" }, index.h("label", { key: '7e39f59eb0fcdd5e0f35f0de36b80bae4d199e8c', htmlFor: this.id, class: "tally-label" }, this.label))), index.h("div", { key: '40ecef47645a053be156a17c50f0ed4a3e2c2d2e', class: "tally-content", id: this.id }, index.h("div", { key: '34808d7cd994a1888bd0b825fae1634ad730ebb8', class: "tally-stats" }, index.h("div", { key: '0e49084939f51ff2dd72221d0f89987b80bc5399', class: "tally-item tally-yes" }, index.h("unity-typography", { key: '81bb681a92294513faf31275cd4e569ffa8a15fa', variant: "h4", class: "tally-count" }, this.yesCount), index.h("unity-typography", { key: '9440146b8adcc4cf9da3c2e3eea229703e0284dc', variant: "caption-text", class: "tally-label" }, "Yes")), index.h("div", { key: '453033c26001d2683181a91e0ebec682ad5d4d38', class: "tally-item tally-no" }, index.h("unity-typography", { key: 'c840b3783bdc163242f4e18c784e0b489fd4c301', variant: "h4", class: "tally-count" }, this.noCount), index.h("unity-typography", { key: '0af346f74b0e574e99efa717f111b18375bd15dd', variant: "caption-text", class: "tally-label" }, "No")), index.h("div", { key: '8a9355d09c683110350f62dd24af0aa404b23c87', class: "tally-item tally-na" }, index.h("unity-typography", { key: '9bb906130f240bf423c6c4920c75b8f9890647b1', variant: "h4", class: "tally-count" }, this.naCount), index.h("unity-typography", { key: '7c51faeeb2c29a7c2e936efaec66677ab50d67b0', variant: "caption-text", class: "tally-label" }, "Not Applicable")), unansweredCount > 0 && (index.h("div", { key: '225d3f0d49da9f15eeae6c3829d7105d0d80c560', class: "tally-item tally-unanswered" }, index.h("unity-typography", { key: 'f167b42959297823e1ffa199be60b558a520d922', variant: "h4", class: "tally-count" }, unansweredCount), index.h("unity-typography", { key: 'de96f235c61bbdd1eb4a4a102a2c80513c543dba', variant: "caption-text", class: "tally-label" }, "Unanswered")))), index.h("div", { key: 'f2abf82180e67933ed34e1d102581c036c7d2614', class: "tally-summary" }, index.h("unity-typography", { key: '7becceb75df4182f6d477b2aa14e8e5464e4534e', variant: "caption-text" }, "Total Questions: ", this.totalFields))), isError && (index.h("div", { key: '56f57a775f1cde86c97e55d1bd4eeb7c2b0b0db7', class: "error-message" }, index.h("unity-typography", { key: 'ef3370bdd1d122fdc9df92fcd990e064989da81e', variant: "caption-text", color: "error" }, this.error))))));
100
+ }
101
+ };
102
+ TallyDisplay.style = tallyCss();
103
+
104
+ exports.form_metadata_display = FormMetadataDisplay;
105
+ exports.tally_display = TallyDisplay;