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