@3t-transform/threeteeui 1.9.102 → 1.9.103

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 (440) hide show
  1. package/dist/cjs/{auto-be8ad100.js → auto-356ad09b.js} +177 -177
  2. package/dist/cjs/{domsanitiser.options-55ce2d65.js → domsanitiser.options-065dbed8.js} +12 -12
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/{tttx-action-dropdown_localcomponent.cjs.entry.js → tttx-action-dropdown_1_9_103.cjs.entry.js} +51 -51
  5. package/dist/cjs/{tttx-button-v2_localcomponent.cjs.entry.js → tttx-button-v2_1_9_103.cjs.entry.js} +147 -147
  6. package/dist/cjs/{tttx-button_localcomponent.cjs.entry.js → tttx-button_1_9_103.cjs.entry.js} +26 -26
  7. package/dist/cjs/{tttx-chart_localcomponent.cjs.entry.js → tttx-chart_1_9_103.cjs.entry.js} +524 -524
  8. package/dist/cjs/{tttx-checkbox-group-caption_localcomponent.cjs.entry.js → tttx-checkbox-group-caption_1_9_103.cjs.entry.js} +9 -9
  9. package/dist/cjs/{tttx-checkbox-group-heading_localcomponent.cjs.entry.js → tttx-checkbox-group-heading_1_9_103.cjs.entry.js} +9 -9
  10. package/dist/cjs/{tttx-checkbox-group_localcomponent.cjs.entry.js → tttx-checkbox-group_1_9_103.cjs.entry.js} +9 -9
  11. package/dist/cjs/{tttx-checkbox_localcomponent.cjs.entry.js → tttx-checkbox_1_9_103.cjs.entry.js} +33 -33
  12. package/dist/cjs/{tttx-comments_localcomponent.cjs.entry.js → tttx-comments_1_9_103.cjs.entry.js} +204 -204
  13. package/dist/cjs/tttx-data-pattern_1_9_103.cjs.entry.js +30 -0
  14. package/dist/cjs/{tttx-datacard_localcomponent.cjs.entry.js → tttx-datacard_1_9_103.cjs.entry.js} +43 -43
  15. package/dist/cjs/tttx-date-range-picker.cjs.entry.js +212 -212
  16. package/dist/cjs/{tttx-dialog-box_localcomponent.cjs.entry.js → tttx-dialog-box_1_9_103.cjs.entry.js} +94 -94
  17. package/dist/cjs/{tttx-dialog_localcomponent.cjs.entry.js → tttx-dialog_1_9_103.cjs.entry.js} +69 -69
  18. package/dist/cjs/{tttx-expander_localcomponent.cjs.entry.js → tttx-expander_1_9_103.cjs.entry.js} +28 -28
  19. package/dist/cjs/{tttx-filter_localcomponent_4.cjs.entry.js → tttx-filter_1_9_103_4.cjs.entry.js} +386 -386
  20. package/dist/cjs/{tttx-form_localcomponent.cjs.entry.js → tttx-form_1_9_103.cjs.entry.js} +985 -985
  21. package/dist/cjs/{tttx-graph_localcomponent.cjs.entry.js → tttx-graph_1_9_103.cjs.entry.js} +124 -124
  22. package/dist/cjs/{tttx-icon_localcomponent.cjs.entry.js → tttx-icon_1_9_103.cjs.entry.js} +24 -24
  23. package/dist/cjs/{tttx-keyvalue-block_localcomponent.cjs.entry.js → tttx-keyvalue-block_1_9_103.cjs.entry.js} +62 -62
  24. package/dist/cjs/{tttx-loading-spinner_localcomponent_3.cjs.entry.js → tttx-loading-spinner_1_9_103_3.cjs.entry.js} +172 -172
  25. package/dist/cjs/{tttx-multiselect-box_localcomponent.cjs.entry.js → tttx-multiselect-box_1_9_103.cjs.entry.js} +175 -175
  26. package/dist/cjs/{tttx-percentage-bar_localcomponent.cjs.entry.js → tttx-percentage-bar_1_9_103.cjs.entry.js} +56 -56
  27. package/dist/cjs/{tttx-qrcode_localcomponent.cjs.entry.js → tttx-qrcode_1_9_103.cjs.entry.js} +28 -28
  28. package/dist/cjs/{tttx-range-slider_localcomponent.cjs.entry.js → tttx-range-slider_1_9_103.cjs.entry.js} +185 -185
  29. package/dist/cjs/{tttx-select-box_localcomponent.cjs.entry.js → tttx-select-box_1_9_103.cjs.entry.js} +239 -239
  30. package/dist/cjs/{tttx-skeleton_loader_localcomponent.cjs.entry.js → tttx-skeleton_loader_1_9_103.cjs.entry.js} +30 -30
  31. package/dist/cjs/{tttx-table_localcomponent.cjs.entry.js → tttx-table_1_9_103.cjs.entry.js} +72 -72
  32. package/dist/cjs/{tttx-tabs_localcomponent.cjs.entry.js → tttx-tabs_1_9_103.cjs.entry.js} +103 -103
  33. package/dist/cjs/{tttx-tag-v2_localcomponent.cjs.entry.js → tttx-tag-v2_1_9_103.cjs.entry.js} +72 -72
  34. package/dist/cjs/{tttx-textarea_localcomponent.cjs.entry.js → tttx-textarea_1_9_103.cjs.entry.js} +50 -50
  35. package/dist/cjs/{tttx-toggle_localcomponent.cjs.entry.js → tttx-toggle_1_9_103.cjs.entry.js} +30 -30
  36. package/dist/cjs/{tttx-tooltip_localcomponent.cjs.entry.js → tttx-tooltip_1_9_103.cjs.entry.js} +87 -87
  37. package/dist/cjs/{tttx-tree-view_localcomponent.cjs.entry.js → tttx-tree-view_1_9_103.cjs.entry.js} +341 -341
  38. package/dist/cjs/tttx.cjs.js +1 -1
  39. package/dist/collection/components/atoms/tttx-button/tttx-button.js +129 -129
  40. package/dist/collection/components/atoms/tttx-button/tttx-button.stories.js +40 -40
  41. package/dist/collection/components/atoms/tttx-button-v2/tttx-button-v2.css +1 -1
  42. package/dist/collection/components/atoms/tttx-button-v2/tttx-button-v2.js +436 -436
  43. package/dist/collection/components/atoms/tttx-button-v2/tttx-button-v2.stories.js +143 -143
  44. package/dist/collection/components/atoms/tttx-checkbox/tttx-checkbox.js +154 -154
  45. package/dist/collection/components/atoms/tttx-checkbox/tttx-checkbox.stories.js +58 -58
  46. package/dist/collection/components/atoms/tttx-datacard/tttx-datacard.js +186 -186
  47. package/dist/collection/components/atoms/tttx-datacard/tttx-datacard.stories.js +92 -92
  48. package/dist/collection/components/atoms/tttx-icon/tttx-icon.js +92 -92
  49. package/dist/collection/components/atoms/tttx-icon/tttx-icon.stories.js +26 -26
  50. package/dist/collection/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.js +137 -137
  51. package/dist/collection/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.stories.js +94 -94
  52. package/dist/collection/components/atoms/tttx-loading-spinner/tttx-loading-spinner.js +194 -194
  53. package/dist/collection/components/atoms/tttx-loading-spinner/tttx-loading-spinner.stories.js +53 -53
  54. package/dist/collection/components/atoms/tttx-percentage-bar/tttx-percentage-bar.js +168 -168
  55. package/dist/collection/components/atoms/tttx-percentage-bar/tttx-percentage-bar.stories.js +52 -52
  56. package/dist/collection/components/atoms/tttx-qrcode/tttx-qrcode.js +81 -81
  57. package/dist/collection/components/atoms/tttx-qrcode/tttx-qrcode.stories.js +22 -22
  58. package/dist/collection/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.js +225 -225
  59. package/dist/collection/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.stories.js +44 -44
  60. package/dist/collection/components/atoms/tttx-tag/tttx-tag.js +157 -157
  61. package/dist/collection/components/atoms/tttx-tag/tttx-tag.stories.js +53 -53
  62. package/dist/collection/components/atoms/tttx-tag-v2/tttx-tag-v2.js +281 -281
  63. package/dist/collection/components/atoms/tttx-tag-v2/tttx-tag-v2.stories.js +84 -84
  64. package/dist/collection/components/atoms/tttx-toggle/tttx-toggle.js +84 -84
  65. package/dist/collection/components/atoms/tttx-toggle/tttx-toggle.stories.js +8 -8
  66. package/dist/collection/components/domsanitiser.options.js +14 -14
  67. package/dist/collection/components/molecules/tttx-action-dropdown/tttx-action-dropdown.js +213 -213
  68. package/dist/collection/components/molecules/tttx-action-dropdown/tttx-action-dropdown.stories.js +55 -55
  69. package/dist/collection/components/molecules/tttx-chart/tttx-chart.js +793 -793
  70. package/dist/collection/components/molecules/tttx-chart/tttx-chart.stories.js +209 -209
  71. package/dist/collection/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-caption.js +17 -17
  72. package/dist/collection/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-heading.js +17 -17
  73. package/dist/collection/components/molecules/tttx-checkbox-group/tttx-checkbox-group.js +18 -18
  74. package/dist/collection/components/molecules/tttx-checkbox-group/tttx-checkbox-group.stories.js +62 -62
  75. package/dist/collection/components/molecules/tttx-comments/tttx-comments.js +536 -536
  76. package/dist/collection/components/molecules/tttx-comments/tttx-comments.stories.js +151 -151
  77. package/dist/collection/components/molecules/tttx-date-range-picker/tttx-date-range-picker.js +292 -292
  78. package/dist/collection/components/molecules/tttx-date-range-picker/tttx-date-range-picker.stories.js +48 -48
  79. package/dist/collection/components/molecules/tttx-dialog/icon-types.js +6 -6
  80. package/dist/collection/components/molecules/tttx-dialog/tttx-dialog.js +218 -218
  81. package/dist/collection/components/molecules/tttx-dialog/tttx-dialog.stories.js +50 -50
  82. package/dist/collection/components/molecules/tttx-dialog-box/tttx-dialog-box.js +246 -246
  83. package/dist/collection/components/molecules/tttx-dialog-box/tttx-dialog-box.stories.js +314 -314
  84. package/dist/collection/components/molecules/tttx-expander/tttx-expander.js +134 -134
  85. package/dist/collection/components/molecules/tttx-expander/tttx-expander.stories.js +46 -46
  86. package/dist/collection/components/molecules/tttx-filter/tttx-filter.js +416 -416
  87. package/dist/collection/components/molecules/tttx-filter/tttx-filter.stories.js +81 -81
  88. package/dist/collection/components/molecules/tttx-form/lib/setErrorState.js +49 -49
  89. package/dist/collection/components/molecules/tttx-form/lib/timecomparatorChecks.js +64 -64
  90. package/dist/collection/components/molecules/tttx-form/lib/validityCheck.js +76 -76
  91. package/dist/collection/components/molecules/tttx-form/tttx-form.js +1267 -1267
  92. package/dist/collection/components/molecules/tttx-form/tttx-form.stories.js +595 -595
  93. package/dist/collection/components/molecules/tttx-graph/gauge-label-plugin.js +14 -14
  94. package/dist/collection/components/molecules/tttx-graph/tttx-graph.js +184 -184
  95. package/dist/collection/components/molecules/tttx-graph/tttx-graph.stories.js +32 -32
  96. package/dist/collection/components/molecules/tttx-list/tttx-list.js +165 -165
  97. package/dist/collection/components/molecules/tttx-list/tttx-list.stories.js +134 -134
  98. package/dist/collection/components/molecules/tttx-multiselect-box/tttx-multiselect-box.js +499 -499
  99. package/dist/collection/components/molecules/tttx-multiselect-box/tttx-multiselect-box.stories.js +151 -151
  100. package/dist/collection/components/molecules/tttx-range-slider/tttx-range-slider.js +304 -304
  101. package/dist/collection/components/molecules/tttx-range-slider/tttx-range-slider.stories.js +22 -22
  102. package/dist/collection/components/molecules/tttx-select-box/tttx-select-box.js +671 -671
  103. package/dist/collection/components/molecules/tttx-select-box/tttx-select-box.stories.js +140 -140
  104. package/dist/collection/components/molecules/tttx-sorter/tttx-sorter.js +253 -253
  105. package/dist/collection/components/molecules/tttx-sorter/tttx-sorter.stories.js +43 -43
  106. package/dist/collection/components/molecules/tttx-standalone-input/tttx-standalone-input.js +764 -764
  107. package/dist/collection/components/molecules/tttx-standalone-input/tttx-standalone-input.stories.js +191 -191
  108. package/dist/collection/components/molecules/tttx-table/tttx-table.css +1 -1
  109. package/dist/collection/components/molecules/tttx-table/tttx-table.js +318 -318
  110. package/dist/collection/components/molecules/tttx-table/tttx-table.stories.js +191 -191
  111. package/dist/collection/components/molecules/tttx-table/tttx-table.types.js +1 -1
  112. package/dist/collection/components/molecules/tttx-tabs/tttx-tabs.js +253 -253
  113. package/dist/collection/components/molecules/tttx-tabs/tttx-tabs.stories.js +82 -82
  114. package/dist/collection/components/molecules/tttx-textarea/tttx-textarea.js +420 -420
  115. package/dist/collection/components/molecules/tttx-textarea/tttx-textarea.stories.js +81 -81
  116. package/dist/collection/components/molecules/tttx-toolbar/tttx-toolbar.js +73 -73
  117. package/dist/collection/components/molecules/tttx-toolbar/tttx-toolbar.stories.js +97 -97
  118. package/dist/collection/components/molecules/tttx-tooltip/tttx-tooltip.js +253 -253
  119. package/dist/collection/components/molecules/tttx-tooltip/tttx-tootip.stories.js +117 -117
  120. package/dist/collection/components/molecules/tttx-tree-view/helper/helper.js +1 -1
  121. package/dist/collection/components/molecules/tttx-tree-view/tttx-tree-view.js +463 -463
  122. package/dist/collection/components/molecules/tttx-tree-view/tttx-tree-view.stories.js +402 -402
  123. package/dist/collection/components/organisms/tttx-data-pattern/tttx-data-pattern.js +176 -176
  124. package/dist/collection/components/organisms/tttx-data-pattern/tttx-data-pattern.stories.js +28 -28
  125. package/dist/collection/components/palette.stories.js +7 -7
  126. package/dist/collection/icons.js +2838 -2838
  127. package/dist/collection/index.js +1 -1
  128. package/dist/collection/shared/domsanitiser.options.js +14 -14
  129. package/dist/components/auto.js +177 -177
  130. package/dist/components/domsanitiser.options.js +12 -12
  131. package/dist/components/index.d.ts +38 -38
  132. package/dist/components/index.js +38 -38
  133. package/dist/components/tttx-action-dropdown_1_9_103.d.ts +11 -0
  134. package/dist/components/{tttx-action-dropdown_localcomponent.js → tttx-action-dropdown_1_9_103.js} +81 -81
  135. package/dist/components/tttx-button-v2.js +182 -182
  136. package/dist/components/tttx-button-v2_1_9_103.d.ts +11 -0
  137. package/dist/components/{tttx-button-v2_localcomponent.js → tttx-button-v2_1_9_103.js} +2 -2
  138. package/dist/components/tttx-button.js +51 -51
  139. package/dist/components/tttx-button_1_9_103.d.ts +11 -0
  140. package/dist/components/{tttx-button_localcomponent.js → tttx-button_1_9_103.js} +2 -2
  141. package/dist/components/tttx-chart_1_9_103.d.ts +11 -0
  142. package/dist/components/{tttx-chart_localcomponent.js → tttx-chart_1_9_103.js} +574 -574
  143. package/dist/components/tttx-checkbox-group-caption_1_9_103.d.ts +11 -0
  144. package/dist/components/{tttx-checkbox-group-caption_localcomponent.js → tttx-checkbox-group-caption_1_9_103.js} +24 -24
  145. package/dist/components/tttx-checkbox-group-heading_1_9_103.d.ts +11 -0
  146. package/dist/components/{tttx-checkbox-group-heading_localcomponent.js → tttx-checkbox-group-heading_1_9_103.js} +24 -24
  147. package/dist/components/tttx-checkbox-group_1_9_103.d.ts +11 -0
  148. package/dist/components/{tttx-checkbox-group_localcomponent.js → tttx-checkbox-group_1_9_103.js} +25 -25
  149. package/dist/components/tttx-checkbox_1_9_103.d.ts +11 -0
  150. package/dist/components/{tttx-checkbox_localcomponent.js → tttx-checkbox_1_9_103.js} +59 -59
  151. package/dist/components/tttx-comments_1_9_103.d.ts +11 -0
  152. package/dist/components/{tttx-comments_localcomponent.js → tttx-comments_1_9_103.js} +241 -241
  153. package/dist/components/tttx-data-pattern_1_9_103.d.ts +11 -0
  154. package/dist/components/{tttx-data-pattern_localcomponent.js → tttx-data-pattern_1_9_103.js} +80 -80
  155. package/dist/components/tttx-datacard_1_9_103.d.ts +11 -0
  156. package/dist/components/{tttx-datacard_localcomponent.js → tttx-datacard_1_9_103.js} +79 -79
  157. package/dist/components/tttx-date-range-picker.js +242 -242
  158. package/dist/components/tttx-dialog-box_1_9_103.d.ts +11 -0
  159. package/dist/components/{tttx-dialog-box_localcomponent.js → tttx-dialog-box_1_9_103.js} +125 -125
  160. package/dist/components/tttx-dialog_1_9_103.d.ts +11 -0
  161. package/dist/components/{tttx-dialog_localcomponent.js → tttx-dialog_1_9_103.js} +103 -103
  162. package/dist/components/tttx-expander_1_9_103.d.ts +11 -0
  163. package/dist/components/{tttx-expander_localcomponent.js → tttx-expander_1_9_103.js} +55 -55
  164. package/dist/components/tttx-filter.js +217 -217
  165. package/dist/components/tttx-filter_1_9_103.d.ts +11 -0
  166. package/dist/components/{tttx-filter_localcomponent.js → tttx-filter_1_9_103.js} +2 -2
  167. package/dist/components/tttx-form_1_9_103.d.ts +11 -0
  168. package/dist/components/{tttx-form_localcomponent.js → tttx-form_1_9_103.js} +1039 -1039
  169. package/dist/components/tttx-graph.js +143 -143
  170. package/dist/components/tttx-graph_1_9_103.d.ts +11 -0
  171. package/dist/components/{tttx-graph_localcomponent.js → tttx-graph_1_9_103.js} +2 -2
  172. package/dist/components/tttx-icon.js +42 -42
  173. package/dist/components/tttx-icon_1_9_103.d.ts +11 -0
  174. package/dist/components/{tttx-icon_localcomponent.js → tttx-icon_1_9_103.js} +2 -2
  175. package/dist/components/tttx-keyvalue-block_1_9_103.d.ts +11 -0
  176. package/dist/components/{tttx-keyvalue-block_localcomponent.js → tttx-keyvalue-block_1_9_103.js} +83 -83
  177. package/dist/components/tttx-list.js +92 -92
  178. package/dist/components/tttx-list_1_9_103.d.ts +11 -0
  179. package/dist/components/{tttx-list_localcomponent.js → tttx-list_1_9_103.js} +2 -2
  180. package/dist/components/tttx-loading-spinner.js +92 -92
  181. package/dist/components/tttx-loading-spinner_1_9_103.d.ts +11 -0
  182. package/dist/components/{tttx-loading-spinner_localcomponent.js → tttx-loading-spinner_1_9_103.js} +2 -2
  183. package/dist/components/tttx-multiselect-box_1_9_103.d.ts +11 -0
  184. package/dist/components/{tttx-multiselect-box_localcomponent.js → tttx-multiselect-box_1_9_103.js} +231 -231
  185. package/dist/components/tttx-percentage-bar_1_9_103.d.ts +11 -0
  186. package/dist/components/{tttx-percentage-bar_localcomponent.js → tttx-percentage-bar_1_9_103.js} +80 -80
  187. package/dist/components/tttx-qrcode_1_9_103.d.ts +11 -0
  188. package/dist/components/{tttx-qrcode_localcomponent.js → tttx-qrcode_1_9_103.js} +47 -47
  189. package/dist/components/tttx-range-slider_1_9_103.d.ts +11 -0
  190. package/dist/components/{tttx-range-slider_localcomponent.js → tttx-range-slider_1_9_103.js} +208 -208
  191. package/dist/components/tttx-select-box.js +295 -295
  192. package/dist/components/tttx-select-box_1_9_103.d.ts +11 -0
  193. package/dist/components/{tttx-select-box_localcomponent.js → tttx-select-box_1_9_103.js} +2 -2
  194. package/dist/components/tttx-skeleton_loader_1_9_103.d.ts +11 -0
  195. package/dist/components/{tttx-skeleton_loader_localcomponent.js → tttx-skeleton_loader_1_9_103.js} +57 -57
  196. package/dist/components/tttx-sorter.js +136 -136
  197. package/dist/components/tttx-sorter_1_9_103.d.ts +11 -0
  198. package/dist/components/{tttx-sorter_localcomponent.js → tttx-sorter_1_9_103.js} +2 -2
  199. package/dist/components/tttx-standalone-input.js +136 -136
  200. package/dist/components/tttx-standalone-input_1_9_103.d.ts +11 -0
  201. package/dist/components/{tttx-standalone-input_localcomponent.js → tttx-standalone-input_1_9_103.js} +2 -2
  202. package/dist/components/tttx-table_1_9_103.d.ts +11 -0
  203. package/dist/components/{tttx-table_localcomponent.js → tttx-table_1_9_103.js} +109 -109
  204. package/dist/components/tttx-tabs_1_9_103.d.ts +11 -0
  205. package/dist/components/{tttx-tabs_localcomponent.js → tttx-tabs_1_9_103.js} +128 -128
  206. package/dist/components/tttx-tag-v2_1_9_103.d.ts +11 -0
  207. package/dist/components/{tttx-tag-v2_localcomponent.js → tttx-tag-v2_1_9_103.js} +105 -105
  208. package/dist/components/tttx-tag.js +44 -44
  209. package/dist/components/tttx-tag_1_9_103.d.ts +11 -0
  210. package/dist/components/{tttx-tag_localcomponent.js → tttx-tag_1_9_103.js} +2 -2
  211. package/dist/components/tttx-textarea_1_9_103.d.ts +11 -0
  212. package/dist/components/{tttx-textarea_localcomponent.js → tttx-textarea_1_9_103.js} +83 -83
  213. package/dist/components/tttx-toggle_1_9_103.d.ts +11 -0
  214. package/dist/components/{tttx-toggle_localcomponent.js → tttx-toggle_1_9_103.js} +49 -49
  215. package/dist/components/tttx-toolbar.js +42 -42
  216. package/dist/components/tttx-toolbar_1_9_103.d.ts +11 -0
  217. package/dist/components/{tttx-toolbar_localcomponent.js → tttx-toolbar_1_9_103.js} +2 -2
  218. package/dist/components/tttx-tooltip_1_9_103.d.ts +11 -0
  219. package/dist/components/{tttx-tooltip_localcomponent.js → tttx-tooltip_1_9_103.js} +114 -114
  220. package/dist/components/tttx-tree-view_1_9_103.d.ts +11 -0
  221. package/dist/components/{tttx-tree-view_localcomponent.js → tttx-tree-view_1_9_103.js} +370 -370
  222. package/dist/esm/{auto-421f2656.js → auto-a07ee1b1.js} +177 -177
  223. package/dist/esm/{domsanitiser.options-38a67458.js → domsanitiser.options-2c1ef894.js} +12 -12
  224. package/dist/esm/loader.js +1 -1
  225. package/dist/esm/polyfills/core-js.js +0 -0
  226. package/dist/esm/polyfills/dom.js +0 -0
  227. package/dist/esm/polyfills/es5-html-element.js +0 -0
  228. package/dist/esm/polyfills/index.js +0 -0
  229. package/dist/esm/polyfills/system.js +0 -0
  230. package/dist/esm/{tttx-action-dropdown_localcomponent.entry.js → tttx-action-dropdown_1_9_103.entry.js} +51 -51
  231. package/dist/esm/{tttx-button-v2_localcomponent.entry.js → tttx-button-v2_1_9_103.entry.js} +147 -147
  232. package/dist/esm/{tttx-button_localcomponent.entry.js → tttx-button_1_9_103.entry.js} +26 -26
  233. package/dist/esm/{tttx-chart_localcomponent.entry.js → tttx-chart_1_9_103.entry.js} +524 -524
  234. package/dist/esm/{tttx-checkbox-group-caption_localcomponent.entry.js → tttx-checkbox-group-caption_1_9_103.entry.js} +9 -9
  235. package/dist/esm/{tttx-checkbox-group-heading_localcomponent.entry.js → tttx-checkbox-group-heading_1_9_103.entry.js} +9 -9
  236. package/dist/esm/{tttx-checkbox-group_localcomponent.entry.js → tttx-checkbox-group_1_9_103.entry.js} +9 -9
  237. package/dist/esm/{tttx-checkbox_localcomponent.entry.js → tttx-checkbox_1_9_103.entry.js} +33 -33
  238. package/dist/esm/{tttx-comments_localcomponent.entry.js → tttx-comments_1_9_103.entry.js} +204 -204
  239. package/dist/esm/tttx-data-pattern_1_9_103.entry.js +26 -0
  240. package/dist/esm/{tttx-datacard_localcomponent.entry.js → tttx-datacard_1_9_103.entry.js} +43 -43
  241. package/dist/esm/tttx-date-range-picker.entry.js +212 -212
  242. package/dist/esm/{tttx-dialog-box_localcomponent.entry.js → tttx-dialog-box_1_9_103.entry.js} +94 -94
  243. package/dist/esm/{tttx-dialog_localcomponent.entry.js → tttx-dialog_1_9_103.entry.js} +69 -69
  244. package/dist/esm/{tttx-expander_localcomponent.entry.js → tttx-expander_1_9_103.entry.js} +28 -28
  245. package/dist/esm/{tttx-filter_localcomponent_4.entry.js → tttx-filter_1_9_103_4.entry.js} +383 -383
  246. package/dist/esm/{tttx-form_localcomponent.entry.js → tttx-form_1_9_103.entry.js} +985 -985
  247. package/dist/esm/{tttx-graph_localcomponent.entry.js → tttx-graph_1_9_103.entry.js} +124 -124
  248. package/dist/esm/{tttx-icon_localcomponent.entry.js → tttx-icon_1_9_103.entry.js} +24 -24
  249. package/dist/esm/{tttx-keyvalue-block_localcomponent.entry.js → tttx-keyvalue-block_1_9_103.entry.js} +62 -62
  250. package/dist/esm/tttx-loading-spinner_1_9_103_3.entry.js +183 -0
  251. package/dist/esm/{tttx-multiselect-box_localcomponent.entry.js → tttx-multiselect-box_1_9_103.entry.js} +175 -175
  252. package/dist/esm/{tttx-percentage-bar_localcomponent.entry.js → tttx-percentage-bar_1_9_103.entry.js} +56 -56
  253. package/dist/esm/{tttx-qrcode_localcomponent.entry.js → tttx-qrcode_1_9_103.entry.js} +28 -28
  254. package/dist/esm/{tttx-range-slider_localcomponent.entry.js → tttx-range-slider_1_9_103.entry.js} +185 -185
  255. package/dist/esm/{tttx-select-box_localcomponent.entry.js → tttx-select-box_1_9_103.entry.js} +239 -239
  256. package/dist/esm/{tttx-skeleton_loader_localcomponent.entry.js → tttx-skeleton_loader_1_9_103.entry.js} +30 -30
  257. package/dist/esm/{tttx-table_localcomponent.entry.js → tttx-table_1_9_103.entry.js} +72 -72
  258. package/dist/esm/{tttx-tabs_localcomponent.entry.js → tttx-tabs_1_9_103.entry.js} +103 -103
  259. package/dist/esm/{tttx-tag-v2_localcomponent.entry.js → tttx-tag-v2_1_9_103.entry.js} +72 -72
  260. package/dist/esm/{tttx-textarea_localcomponent.entry.js → tttx-textarea_1_9_103.entry.js} +50 -50
  261. package/dist/esm/{tttx-toggle_localcomponent.entry.js → tttx-toggle_1_9_103.entry.js} +30 -30
  262. package/dist/esm/{tttx-tooltip_localcomponent.entry.js → tttx-tooltip_1_9_103.entry.js} +87 -87
  263. package/dist/esm/{tttx-tree-view_localcomponent.entry.js → tttx-tree-view_1_9_103.entry.js} +341 -341
  264. package/dist/esm/tttx.js +1 -1
  265. package/dist/tttx/p-0c5bc253.entry.js +1 -0
  266. package/dist/tttx/p-10d2d044.entry.js +1 -0
  267. package/dist/tttx/p-1623f3cf.entry.js +1 -1
  268. package/dist/tttx/p-16aa3f67.entry.js +1 -0
  269. package/dist/tttx/p-21707b8d.entry.js +1 -1
  270. package/dist/tttx/p-2251ab85.entry.js +1 -1
  271. package/dist/tttx/p-2d19c46c.entry.js +1 -1
  272. package/dist/tttx/p-358eaa44.entry.js +1 -1
  273. package/dist/tttx/p-362999b3.entry.js +1 -1
  274. package/dist/tttx/p-3ec67d75.entry.js +1 -1
  275. package/dist/tttx/p-44f0af69.entry.js +1 -1
  276. package/dist/tttx/p-4664d065.entry.js +1 -1
  277. package/dist/tttx/p-486ca932.entry.js +1 -0
  278. package/dist/tttx/p-59115c8f.entry.js +1 -0
  279. package/dist/tttx/p-5d289334.entry.js +1 -1
  280. package/dist/tttx/p-6ec18b4a.entry.js +1 -1
  281. package/dist/tttx/p-700c2816.entry.js +1 -0
  282. package/dist/tttx/p-7b5b0670.entry.js +1 -1
  283. package/dist/tttx/p-7d1712fe.entry.js +1 -1
  284. package/dist/tttx/{p-41b69e01.entry.js → p-8f85ab3e.entry.js} +1 -1
  285. package/dist/tttx/p-a1b8ecda.entry.js +1 -1
  286. package/dist/tttx/p-a43e2c5e.entry.js +1 -1
  287. package/dist/tttx/p-b8cc0cb2.entry.js +1 -1
  288. package/dist/tttx/p-b9003a76.entry.js +1 -1
  289. package/dist/tttx/p-bb59054f.entry.js +1 -1
  290. package/dist/tttx/p-c66bc14c.entry.js +1 -1
  291. package/dist/tttx/p-c8051143.entry.js +1 -1
  292. package/dist/tttx/p-ca93f786.entry.js +1 -1
  293. package/dist/tttx/p-d21b0507.entry.js +1 -1
  294. package/dist/tttx/p-d945d492.entry.js +1 -1
  295. package/dist/tttx/{p-34e0e487.entry.js → p-df708b75.entry.js} +2 -2
  296. package/dist/tttx/p-f0c1380f.entry.js +1 -1
  297. package/dist/tttx/{p-0bb158ce.js → p-f411d1e5.js} +2 -2
  298. package/dist/tttx/p-fa25ee03.entry.js +1 -0
  299. package/dist/tttx/p-fbdd1046.entry.js +1 -0
  300. package/dist/tttx/tttx.esm.js +1 -1
  301. package/dist/types/components/atoms/tttx-button/tttx-button.d.ts +11 -11
  302. package/dist/types/components/atoms/tttx-button/tttx-button.stories.d.ts +11 -11
  303. package/dist/types/components/atoms/tttx-button-v2/tttx-button-v2.d.ts +36 -36
  304. package/dist/types/components/atoms/tttx-button-v2/tttx-button-v2.stories.d.ts +68 -68
  305. package/dist/types/components/atoms/tttx-checkbox/tttx-checkbox.d.ts +17 -17
  306. package/dist/types/components/atoms/tttx-datacard/tttx-datacard.d.ts +21 -21
  307. package/dist/types/components/atoms/tttx-datacard/tttx-datacard.stories.d.ts +44 -44
  308. package/dist/types/components/atoms/tttx-icon/tttx-icon.d.ts +9 -9
  309. package/dist/types/components/atoms/tttx-icon/tttx-icon.stories.d.ts +25 -25
  310. package/dist/types/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.d.ts +13 -13
  311. package/dist/types/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.stories.d.ts +11 -11
  312. package/dist/types/components/atoms/tttx-loading-spinner/tttx-loading-spinner.d.ts +23 -23
  313. package/dist/types/components/atoms/tttx-loading-spinner/tttx-loading-spinner.stories.d.ts +47 -47
  314. package/dist/types/components/atoms/tttx-percentage-bar/tttx-percentage-bar.d.ts +22 -22
  315. package/dist/types/components/atoms/tttx-percentage-bar/tttx-percentage-bar.stories.d.ts +10 -10
  316. package/dist/types/components/atoms/tttx-qrcode/tttx-qrcode.d.ts +8 -8
  317. package/dist/types/components/atoms/tttx-qrcode/tttx-qrcode.stories.d.ts +23 -23
  318. package/dist/types/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.d.ts +14 -14
  319. package/dist/types/components/atoms/tttx-tag/tttx-tag.d.ts +10 -10
  320. package/dist/types/components/atoms/tttx-tag/tttx-tag.stories.d.ts +51 -51
  321. package/dist/types/components/atoms/tttx-tag-v2/tttx-tag-v2.d.ts +15 -15
  322. package/dist/types/components/atoms/tttx-tag-v2/tttx-tag-v2.stories.d.ts +48 -48
  323. package/dist/types/components/atoms/tttx-toggle/tttx-toggle.d.ts +11 -11
  324. package/dist/types/components/atoms/tttx-toggle/tttx-toggle.stories.d.ts +6 -6
  325. package/dist/types/components/domsanitiser.options.d.ts +10 -10
  326. package/dist/types/components/molecules/tttx-action-dropdown/tttx-action-dropdown.d.ts +21 -21
  327. package/dist/types/components/molecules/tttx-chart/tttx-chart.d.ts +60 -60
  328. package/dist/types/components/molecules/tttx-chart/tttx-chart.stories.d.ts +38 -38
  329. package/dist/types/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-caption.d.ts +3 -3
  330. package/dist/types/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-heading.d.ts +3 -3
  331. package/dist/types/components/molecules/tttx-checkbox-group/tttx-checkbox-group.d.ts +3 -3
  332. package/dist/types/components/molecules/tttx-checkbox-group/tttx-checkbox-group.stories.d.ts +15 -15
  333. package/dist/types/components/molecules/tttx-comments/tttx-comments.d.ts +68 -68
  334. package/dist/types/components/molecules/tttx-date-range-picker/tttx-date-range-picker.d.ts +42 -42
  335. package/dist/types/components/molecules/tttx-dialog/icon-types.d.ts +18 -18
  336. package/dist/types/components/molecules/tttx-dialog/tttx-dialog.d.ts +27 -27
  337. package/dist/types/components/molecules/tttx-dialog-box/tttx-dialog-box.d.ts +26 -26
  338. package/dist/types/components/molecules/tttx-dialog-box/tttx-dialog-box.stories.d.ts +24 -24
  339. package/dist/types/components/molecules/tttx-expander/tttx-expander.d.ts +16 -16
  340. package/dist/types/components/molecules/tttx-filter/tttx-filter.d.ts +44 -44
  341. package/dist/types/components/molecules/tttx-form/lib/setErrorState.d.ts +14 -14
  342. package/dist/types/components/molecules/tttx-form/lib/timecomparatorChecks.d.ts +4 -4
  343. package/dist/types/components/molecules/tttx-form/lib/validityCheck.d.ts +15 -15
  344. package/dist/types/components/molecules/tttx-form/tttx-form.d.ts +297 -297
  345. package/dist/types/components/molecules/tttx-graph/gauge-label-plugin.d.ts +4 -4
  346. package/dist/types/components/molecules/tttx-graph/tttx-graph.d.ts +13 -13
  347. package/dist/types/components/molecules/tttx-graph/tttx-graph.stories.d.ts +26 -26
  348. package/dist/types/components/molecules/tttx-list/tttx-list.d.ts +23 -23
  349. package/dist/types/components/molecules/tttx-multiselect-box/tttx-multiselect-box.d.ts +50 -50
  350. package/dist/types/components/molecules/tttx-range-slider/tttx-range-slider.d.ts +45 -45
  351. package/dist/types/components/molecules/tttx-range-slider/tttx-range-slider.stories.d.ts +7 -7
  352. package/dist/types/components/molecules/tttx-select-box/tttx-select-box.d.ts +55 -55
  353. package/dist/types/components/molecules/tttx-select-box/tttx-select-box.stories.d.ts +28 -28
  354. package/dist/types/components/molecules/tttx-sorter/tttx-sorter.d.ts +21 -21
  355. package/dist/types/components/molecules/tttx-standalone-input/tttx-standalone-input.d.ts +69 -69
  356. package/dist/types/components/molecules/tttx-table/tttx-table.d.ts +32 -32
  357. package/dist/types/components/molecules/tttx-table/tttx-table.types.d.ts +6 -6
  358. package/dist/types/components/molecules/tttx-tabs/tttx-tabs.d.ts +25 -25
  359. package/dist/types/components/molecules/tttx-textarea/tttx-textarea.d.ts +42 -42
  360. package/dist/types/components/molecules/tttx-textarea/tttx-textarea.stories.d.ts +89 -89
  361. package/dist/types/components/molecules/tttx-toolbar/tttx-toolbar.d.ts +8 -8
  362. package/dist/types/components/molecules/tttx-toolbar/tttx-toolbar.stories.d.ts +19 -19
  363. package/dist/types/components/molecules/tttx-tooltip/tttx-tooltip.d.ts +37 -37
  364. package/dist/types/components/molecules/tttx-tooltip/tttx-tootip.stories.d.ts +12 -12
  365. package/dist/types/components/molecules/tttx-tree-view/helper/helper.d.ts +24 -24
  366. package/dist/types/components/molecules/tttx-tree-view/tttx-tree-view.d.ts +57 -57
  367. package/dist/types/components/organisms/tttx-data-pattern/tttx-data-pattern.d.ts +11 -11
  368. package/dist/types/components/organisms/tttx-data-pattern/tttx-data-pattern.stories.d.ts +13 -13
  369. package/dist/types/components/palette.stories.d.ts +6 -6
  370. package/dist/types/components.d.ts +451 -451
  371. package/dist/types/icons.d.ts +2 -2
  372. package/dist/types/index.d.ts +1 -1
  373. package/dist/types/shared/domsanitiser.options.d.ts +10 -10
  374. package/package.json +1 -1
  375. package/dist/cjs/tttx-data-pattern_localcomponent.cjs.entry.js +0 -30
  376. package/dist/components/tttx-action-dropdown_localcomponent.d.ts +0 -11
  377. package/dist/components/tttx-button-v2_localcomponent.d.ts +0 -11
  378. package/dist/components/tttx-button_localcomponent.d.ts +0 -11
  379. package/dist/components/tttx-chart_localcomponent.d.ts +0 -11
  380. package/dist/components/tttx-checkbox-group-caption_localcomponent.d.ts +0 -11
  381. package/dist/components/tttx-checkbox-group-heading_localcomponent.d.ts +0 -11
  382. package/dist/components/tttx-checkbox-group_localcomponent.d.ts +0 -11
  383. package/dist/components/tttx-checkbox_localcomponent.d.ts +0 -11
  384. package/dist/components/tttx-comments_localcomponent.d.ts +0 -11
  385. package/dist/components/tttx-data-pattern_localcomponent.d.ts +0 -11
  386. package/dist/components/tttx-datacard_localcomponent.d.ts +0 -11
  387. package/dist/components/tttx-dialog-box_localcomponent.d.ts +0 -11
  388. package/dist/components/tttx-dialog_localcomponent.d.ts +0 -11
  389. package/dist/components/tttx-expander_localcomponent.d.ts +0 -11
  390. package/dist/components/tttx-filter_localcomponent.d.ts +0 -11
  391. package/dist/components/tttx-form_localcomponent.d.ts +0 -11
  392. package/dist/components/tttx-graph_localcomponent.d.ts +0 -11
  393. package/dist/components/tttx-icon_localcomponent.d.ts +0 -11
  394. package/dist/components/tttx-keyvalue-block_localcomponent.d.ts +0 -11
  395. package/dist/components/tttx-list_localcomponent.d.ts +0 -11
  396. package/dist/components/tttx-loading-spinner_localcomponent.d.ts +0 -11
  397. package/dist/components/tttx-multiselect-box_localcomponent.d.ts +0 -11
  398. package/dist/components/tttx-percentage-bar_localcomponent.d.ts +0 -11
  399. package/dist/components/tttx-qrcode_localcomponent.d.ts +0 -11
  400. package/dist/components/tttx-range-slider_localcomponent.d.ts +0 -11
  401. package/dist/components/tttx-select-box_localcomponent.d.ts +0 -11
  402. package/dist/components/tttx-skeleton_loader_localcomponent.d.ts +0 -11
  403. package/dist/components/tttx-sorter_localcomponent.d.ts +0 -11
  404. package/dist/components/tttx-standalone-input_localcomponent.d.ts +0 -11
  405. package/dist/components/tttx-table_localcomponent.d.ts +0 -11
  406. package/dist/components/tttx-tabs_localcomponent.d.ts +0 -11
  407. package/dist/components/tttx-tag-v2_localcomponent.d.ts +0 -11
  408. package/dist/components/tttx-tag_localcomponent.d.ts +0 -11
  409. package/dist/components/tttx-textarea_localcomponent.d.ts +0 -11
  410. package/dist/components/tttx-toggle_localcomponent.d.ts +0 -11
  411. package/dist/components/tttx-toolbar_localcomponent.d.ts +0 -11
  412. package/dist/components/tttx-tooltip_localcomponent.d.ts +0 -11
  413. package/dist/components/tttx-tree-view_localcomponent.d.ts +0 -11
  414. package/dist/esm/tttx-data-pattern_localcomponent.entry.js +0 -26
  415. package/dist/esm/tttx-loading-spinner_localcomponent_3.entry.js +0 -183
  416. package/dist/tttx/p-00a849cf.entry.js +0 -1
  417. package/dist/tttx/p-41f0bf7f.entry.js +0 -1
  418. package/dist/tttx/p-82b4e575.entry.js +0 -1
  419. package/dist/tttx/p-86e4c8cc.entry.js +0 -1
  420. package/dist/tttx/p-b161205b.entry.js +0 -1
  421. package/dist/tttx/p-b3f49d83.entry.js +0 -1
  422. package/dist/tttx/p-d4c4edbd.entry.js +0 -1
  423. package/dist/tttx/p-e21e3a9c.entry.js +0 -1
  424. package/dist/types/components/atoms/tttx-checkbox/tttx-checkbox.stories.d.ts +0 -47
  425. package/dist/types/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.stories.d.ts +0 -58
  426. package/dist/types/components/molecules/tttx-action-dropdown/tttx-action-dropdown.stories.d.ts +0 -36
  427. package/dist/types/components/molecules/tttx-comments/tttx-comments.stories.d.ts +0 -8
  428. package/dist/types/components/molecules/tttx-date-range-picker/tttx-date-range-picker.stories.d.ts +0 -28
  429. package/dist/types/components/molecules/tttx-dialog/tttx-dialog.stories.d.ts +0 -42
  430. package/dist/types/components/molecules/tttx-expander/tttx-expander.stories.d.ts +0 -27
  431. package/dist/types/components/molecules/tttx-filter/tttx-filter.stories.d.ts +0 -76
  432. package/dist/types/components/molecules/tttx-form/tttx-form.stories.d.ts +0 -718
  433. package/dist/types/components/molecules/tttx-list/tttx-list.stories.d.ts +0 -15
  434. package/dist/types/components/molecules/tttx-multiselect-box/tttx-multiselect-box.stories.d.ts +0 -17
  435. package/dist/types/components/molecules/tttx-sorter/tttx-sorter.stories.d.ts +0 -30
  436. package/dist/types/components/molecules/tttx-standalone-input/tttx-standalone-input.stories.d.ts +0 -150
  437. package/dist/types/components/molecules/tttx-table/tttx-table.stories.d.ts +0 -79
  438. package/dist/types/components/molecules/tttx-tabs/tttx-tabs.stories.d.ts +0 -13
  439. package/dist/types/components/molecules/tttx-tree-view/tttx-tree-view.stories.d.ts +0 -15
  440. /package/dist/tttx/{p-55799798.js → p-62d92a44.js} +0 -0
@@ -1,998 +1,998 @@
1
1
  import { r as registerInstance, c as createEvent, h, H as Host } from './index-b614efb4.js';
2
- import { p as purify, d as domSanitiserOptions } from './domsanitiser.options-38a67458.js';
2
+ import { p as purify, d as domSanitiserOptions } from './domsanitiser.options-2c1ef894.js';
3
3
  import './_commonjsHelpers-9943807e.js';
4
4
 
5
- /**
6
- * Validates the input field on focusout event by checking its validity state,
7
- * sets an error message if there's an issue, and emits a "dataChanged" event to
8
- * the parent component with the field name and its new value.
9
- *
10
- * @param {Event | FocusEvent} event - The focusout event triggered by the input field.
11
- * @return {{ target: FormField; hasError: boolean; errorMessage: string; }}
12
- */
13
- function validityCheck(event) {
14
- var _a, _b, _c, _d;
15
- if (event.preventDefault) {
16
- event.preventDefault();
17
- }
18
- const target = event.target;
19
- let hasError = true;
20
- let errorMessage = '';
21
- // validity object on HTML5 inputs has the following options
22
- /*
23
- badInput
24
- customError
25
- patternMismatch
26
- rangeOverflow
27
- rangeUnderflow
28
- stepMismatch
29
- tooLong
30
- tooShort
31
- typeMismatch
32
- valid
33
- valueMissing
34
- */
35
- // customErrors can be set with
36
- // target.setCustomValidity('custom error!');
37
- // and cleared with
38
- // target.setCustomValidity('');
39
- //handle whitespace-only input
40
- if (!target.hasAttribute('custom-validation-set')) {
41
- if (target.value.length && !target.value.replace(/\s/g, '').length) {
42
- errorMessage = 'This field cannot be left blank';
43
- target.setCustomValidity(errorMessage);
44
- }
45
- else {
46
- if (target.setCustomValidity) // tests are dumb as a brick
47
- target.setCustomValidity('');
48
- }
49
- }
50
- // Check the validity of the input field and set an error message if needed
51
- switch (true) {
52
- // The field is required, but has no value
53
- case target.validity.valueMissing:
54
- errorMessage = (_a = target.dataset.required) !== null && _a !== void 0 ? _a : 'This field is required';
55
- break;
56
- // The field's value does not match the expected pattern
57
- case target.validity.patternMismatch:
58
- errorMessage = (_b = target.dataset.pattern) !== null && _b !== void 0 ? _b : 'Incorrect format';
59
- break;
60
- // The field's value is not of the correct input type
61
- case target.validity.badInput:
62
- // IE string in a number field
63
- errorMessage = (_c = target.dataset.badinput) !== null && _c !== void 0 ? _c : 'Wrong input type';
64
- break;
65
- // The field's value is above or below the range set in the "min" and "max" attributes
66
- case target.validity.rangeOverflow || target.validity.rangeUnderflow:
67
- // IE date or number is above or below value set in min or max tags
68
- errorMessage = (_d = target.dataset.range) !== null && _d !== void 0 ? _d : 'Invalid value';
69
- break;
70
- case target.validity.customError:
71
- errorMessage = target.validationMessage;
72
- break;
73
- // No error detected
74
- default:
75
- hasError = false;
76
- }
77
- // Return the error state
78
- return { target, hasError, errorMessage };
5
+ /**
6
+ * Validates the input field on focusout event by checking its validity state,
7
+ * sets an error message if there's an issue, and emits a "dataChanged" event to
8
+ * the parent component with the field name and its new value.
9
+ *
10
+ * @param {Event | FocusEvent} event - The focusout event triggered by the input field.
11
+ * @return {{ target: FormField; hasError: boolean; errorMessage: string; }}
12
+ */
13
+ function validityCheck(event) {
14
+ var _a, _b, _c, _d;
15
+ if (event.preventDefault) {
16
+ event.preventDefault();
17
+ }
18
+ const target = event.target;
19
+ let hasError = true;
20
+ let errorMessage = '';
21
+ // validity object on HTML5 inputs has the following options
22
+ /*
23
+ badInput
24
+ customError
25
+ patternMismatch
26
+ rangeOverflow
27
+ rangeUnderflow
28
+ stepMismatch
29
+ tooLong
30
+ tooShort
31
+ typeMismatch
32
+ valid
33
+ valueMissing
34
+ */
35
+ // customErrors can be set with
36
+ // target.setCustomValidity('custom error!');
37
+ // and cleared with
38
+ // target.setCustomValidity('');
39
+ //handle whitespace-only input
40
+ if (!target.hasAttribute('custom-validation-set')) {
41
+ if (target.value.length && !target.value.replace(/\s/g, '').length) {
42
+ errorMessage = 'This field cannot be left blank';
43
+ target.setCustomValidity(errorMessage);
44
+ }
45
+ else {
46
+ if (target.setCustomValidity) // tests are dumb as a brick
47
+ target.setCustomValidity('');
48
+ }
49
+ }
50
+ // Check the validity of the input field and set an error message if needed
51
+ switch (true) {
52
+ // The field is required, but has no value
53
+ case target.validity.valueMissing:
54
+ errorMessage = (_a = target.dataset.required) !== null && _a !== void 0 ? _a : 'This field is required';
55
+ break;
56
+ // The field's value does not match the expected pattern
57
+ case target.validity.patternMismatch:
58
+ errorMessage = (_b = target.dataset.pattern) !== null && _b !== void 0 ? _b : 'Incorrect format';
59
+ break;
60
+ // The field's value is not of the correct input type
61
+ case target.validity.badInput:
62
+ // IE string in a number field
63
+ errorMessage = (_c = target.dataset.badinput) !== null && _c !== void 0 ? _c : 'Wrong input type';
64
+ break;
65
+ // The field's value is above or below the range set in the "min" and "max" attributes
66
+ case target.validity.rangeOverflow || target.validity.rangeUnderflow:
67
+ // IE date or number is above or below value set in min or max tags
68
+ errorMessage = (_d = target.dataset.range) !== null && _d !== void 0 ? _d : 'Invalid value';
69
+ break;
70
+ case target.validity.customError:
71
+ errorMessage = target.validationMessage;
72
+ break;
73
+ // No error detected
74
+ default:
75
+ hasError = false;
76
+ }
77
+ // Return the error state
78
+ return { target, hasError, errorMessage };
79
79
  }
80
80
 
81
- /**
82
- * Sets the error state of an input field by updating its class and error message.
83
- * If an error was detected, it sets the input field's class to "invalid" and
84
- * displays the error message in an error bubble. If no error was detected,
85
- * it removes the "invalid" class from the input field and clears the error bubble.
86
- *
87
- * @param {FormField} target - The input field to update.
88
- * @param {boolean} hasError - Whether an error was detected in the field.
89
- * @param {string} errorMessage - The error message to display (if any).
90
- * @return {void}
91
- */
92
- function setErrorState(target, hasError, errorMessage, parent = undefined) {
93
- // Find the error bubble element for the input field
94
- let errorBubble;
95
- if (parent !== undefined) {
96
- errorBubble = parent.querySelector('.errorBubble');
97
- }
98
- else {
99
- if (target.parentElement.nodeName.toLowerCase() === 'label') {
100
- errorBubble = target.parentElement.querySelector('.errorBubble');
101
- }
102
- else {
103
- errorBubble = target.parentElement.parentElement.querySelector('.errorBubble');
104
- }
105
- }
106
- if (!errorBubble)
107
- return;
108
- // If an error was detected, set the input field's class to "invalid" and display the error message in the error bubble
109
- if (hasError) {
110
- target.classList.add('invalid');
111
- errorBubble.classList.add('visible');
112
- const errorIcon = document.createElement('span');
113
- // Set the class of the error icon to a pre-defined CSS class that specifies the icon's appearance
114
- errorIcon.className = 'material-symbols-rounded';
115
- // Set the text content of the error icon to the word "warning"
116
- errorIcon.textContent = 'warning';
117
- // errorBubble.replaceChildren cannot be used here because the tests don't support this new feature :(
118
- errorBubble.innerHTML = '';
119
- errorBubble.append(errorIcon);
120
- errorBubble.append(errorMessage);
121
- }
122
- // If no error was detected, remove the "invalid" class from the input field and clear the error bubble
123
- else {
124
- errorBubble.classList.remove('visible');
125
- target.classList.remove('invalid');
126
- errorBubble.innerHTML = '';
127
- }
81
+ /**
82
+ * Sets the error state of an input field by updating its class and error message.
83
+ * If an error was detected, it sets the input field's class to "invalid" and
84
+ * displays the error message in an error bubble. If no error was detected,
85
+ * it removes the "invalid" class from the input field and clears the error bubble.
86
+ *
87
+ * @param {FormField} target - The input field to update.
88
+ * @param {boolean} hasError - Whether an error was detected in the field.
89
+ * @param {string} errorMessage - The error message to display (if any).
90
+ * @return {void}
91
+ */
92
+ function setErrorState(target, hasError, errorMessage, parent = undefined) {
93
+ // Find the error bubble element for the input field
94
+ let errorBubble;
95
+ if (parent !== undefined) {
96
+ errorBubble = parent.querySelector('.errorBubble');
97
+ }
98
+ else {
99
+ if (target.parentElement.nodeName.toLowerCase() === 'label') {
100
+ errorBubble = target.parentElement.querySelector('.errorBubble');
101
+ }
102
+ else {
103
+ errorBubble = target.parentElement.parentElement.querySelector('.errorBubble');
104
+ }
105
+ }
106
+ if (!errorBubble)
107
+ return;
108
+ // If an error was detected, set the input field's class to "invalid" and display the error message in the error bubble
109
+ if (hasError) {
110
+ target.classList.add('invalid');
111
+ errorBubble.classList.add('visible');
112
+ const errorIcon = document.createElement('span');
113
+ // Set the class of the error icon to a pre-defined CSS class that specifies the icon's appearance
114
+ errorIcon.className = 'material-symbols-rounded';
115
+ // Set the text content of the error icon to the word "warning"
116
+ errorIcon.textContent = 'warning';
117
+ // errorBubble.replaceChildren cannot be used here because the tests don't support this new feature :(
118
+ errorBubble.innerHTML = '';
119
+ errorBubble.append(errorIcon);
120
+ errorBubble.append(errorMessage);
121
+ }
122
+ // If no error was detected, remove the "invalid" class from the input field and clear the error bubble
123
+ else {
124
+ errorBubble.classList.remove('visible');
125
+ target.classList.remove('invalid');
126
+ errorBubble.innerHTML = '';
127
+ }
128
128
  }
129
129
 
130
- function startEndTimeComparator(event) {
131
- var _a, _b;
132
- const target = event.target;
133
- const formKey = target.getAttribute('data-formkey');
134
- const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[data-formkey=${formKey}]`));
135
- if (timeFields.length === 4) {
136
- const startTime = timeFields.find(t => t.name.endsWith('starttime'));
137
- const endTime = timeFields.find(t => t.name.endsWith('endtime'));
138
- const startDate = timeFields.find(t => t.name.endsWith('startdate'));
139
- const endDate = timeFields.find(t => t.name.endsWith('enddate'));
140
- if (startTime.valueAsNumber >= endTime.valueAsNumber && ((_a = startDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) === ((_b = endDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
141
- setErrorState(endTime, true, 'End time cannot be the same or before the start time');
142
- if (target.name.endsWith('starttime')) {
143
- this.validityCheckWrapper(event);
144
- }
145
- }
146
- else {
147
- // clear any end time comparitor errors and perform the standard validity check on the event
148
- endTime.setCustomValidity('');
149
- setErrorState(endTime, false, null);
150
- this.validityCheckWrapper(event);
151
- }
152
- }
153
- }
154
- function clearTimeComparator(event) {
155
- const target = event.target;
156
- const formKey = target.getAttribute('data-formkey');
157
- const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[type=time][data-formkey=${formKey}]`));
158
- if (timeFields.length) {
159
- const endTime = timeFields.find(t => t.name.endsWith('endtime'));
160
- endTime.setCustomValidity('');
161
- setErrorState(endTime, false, null);
162
- }
163
- }
164
- function endDateComparisonValidator(event, triggeredByStartDate = false) {
165
- var _a, _b, _c, _d;
166
- const endDate = event.target;
167
- if (!endDate.value && triggeredByStartDate) {
168
- return;
169
- }
170
- const compareWithName = endDate.getAttribute('data-compare-with');
171
- const startDate = endDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareWithName}]`);
172
- if (((_a = endDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) < ((_b = startDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
173
- endDate.setCustomValidity(endDate.getAttribute('data-compare'));
174
- setErrorState(endDate, true, endDate.getAttribute('data-compare'));
175
- }
176
- else if (((_c = endDate.valueAsDate) === null || _c === void 0 ? void 0 : _c.valueOf()) === ((_d = startDate.valueAsDate) === null || _d === void 0 ? void 0 : _d.valueOf())) {
177
- endDate.setCustomValidity('');
178
- this.validityCheckWrapper(event);
179
- startEndTimeComparator.bind(this)(event);
180
- }
181
- else {
182
- clearTimeComparator.bind(this)(event);
183
- this.validityCheckWrapper(event);
184
- }
185
- }
186
- function startDateComparisonValidator(event) {
187
- const startDate = event.target;
188
- const compareToName = startDate.getAttribute('data-compare-to');
189
- const endDate = startDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareToName}]`);
190
- endDateComparisonValidator.bind(this)({ target: endDate }, true);
191
- this.validityCheckWrapper(event);
130
+ function startEndTimeComparator(event) {
131
+ var _a, _b;
132
+ const target = event.target;
133
+ const formKey = target.getAttribute('data-formkey');
134
+ const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[data-formkey=${formKey}]`));
135
+ if (timeFields.length === 4) {
136
+ const startTime = timeFields.find(t => t.name.endsWith('starttime'));
137
+ const endTime = timeFields.find(t => t.name.endsWith('endtime'));
138
+ const startDate = timeFields.find(t => t.name.endsWith('startdate'));
139
+ const endDate = timeFields.find(t => t.name.endsWith('enddate'));
140
+ if (startTime.valueAsNumber >= endTime.valueAsNumber && ((_a = startDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) === ((_b = endDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
141
+ setErrorState(endTime, true, 'End time cannot be the same or before the start time');
142
+ if (target.name.endsWith('starttime')) {
143
+ this.validityCheckWrapper(event);
144
+ }
145
+ }
146
+ else {
147
+ // clear any end time comparitor errors and perform the standard validity check on the event
148
+ endTime.setCustomValidity('');
149
+ setErrorState(endTime, false, null);
150
+ this.validityCheckWrapper(event);
151
+ }
152
+ }
153
+ }
154
+ function clearTimeComparator(event) {
155
+ const target = event.target;
156
+ const formKey = target.getAttribute('data-formkey');
157
+ const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[type=time][data-formkey=${formKey}]`));
158
+ if (timeFields.length) {
159
+ const endTime = timeFields.find(t => t.name.endsWith('endtime'));
160
+ endTime.setCustomValidity('');
161
+ setErrorState(endTime, false, null);
162
+ }
163
+ }
164
+ function endDateComparisonValidator(event, triggeredByStartDate = false) {
165
+ var _a, _b, _c, _d;
166
+ const endDate = event.target;
167
+ if (!endDate.value && triggeredByStartDate) {
168
+ return;
169
+ }
170
+ const compareWithName = endDate.getAttribute('data-compare-with');
171
+ const startDate = endDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareWithName}]`);
172
+ if (((_a = endDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) < ((_b = startDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
173
+ endDate.setCustomValidity(endDate.getAttribute('data-compare'));
174
+ setErrorState(endDate, true, endDate.getAttribute('data-compare'));
175
+ }
176
+ else if (((_c = endDate.valueAsDate) === null || _c === void 0 ? void 0 : _c.valueOf()) === ((_d = startDate.valueAsDate) === null || _d === void 0 ? void 0 : _d.valueOf())) {
177
+ endDate.setCustomValidity('');
178
+ this.validityCheckWrapper(event);
179
+ startEndTimeComparator.bind(this)(event);
180
+ }
181
+ else {
182
+ clearTimeComparator.bind(this)(event);
183
+ this.validityCheckWrapper(event);
184
+ }
185
+ }
186
+ function startDateComparisonValidator(event) {
187
+ const startDate = event.target;
188
+ const compareToName = startDate.getAttribute('data-compare-to');
189
+ const endDate = startDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareToName}]`);
190
+ endDateComparisonValidator.bind(this)({ target: endDate }, true);
191
+ this.validityCheckWrapper(event);
192
192
  }
193
193
 
194
194
  const tttxFormCss = ".material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}.material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}label{font-weight:500;font-size:16px;line-height:18.752px;color:#212121}label .optional{color:#757575;font-weight:normal}label .outer-container{position:relative}label .outer-container .left-icons,label .outer-container .right-icons{display:flex;position:absolute;height:24px;gap:8px}label .outer-container .left-icons tttx-icon,label .outer-container .right-icons tttx-icon{height:24px;width:24px}label .outer-container .left-icons{left:8px}label .outer-container .right-icons{right:8px}label .outer-container input,label .outer-container textarea{color:#212121;box-sizing:border-box;border:1px solid #d5d5d5;border-radius:4px;margin-top:4px;padding:0;padding-left:16px;padding-right:16px;}label .outer-container input.has-input-icon,label .outer-container textarea.has-input-icon{padding-left:40px}label .outer-container input.has-input-icon.has-left-icon,label .outer-container textarea.has-input-icon.has-left-icon{padding-left:72px}label .outer-container input.has-left-icon,label .outer-container textarea.has-left-icon{padding-left:40px}label .outer-container input.has-right-icon,label .outer-container textarea.has-right-icon{padding-right:40px}label .outer-container input.invalid,label .outer-container textarea.invalid{border:1px solid #dc0000}label .outer-container input:not([type=submit]),label .outer-container textarea:not([type=submit]){font-family:\"Roboto\", serif;width:100%;height:36px;font-size:16px;line-height:18.752px}label .outer-container input[type=radio],label .outer-container textarea[type=radio]{width:20px;height:20px}label .outer-container input[type=date],label .outer-container textarea[type=date]{background:white;display:block;min-width:calc(100% - 18px);line-height:37px}label .outer-container input[readonly],label .outer-container textarea[readonly]{cursor:default;pointer-events:none;user-select:none;color:gray}label .outer-container input:focus,label .outer-container textarea:focus{border-color:#1479c6}label .outer-container input:focus-visible,label .outer-container textarea:focus-visible{outline:none}label .outer-container textarea{padding:8px;height:auto;min-height:100px;resize:vertical}label .outer-container textarea.resize-none{resize:none}label .outer-container.inputBlock{display:flex;align-items:center;line-height:21px}label .outer-container.inputBlock .left-icons,label .outer-container.inputBlock .right-icons{margin-top:4px}label .outer-container.inputBlock.readonly{pointer-events:none;user-select:none;color:gray}label .outer-container.inputBlock.radioBlock{display:block}label .outer-container.inputInline{display:flex;white-space:nowrap;align-items:center;margin:0}label .outer-container.inputInline input{margin-top:0}label .secondarylabel{color:#757575;font-size:14px;line-height:16.408px;font-weight:normal;display:flex;margin-top:4px}label .errorBubble{position:relative;font-size:14px;line-height:16.408px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center;margin-top:4px}label .errorBubble:not(.visible){display:none}label .errorBubble span{color:#dc0000;font-size:16px;margin-right:4px}.material-symbols-rounded{font-family:\"Material Symbols Rounded\", sans-serif;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:#9e9e9e}button{cursor:pointer}.button{font-family:Roboto, serif;box-sizing:border-box;height:36px;min-width:36px;padding:0;margin:0;background:transparent;color:#212121;border:1px solid #c8c8c8;border-radius:4px;text-transform:uppercase;display:flex;justify-content:left;align-items:center;font-size:14px;font-weight:500}.button-content{display:block;padding:0 16px}.icon-left,.icon-right{margin-top:4px}.iconleft{padding-left:8px}.iconleft .button-content{padding-left:4px}.iconright{padding-right:8px}.iconright .button-content{padding-right:4px}.notext{padding:0 6px}.button:active{background:rgba(17, 17, 17, 0.2);border:1px solid #d5d5d5}.blackout{background:#363636;border:1px solid #363636;color:white}.blackout:active{background:#212121;border:1px solid #212121}.primary{background:#1479c6;border:1px solid #1479c6;color:white}.primary:active{background:#1464a2;border:1px solid #1464a2}.borderless{background:transparent;border:none;color:#212121}.borderless:active{background:rgba(17, 17, 17, 0.2);border:none}.borderless-circle{background:transparent;border:none;color:#212121;border-radius:50%}.borderless-circle:active{border:none}.borderless-circle:focus{border-color:transparent}.danger{background:#dc0000;border:1px solid #dc0000;color:white}.danger:active{background:#b00000;border:1px solid #b00000}.disabled{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}.disabled:active{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}@media (hover: hover){.button:hover{background:rgba(17, 17, 17, 0.1);border:1px solid #d5d5d5}.primary:hover{background:#146eb3;border:1px solid #146eb3}.borderless:hover{background:rgba(17, 17, 17, 0.1);border:none}.borderless-circle:hover{background:rgba(17, 17, 17, 0.1);border:none}.danger:hover{background:#c60000;border:1px solid #c60000}.disabled:hover{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}.blackout:hover{background:#212121;border:1px solid #212121}}:host{display:block}fieldset{margin:0;padding:0;border:none}label{display:block;position:relative;margin-bottom:16px}.inlineLabel{font-weight:400;display:inline-block;vertical-align:top;padding-top:4px}input[type=checkbox]{width:18px;height:18px}input~label{font-weight:400}select{font-family:\"Roboto\", serif;box-sizing:border-box;width:100%;height:36px;padding:0 16px;font-size:16px;border:1px solid #d5d5d5;border-radius:4px;margin-top:4px}.placeholder{color:#9e9e9e}.placeholder option{color:initial}select.invalid:invalid{border:1px solid #dc0000}select~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center}select~.errorBubble:not(.visible){visibility:hidden}select~.errorBubble span{color:#dc0000;font-size:16px;margin-right:4px;height:16px}select.invalid:invalid~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;visibility:visible}select:focus{border-color:#1479c6}select:focus-visible{outline:none}.button{padding:0 16px}.footer{display:flex;gap:16px;flex-direction:row-reverse}label.flex-label{display:flex;flex-direction:column;width:346px;box-sizing:border-box}label>.outer-container>input[type=date]{min-width:0;width:200px}label.flex-label input[type=time]{min-width:auto;text-align:center;width:130px;margin-left:16px}label>.outer-container>input[type=date],label.flex-label input[type=time]{line-height:36px}input[type=radio]~span{transform:translateY(-17%);display:inline-block;margin-left:5px}";
195
195
 
196
- const TttxForm = class {
197
- constructor(hostRef) {
198
- registerInstance(this, hostRef);
199
- this.dataSubmitted = createEvent(this, "dataSubmitted", 7);
200
- this.dataChanged = createEvent(this, "dataChanged", 7);
201
- this.searchTermChanged = createEvent(this, "searchTermChanged", 7);
202
- this.selectToggleOpen = createEvent(this, "selectToggleOpen", 7);
203
- // Create a new template element using the HTMLTemplateElement interface.
204
- this.template = document.createElement('template');
205
- this.formschema = undefined;
206
- this.data = undefined;
207
- }
208
- // This method is called whenever the "formschema" property changes
209
- onFormSchemaChange(newValue) {
210
- // Check if the new value is a string, indicating that it needs to be parsed
211
- if (typeof newValue === 'string') {
212
- // Parse the string and set the "_formSchema" property
213
- this._formSchema = JSON.parse(newValue);
214
- }
215
- else {
216
- // If the new value is already an object, set the "_formSchema" property directly
217
- this._formSchema = newValue;
218
- }
219
- return this._formSchema;
220
- }
221
- onDataChange(newValue) {
222
- if (typeof newValue === 'string') {
223
- this._data = JSON.parse(newValue);
224
- }
225
- else {
226
- this._data = newValue;
227
- }
228
- return this._data;
229
- }
230
- /**
231
- * Handles the focus event for a form field and emits a "dataChanged" event
232
- * to the parent component with the field name and its new value.
233
- *
234
- * @param {KeyboardEvent | Event} event - The focus event triggered by the field.
235
- * @return {void}
236
- */
237
- fieldChanged(event) {
238
- // Extract the name and value of the field from the event
239
- const target = event.target;
240
- const fieldName = target.name;
241
- let fieldValue = target.value;
242
- if (target.type === 'checkbox') {
243
- fieldValue = target.checked ? 'on' : 'off';
244
- }
245
- // Emit an event to signal that the field's data has changed
246
- this.dataChanged.emit({ name: fieldName, value: fieldValue });
247
- }
248
- async submit() {
249
- this.submitButton.click();
250
- }
251
- async showLoadingSpinner(fieldname, value) {
252
- const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
253
- tttxSelect.isLoading = value;
254
- }
255
- async setSelectedItem(fieldname, id) {
256
- const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
257
- // select option with id
258
- await tttxSelect.setSelectedItem(id);
259
- }
260
- /**
261
- * Replace all children in a given select list with a list of new options
262
- * @param { string } fieldname the form name of the given field
263
- * @param { {label: string, value: string}[] } options a list of option values and labels
264
- */
265
- async setSelectOptions(fieldname, options, skipDefultSelection) {
266
- const select = this.fieldset.querySelector(`[name=${fieldname}]`);
267
- const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
268
- const fragment = new DocumentFragment();
269
- for (const option of options) {
270
- const o = document.createElement('option');
271
- o.innerText = option.label;
272
- o.value = option.value;
273
- if (option.disabled) {
274
- o.disabled = true;
275
- }
276
- fragment.appendChild(o);
277
- }
278
- select.replaceChildren(fragment);
279
- tttxSelect.optionsData = options;
280
- // skip the first option selection if skipDefultSelection is true.
281
- if (!skipDefultSelection) {
282
- await tttxSelect.setSelectedItem(options.length > 0 ? options[0].value : undefined);
283
- }
284
- }
285
- async isValid() {
286
- const valid = this.form.checkValidity();
287
- const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
288
- if (allElements.length || !valid) {
289
- return false;
290
- }
291
- return true;
292
- }
293
- /**
294
- * Submits the form data to the server.
295
- *
296
- * @param {SubmitEvent} event - The event object for the form submission.
297
- * @returns {void}
298
- */
299
- doSubmit(event) {
300
- // prevent the form from submitting normally
301
- event.preventDefault();
302
- const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
303
- if (allElements.length) {
304
- return;
305
- }
306
- // create a new FormData object with the form data
307
- const formData = new FormData(event.target);
308
- // get a list of checkboxes, if any, so we can manually set unchecked box data
309
- const formProperties = this._formSchema.properties;
310
- for (const formKey of Object.keys(formProperties)) {
311
- if (formProperties[formKey].form.type === 'checkbox' && !formData.has(formKey)) {
312
- formData.append(formKey, 'off');
313
- }
314
- }
315
- // emit the form data through the `dataSubmitted` event
316
- this.dataSubmitted.emit(formData);
317
- }
318
- // This method is called before the component is loaded into the DOM
319
- componentWillLoad() {
320
- // Initialize the form schema by calling the "onFormSchemaChange" method with the current "formschema" property
321
- this.onFormSchemaChange(this.formschema);
322
- if (this.data) {
323
- this.onDataChange(this.data);
324
- }
325
- }
326
- // This method is called before the component is rendered
327
- componentWillRender() {
328
- // Clear the template to account for a potential re-render scenario
329
- this.template = document.createElement('template');
330
- // Populate the form from the form schema
331
- this.populateFormFromSchema();
332
- }
333
- /**
334
- * Creates a new HTMLSelectElement with a set of options.
335
- *
336
- * @param {string} formKey - The name of the dropdown field, as specified in the form schema.
337
- * @param {object} formProperties - An object containing additional properties, such as the field type and options properties.
338
- * @param {'select'} formProperties.type - The type of form field. In this case, it will always be "select".
339
- * @param {object} formProperties.validation - A set of validation rules for the field.
340
- * @param {Array<{label:string, value:string, placeholder?:boolean}>} formProperties.options - A list of properties to pass to the select options.
341
- * @param {string} formProperties.options[].label - The visible value of the option.
342
- * @param {string} formProperties.options[].value - The actual value of the option.
343
- * @param {boolean} [formProperties.options[].placeholder]
344
- */
345
- createSelect(formKey, formProperties) {
346
- var _a, _b, _c, _d, _e, _f;
347
- const select = document.createElement('select');
348
- select.setAttribute('name', formKey);
349
- (_a = formProperties.options) === null || _a === void 0 ? void 0 : _a.forEach(optionProperties => {
350
- this.appendOption(select, optionProperties);
351
- });
352
- if ((_b = this._data) === null || _b === void 0 ? void 0 : _b[formKey]) {
353
- select.classList.remove('placeholder');
354
- }
355
- const tttxSelect = document.createElement('tttx-select-box_localcomponent');
356
- tttxSelect.optionsData = (_c = formProperties.options) === null || _c === void 0 ? void 0 : _c.filter(o => !o.placeholder);
357
- tttxSelect.placeholder = (_e = (_d = formProperties.options) === null || _d === void 0 ? void 0 : _d.filter(o => o.placeholder)[0]) === null || _e === void 0 ? void 0 : _e.label;
358
- tttxSelect.inline = false;
359
- tttxSelect.searchEnabled = true;
360
- tttxSelect.useExternalFiltering = formProperties.useExternalFiltering || false;
361
- tttxSelect.style.width = '100%';
362
- tttxSelect.style.marginTop = '6px';
363
- tttxSelect.isLoading = formProperties.isLoading || false;
364
- tttxSelect.readOnly = (_f = formProperties.readOnly) !== null && _f !== void 0 ? _f : false;
365
- tttxSelect.setAttribute('name', 'overlay-' + formKey);
366
- const fragment = document.createDocumentFragment();
367
- fragment.append(tttxSelect);
368
- select.style.display = 'none';
369
- tttxSelect.addEventListener('selectItemEvent', this.selectItemEventCallback.bind(select));
370
- // emit the event for searchTermChanged.
371
- tttxSelect.addEventListener('multiselectSearchUpdated', (ev) => this.searchTermChanged.emit({
372
- name: formKey,
373
- value: ev.detail,
374
- type: 'SearchTermChanged'
375
- }));
376
- tttxSelect.addEventListener('toggleOpen', (ev) => this.selectToggleOpen.emit({
377
- name: formKey,
378
- value: ev.detail,
379
- type: 'ToggleOpen'
380
- }));
381
- return { input: select, overlay: fragment };
382
- }
383
- selectItemEventCallback(ev) {
384
- // this function MUST be bound to a HTMLSelectElement
385
- // 'this' will be the select element
386
- // the function was split out for testing
387
- const select = this;
388
- select.value = ev.detail.value;
389
- select.onblur({ target: select }); // triggers validator
390
- select.onchange({ target: select }); // triggers dataChanged event
391
- }
392
- /**
393
- * Appends an option to a select element
394
- *
395
- * @param {HTMLSelectElement} select - The select elements to attach the option to.
396
- * @param {Object} optionProperties
397
- * @param {string} optionProperties.value - The value of the option.
398
- * @param {string} optionProperties.label - The label which will be displayed on the form for the option.
399
- * @param {boolean} [optionProperties.placeholder]
400
- */
401
- appendOption(select, optionProperties) {
402
- const option = document.createElement('option');
403
- option.setAttribute('value', optionProperties.value);
404
- if (optionProperties.placeholder) {
405
- option.setAttribute('disabled', (optionProperties.disabled) ? 'true' : '');
406
- option.setAttribute('selected', '');
407
- option.setAttribute('hidden', '');
408
- select.classList.add('placeholder');
409
- }
410
- if (optionProperties.label)
411
- option.innerHTML = purify.sanitize(optionProperties.label, domSanitiserOptions);
412
- select.appendChild(option);
413
- }
414
- /**
415
- * Creates a new HTMLInputElement with the specified name, type, and placeholder (if any),
416
- * and sets its autocomplete and autocapitalization properties to off.
417
- *
418
- * @param {string} formKey - The name of the input field, as specified in the form schema.
419
- * @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
420
- * @param {string} formProperties.type - The type of the input field (e.g., "text", "email", "number", etc.).
421
- * @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
422
- * @return {HTMLInputElement} - The new input element.
423
- */
424
- createInput(formKey, formProperties) {
425
- var _a;
426
- // Create a new <input> element with the specified name and type
427
- const input = document.createElement('input');
428
- input.type = formProperties.type;
429
- input.name = formKey;
430
- // Set the placeholder attribute to the specified value (if any)
431
- input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
432
- // Disable autocomplete and autocapitalization
433
- input.autocomplete = 'off';
434
- input.autocapitalize = 'off';
435
- if (formProperties.readonly) {
436
- input.readOnly = true;
437
- }
438
- if (formProperties.maskedValue) {
439
- // Clear input on focus
440
- input.onfocus = () => {
441
- if (input.value === formProperties.maskedValue) {
442
- input.value = '';
443
- }
444
- };
445
- // Restore value or update it on blur
446
- input.addEventListener('blur', () => {
447
- if (input.value.trim() === '') {
448
- input.value = formProperties.maskedValue;
449
- }
450
- else {
451
- formProperties.value = input.value;
452
- }
453
- });
454
- }
455
- // Return the input element
456
- return input;
457
- }
458
- /**
459
- * Creates a new HTMLTextAreaElement with the specified name and placeholder (if any),
460
- * and sets its autocomplete and autocapitalization properties to off.
461
- *
462
- * @param {string} formKey - The name of the input field, as specified in the form schema.
463
- * @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
464
- * @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
465
- * @return {HTMLTextAreaElement} - The new input element.
466
- */
467
- createTextArea(formKey, formProperties) {
468
- var _a;
469
- const input = document.createElement('textarea');
470
- input.name = formKey;
471
- // Set the placeholder attribute to the specified value (if any)
472
- input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
473
- // Disable autocomplete and autocapitalization
474
- input.autocomplete = 'off';
475
- input.autocapitalize = 'off';
476
- if (formProperties.readonly) {
477
- input.readOnly = true;
478
- }
479
- if (formProperties.resize === 'none') {
480
- input.classList.add('resize-none');
481
- }
482
- // Return the input element
483
- return input;
484
- }
485
- createStartEndDateComponent(formKey, formProperties) {
486
- var _a, _b, _c, _d;
487
- const startDate = document.createElement('input');
488
- const endDate = document.createElement('input');
489
- startDate.type = endDate.type = 'date';
490
- startDate.name = `${formKey}-startdate`;
491
- endDate.name = `${formKey}-enddate`;
492
- startDate.setAttribute('data-formkey', formKey);
493
- endDate.setAttribute('data-formkey', formKey);
494
- if (formProperties.readonly) {
495
- startDate.readOnly = true;
496
- endDate.readOnly = true;
497
- }
498
- this.applyValidation(startDate, Object.assign({ required: { message: 'Please enter a start date' }, dateCompare: { to: endDate.name } }, (_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.startDate));
499
- this.applyValidation(endDate, Object.assign({ required: { message: 'Please enter an end date' }, dateCompare: { with: startDate.name, message: 'End date cannot be before the start date' } }, (_b = formProperties.validation) === null || _b === void 0 ? void 0 : _b.endDate));
500
- let startTime;
501
- let endTime;
502
- if (formProperties.includeTime) {
503
- startTime = document.createElement('input');
504
- endTime = document.createElement('input');
505
- startTime.type = endTime.type = 'time';
506
- startTime.name = `${formKey}-starttime`;
507
- endTime.name = `${formKey}-endtime`;
508
- startTime.setAttribute('data-formkey', formKey);
509
- endTime.setAttribute('data-formkey', formKey);
510
- if (formProperties.readonly) {
511
- startTime.readOnly = true;
512
- endTime.readOnly = true;
513
- }
514
- this.applyValidation(startTime, Object.assign({ required: { message: 'Please enter a start time' } }, (_c = formProperties.validation) === null || _c === void 0 ? void 0 : _c.startTime));
515
- this.applyValidation(endTime, Object.assign({ required: { message: 'Please enter an end time' } }, (_d = formProperties.validation) === null || _d === void 0 ? void 0 : _d.endTime));
516
- }
517
- const startLabel = document.createElement('label');
518
- startLabel.innerText = 'Start date';
519
- const endLabel = document.createElement('label');
520
- endLabel.innerText = 'End date';
521
- const startContainer = document.createElement('div');
522
- const endContainer = document.createElement('div');
523
- startContainer.className = endContainer.className = 'outer-container inputBlock';
524
- startLabel.className = endLabel.className = 'flex-label';
525
- startContainer.append(startDate);
526
- if (startTime) {
527
- startContainer.append(startTime);
528
- }
529
- startLabel.append(startContainer);
530
- startLabel.append(this.createErrorBubble());
531
- endContainer.append(endDate);
532
- if (endTime) {
533
- endContainer.append(endTime);
534
- }
535
- endLabel.append(endContainer);
536
- endLabel.append(this.createErrorBubble());
537
- return { start: startLabel, end: endLabel };
538
- }
539
- /**
540
- * Applies validation attributes to an input element based on the specified validation object.
541
- * If a certain property is present in the object, it will set the corresponding attribute on
542
- * the input element (e.g., "required" will set the "required" and "data-required" attributes,
543
- * "pattern" will set the "pattern" and "data-pattern" attributes, etc.).
544
- *
545
- * @param {FormField} input - The input element to apply validation attributes to.
546
- * @param {object} validation - An object containing the validation rules for the input field.
547
- * @param {object} [validation.required] - An object containing a "message" property to display if the field is required.
548
- * @param {string} [validation.required.message]
549
- * @param {object} [validation.pattern] - An object containing a "pattern" property to match against the field value, and a "message" property to display if the pattern doesn't match.
550
- * @param {string} [validation.pattern.pattern]
551
- * @param {string} [validation.pattern.message]
552
- * @param {object} [validation.badInput] - An object containing a "message" property to display if the field value is invalid.
553
- * @param {string} [validation.badInput.message]
554
- * @param {object} [validation.minmax] - An object containing "min" and "max" properties to validate the field value against, and a "message" property to display if the value is out of range.
555
- * @param {string} [validation.minmax.min]
556
- * @param {string} [validation.minmax.max]
557
- * @param {string} [validation.minmax.message]
558
- * @param {string} [validation.maxlength] - The maximum length of the input field.
559
- * @param {string} [validation.datecompare] - To compare start and end date fields.
560
- * @return {void}
561
- */
562
- applyValidation(input, validation) {
563
- var _a, _b;
564
- // If the "required" property is present, add the "required" attribute to the input element and
565
- // set its "data-required" attribute to the specified message (if any)
566
- if (validation.required) {
567
- input.setAttribute('required', '');
568
- input.setAttribute('data-required', (_a = validation.required.message) !== null && _a !== void 0 ? _a : '');
569
- }
570
- // If the "pattern" property is present, add the "pattern" attribute to the input element and set
571
- // its "data-pattern" attribute to the specified message (if any)
572
- if (validation.pattern) {
573
- input.setAttribute('pattern', validation.pattern.pattern);
574
- input.setAttribute('data-pattern', (_b = validation.pattern.message) !== null && _b !== void 0 ? _b : '');
575
- }
576
- // If the "badInput" property is present, set the input element's "data-badinput" attribute to
577
- // the specified message
578
- if (validation.badInput) {
579
- input.setAttribute('data-badinput', validation.badInput.message);
580
- }
581
- // If the "minmax" property is present, add the "min" and "max" attributes to the input element
582
- // and set its "data-range" attribute to the specified message (if any)
583
- if (validation.minmax) {
584
- input.setAttribute('min', validation.minmax.min);
585
- input.setAttribute('max', validation.minmax.max);
586
- input.setAttribute('data-range', validation.minmax.message);
587
- }
588
- // If the "maxlength" property is present, add the "maxlength" attribute to the input element
589
- if (validation.maxlength) {
590
- input.setAttribute('maxlength', validation.maxlength);
591
- }
592
- // Custom validation parameters for start date and end date comparison
593
- if (validation.dateCompare) {
594
- if (validation.dateCompare.message && validation.dateCompare.with) {
595
- input.setAttribute('data-compare', validation.dateCompare.message);
596
- input.setAttribute('data-compare-with', validation.dateCompare.with);
597
- }
598
- if (validation.dateCompare.to) {
599
- input.setAttribute('data-compare-to', validation.dateCompare.to);
600
- }
601
- }
602
- }
603
- // Create a new error bubble element
604
- createErrorBubble() {
605
- // Create a new <div> element with the "errorBubble" class
606
- const errorBubble = document.createElement('div');
607
- errorBubble.className = 'errorBubble';
608
- // Return the error bubble element
609
- return errorBubble;
610
- }
611
- /**
612
- *
613
- * @param {Record<string, any>} formProperties
614
- * @param {HTMLInputElement | HTMLSelectElement} input
615
- * @param {HTMLLabelElement} label
616
- * @returns {void}
617
- */
618
- appendCheckboxInput(formProperties, input, label) {
619
- if (formProperties.label) {
620
- const lineBreak = document.createElement('br');
621
- label.appendChild(lineBreak);
622
- }
623
- // Append the input element and error bubble element to the label
624
- label.appendChild(input);
625
- if (!formProperties.inlineLabel)
626
- return;
627
- const inlineLabel = document.createElement('span');
628
- inlineLabel.className = 'inlineLabel';
629
- inlineLabel.textContent = formProperties.inlineLabel;
630
- label.appendChild(inlineLabel);
631
- }
632
- /**
633
- * Creates a new <label> element with the "inputBlock" class and the specified label text,
634
- * and appends the input element and error bubble element to it. If the form property has
635
- * no validation object, it adds an "optional" span element to the label.
636
- *
637
- * @param {Record<string, any>} formProperties - An object containing properties for the form field, including its label text and validation rules.
638
- * @param {HTMLInputElement | HTMLSelectElement} input - The input element to associate with the label.
639
- * @param {never} overlay - The Child Element which will be rendered atop the standard HTML5 element
640
- * @param {HTMLDivElement} errorBubble - The error bubble element to display error messages in.
641
- * @return {HTMLLabelElement} - The new label element.
642
- */
643
- createLabel(formProperties, input, overlay = null, errorBubble) {
644
- var _a;
645
- const outerContainer = document.createElement('div');
646
- let outerContainerClassName = 'outer-container inputBlock';
647
- // Create a new <label> element with the "inputBlock" class and the specified text
648
- const label = document.createElement('label');
649
- label.innerText = formProperties.label;
650
- // If the form property has no validation object, add an "optional" span element to the label
651
- if (!((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) && formProperties.label) {
652
- const optionalSpan = document.createElement('span');
653
- optionalSpan.className = 'optional';
654
- optionalSpan.innerHTML = '&nbsp;(optional)';
655
- label.appendChild(optionalSpan);
656
- }
657
- if (formProperties.type === 'radio') {
658
- outerContainerClassName += ' radioBlock';
659
- }
660
- outerContainer.className = outerContainerClassName;
661
- if (formProperties.readonly) {
662
- label.classList.add('readonly');
663
- }
664
- if (formProperties.type === 'checkbox') {
665
- this.appendCheckboxInput(formProperties, input, label);
666
- }
667
- else {
668
- // Append the input element and error bubble element to the outerContainer
669
- if (overlay) {
670
- outerContainer.appendChild(overlay);
671
- }
672
- outerContainer.appendChild(input);
673
- }
674
- if (formProperties.type !== 'checkbox') {
675
- label.appendChild(outerContainer);
676
- }
677
- label.appendChild(errorBubble);
678
- // Return the label element
679
- return label;
680
- }
681
- /**
682
- * Creates a new radio input with a set of options.
683
- *
684
- * @param {string} formKey - The name of the dropdown field, as specified in the form schema.
685
- * @param {Object} formProperties - An object containing additional properties, such as the field type and options properties.
686
- * @param {'radio'} formProperties.type - The type of form field. In this case, it will always be "radio".
687
- * @param {Object} formProperties.validation - A set of validation rules for the field.
688
- * @param {Object[]} formProperties.options - A list of properties to pass to the select options.
689
- * @param {string} formProperties.options.label - The visible value of the option.
690
- * @param {string} formProperties.options.value - The actual value of the option.
691
- */
692
- createRadio(formKey, formProperties) {
693
- var _a, _b;
694
- const fragment = document.createDocumentFragment();
695
- for (const optionProperties of formProperties.options) {
696
- // Create a new <input> element with the specified name and type
697
- const input = document.createElement('input');
698
- input.type = 'radio';
699
- input.name = formKey;
700
- input.value = optionProperties.value;
701
- if ((_a = formProperties === null || formProperties === void 0 ? void 0 : formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) {
702
- input.setAttribute('required', 'required');
703
- input.setAttribute('data-required', (_b = formProperties.validation.required.message) !== null && _b !== void 0 ? _b : '');
704
- }
705
- const span = document.createElement('span');
706
- span.innerText = optionProperties.label;
707
- fragment.appendChild(input);
708
- fragment.appendChild(span);
709
- fragment.appendChild(document.createElement('br'));
710
- }
711
- return fragment;
712
- }
713
- /**
714
- * Populates the form template with input fields and labels based on the properties of the
715
- * current form schema. For each property in the schema, it creates an input element, applies
716
- * any validation rules to it, creates an error bubble and label element, and appends them
717
- * to the form template. Finally, it creates and appends a submit button element to the form.
718
- *
719
- * @return {void}
720
- */
721
- populateFormFromSchema() {
722
- var _a;
723
- // If there is no form schema, return early
724
- if (!this._formSchema) {
725
- return;
726
- }
727
- // Get the properties of the form schema and their keys
728
- const properties = this._formSchema.properties;
729
- const propertyKeys = Object.keys(properties);
730
- // Loop through each property key and create an input, label, and error bubble for it
731
- for (const formKey of propertyKeys) {
732
- const formItem = properties[formKey];
733
- const formProperties = formItem.form;
734
- // complex form types which require
735
- // custom HTML should be done here
736
- if (formProperties.type === 'startenddate') {
737
- const { start, end } = this.createStartEndDateComponent(formKey, formProperties);
738
- this.template.content.append(start);
739
- this.template.content.append(end);
740
- continue;
741
- }
742
- let fragments = {};
743
- switch (formProperties.type) {
744
- case 'select':
745
- fragments = this.createSelect(formKey, formProperties);
746
- break;
747
- case 'radio':
748
- fragments.input = this.createRadio(formKey, formProperties);
749
- break;
750
- case 'textarea':
751
- fragments.input = this.createTextArea(formKey, formProperties);
752
- break;
753
- default:
754
- fragments.input = this.createInput(formKey, formProperties);
755
- }
756
- // If the form property has validation, apply it to the input
757
- if (formProperties.validation &&
758
- formProperties.type !== 'radio') {
759
- this.applyValidation(fragments.input, formProperties.validation);
760
- }
761
- // Create an error bubble and label element for the input
762
- const errorBubble = this.createErrorBubble();
763
- const label = this.createLabel(formProperties, fragments.input, fragments.overlay, errorBubble);
764
- // If explicitly setting input as invalid, set invalid state and error message on render
765
- if ((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.invalid) {
766
- const errorMessage = formProperties.validation.invalid.message;
767
- fragments.input.setCustomValidity(errorMessage); // Prevents the invalid styling from resetting on blur
768
- setErrorState(fragments.input, true, errorMessage);
769
- }
770
- // Append the label element to the form template
771
- this.template.content.append(label);
772
- if (formProperties.disabled) {
773
- this.toggleFormField(fragments.input, true);
774
- }
775
- }
776
- }
777
- /**
778
- * Clones the form template and binds event listeners to its input elements. First, it checks if
779
- * there is a form schema present. If so, it clones the template's content, binds events to form
780
- * input elements, and appends the cloned form elements to the fieldset. The event listeners include
781
- * "oninvalid" (to check input validity on submit), "onblur" (to check input validity on blur),
782
- * "onkeyup" (to handle changes in input fields), and "onchange" (to handle changes in select fields).
783
- *
784
- * @return {void}
785
- */
786
- componentDidRender() {
787
- // If there's no form schema, return
788
- if (!this._formSchema) {
789
- return;
790
- }
791
- // Clone the template's content and store it in a variable
792
- const formItems = this.template.content;
793
- // Bind event listeners to form elements
794
- const properties = this._formSchema.properties;
795
- const propertyKeys = Object.keys(properties);
796
- for (const formKey of propertyKeys) {
797
- this.applyValidationFunctionsToFormElement(formItems, formKey, properties);
798
- }
799
- // populate with existing form data if available
800
- if ((this._data && Object.keys(this._data).length > 0)) {
801
- this.populateFormWithExistingData(formItems);
802
- }
803
- // Append the cloned form elements to the fieldset
804
- this.fieldset.replaceChildren(formItems);
805
- }
806
- /**
807
- * Assign validation events to a given form item
808
- * @param formItems The document fragment template of form items to be rendered
809
- * @param formKey The key of the form item to bind events too
810
- * @param properties The form item's properties, such as type and name
811
- */
812
- applyValidationFunctionsToFormElement(formItems, formKey, properties) {
813
- const formItemsByKey = formItems.querySelectorAll(`[name^=${formKey}]`);
814
- for (const formInput of formItemsByKey) {
815
- // Bind events to form input elements
816
- formInput.oninvalid = this.validityCheckWrapper.bind(this);
817
- formInput.onblur = this.validityCheckWrapper.bind(this);
818
- formInput.onkeyup = this.fieldChanged.bind(this);
819
- formInput.onchange = this.fieldChanged.bind(this);
820
- if (properties[formKey].form.type === 'select' && formInput.classList.contains('placeholder')) {
821
- formInput.addEventListener('change', this.selectRemovePlaceholderCallback.bind(formInput));
822
- }
823
- if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-with')) {
824
- formInput.oninvalid = endDateComparisonValidator.bind(this);
825
- formInput.onblur = endDateComparisonValidator.bind(this);
826
- }
827
- if (properties[formKey].form.type === 'startenddate' && formInput.type === 'time') {
828
- formInput.oninvalid = startEndTimeComparator.bind(this);
829
- formInput.onblur = startEndTimeComparator.bind(this);
830
- }
831
- if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-to')) {
832
- formInput.oninvalid = startDateComparisonValidator.bind(this);
833
- formInput.onblur = startDateComparisonValidator.bind(this);
834
- }
835
- }
836
- }
837
- /**
838
- * If data exists, set form input values before rendering
839
- * @param formItems The document fragment template of form items to be rendered
840
- */
841
- populateFormWithExistingData(formItems) {
842
- var _a;
843
- const dataKeys = Object.keys(this._data);
844
- for (const key of dataKeys) {
845
- const formItemsByKey = formItems.querySelectorAll(`[name=${key}]`);
846
- for (const formItem of formItemsByKey) {
847
- switch (formItem.type) {
848
- case 'checkbox':
849
- if (this._data[key] === 'on') {
850
- formItem.checked = true;
851
- }
852
- break;
853
- case 'radio':
854
- if (formItem.value === this._data[key]) {
855
- formItem.checked = true;
856
- }
857
- break;
858
- case 'select':
859
- case 'select-one':
860
- formItems.querySelector(`[name=overlay-${key}]`)['selectedValue'] = this._data[key];
861
- formItem.value = this._data[key];
862
- break;
863
- case 'date':
864
- formItem.value = (_a = this._data[key]) === null || _a === void 0 ? void 0 : _a.split('T')[0];
865
- break;
866
- default:
867
- formItem.value = this._data[key];
868
- }
869
- }
870
- }
871
- }
872
- /**
873
- * Remove the placeholder class on the bound THIS select element
874
- */
875
- selectRemovePlaceholderCallback() {
876
- const select = this;
877
- select.classList.remove('placeholder');
878
- }
879
- /**
880
- * A wrapper around validity check and set error state
881
- */
882
- validityCheckWrapper(event) {
883
- const { target, hasError, errorMessage } = validityCheck(event);
884
- setErrorState(target, hasError, errorMessage);
885
- }
886
- assignFieldsetReference(el) {
887
- this.fieldset = el;
888
- }
889
- assignButtonReference(el) {
890
- this.submitButton = el;
891
- }
892
- /**
893
- * An external validation trigger to apply to a form field
894
- * @param { string } fieldName The form field name to apply the validation too
895
- * @param { string } message The validation message to display under the form field
896
- */
897
- async setValidationFor(fieldName, message) {
898
- const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
899
- if (formField.disabled) {
900
- return;
901
- }
902
- formField.setCustomValidity(message);
903
- formField.setAttribute('custom-validation-set', 'true');
904
- setErrorState(formField, true, message);
905
- }
906
- /**
907
- * Clear the validation message on a given form field
908
- * @param { string } fieldName The form field name to clear the validation of
909
- */
910
- async clearValidationFor(fieldName) {
911
- const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
912
- formField.setCustomValidity('');
913
- formField.removeAttribute('custom-validation-set');
914
- setErrorState(formField, false, '');
915
- }
916
- toggleFormField(formField, disabled) {
917
- formField.disabled = disabled;
918
- let parent = formField.parentElement;
919
- if (parent) {
920
- do {
921
- if (parent.nodeName !== 'LABEL') {
922
- parent = parent.parentElement;
923
- }
924
- } while (parent && parent.nodeName !== 'LABEL');
925
- if (parent) {
926
- parent.style.display = (disabled) ? 'none' : 'block';
927
- }
928
- }
929
- }
930
- /**
931
- * Disable a form field and visually remove it from the form.
932
- * If custom validation is set, this function will return without affecting the form field.
933
- * @param { string } fieldName The form field name to disable
934
- */
935
- async disableFormField(fieldName) {
936
- const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
937
- if (formField.hasAttribute('custom-validation-set')) {
938
- return;
939
- }
940
- this.toggleFormField(formField, true);
941
- }
942
- /**
943
- * Enable a form field and visually add it back to the form.
944
- * @param { string } fieldName The form field name to enable
945
- */
946
- async enableFormField(fieldName) {
947
- const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
948
- this.toggleFormField(formField, false);
949
- }
950
- /**
951
- * Set the value of a form field progromatically
952
- * @param { string } fieldName The form field name having it's value set
953
- * @param { string } fieldValue The form field value to set
954
- */
955
- async setInputFieldValue(fieldName, fieldValue) {
956
- const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
957
- formField.value = fieldValue;
958
- }
959
- /**
960
- * Change the readonly property on an input field. If set to 'true' any validation will also be cleared.
961
- * @param { string } fieldName The form field name to set
962
- * @param { boolean } readonly The state of the read-only attribute
963
- */
964
- async setFieldReadOnlyMode(fieldName, readonly) {
965
- const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
966
- if (formField && formField.nodeName === 'SELECT') {
967
- const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldName}]`);
968
- tttxSelect.readOnly = readonly;
969
- formField.disabled = readonly;
970
- }
971
- else {
972
- formField.readOnly = readonly;
973
- }
974
- if (readonly) {
975
- await this.clearValidationFor(fieldName);
976
- }
977
- }
978
- /**
979
- * Renders the component's template as a form element with a fieldset container. The form's
980
- * "onSubmit" event is bound to the "doSubmit" function, which handles the form submission
981
- * and emits a "dataSubmitted" event with the form data. The fieldset element is assigned
982
- * to the "fieldset" instance variable using a ref, so it can be populated with form elements
983
- * later on.
984
- */
985
- render() {
986
- //react rendering so we can't JEST it
987
- //ignore so it doesn't ruin coverage
988
- /*istanbul ignore next*/
989
- return (h(Host, null, h("form", { onSubmit: this.doSubmit.bind(this), ref: frm => this.form = frm }, h("fieldset", { ref: this.assignFieldsetReference.bind(this) }), h("input", { type: "submit", ref: this.assignButtonReference.bind(this), style: { display: 'none' } }))));
990
- }
991
- static get watchers() { return {
992
- "formschema": ["onFormSchemaChange"],
993
- "data": ["onDataChange"]
994
- }; }
995
- };
196
+ const TttxForm = class {
197
+ constructor(hostRef) {
198
+ registerInstance(this, hostRef);
199
+ this.dataSubmitted = createEvent(this, "dataSubmitted", 7);
200
+ this.dataChanged = createEvent(this, "dataChanged", 7);
201
+ this.searchTermChanged = createEvent(this, "searchTermChanged", 7);
202
+ this.selectToggleOpen = createEvent(this, "selectToggleOpen", 7);
203
+ // Create a new template element using the HTMLTemplateElement interface.
204
+ this.template = document.createElement('template');
205
+ this.formschema = undefined;
206
+ this.data = undefined;
207
+ }
208
+ // This method is called whenever the "formschema" property changes
209
+ onFormSchemaChange(newValue) {
210
+ // Check if the new value is a string, indicating that it needs to be parsed
211
+ if (typeof newValue === 'string') {
212
+ // Parse the string and set the "_formSchema" property
213
+ this._formSchema = JSON.parse(newValue);
214
+ }
215
+ else {
216
+ // If the new value is already an object, set the "_formSchema" property directly
217
+ this._formSchema = newValue;
218
+ }
219
+ return this._formSchema;
220
+ }
221
+ onDataChange(newValue) {
222
+ if (typeof newValue === 'string') {
223
+ this._data = JSON.parse(newValue);
224
+ }
225
+ else {
226
+ this._data = newValue;
227
+ }
228
+ return this._data;
229
+ }
230
+ /**
231
+ * Handles the focus event for a form field and emits a "dataChanged" event
232
+ * to the parent component with the field name and its new value.
233
+ *
234
+ * @param {KeyboardEvent | Event} event - The focus event triggered by the field.
235
+ * @return {void}
236
+ */
237
+ fieldChanged(event) {
238
+ // Extract the name and value of the field from the event
239
+ const target = event.target;
240
+ const fieldName = target.name;
241
+ let fieldValue = target.value;
242
+ if (target.type === 'checkbox') {
243
+ fieldValue = target.checked ? 'on' : 'off';
244
+ }
245
+ // Emit an event to signal that the field's data has changed
246
+ this.dataChanged.emit({ name: fieldName, value: fieldValue });
247
+ }
248
+ async submit() {
249
+ this.submitButton.click();
250
+ }
251
+ async showLoadingSpinner(fieldname, value) {
252
+ const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
253
+ tttxSelect.isLoading = value;
254
+ }
255
+ async setSelectedItem(fieldname, id) {
256
+ const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
257
+ // select option with id
258
+ await tttxSelect.setSelectedItem(id);
259
+ }
260
+ /**
261
+ * Replace all children in a given select list with a list of new options
262
+ * @param { string } fieldname the form name of the given field
263
+ * @param { {label: string, value: string}[] } options a list of option values and labels
264
+ */
265
+ async setSelectOptions(fieldname, options, skipDefultSelection) {
266
+ const select = this.fieldset.querySelector(`[name=${fieldname}]`);
267
+ const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
268
+ const fragment = new DocumentFragment();
269
+ for (const option of options) {
270
+ const o = document.createElement('option');
271
+ o.innerText = option.label;
272
+ o.value = option.value;
273
+ if (option.disabled) {
274
+ o.disabled = true;
275
+ }
276
+ fragment.appendChild(o);
277
+ }
278
+ select.replaceChildren(fragment);
279
+ tttxSelect.optionsData = options;
280
+ // skip the first option selection if skipDefultSelection is true.
281
+ if (!skipDefultSelection) {
282
+ await tttxSelect.setSelectedItem(options.length > 0 ? options[0].value : undefined);
283
+ }
284
+ }
285
+ async isValid() {
286
+ const valid = this.form.checkValidity();
287
+ const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
288
+ if (allElements.length || !valid) {
289
+ return false;
290
+ }
291
+ return true;
292
+ }
293
+ /**
294
+ * Submits the form data to the server.
295
+ *
296
+ * @param {SubmitEvent} event - The event object for the form submission.
297
+ * @returns {void}
298
+ */
299
+ doSubmit(event) {
300
+ // prevent the form from submitting normally
301
+ event.preventDefault();
302
+ const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
303
+ if (allElements.length) {
304
+ return;
305
+ }
306
+ // create a new FormData object with the form data
307
+ const formData = new FormData(event.target);
308
+ // get a list of checkboxes, if any, so we can manually set unchecked box data
309
+ const formProperties = this._formSchema.properties;
310
+ for (const formKey of Object.keys(formProperties)) {
311
+ if (formProperties[formKey].form.type === 'checkbox' && !formData.has(formKey)) {
312
+ formData.append(formKey, 'off');
313
+ }
314
+ }
315
+ // emit the form data through the `dataSubmitted` event
316
+ this.dataSubmitted.emit(formData);
317
+ }
318
+ // This method is called before the component is loaded into the DOM
319
+ componentWillLoad() {
320
+ // Initialize the form schema by calling the "onFormSchemaChange" method with the current "formschema" property
321
+ this.onFormSchemaChange(this.formschema);
322
+ if (this.data) {
323
+ this.onDataChange(this.data);
324
+ }
325
+ }
326
+ // This method is called before the component is rendered
327
+ componentWillRender() {
328
+ // Clear the template to account for a potential re-render scenario
329
+ this.template = document.createElement('template');
330
+ // Populate the form from the form schema
331
+ this.populateFormFromSchema();
332
+ }
333
+ /**
334
+ * Creates a new HTMLSelectElement with a set of options.
335
+ *
336
+ * @param {string} formKey - The name of the dropdown field, as specified in the form schema.
337
+ * @param {object} formProperties - An object containing additional properties, such as the field type and options properties.
338
+ * @param {'select'} formProperties.type - The type of form field. In this case, it will always be "select".
339
+ * @param {object} formProperties.validation - A set of validation rules for the field.
340
+ * @param {Array<{label:string, value:string, placeholder?:boolean}>} formProperties.options - A list of properties to pass to the select options.
341
+ * @param {string} formProperties.options[].label - The visible value of the option.
342
+ * @param {string} formProperties.options[].value - The actual value of the option.
343
+ * @param {boolean} [formProperties.options[].placeholder]
344
+ */
345
+ createSelect(formKey, formProperties) {
346
+ var _a, _b, _c, _d, _e, _f;
347
+ const select = document.createElement('select');
348
+ select.setAttribute('name', formKey);
349
+ (_a = formProperties.options) === null || _a === void 0 ? void 0 : _a.forEach(optionProperties => {
350
+ this.appendOption(select, optionProperties);
351
+ });
352
+ if ((_b = this._data) === null || _b === void 0 ? void 0 : _b[formKey]) {
353
+ select.classList.remove('placeholder');
354
+ }
355
+ const tttxSelect = document.createElement('tttx-select-box_1_9_103');
356
+ tttxSelect.optionsData = (_c = formProperties.options) === null || _c === void 0 ? void 0 : _c.filter(o => !o.placeholder);
357
+ tttxSelect.placeholder = (_e = (_d = formProperties.options) === null || _d === void 0 ? void 0 : _d.filter(o => o.placeholder)[0]) === null || _e === void 0 ? void 0 : _e.label;
358
+ tttxSelect.inline = false;
359
+ tttxSelect.searchEnabled = true;
360
+ tttxSelect.useExternalFiltering = formProperties.useExternalFiltering || false;
361
+ tttxSelect.style.width = '100%';
362
+ tttxSelect.style.marginTop = '6px';
363
+ tttxSelect.isLoading = formProperties.isLoading || false;
364
+ tttxSelect.readOnly = (_f = formProperties.readOnly) !== null && _f !== void 0 ? _f : false;
365
+ tttxSelect.setAttribute('name', 'overlay-' + formKey);
366
+ const fragment = document.createDocumentFragment();
367
+ fragment.append(tttxSelect);
368
+ select.style.display = 'none';
369
+ tttxSelect.addEventListener('selectItemEvent', this.selectItemEventCallback.bind(select));
370
+ // emit the event for searchTermChanged.
371
+ tttxSelect.addEventListener('multiselectSearchUpdated', (ev) => this.searchTermChanged.emit({
372
+ name: formKey,
373
+ value: ev.detail,
374
+ type: 'SearchTermChanged'
375
+ }));
376
+ tttxSelect.addEventListener('toggleOpen', (ev) => this.selectToggleOpen.emit({
377
+ name: formKey,
378
+ value: ev.detail,
379
+ type: 'ToggleOpen'
380
+ }));
381
+ return { input: select, overlay: fragment };
382
+ }
383
+ selectItemEventCallback(ev) {
384
+ // this function MUST be bound to a HTMLSelectElement
385
+ // 'this' will be the select element
386
+ // the function was split out for testing
387
+ const select = this;
388
+ select.value = ev.detail.value;
389
+ select.onblur({ target: select }); // triggers validator
390
+ select.onchange({ target: select }); // triggers dataChanged event
391
+ }
392
+ /**
393
+ * Appends an option to a select element
394
+ *
395
+ * @param {HTMLSelectElement} select - The select elements to attach the option to.
396
+ * @param {Object} optionProperties
397
+ * @param {string} optionProperties.value - The value of the option.
398
+ * @param {string} optionProperties.label - The label which will be displayed on the form for the option.
399
+ * @param {boolean} [optionProperties.placeholder]
400
+ */
401
+ appendOption(select, optionProperties) {
402
+ const option = document.createElement('option');
403
+ option.setAttribute('value', optionProperties.value);
404
+ if (optionProperties.placeholder) {
405
+ option.setAttribute('disabled', (optionProperties.disabled) ? 'true' : '');
406
+ option.setAttribute('selected', '');
407
+ option.setAttribute('hidden', '');
408
+ select.classList.add('placeholder');
409
+ }
410
+ if (optionProperties.label)
411
+ option.innerHTML = purify.sanitize(optionProperties.label, domSanitiserOptions);
412
+ select.appendChild(option);
413
+ }
414
+ /**
415
+ * Creates a new HTMLInputElement with the specified name, type, and placeholder (if any),
416
+ * and sets its autocomplete and autocapitalization properties to off.
417
+ *
418
+ * @param {string} formKey - The name of the input field, as specified in the form schema.
419
+ * @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
420
+ * @param {string} formProperties.type - The type of the input field (e.g., "text", "email", "number", etc.).
421
+ * @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
422
+ * @return {HTMLInputElement} - The new input element.
423
+ */
424
+ createInput(formKey, formProperties) {
425
+ var _a;
426
+ // Create a new <input> element with the specified name and type
427
+ const input = document.createElement('input');
428
+ input.type = formProperties.type;
429
+ input.name = formKey;
430
+ // Set the placeholder attribute to the specified value (if any)
431
+ input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
432
+ // Disable autocomplete and autocapitalization
433
+ input.autocomplete = 'off';
434
+ input.autocapitalize = 'off';
435
+ if (formProperties.readonly) {
436
+ input.readOnly = true;
437
+ }
438
+ if (formProperties.maskedValue) {
439
+ // Clear input on focus
440
+ input.onfocus = () => {
441
+ if (input.value === formProperties.maskedValue) {
442
+ input.value = '';
443
+ }
444
+ };
445
+ // Restore value or update it on blur
446
+ input.addEventListener('blur', () => {
447
+ if (input.value.trim() === '') {
448
+ input.value = formProperties.maskedValue;
449
+ }
450
+ else {
451
+ formProperties.value = input.value;
452
+ }
453
+ });
454
+ }
455
+ // Return the input element
456
+ return input;
457
+ }
458
+ /**
459
+ * Creates a new HTMLTextAreaElement with the specified name and placeholder (if any),
460
+ * and sets its autocomplete and autocapitalization properties to off.
461
+ *
462
+ * @param {string} formKey - The name of the input field, as specified in the form schema.
463
+ * @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
464
+ * @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
465
+ * @return {HTMLTextAreaElement} - The new input element.
466
+ */
467
+ createTextArea(formKey, formProperties) {
468
+ var _a;
469
+ const input = document.createElement('textarea');
470
+ input.name = formKey;
471
+ // Set the placeholder attribute to the specified value (if any)
472
+ input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
473
+ // Disable autocomplete and autocapitalization
474
+ input.autocomplete = 'off';
475
+ input.autocapitalize = 'off';
476
+ if (formProperties.readonly) {
477
+ input.readOnly = true;
478
+ }
479
+ if (formProperties.resize === 'none') {
480
+ input.classList.add('resize-none');
481
+ }
482
+ // Return the input element
483
+ return input;
484
+ }
485
+ createStartEndDateComponent(formKey, formProperties) {
486
+ var _a, _b, _c, _d;
487
+ const startDate = document.createElement('input');
488
+ const endDate = document.createElement('input');
489
+ startDate.type = endDate.type = 'date';
490
+ startDate.name = `${formKey}-startdate`;
491
+ endDate.name = `${formKey}-enddate`;
492
+ startDate.setAttribute('data-formkey', formKey);
493
+ endDate.setAttribute('data-formkey', formKey);
494
+ if (formProperties.readonly) {
495
+ startDate.readOnly = true;
496
+ endDate.readOnly = true;
497
+ }
498
+ this.applyValidation(startDate, Object.assign({ required: { message: 'Please enter a start date' }, dateCompare: { to: endDate.name } }, (_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.startDate));
499
+ this.applyValidation(endDate, Object.assign({ required: { message: 'Please enter an end date' }, dateCompare: { with: startDate.name, message: 'End date cannot be before the start date' } }, (_b = formProperties.validation) === null || _b === void 0 ? void 0 : _b.endDate));
500
+ let startTime;
501
+ let endTime;
502
+ if (formProperties.includeTime) {
503
+ startTime = document.createElement('input');
504
+ endTime = document.createElement('input');
505
+ startTime.type = endTime.type = 'time';
506
+ startTime.name = `${formKey}-starttime`;
507
+ endTime.name = `${formKey}-endtime`;
508
+ startTime.setAttribute('data-formkey', formKey);
509
+ endTime.setAttribute('data-formkey', formKey);
510
+ if (formProperties.readonly) {
511
+ startTime.readOnly = true;
512
+ endTime.readOnly = true;
513
+ }
514
+ this.applyValidation(startTime, Object.assign({ required: { message: 'Please enter a start time' } }, (_c = formProperties.validation) === null || _c === void 0 ? void 0 : _c.startTime));
515
+ this.applyValidation(endTime, Object.assign({ required: { message: 'Please enter an end time' } }, (_d = formProperties.validation) === null || _d === void 0 ? void 0 : _d.endTime));
516
+ }
517
+ const startLabel = document.createElement('label');
518
+ startLabel.innerText = 'Start date';
519
+ const endLabel = document.createElement('label');
520
+ endLabel.innerText = 'End date';
521
+ const startContainer = document.createElement('div');
522
+ const endContainer = document.createElement('div');
523
+ startContainer.className = endContainer.className = 'outer-container inputBlock';
524
+ startLabel.className = endLabel.className = 'flex-label';
525
+ startContainer.append(startDate);
526
+ if (startTime) {
527
+ startContainer.append(startTime);
528
+ }
529
+ startLabel.append(startContainer);
530
+ startLabel.append(this.createErrorBubble());
531
+ endContainer.append(endDate);
532
+ if (endTime) {
533
+ endContainer.append(endTime);
534
+ }
535
+ endLabel.append(endContainer);
536
+ endLabel.append(this.createErrorBubble());
537
+ return { start: startLabel, end: endLabel };
538
+ }
539
+ /**
540
+ * Applies validation attributes to an input element based on the specified validation object.
541
+ * If a certain property is present in the object, it will set the corresponding attribute on
542
+ * the input element (e.g., "required" will set the "required" and "data-required" attributes,
543
+ * "pattern" will set the "pattern" and "data-pattern" attributes, etc.).
544
+ *
545
+ * @param {FormField} input - The input element to apply validation attributes to.
546
+ * @param {object} validation - An object containing the validation rules for the input field.
547
+ * @param {object} [validation.required] - An object containing a "message" property to display if the field is required.
548
+ * @param {string} [validation.required.message]
549
+ * @param {object} [validation.pattern] - An object containing a "pattern" property to match against the field value, and a "message" property to display if the pattern doesn't match.
550
+ * @param {string} [validation.pattern.pattern]
551
+ * @param {string} [validation.pattern.message]
552
+ * @param {object} [validation.badInput] - An object containing a "message" property to display if the field value is invalid.
553
+ * @param {string} [validation.badInput.message]
554
+ * @param {object} [validation.minmax] - An object containing "min" and "max" properties to validate the field value against, and a "message" property to display if the value is out of range.
555
+ * @param {string} [validation.minmax.min]
556
+ * @param {string} [validation.minmax.max]
557
+ * @param {string} [validation.minmax.message]
558
+ * @param {string} [validation.maxlength] - The maximum length of the input field.
559
+ * @param {string} [validation.datecompare] - To compare start and end date fields.
560
+ * @return {void}
561
+ */
562
+ applyValidation(input, validation) {
563
+ var _a, _b;
564
+ // If the "required" property is present, add the "required" attribute to the input element and
565
+ // set its "data-required" attribute to the specified message (if any)
566
+ if (validation.required) {
567
+ input.setAttribute('required', '');
568
+ input.setAttribute('data-required', (_a = validation.required.message) !== null && _a !== void 0 ? _a : '');
569
+ }
570
+ // If the "pattern" property is present, add the "pattern" attribute to the input element and set
571
+ // its "data-pattern" attribute to the specified message (if any)
572
+ if (validation.pattern) {
573
+ input.setAttribute('pattern', validation.pattern.pattern);
574
+ input.setAttribute('data-pattern', (_b = validation.pattern.message) !== null && _b !== void 0 ? _b : '');
575
+ }
576
+ // If the "badInput" property is present, set the input element's "data-badinput" attribute to
577
+ // the specified message
578
+ if (validation.badInput) {
579
+ input.setAttribute('data-badinput', validation.badInput.message);
580
+ }
581
+ // If the "minmax" property is present, add the "min" and "max" attributes to the input element
582
+ // and set its "data-range" attribute to the specified message (if any)
583
+ if (validation.minmax) {
584
+ input.setAttribute('min', validation.minmax.min);
585
+ input.setAttribute('max', validation.minmax.max);
586
+ input.setAttribute('data-range', validation.minmax.message);
587
+ }
588
+ // If the "maxlength" property is present, add the "maxlength" attribute to the input element
589
+ if (validation.maxlength) {
590
+ input.setAttribute('maxlength', validation.maxlength);
591
+ }
592
+ // Custom validation parameters for start date and end date comparison
593
+ if (validation.dateCompare) {
594
+ if (validation.dateCompare.message && validation.dateCompare.with) {
595
+ input.setAttribute('data-compare', validation.dateCompare.message);
596
+ input.setAttribute('data-compare-with', validation.dateCompare.with);
597
+ }
598
+ if (validation.dateCompare.to) {
599
+ input.setAttribute('data-compare-to', validation.dateCompare.to);
600
+ }
601
+ }
602
+ }
603
+ // Create a new error bubble element
604
+ createErrorBubble() {
605
+ // Create a new <div> element with the "errorBubble" class
606
+ const errorBubble = document.createElement('div');
607
+ errorBubble.className = 'errorBubble';
608
+ // Return the error bubble element
609
+ return errorBubble;
610
+ }
611
+ /**
612
+ *
613
+ * @param {Record<string, any>} formProperties
614
+ * @param {HTMLInputElement | HTMLSelectElement} input
615
+ * @param {HTMLLabelElement} label
616
+ * @returns {void}
617
+ */
618
+ appendCheckboxInput(formProperties, input, label) {
619
+ if (formProperties.label) {
620
+ const lineBreak = document.createElement('br');
621
+ label.appendChild(lineBreak);
622
+ }
623
+ // Append the input element and error bubble element to the label
624
+ label.appendChild(input);
625
+ if (!formProperties.inlineLabel)
626
+ return;
627
+ const inlineLabel = document.createElement('span');
628
+ inlineLabel.className = 'inlineLabel';
629
+ inlineLabel.textContent = formProperties.inlineLabel;
630
+ label.appendChild(inlineLabel);
631
+ }
632
+ /**
633
+ * Creates a new <label> element with the "inputBlock" class and the specified label text,
634
+ * and appends the input element and error bubble element to it. If the form property has
635
+ * no validation object, it adds an "optional" span element to the label.
636
+ *
637
+ * @param {Record<string, any>} formProperties - An object containing properties for the form field, including its label text and validation rules.
638
+ * @param {HTMLInputElement | HTMLSelectElement} input - The input element to associate with the label.
639
+ * @param {never} overlay - The Child Element which will be rendered atop the standard HTML5 element
640
+ * @param {HTMLDivElement} errorBubble - The error bubble element to display error messages in.
641
+ * @return {HTMLLabelElement} - The new label element.
642
+ */
643
+ createLabel(formProperties, input, overlay = null, errorBubble) {
644
+ var _a;
645
+ const outerContainer = document.createElement('div');
646
+ let outerContainerClassName = 'outer-container inputBlock';
647
+ // Create a new <label> element with the "inputBlock" class and the specified text
648
+ const label = document.createElement('label');
649
+ label.innerText = formProperties.label;
650
+ // If the form property has no validation object, add an "optional" span element to the label
651
+ if (!((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) && formProperties.label) {
652
+ const optionalSpan = document.createElement('span');
653
+ optionalSpan.className = 'optional';
654
+ optionalSpan.innerHTML = '&nbsp;(optional)';
655
+ label.appendChild(optionalSpan);
656
+ }
657
+ if (formProperties.type === 'radio') {
658
+ outerContainerClassName += ' radioBlock';
659
+ }
660
+ outerContainer.className = outerContainerClassName;
661
+ if (formProperties.readonly) {
662
+ label.classList.add('readonly');
663
+ }
664
+ if (formProperties.type === 'checkbox') {
665
+ this.appendCheckboxInput(formProperties, input, label);
666
+ }
667
+ else {
668
+ // Append the input element and error bubble element to the outerContainer
669
+ if (overlay) {
670
+ outerContainer.appendChild(overlay);
671
+ }
672
+ outerContainer.appendChild(input);
673
+ }
674
+ if (formProperties.type !== 'checkbox') {
675
+ label.appendChild(outerContainer);
676
+ }
677
+ label.appendChild(errorBubble);
678
+ // Return the label element
679
+ return label;
680
+ }
681
+ /**
682
+ * Creates a new radio input with a set of options.
683
+ *
684
+ * @param {string} formKey - The name of the dropdown field, as specified in the form schema.
685
+ * @param {Object} formProperties - An object containing additional properties, such as the field type and options properties.
686
+ * @param {'radio'} formProperties.type - The type of form field. In this case, it will always be "radio".
687
+ * @param {Object} formProperties.validation - A set of validation rules for the field.
688
+ * @param {Object[]} formProperties.options - A list of properties to pass to the select options.
689
+ * @param {string} formProperties.options.label - The visible value of the option.
690
+ * @param {string} formProperties.options.value - The actual value of the option.
691
+ */
692
+ createRadio(formKey, formProperties) {
693
+ var _a, _b;
694
+ const fragment = document.createDocumentFragment();
695
+ for (const optionProperties of formProperties.options) {
696
+ // Create a new <input> element with the specified name and type
697
+ const input = document.createElement('input');
698
+ input.type = 'radio';
699
+ input.name = formKey;
700
+ input.value = optionProperties.value;
701
+ if ((_a = formProperties === null || formProperties === void 0 ? void 0 : formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) {
702
+ input.setAttribute('required', 'required');
703
+ input.setAttribute('data-required', (_b = formProperties.validation.required.message) !== null && _b !== void 0 ? _b : '');
704
+ }
705
+ const span = document.createElement('span');
706
+ span.innerText = optionProperties.label;
707
+ fragment.appendChild(input);
708
+ fragment.appendChild(span);
709
+ fragment.appendChild(document.createElement('br'));
710
+ }
711
+ return fragment;
712
+ }
713
+ /**
714
+ * Populates the form template with input fields and labels based on the properties of the
715
+ * current form schema. For each property in the schema, it creates an input element, applies
716
+ * any validation rules to it, creates an error bubble and label element, and appends them
717
+ * to the form template. Finally, it creates and appends a submit button element to the form.
718
+ *
719
+ * @return {void}
720
+ */
721
+ populateFormFromSchema() {
722
+ var _a;
723
+ // If there is no form schema, return early
724
+ if (!this._formSchema) {
725
+ return;
726
+ }
727
+ // Get the properties of the form schema and their keys
728
+ const properties = this._formSchema.properties;
729
+ const propertyKeys = Object.keys(properties);
730
+ // Loop through each property key and create an input, label, and error bubble for it
731
+ for (const formKey of propertyKeys) {
732
+ const formItem = properties[formKey];
733
+ const formProperties = formItem.form;
734
+ // complex form types which require
735
+ // custom HTML should be done here
736
+ if (formProperties.type === 'startenddate') {
737
+ const { start, end } = this.createStartEndDateComponent(formKey, formProperties);
738
+ this.template.content.append(start);
739
+ this.template.content.append(end);
740
+ continue;
741
+ }
742
+ let fragments = {};
743
+ switch (formProperties.type) {
744
+ case 'select':
745
+ fragments = this.createSelect(formKey, formProperties);
746
+ break;
747
+ case 'radio':
748
+ fragments.input = this.createRadio(formKey, formProperties);
749
+ break;
750
+ case 'textarea':
751
+ fragments.input = this.createTextArea(formKey, formProperties);
752
+ break;
753
+ default:
754
+ fragments.input = this.createInput(formKey, formProperties);
755
+ }
756
+ // If the form property has validation, apply it to the input
757
+ if (formProperties.validation &&
758
+ formProperties.type !== 'radio') {
759
+ this.applyValidation(fragments.input, formProperties.validation);
760
+ }
761
+ // Create an error bubble and label element for the input
762
+ const errorBubble = this.createErrorBubble();
763
+ const label = this.createLabel(formProperties, fragments.input, fragments.overlay, errorBubble);
764
+ // If explicitly setting input as invalid, set invalid state and error message on render
765
+ if ((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.invalid) {
766
+ const errorMessage = formProperties.validation.invalid.message;
767
+ fragments.input.setCustomValidity(errorMessage); // Prevents the invalid styling from resetting on blur
768
+ setErrorState(fragments.input, true, errorMessage);
769
+ }
770
+ // Append the label element to the form template
771
+ this.template.content.append(label);
772
+ if (formProperties.disabled) {
773
+ this.toggleFormField(fragments.input, true);
774
+ }
775
+ }
776
+ }
777
+ /**
778
+ * Clones the form template and binds event listeners to its input elements. First, it checks if
779
+ * there is a form schema present. If so, it clones the template's content, binds events to form
780
+ * input elements, and appends the cloned form elements to the fieldset. The event listeners include
781
+ * "oninvalid" (to check input validity on submit), "onblur" (to check input validity on blur),
782
+ * "onkeyup" (to handle changes in input fields), and "onchange" (to handle changes in select fields).
783
+ *
784
+ * @return {void}
785
+ */
786
+ componentDidRender() {
787
+ // If there's no form schema, return
788
+ if (!this._formSchema) {
789
+ return;
790
+ }
791
+ // Clone the template's content and store it in a variable
792
+ const formItems = this.template.content;
793
+ // Bind event listeners to form elements
794
+ const properties = this._formSchema.properties;
795
+ const propertyKeys = Object.keys(properties);
796
+ for (const formKey of propertyKeys) {
797
+ this.applyValidationFunctionsToFormElement(formItems, formKey, properties);
798
+ }
799
+ // populate with existing form data if available
800
+ if ((this._data && Object.keys(this._data).length > 0)) {
801
+ this.populateFormWithExistingData(formItems);
802
+ }
803
+ // Append the cloned form elements to the fieldset
804
+ this.fieldset.replaceChildren(formItems);
805
+ }
806
+ /**
807
+ * Assign validation events to a given form item
808
+ * @param formItems The document fragment template of form items to be rendered
809
+ * @param formKey The key of the form item to bind events too
810
+ * @param properties The form item's properties, such as type and name
811
+ */
812
+ applyValidationFunctionsToFormElement(formItems, formKey, properties) {
813
+ const formItemsByKey = formItems.querySelectorAll(`[name^=${formKey}]`);
814
+ for (const formInput of formItemsByKey) {
815
+ // Bind events to form input elements
816
+ formInput.oninvalid = this.validityCheckWrapper.bind(this);
817
+ formInput.onblur = this.validityCheckWrapper.bind(this);
818
+ formInput.onkeyup = this.fieldChanged.bind(this);
819
+ formInput.onchange = this.fieldChanged.bind(this);
820
+ if (properties[formKey].form.type === 'select' && formInput.classList.contains('placeholder')) {
821
+ formInput.addEventListener('change', this.selectRemovePlaceholderCallback.bind(formInput));
822
+ }
823
+ if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-with')) {
824
+ formInput.oninvalid = endDateComparisonValidator.bind(this);
825
+ formInput.onblur = endDateComparisonValidator.bind(this);
826
+ }
827
+ if (properties[formKey].form.type === 'startenddate' && formInput.type === 'time') {
828
+ formInput.oninvalid = startEndTimeComparator.bind(this);
829
+ formInput.onblur = startEndTimeComparator.bind(this);
830
+ }
831
+ if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-to')) {
832
+ formInput.oninvalid = startDateComparisonValidator.bind(this);
833
+ formInput.onblur = startDateComparisonValidator.bind(this);
834
+ }
835
+ }
836
+ }
837
+ /**
838
+ * If data exists, set form input values before rendering
839
+ * @param formItems The document fragment template of form items to be rendered
840
+ */
841
+ populateFormWithExistingData(formItems) {
842
+ var _a;
843
+ const dataKeys = Object.keys(this._data);
844
+ for (const key of dataKeys) {
845
+ const formItemsByKey = formItems.querySelectorAll(`[name=${key}]`);
846
+ for (const formItem of formItemsByKey) {
847
+ switch (formItem.type) {
848
+ case 'checkbox':
849
+ if (this._data[key] === 'on') {
850
+ formItem.checked = true;
851
+ }
852
+ break;
853
+ case 'radio':
854
+ if (formItem.value === this._data[key]) {
855
+ formItem.checked = true;
856
+ }
857
+ break;
858
+ case 'select':
859
+ case 'select-one':
860
+ formItems.querySelector(`[name=overlay-${key}]`)['selectedValue'] = this._data[key];
861
+ formItem.value = this._data[key];
862
+ break;
863
+ case 'date':
864
+ formItem.value = (_a = this._data[key]) === null || _a === void 0 ? void 0 : _a.split('T')[0];
865
+ break;
866
+ default:
867
+ formItem.value = this._data[key];
868
+ }
869
+ }
870
+ }
871
+ }
872
+ /**
873
+ * Remove the placeholder class on the bound THIS select element
874
+ */
875
+ selectRemovePlaceholderCallback() {
876
+ const select = this;
877
+ select.classList.remove('placeholder');
878
+ }
879
+ /**
880
+ * A wrapper around validity check and set error state
881
+ */
882
+ validityCheckWrapper(event) {
883
+ const { target, hasError, errorMessage } = validityCheck(event);
884
+ setErrorState(target, hasError, errorMessage);
885
+ }
886
+ assignFieldsetReference(el) {
887
+ this.fieldset = el;
888
+ }
889
+ assignButtonReference(el) {
890
+ this.submitButton = el;
891
+ }
892
+ /**
893
+ * An external validation trigger to apply to a form field
894
+ * @param { string } fieldName The form field name to apply the validation too
895
+ * @param { string } message The validation message to display under the form field
896
+ */
897
+ async setValidationFor(fieldName, message) {
898
+ const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
899
+ if (formField.disabled) {
900
+ return;
901
+ }
902
+ formField.setCustomValidity(message);
903
+ formField.setAttribute('custom-validation-set', 'true');
904
+ setErrorState(formField, true, message);
905
+ }
906
+ /**
907
+ * Clear the validation message on a given form field
908
+ * @param { string } fieldName The form field name to clear the validation of
909
+ */
910
+ async clearValidationFor(fieldName) {
911
+ const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
912
+ formField.setCustomValidity('');
913
+ formField.removeAttribute('custom-validation-set');
914
+ setErrorState(formField, false, '');
915
+ }
916
+ toggleFormField(formField, disabled) {
917
+ formField.disabled = disabled;
918
+ let parent = formField.parentElement;
919
+ if (parent) {
920
+ do {
921
+ if (parent.nodeName !== 'LABEL') {
922
+ parent = parent.parentElement;
923
+ }
924
+ } while (parent && parent.nodeName !== 'LABEL');
925
+ if (parent) {
926
+ parent.style.display = (disabled) ? 'none' : 'block';
927
+ }
928
+ }
929
+ }
930
+ /**
931
+ * Disable a form field and visually remove it from the form.
932
+ * If custom validation is set, this function will return without affecting the form field.
933
+ * @param { string } fieldName The form field name to disable
934
+ */
935
+ async disableFormField(fieldName) {
936
+ const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
937
+ if (formField.hasAttribute('custom-validation-set')) {
938
+ return;
939
+ }
940
+ this.toggleFormField(formField, true);
941
+ }
942
+ /**
943
+ * Enable a form field and visually add it back to the form.
944
+ * @param { string } fieldName The form field name to enable
945
+ */
946
+ async enableFormField(fieldName) {
947
+ const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
948
+ this.toggleFormField(formField, false);
949
+ }
950
+ /**
951
+ * Set the value of a form field progromatically
952
+ * @param { string } fieldName The form field name having it's value set
953
+ * @param { string } fieldValue The form field value to set
954
+ */
955
+ async setInputFieldValue(fieldName, fieldValue) {
956
+ const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
957
+ formField.value = fieldValue;
958
+ }
959
+ /**
960
+ * Change the readonly property on an input field. If set to 'true' any validation will also be cleared.
961
+ * @param { string } fieldName The form field name to set
962
+ * @param { boolean } readonly The state of the read-only attribute
963
+ */
964
+ async setFieldReadOnlyMode(fieldName, readonly) {
965
+ const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
966
+ if (formField && formField.nodeName === 'SELECT') {
967
+ const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldName}]`);
968
+ tttxSelect.readOnly = readonly;
969
+ formField.disabled = readonly;
970
+ }
971
+ else {
972
+ formField.readOnly = readonly;
973
+ }
974
+ if (readonly) {
975
+ await this.clearValidationFor(fieldName);
976
+ }
977
+ }
978
+ /**
979
+ * Renders the component's template as a form element with a fieldset container. The form's
980
+ * "onSubmit" event is bound to the "doSubmit" function, which handles the form submission
981
+ * and emits a "dataSubmitted" event with the form data. The fieldset element is assigned
982
+ * to the "fieldset" instance variable using a ref, so it can be populated with form elements
983
+ * later on.
984
+ */
985
+ render() {
986
+ //react rendering so we can't JEST it
987
+ //ignore so it doesn't ruin coverage
988
+ /*istanbul ignore next*/
989
+ return (h(Host, null, h("form", { onSubmit: this.doSubmit.bind(this), ref: frm => this.form = frm }, h("fieldset", { ref: this.assignFieldsetReference.bind(this) }), h("input", { type: "submit", ref: this.assignButtonReference.bind(this), style: { display: 'none' } }))));
990
+ }
991
+ static get watchers() { return {
992
+ "formschema": ["onFormSchemaChange"],
993
+ "data": ["onDataChange"]
994
+ }; }
995
+ };
996
996
  TttxForm.style = tttxFormCss;
997
997
 
998
- export { TttxForm as tttx_form_localcomponent };
998
+ export { TttxForm as tttx_form_1_9_103 };