iss-ctrl 0.0.11 → 0.0.13

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 (328) hide show
  1. package/fesm2022/{iss-ctrl-iss-ctrl-hz0ibyPg.mjs → iss-ctrl-iss-ctrl-BN9rcLt2.mjs} +1293 -198
  2. package/fesm2022/iss-ctrl-iss-ctrl-BN9rcLt2.mjs.map +1 -0
  3. package/fesm2022/iss-ctrl-iss-ctrl-DOmgkxUv.mjs +8924 -0
  4. package/fesm2022/iss-ctrl-iss-ctrl-DOmgkxUv.mjs.map +1 -0
  5. package/fesm2022/iss-ctrl-iss-ctrl-WfIqBEcL.mjs +8913 -0
  6. package/fesm2022/iss-ctrl-iss-ctrl-WfIqBEcL.mjs.map +1 -0
  7. package/fesm2022/{iss-ctrl-load-event-BW5dKG8R.mjs → iss-ctrl-load-event-AgBohfHa.mjs} +3 -3
  8. package/fesm2022/{iss-ctrl-load-event-BW5dKG8R.mjs.map → iss-ctrl-load-event-AgBohfHa.mjs.map} +1 -1
  9. package/fesm2022/iss-ctrl-load-event-D70VZuyD.mjs +60 -0
  10. package/fesm2022/iss-ctrl-load-event-D70VZuyD.mjs.map +1 -0
  11. package/fesm2022/iss-ctrl-load-event-SlQmVmyf.mjs +60 -0
  12. package/fesm2022/iss-ctrl-load-event-SlQmVmyf.mjs.map +1 -0
  13. package/fesm2022/{iss-ctrl-load-options-event-ClX9TiiD.mjs → iss-ctrl-load-options-event-CBejHpME.mjs} +3 -3
  14. package/fesm2022/{iss-ctrl-load-options-event-ClX9TiiD.mjs.map → iss-ctrl-load-options-event-CBejHpME.mjs.map} +1 -1
  15. package/fesm2022/iss-ctrl-load-options-event-ClQPHNBO.mjs +50 -0
  16. package/fesm2022/iss-ctrl-load-options-event-ClQPHNBO.mjs.map +1 -0
  17. package/fesm2022/iss-ctrl-load-options-event-DHmaMAOb.mjs +50 -0
  18. package/fesm2022/iss-ctrl-load-options-event-DHmaMAOb.mjs.map +1 -0
  19. package/fesm2022/{iss-ctrl-load-value-event-DThpI9BA.mjs → iss-ctrl-load-value-event-Bu9-rZ6T.mjs} +3 -3
  20. package/fesm2022/{iss-ctrl-load-value-event-DThpI9BA.mjs.map → iss-ctrl-load-value-event-Bu9-rZ6T.mjs.map} +1 -1
  21. package/fesm2022/iss-ctrl-load-value-event-CDAKsE_O.mjs +52 -0
  22. package/fesm2022/iss-ctrl-load-value-event-CDAKsE_O.mjs.map +1 -0
  23. package/fesm2022/iss-ctrl-load-value-event-Cpuy1og1.mjs +52 -0
  24. package/fesm2022/iss-ctrl-load-value-event-Cpuy1og1.mjs.map +1 -0
  25. package/fesm2022/{iss-ctrl-note.field-4uLl0oS_.mjs → iss-ctrl-note.field-C9cVaAz0.mjs} +24 -2
  26. package/fesm2022/iss-ctrl-note.field-C9cVaAz0.mjs.map +1 -0
  27. package/fesm2022/iss-ctrl-note.field-IM4x1O3b.mjs +65 -0
  28. package/fesm2022/iss-ctrl-note.field-IM4x1O3b.mjs.map +1 -0
  29. package/fesm2022/iss-ctrl-note.field-onDjqI_X.mjs +65 -0
  30. package/fesm2022/iss-ctrl-note.field-onDjqI_X.mjs.map +1 -0
  31. package/fesm2022/{iss-ctrl-replace-api-keys-BQL9zimJ.mjs → iss-ctrl-replace-api-keys-CLP4wBYu.mjs} +2 -2
  32. package/fesm2022/{iss-ctrl-replace-api-keys-BQL9zimJ.mjs.map → iss-ctrl-replace-api-keys-CLP4wBYu.mjs.map} +1 -1
  33. package/fesm2022/iss-ctrl-replace-api-keys-Chwe42Nu.mjs +57 -0
  34. package/fesm2022/iss-ctrl-replace-api-keys-Chwe42Nu.mjs.map +1 -0
  35. package/fesm2022/iss-ctrl-replace-api-keys-CvhCKvNB.mjs +57 -0
  36. package/fesm2022/iss-ctrl-replace-api-keys-CvhCKvNB.mjs.map +1 -0
  37. package/fesm2022/{iss-ctrl-set-value-event-BbEYFBe3.mjs → iss-ctrl-set-value-event-C7YYwHZV.mjs} +2 -2
  38. package/fesm2022/{iss-ctrl-set-value-event-BbEYFBe3.mjs.map → iss-ctrl-set-value-event-C7YYwHZV.mjs.map} +1 -1
  39. package/fesm2022/iss-ctrl-set-value-event-CrpzRR6X.mjs +61 -0
  40. package/fesm2022/iss-ctrl-set-value-event-CrpzRR6X.mjs.map +1 -0
  41. package/fesm2022/iss-ctrl-set-value-event-DiHESiPT.mjs +61 -0
  42. package/fesm2022/iss-ctrl-set-value-event-DiHESiPT.mjs.map +1 -0
  43. package/fesm2022/iss-ctrl-table.field-BP-HMKO3.mjs +592 -0
  44. package/fesm2022/iss-ctrl-table.field-BP-HMKO3.mjs.map +1 -0
  45. package/fesm2022/iss-ctrl-table.field-CDSVakji.mjs +592 -0
  46. package/fesm2022/iss-ctrl-table.field-CDSVakji.mjs.map +1 -0
  47. package/fesm2022/{iss-ctrl-table.field-kPIwve-M.mjs → iss-ctrl-table.field-DxwfNXNc.mjs} +77 -2
  48. package/fesm2022/iss-ctrl-table.field-DxwfNXNc.mjs.map +1 -0
  49. package/fesm2022/{iss-ctrl-trigger-based-on-json-value-DuLD4SOS.mjs → iss-ctrl-trigger-based-on-json-value-CprcFCWi.mjs} +2 -2
  50. package/fesm2022/{iss-ctrl-trigger-based-on-json-value-DuLD4SOS.mjs.map → iss-ctrl-trigger-based-on-json-value-CprcFCWi.mjs.map} +1 -1
  51. package/fesm2022/iss-ctrl-trigger-based-on-json-value-DS4TR38v.mjs +24 -0
  52. package/fesm2022/iss-ctrl-trigger-based-on-json-value-DS4TR38v.mjs.map +1 -0
  53. package/fesm2022/iss-ctrl-trigger-based-on-json-value-Dp0EhVLA.mjs +24 -0
  54. package/fesm2022/iss-ctrl-trigger-based-on-json-value-Dp0EhVLA.mjs.map +1 -0
  55. package/fesm2022/{iss-ctrl-user-picker.field-l-0bW6lP.mjs → iss-ctrl-user-picker.field-8Jb1325c.mjs} +33 -8
  56. package/fesm2022/iss-ctrl-user-picker.field-8Jb1325c.mjs.map +1 -0
  57. package/fesm2022/iss-ctrl-user-picker.field-Mqi37i7D.mjs +225 -0
  58. package/fesm2022/iss-ctrl-user-picker.field-Mqi37i7D.mjs.map +1 -0
  59. package/fesm2022/iss-ctrl-user-picker.field-PxT_dZ_O.mjs +225 -0
  60. package/fesm2022/iss-ctrl-user-picker.field-PxT_dZ_O.mjs.map +1 -0
  61. package/fesm2022/iss-ctrl.mjs +1 -1
  62. package/package.json +1 -1
  63. package/types/iss-ctrl.d.ts +1115 -0
  64. package/upgrade.scss +16 -0
  65. package/fesm2022/iss-ctrl-iss-ctrl-hz0ibyPg.mjs.map +0 -1
  66. package/fesm2022/iss-ctrl-note.field-4uLl0oS_.mjs.map +0 -1
  67. package/fesm2022/iss-ctrl-table.field-kPIwve-M.mjs.map +0 -1
  68. package/fesm2022/iss-ctrl-user-picker.field-l-0bW6lP.mjs.map +0 -1
  69. package/src/components/controls/mobile/flags/ad.svg +0 -282
  70. package/src/components/controls/mobile/flags/ae.svg +0 -6
  71. package/src/components/controls/mobile/flags/af.svg +0 -9
  72. package/src/components/controls/mobile/flags/ag.svg +0 -15
  73. package/src/components/controls/mobile/flags/ai.svg +0 -35
  74. package/src/components/controls/mobile/flags/al.svg +0 -7
  75. package/src/components/controls/mobile/flags/am.svg +0 -5
  76. package/src/components/controls/mobile/flags/ao.svg +0 -19
  77. package/src/components/controls/mobile/flags/aq.svg +0 -45
  78. package/src/components/controls/mobile/flags/ar.svg +0 -66
  79. package/src/components/controls/mobile/flags/as.svg +0 -225
  80. package/src/components/controls/mobile/flags/at.svg +0 -4
  81. package/src/components/controls/mobile/flags/au.svg +0 -32
  82. package/src/components/controls/mobile/flags/aw.svg +0 -11
  83. package/src/components/controls/mobile/flags/ax.svg +0 -11
  84. package/src/components/controls/mobile/flags/az.svg +0 -11
  85. package/src/components/controls/mobile/flags/ba.svg +0 -18
  86. package/src/components/controls/mobile/flags/bb.svg +0 -11
  87. package/src/components/controls/mobile/flags/bd.svg +0 -4
  88. package/src/components/controls/mobile/flags/be.svg +0 -5
  89. package/src/components/controls/mobile/flags/bf.svg +0 -14
  90. package/src/components/controls/mobile/flags/bg.svg +0 -5
  91. package/src/components/controls/mobile/flags/bh.svg +0 -4
  92. package/src/components/controls/mobile/flags/bi.svg +0 -26
  93. package/src/components/controls/mobile/flags/bj.svg +0 -5
  94. package/src/components/controls/mobile/flags/bl.svg +0 -5
  95. package/src/components/controls/mobile/flags/bm.svg +0 -374
  96. package/src/components/controls/mobile/flags/bn.svg +0 -70
  97. package/src/components/controls/mobile/flags/bo.svg +0 -3625
  98. package/src/components/controls/mobile/flags/bq.svg +0 -5
  99. package/src/components/controls/mobile/flags/br.svg +0 -92
  100. package/src/components/controls/mobile/flags/bs.svg +0 -5
  101. package/src/components/controls/mobile/flags/bt.svg +0 -487
  102. package/src/components/controls/mobile/flags/bv.svg +0 -11
  103. package/src/components/controls/mobile/flags/bw.svg +0 -5
  104. package/src/components/controls/mobile/flags/by.svg +0 -15
  105. package/src/components/controls/mobile/flags/bz.svg +0 -629
  106. package/src/components/controls/mobile/flags/ca.svg +0 -7
  107. package/src/components/controls/mobile/flags/cc.svg +0 -33
  108. package/src/components/controls/mobile/flags/cd.svg +0 -5
  109. package/src/components/controls/mobile/flags/cf.svg +0 -7
  110. package/src/components/controls/mobile/flags/cg.svg +0 -5
  111. package/src/components/controls/mobile/flags/ch.svg +0 -4
  112. package/src/components/controls/mobile/flags/ci.svg +0 -5
  113. package/src/components/controls/mobile/flags/ck.svg +0 -29
  114. package/src/components/controls/mobile/flags/cl.svg +0 -14
  115. package/src/components/controls/mobile/flags/cm.svg +0 -15
  116. package/src/components/controls/mobile/flags/cn.svg +0 -11
  117. package/src/components/controls/mobile/flags/co.svg +0 -5
  118. package/src/components/controls/mobile/flags/cr.svg +0 -1332
  119. package/src/components/controls/mobile/flags/cu.svg +0 -6
  120. package/src/components/controls/mobile/flags/cv.svg +0 -24
  121. package/src/components/controls/mobile/flags/cw.svg +0 -16
  122. package/src/components/controls/mobile/flags/cx.svg +0 -24
  123. package/src/components/controls/mobile/flags/cy.svg +0 -13
  124. package/src/components/controls/mobile/flags/cz.svg +0 -5
  125. package/src/components/controls/mobile/flags/de.svg +0 -5
  126. package/src/components/controls/mobile/flags/dj.svg +0 -6
  127. package/src/components/controls/mobile/flags/dk.svg +0 -5
  128. package/src/components/controls/mobile/flags/dm.svg +0 -198
  129. package/src/components/controls/mobile/flags/do.svg +0 -238
  130. package/src/components/controls/mobile/flags/dz.svg +0 -5
  131. package/src/components/controls/mobile/flags/ec.svg +0 -1292
  132. package/src/components/controls/mobile/flags/ee.svg +0 -5
  133. package/src/components/controls/mobile/flags/eg.svg +0 -125
  134. package/src/components/controls/mobile/flags/eh.svg +0 -12
  135. package/src/components/controls/mobile/flags/er.svg +0 -9
  136. package/src/components/controls/mobile/flags/es.svg +0 -445
  137. package/src/components/controls/mobile/flags/et.svg +0 -16
  138. package/src/components/controls/mobile/flags/eu.svg +0 -28
  139. package/src/components/controls/mobile/flags/fi.svg +0 -5
  140. package/src/components/controls/mobile/flags/fj.svg +0 -203
  141. package/src/components/controls/mobile/flags/fk.svg +0 -922
  142. package/src/components/controls/mobile/flags/flags.png +0 -0
  143. package/src/components/controls/mobile/flags/flags@2x.png +0 -0
  144. package/src/components/controls/mobile/flags/fm.svg +0 -16
  145. package/src/components/controls/mobile/flags/fo.svg +0 -11
  146. package/src/components/controls/mobile/flags/fonts.css +0 -271
  147. package/src/components/controls/mobile/flags/fr.svg +0 -5
  148. package/src/components/controls/mobile/flags/ga.svg +0 -5
  149. package/src/components/controls/mobile/flags/gb-eng.svg +0 -7
  150. package/src/components/controls/mobile/flags/gb-nir.svg +0 -15
  151. package/src/components/controls/mobile/flags/gb-sct.svg +0 -11
  152. package/src/components/controls/mobile/flags/gb-wls.svg +0 -16
  153. package/src/components/controls/mobile/flags/gb.svg +0 -15
  154. package/src/components/controls/mobile/flags/gd.svg +0 -11
  155. package/src/components/controls/mobile/flags/ge.svg +0 -17
  156. package/src/components/controls/mobile/flags/gf.svg +0 -5
  157. package/src/components/controls/mobile/flags/gg.svg +0 -8
  158. package/src/components/controls/mobile/flags/gh.svg +0 -6
  159. package/src/components/controls/mobile/flags/gi.svg +0 -69
  160. package/src/components/controls/mobile/flags/gl.svg +0 -4
  161. package/src/components/controls/mobile/flags/gm.svg +0 -7
  162. package/src/components/controls/mobile/flags/gn.svg +0 -5
  163. package/src/components/controls/mobile/flags/gp.svg +0 -5
  164. package/src/components/controls/mobile/flags/gq.svg +0 -88
  165. package/src/components/controls/mobile/flags/gr.svg +0 -4
  166. package/src/components/controls/mobile/flags/gs.svg +0 -693
  167. package/src/components/controls/mobile/flags/gt.svg +0 -317
  168. package/src/components/controls/mobile/flags/gu.svg +0 -58
  169. package/src/components/controls/mobile/flags/gw.svg +0 -13
  170. package/src/components/controls/mobile/flags/gy.svg +0 -7
  171. package/src/components/controls/mobile/flags/hk.svg +0 -17
  172. package/src/components/controls/mobile/flags/hm.svg +0 -32
  173. package/src/components/controls/mobile/flags/hn.svg +0 -10
  174. package/src/components/controls/mobile/flags/hr.svg +0 -282
  175. package/src/components/controls/mobile/flags/ht.svg +0 -1470
  176. package/src/components/controls/mobile/flags/hu.svg +0 -5
  177. package/src/components/controls/mobile/flags/id.svg +0 -4
  178. package/src/components/controls/mobile/flags/ie.svg +0 -5
  179. package/src/components/controls/mobile/flags/il.svg +0 -5
  180. package/src/components/controls/mobile/flags/im.svg +0 -33
  181. package/src/components/controls/mobile/flags/in.svg +0 -25
  182. package/src/components/controls/mobile/flags/io.svg +0 -895
  183. package/src/components/controls/mobile/flags/iq.svg +0 -12
  184. package/src/components/controls/mobile/flags/ir.svg +0 -31
  185. package/src/components/controls/mobile/flags/is.svg +0 -5
  186. package/src/components/controls/mobile/flags/it.svg +0 -5
  187. package/src/components/controls/mobile/flags/je.svg +0 -40
  188. package/src/components/controls/mobile/flags/jm.svg +0 -9
  189. package/src/components/controls/mobile/flags/jo.svg +0 -10
  190. package/src/components/controls/mobile/flags/jp.svg +0 -4
  191. package/src/components/controls/mobile/flags/ke.svg +0 -28
  192. package/src/components/controls/mobile/flags/kg.svg +0 -7
  193. package/src/components/controls/mobile/flags/kh.svg +0 -133
  194. package/src/components/controls/mobile/flags/ki.svg +0 -54
  195. package/src/components/controls/mobile/flags/km.svg +0 -13
  196. package/src/components/controls/mobile/flags/kn.svg +0 -24
  197. package/src/components/controls/mobile/flags/kp.svg +0 -16
  198. package/src/components/controls/mobile/flags/kr.svg +0 -16
  199. package/src/components/controls/mobile/flags/kw.svg +0 -6
  200. package/src/components/controls/mobile/flags/ky.svg +0 -153
  201. package/src/components/controls/mobile/flags/kz.svg +0 -49
  202. package/src/components/controls/mobile/flags/la.svg +0 -5
  203. package/src/components/controls/mobile/flags/lb.svg +0 -8
  204. package/src/components/controls/mobile/flags/lc.svg +0 -6
  205. package/src/components/controls/mobile/flags/li.svg +0 -75
  206. package/src/components/controls/mobile/flags/lk.svg +0 -50
  207. package/src/components/controls/mobile/flags/lr.svg +0 -15
  208. package/src/components/controls/mobile/flags/ls.svg +0 -32
  209. package/src/components/controls/mobile/flags/lt.svg +0 -5
  210. package/src/components/controls/mobile/flags/lu.svg +0 -5
  211. package/src/components/controls/mobile/flags/lv.svg +0 -4
  212. package/src/components/controls/mobile/flags/ly.svg +0 -8
  213. package/src/components/controls/mobile/flags/ma.svg +0 -4
  214. package/src/components/controls/mobile/flags/mc.svg +0 -4
  215. package/src/components/controls/mobile/flags/md.svg +0 -102
  216. package/src/components/controls/mobile/flags/me.svg +0 -240
  217. package/src/components/controls/mobile/flags/mf.svg +0 -5
  218. package/src/components/controls/mobile/flags/mg.svg +0 -5
  219. package/src/components/controls/mobile/flags/mh.svg +0 -18
  220. package/src/components/controls/mobile/flags/mk.svg +0 -6
  221. package/src/components/controls/mobile/flags/ml.svg +0 -5
  222. package/src/components/controls/mobile/flags/mm.svg +0 -12
  223. package/src/components/controls/mobile/flags/mn.svg +0 -12
  224. package/src/components/controls/mobile/flags/mo.svg +0 -13
  225. package/src/components/controls/mobile/flags/mp.svg +0 -2919
  226. package/src/components/controls/mobile/flags/mq.svg +0 -5
  227. package/src/components/controls/mobile/flags/mr.svg +0 -5
  228. package/src/components/controls/mobile/flags/ms.svg +0 -59
  229. package/src/components/controls/mobile/flags/mt.svg +0 -52
  230. package/src/components/controls/mobile/flags/mu.svg +0 -6
  231. package/src/components/controls/mobile/flags/mv.svg +0 -8
  232. package/src/components/controls/mobile/flags/mw.svg +0 -24
  233. package/src/components/controls/mobile/flags/mx.svg +0 -1129
  234. package/src/components/controls/mobile/flags/my.svg +0 -12
  235. package/src/components/controls/mobile/flags/mz.svg +0 -50
  236. package/src/components/controls/mobile/flags/na.svg +0 -17
  237. package/src/components/controls/mobile/flags/nc.svg +0 -5
  238. package/src/components/controls/mobile/flags/ne.svg +0 -6
  239. package/src/components/controls/mobile/flags/nf.svg +0 -8
  240. package/src/components/controls/mobile/flags/ng.svg +0 -4
  241. package/src/components/controls/mobile/flags/ni.svg +0 -281
  242. package/src/components/controls/mobile/flags/nl.svg +0 -5
  243. package/src/components/controls/mobile/flags/no.svg +0 -11
  244. package/src/components/controls/mobile/flags/np.svg +0 -33
  245. package/src/components/controls/mobile/flags/nr.svg +0 -8
  246. package/src/components/controls/mobile/flags/nu.svg +0 -23
  247. package/src/components/controls/mobile/flags/nz.svg +0 -37
  248. package/src/components/controls/mobile/flags/om.svg +0 -307
  249. package/src/components/controls/mobile/flags/pa.svg +0 -15
  250. package/src/components/controls/mobile/flags/pe.svg +0 -767
  251. package/src/components/controls/mobile/flags/pf.svg +0 -38
  252. package/src/components/controls/mobile/flags/pg.svg +0 -16
  253. package/src/components/controls/mobile/flags/ph.svg +0 -28
  254. package/src/components/controls/mobile/flags/pk.svg +0 -7
  255. package/src/components/controls/mobile/flags/pl.svg +0 -4
  256. package/src/components/controls/mobile/flags/pm.svg +0 -5
  257. package/src/components/controls/mobile/flags/pn.svg +0 -131
  258. package/src/components/controls/mobile/flags/pr.svg +0 -6
  259. package/src/components/controls/mobile/flags/ps.svg +0 -6
  260. package/src/components/controls/mobile/flags/pt.svg +0 -79
  261. package/src/components/controls/mobile/flags/pw.svg +0 -4
  262. package/src/components/controls/mobile/flags/py.svg +0 -192
  263. package/src/components/controls/mobile/flags/qa.svg +0 -7
  264. package/src/components/controls/mobile/flags/re.svg +0 -5
  265. package/src/components/controls/mobile/flags/ro.svg +0 -5
  266. package/src/components/controls/mobile/flags/rs.svg +0 -1143
  267. package/src/components/controls/mobile/flags/ru.svg +0 -5
  268. package/src/components/controls/mobile/flags/rw.svg +0 -17
  269. package/src/components/controls/mobile/flags/sa.svg +0 -23
  270. package/src/components/controls/mobile/flags/sb.svg +0 -30
  271. package/src/components/controls/mobile/flags/sc.svg +0 -7
  272. package/src/components/controls/mobile/flags/sd.svg +0 -6
  273. package/src/components/controls/mobile/flags/se.svg +0 -5
  274. package/src/components/controls/mobile/flags/sg.svg +0 -15
  275. package/src/components/controls/mobile/flags/sh.svg +0 -15
  276. package/src/components/controls/mobile/flags/si.svg +0 -30
  277. package/src/components/controls/mobile/flags/sj.svg +0 -11
  278. package/src/components/controls/mobile/flags/sk.svg +0 -21
  279. package/src/components/controls/mobile/flags/sl.svg +0 -5
  280. package/src/components/controls/mobile/flags/sm.svg +0 -847
  281. package/src/components/controls/mobile/flags/sn.svg +0 -15
  282. package/src/components/controls/mobile/flags/so.svg +0 -13
  283. package/src/components/controls/mobile/flags/sr.svg +0 -6
  284. package/src/components/controls/mobile/flags/ss.svg +0 -8
  285. package/src/components/controls/mobile/flags/st.svg +0 -16
  286. package/src/components/controls/mobile/flags/stc-icons.css +0 -1
  287. package/src/components/controls/mobile/flags/sv.svg +0 -3368
  288. package/src/components/controls/mobile/flags/sx.svg +0 -172
  289. package/src/components/controls/mobile/flags/sy.svg +0 -6
  290. package/src/components/controls/mobile/flags/sz.svg +0 -54
  291. package/src/components/controls/mobile/flags/tc.svg +0 -88
  292. package/src/components/controls/mobile/flags/td.svg +0 -5
  293. package/src/components/controls/mobile/flags/tf.svg +0 -18
  294. package/src/components/controls/mobile/flags/tg.svg +0 -15
  295. package/src/components/controls/mobile/flags/th.svg +0 -5
  296. package/src/components/controls/mobile/flags/tj.svg +0 -32
  297. package/src/components/controls/mobile/flags/tk.svg +0 -25
  298. package/src/components/controls/mobile/flags/tl.svg +0 -6
  299. package/src/components/controls/mobile/flags/tm.svg +0 -349
  300. package/src/components/controls/mobile/flags/tn.svg +0 -9
  301. package/src/components/controls/mobile/flags/to.svg +0 -8
  302. package/src/components/controls/mobile/flags/tr.svg +0 -6
  303. package/src/components/controls/mobile/flags/tt.svg +0 -5
  304. package/src/components/controls/mobile/flags/tv.svg +0 -18
  305. package/src/components/controls/mobile/flags/tw.svg +0 -12
  306. package/src/components/controls/mobile/flags/tz.svg +0 -13
  307. package/src/components/controls/mobile/flags/ua.svg +0 -4
  308. package/src/components/controls/mobile/flags/ug.svg +0 -46
  309. package/src/components/controls/mobile/flags/um.svg +0 -25
  310. package/src/components/controls/mobile/flags/us.svg +0 -25
  311. package/src/components/controls/mobile/flags/uy.svg +0 -138
  312. package/src/components/controls/mobile/flags/uz.svg +0 -30
  313. package/src/components/controls/mobile/flags/va.svg +0 -277
  314. package/src/components/controls/mobile/flags/vc.svg +0 -9
  315. package/src/components/controls/mobile/flags/ve.svg +0 -28
  316. package/src/components/controls/mobile/flags/vg.svg +0 -96
  317. package/src/components/controls/mobile/flags/vi.svg +0 -311
  318. package/src/components/controls/mobile/flags/vn.svg +0 -12
  319. package/src/components/controls/mobile/flags/vu.svg +0 -20
  320. package/src/components/controls/mobile/flags/wf.svg +0 -7
  321. package/src/components/controls/mobile/flags/ws.svg +0 -14
  322. package/src/components/controls/mobile/flags/xk.svg +0 -11
  323. package/src/components/controls/mobile/flags/ye.svg +0 -5
  324. package/src/components/controls/mobile/flags/yt.svg +0 -5
  325. package/src/components/controls/mobile/flags/za.svg +0 -17
  326. package/src/components/controls/mobile/flags/zm.svg +0 -20
  327. package/src/components/controls/mobile/flags/zw.svg +0 -130
  328. package/src/upgrade.scss +0 -68
@@ -49,19 +49,102 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
49
49
  args: [{ name: "selectStatus" }]
50
50
  }] });
51
51
 
52
+ /**
53
+ * Base class for every `iss-ctrl-*` control.
54
+ *
55
+ * Controls are the presentational layer: they know nothing about {@link IssField} and are
56
+ * driven purely by bindings, so they can be used standalone inside any reactive form.
57
+ * Every control below inherits the properties declared here and adds its own on top.
58
+ *
59
+ * ### Inherited inputs
60
+ * | Property | Type | Default | Description |
61
+ * | --- | --- | --- | --- |
62
+ * | `formControlName` | `string` | `""` | Name of the control in the surrounding `FormGroup`. |
63
+ * | `placeholder` | `string` | `""` | Placeholder text shown while the field is empty. |
64
+ * | `readonly` | `boolean` | `false` | Renders the value but blocks every interaction. |
65
+ * | `multiple` | `boolean \| undefined` | `false` | Allows more than one value, where the control supports it. |
66
+ * | `min` | `number \| string \| null` | `null` | Lower bound (number or date/time string). |
67
+ * | `max` | `number \| string \| null` | `null` | Upper bound (number or date/time string). |
68
+ * | `minLength` | `number \| null` | `null` | Minimum number of characters. |
69
+ * | `maxLength` | `number \| null` | `null` | Maximum number of characters. |
70
+ * | `hints` | `Hint[]` | `[]` | Helper messages rendered under the field. |
71
+ * | `className` | `string \| null` | `null` | Extra CSS classes for the host. |
72
+ *
73
+ * ### Inherited outputs
74
+ * | Event | Payload | Description |
75
+ * | --- | --- | --- |
76
+ * | `(onChange)` | `any` | Fires after every committed value change. |
77
+ *
78
+ * ### Not inputs
79
+ * `disabled` and `touched` are signals owned by the control. Disable a control through the
80
+ * forms API (`ctrl.disable()` or a `disabled` field config), never with a template binding.
81
+ *
82
+ * ### Content projection
83
+ * Controls that render a `mat-form-field` project `<label>` into the floating label.
84
+ * An omitted label — or one that interpolates to an empty string — leaves `<mat-label>`
85
+ * empty, and `upgrade.scss` collapses the floating-label space for it. No label markup is
86
+ * removed at runtime, so a label that arrives later simply shows up.
87
+ *
88
+ * @example
89
+ * ```html
90
+ * <iss-ctrl-input formControlName="email" [readonly]="false" (onChange)="save($event)">
91
+ * <label>Email</label>
92
+ * </iss-ctrl-input>
93
+ * ```
94
+ */
52
95
  class ControlBase {
96
+ /**
97
+ * Name of this control inside the surrounding `FormGroup`.
98
+ */
53
99
  formControlName = input("", ...(ngDevMode ? [{ debugName: "formControlName" }] : /* istanbul ignore next */ []));
100
+ /**
101
+ * Lower bound forwarded to the underlying input — a number, or a date/time string.
102
+ */
54
103
  min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
104
+ /**
105
+ * Upper bound forwarded to the underlying input — a number, or a date/time string.
106
+ */
55
107
  max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
108
+ /**
109
+ * Minimum number of characters accepted by the underlying input.
110
+ */
56
111
  minLength = input(null, ...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
112
+ /**
113
+ * Maximum number of characters accepted by the underlying input.
114
+ */
57
115
  maxLength = input(null, ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
116
+ /**
117
+ * Disabled state. **Not an input** — it is set by the forms API through
118
+ * {@link ControlBase.setDisabledState}. Disable via `ctrl.disable()` or the field config.
119
+ */
58
120
  disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
121
+ /**
122
+ * Renders the current value but blocks every user interaction.
123
+ */
59
124
  readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
125
+ /**
126
+ * Allows selecting/entering more than one value, on controls that support it.
127
+ */
60
128
  multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
129
+ /**
130
+ * Placeholder text shown while the control has no value.
131
+ */
61
132
  placeholder = input("", ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
133
+ /**
134
+ * Helper messages rendered beneath the field. See {@link Hint}.
135
+ */
62
136
  hints = input([], ...(ngDevMode ? [{ debugName: "hints" }] : /* istanbul ignore next */ []));
137
+ /**
138
+ * Extra CSS class names applied to the control host.
139
+ */
63
140
  className = input(null, ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
141
+ /**
142
+ * Whether the user has interacted with the control. Owned by the control, not an input.
143
+ */
64
144
  touched = signal(false, ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
145
+ /**
146
+ * Emits the committed value after every change.
147
+ */
65
148
  onChange = output();
66
149
  ctrl = new FormControl(null);
67
150
  registerOnChange(fn) {
@@ -121,8 +204,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
121
204
  args: [{ template: `` }]
122
205
  }], propDecorators: { formControlName: [{ type: i0.Input, args: [{ isSignal: true, alias: "formControlName", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hints: [{ type: i0.Input, args: [{ isSignal: true, alias: "hints", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], onChange: [{ type: i0.Output, args: ["onChange"] }] } });
123
206
 
207
+ /**
208
+ * `<iss-ctrl-checkbox>` — a list of checkboxes over a fixed set of options.
209
+ *
210
+ * The form value is the comma separated list of selected option values, while `(onChange)`
211
+ * emits the resolved `Option[]` (or `null` when nothing is selected).
212
+ *
213
+ * @example
214
+ * ```html
215
+ * <iss-ctrl-checkbox formControlName="days" [options]="days" (onChange)="pick($event)"/>
216
+ * ```
217
+ *
218
+ * ### Own inputs
219
+ * | Property | Type | Default | Description |
220
+ * | --- | --- | --- | --- |
221
+ * | `options` | `Option[]` | **required** | The selectable choices. |
222
+ *
223
+ * ### Inherited from {@link ControlBase}
224
+ * `formControlName` · `readonly` · `className` · `(onChange)`
225
+ *
226
+ * Does not project a label — the field label is rendered by the wrapping `iss-field-*`.
227
+ */
124
228
  class CheckboxControl extends ControlBase {
229
+ /**
230
+ * Selectable choices, each a `{ value, label }` pair. Required.
231
+ */
125
232
  options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
233
+ /**
234
+ * Currently checked options, keyed by value. Internal state, not an input.
235
+ */
126
236
  selectedOptions = signal(new Map(), ...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
127
237
  writeValue(value) {
128
238
  this.#reset();
@@ -191,7 +301,7 @@ class CheckboxControl extends ControlBase {
191
301
  <ul class="list-unstyled">
192
302
  @for (option of options(); track option.value) {
193
303
  <li class="mb-2">
194
- <mat-checkbox [checked]="option | selectStatus: selectedOptions()" [disabled]="disabled() || readonly()" (change)="onCheckboxChange($event.checked, option.value)">
304
+ <mat-checkbox [checked]="option | selectStatus: selectedOptions()" [disabled]="disabled() || readonly()" (change)="onCheckboxChange($event.checked, option.value)">
195
305
  {{ option.label }}
196
306
  </mat-checkbox>
197
307
  </li>
@@ -211,7 +321,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
211
321
  <ul class="list-unstyled">
212
322
  @for (option of options(); track option.value) {
213
323
  <li class="mb-2">
214
- <mat-checkbox [checked]="option | selectStatus: selectedOptions()" [disabled]="disabled() || readonly()" (change)="onCheckboxChange($event.checked, option.value)">
324
+ <mat-checkbox [checked]="option | selectStatus: selectedOptions()" [disabled]="disabled() || readonly()" (change)="onCheckboxChange($event.checked, option.value)">
215
325
  {{ option.label }}
216
326
  </mat-checkbox>
217
327
  </li>
@@ -221,7 +331,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
221
331
  }]
222
332
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }] } });
223
333
 
334
+ /**
335
+ * `<iss-ctrl-chips>` — free text entered as removable chips.
336
+ *
337
+ * Each `Enter` turns the typed text into a chip. The form value is the comma separated list
338
+ * of chip labels.
339
+ *
340
+ * @example
341
+ * ```html
342
+ * <iss-ctrl-chips formControlName="tags" placeholder="Add a tag">
343
+ * <label>Tags</label>
344
+ * </iss-ctrl-chips>
345
+ * ```
346
+ *
347
+ * ### Own inputs
348
+ * None — the control is configured entirely through the inherited properties.
349
+ *
350
+ * ### Inherited from {@link ControlBase}
351
+ * `formControlName` · `readonly` · `className` · `(onChange)` · `placeholder`
352
+ *
353
+ * Projects `<label>` into the floating label; omit it to render the control without one.
354
+ */
224
355
  class ChipsControl extends ControlBase {
356
+ /**
357
+ * The chips currently rendered. Internal state, not an input.
358
+ */
225
359
  keywords = signal([], ...(ngDevMode ? [{ debugName: "keywords" }] : /* istanbul ignore next */ []));
226
360
  writeValue(value) {
227
361
  if (typeof value === "string") {
@@ -269,15 +403,14 @@ class ChipsControl extends ControlBase {
269
403
  { provide: NG_VALUE_ACCESSOR, useExisting: ChipsControl, multi: true }
270
404
  ], usesInheritance: true, ngImport: i0, template: `
271
405
  <mat-form-field floatLabel="auto" class="">
272
- <mat-label class="fs-16 fc-black">
273
- <ng-content select="label"></ng-content>
274
- </mat-label>
406
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
407
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
275
408
  <input
276
409
  matInput
277
- [placeholder]="placeholder()"
278
- [matChipInputFor]="chipGrid"
279
- [disabled]="disabled()"
280
- [readonly]="readonly()"
410
+ [placeholder]="placeholder()"
411
+ [matChipInputFor]="chipGrid"
412
+ [disabled]="disabled()"
413
+ [readonly]="readonly()"
281
414
  (matChipInputTokenEnd)="add($event)"
282
415
  />
283
416
  </mat-form-field>
@@ -285,7 +418,7 @@ class ChipsControl extends ControlBase {
285
418
  @for (keyword of keywords(); track keyword) {
286
419
  <mat-chip-row (removed)="remove(keyword)">
287
420
  {{ keyword }}
288
- <button matChipRemove [disabled]="disabled() || readonly()">
421
+ <button matChipRemove [disabled]="disabled() || readonly()">
289
422
  <ds-icon icon="trash" class="fc-red"></ds-icon>
290
423
  </button>
291
424
  </mat-chip-row>
@@ -313,15 +446,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
313
446
  ],
314
447
  template: `
315
448
  <mat-form-field floatLabel="auto" class="">
316
- <mat-label class="fs-16 fc-black">
317
- <ng-content select="label"></ng-content>
318
- </mat-label>
449
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
450
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
319
451
  <input
320
452
  matInput
321
- [placeholder]="placeholder()"
322
- [matChipInputFor]="chipGrid"
323
- [disabled]="disabled()"
324
- [readonly]="readonly()"
453
+ [placeholder]="placeholder()"
454
+ [matChipInputFor]="chipGrid"
455
+ [disabled]="disabled()"
456
+ [readonly]="readonly()"
325
457
  (matChipInputTokenEnd)="add($event)"
326
458
  />
327
459
  </mat-form-field>
@@ -329,7 +461,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
329
461
  @for (keyword of keywords(); track keyword) {
330
462
  <mat-chip-row (removed)="remove(keyword)">
331
463
  {{ keyword }}
332
- <button matChipRemove [disabled]="disabled() || readonly()">
464
+ <button matChipRemove [disabled]="disabled() || readonly()">
333
465
  <ds-icon icon="trash" class="fc-red"></ds-icon>
334
466
  </button>
335
467
  </mat-chip-row>
@@ -355,9 +487,43 @@ const DATE_FORMAT_ADAPTER = {
355
487
  };
356
488
  const DATETIME_FORMAT = "dd/MM/yyyy hh:mm a";
357
489
 
490
+ /**
491
+ * `<iss-ctrl-date-picker>` — single date selection through a Material calendar.
492
+ *
493
+ * The input itself is read-only; clicking it opens the calendar. The emitted value is a
494
+ * `yyyy-MM-dd` string, and a clear button appears once a date is picked.
495
+ *
496
+ * @example
497
+ * ```html
498
+ * <iss-ctrl-date-picker formControlName="startsOn" [minDate]="today" [disabledDays]="[5, 6]">
499
+ * <label>Start date</label>
500
+ * </iss-ctrl-date-picker>
501
+ * ```
502
+ *
503
+ * ### Own inputs
504
+ * | Property | Type | Default | Description |
505
+ * | --- | --- | --- | --- |
506
+ * | `minDate` | `Date \| null` | `null` | Earliest selectable date. |
507
+ * | `maxDate` | `Date \| null` | `null` | Latest selectable date. |
508
+ * | `disabledDays` | `number[]` | `[]` | Week days to block, `0` = Sunday … `6` = Saturday. |
509
+ *
510
+ * ### Inherited from {@link ControlBase}
511
+ * `formControlName` · `readonly` · `className` · `(onChange)`
512
+ *
513
+ * Projects `<label>` into the floating label; omit it to render the control without one.
514
+ */
358
515
  class DatePickerControl extends ControlBase {
516
+ /**
517
+ * Week days that cannot be selected — `0` is Sunday through `6` for Saturday.
518
+ */
359
519
  disabledDays = input([], ...(ngDevMode ? [{ debugName: "disabledDays" }] : /* istanbul ignore next */ []));
520
+ /**
521
+ * Earliest selectable date.
522
+ */
360
523
  minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
524
+ /**
525
+ * Latest selectable date.
526
+ */
361
527
  maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
362
528
  clear(event) {
363
529
  if (this.readonly()) {
@@ -397,17 +563,16 @@ class DatePickerControl extends ControlBase {
397
563
  { provide: NG_VALIDATORS, useExisting: DatePickerControl, multi: true },
398
564
  ], usesInheritance: true, ngImport: i0, template: `
399
565
  <mat-form-field floatLabel="auto" class="">
400
- <mat-label class="fs-16 fc-black">
401
- <ng-content select="label"></ng-content>
402
- </mat-label>
566
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
567
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
403
568
  <input
404
569
  class="cursor-pointer"
405
570
  matInput
406
571
  readonly
407
572
  [matDatepicker]="picker"
408
- (click)="openPicker(picker)"
409
- [formControl]="ctrl"
410
- [readonly]="readonly()"
573
+ (click)="openPicker(picker)"
574
+ [formControl]="ctrl"
575
+ [readonly]="readonly()"
411
576
  [min]="minDate()"
412
577
  [max]="maxDate()"
413
578
  [matDatepickerFilter]="calendarDaysFilter"
@@ -416,7 +581,7 @@ class DatePickerControl extends ControlBase {
416
581
  @if (ctrl.getRawValue()) {
417
582
  <mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
418
583
  }
419
- <mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
584
+ <mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
420
585
  <mat-datepicker #picker></mat-datepicker>
421
586
 
422
587
  </mat-form-field>
@@ -432,17 +597,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
432
597
  { provide: NG_VALIDATORS, useExisting: DatePickerControl, multi: true },
433
598
  ], template: `
434
599
  <mat-form-field floatLabel="auto" class="">
435
- <mat-label class="fs-16 fc-black">
436
- <ng-content select="label"></ng-content>
437
- </mat-label>
600
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
601
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
438
602
  <input
439
603
  class="cursor-pointer"
440
604
  matInput
441
605
  readonly
442
606
  [matDatepicker]="picker"
443
- (click)="openPicker(picker)"
444
- [formControl]="ctrl"
445
- [readonly]="readonly()"
607
+ (click)="openPicker(picker)"
608
+ [formControl]="ctrl"
609
+ [readonly]="readonly()"
446
610
  [min]="minDate()"
447
611
  [max]="maxDate()"
448
612
  [matDatepickerFilter]="calendarDaysFilter"
@@ -451,18 +615,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
451
615
  @if (ctrl.getRawValue()) {
452
616
  <mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
453
617
  }
454
- <mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
618
+ <mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
455
619
  <mat-datepicker #picker></mat-datepicker>
456
620
 
457
621
  </mat-form-field>
458
622
  ` }]
459
623
  }], propDecorators: { disabledDays: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDays", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }] } });
460
624
 
625
+ /**
626
+ * `<iss-ctrl-date-range-picker>` — a start/end date range in one field.
627
+ *
628
+ * A half-filled range is not a value: clearing either endpoint clears the form value and
629
+ * emits `null`. The form value is a `yyyy-MM-dd` string pair; `(onDateRangeObjectChange)`
630
+ * emits the same range as a {@link DateRangeEmission} object.
631
+ *
632
+ * @example
633
+ * ```html
634
+ * <iss-ctrl-date-range-picker formControlName="period" (onDateRangeObjectChange)="apply($event)">
635
+ * <label>Period</label>
636
+ * </iss-ctrl-date-range-picker>
637
+ * ```
638
+ *
639
+ * ### Own inputs
640
+ * | Property | Type | Default | Description |
641
+ * | --- | --- | --- | --- |
642
+ * | `minDate` | `Date \| null` | `null` | Earliest selectable date. |
643
+ * | `maxDate` | `Date \| null` | `null` | Latest selectable date. |
644
+ * | `disabledDays` | `number[]` | `[]` | Week days to block, `0` = Sunday … `6` = Saturday. |
645
+ *
646
+ * ### Inherited from {@link ControlBase}
647
+ * `formControlName` · `readonly` · `className` · `(onChange)`
648
+ *
649
+ * ### Outputs
650
+ * - `(onDateRangeObjectChange)` — `DateRangeEmission | null`, the range as an object.
651
+ *
652
+ * Projects `<label>` into the floating label; omit it to render the control without one.
653
+ */
461
654
  class DateRangePickerControl extends ControlBase {
655
+ /**
656
+ * Week days that cannot be selected — `0` is Sunday through `6` for Saturday.
657
+ */
462
658
  disabledDays = input([], ...(ngDevMode ? [{ debugName: "disabledDays" }] : /* istanbul ignore next */ []));
659
+ /**
660
+ * Earliest selectable date.
661
+ */
463
662
  minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
663
+ /**
664
+ * Latest selectable date.
665
+ */
464
666
  maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
667
+ /**
668
+ * Emits the selected range as an object, or `null` while the range is incomplete.
669
+ */
465
670
  onDateRangeObjectChange = output();
671
+ /**
672
+ * The `start`/`end` form group backing the range input. Internal state.
673
+ */
466
674
  range = new FormGroup({
467
675
  start: new FormControl(null),
468
676
  end: new FormControl(null),
@@ -565,9 +773,8 @@ class DateRangePickerControl extends ControlBase {
565
773
  ], usesInheritance: true, ngImport: i0, template: `
566
774
  <mat-form-field floatLabel="auto" class="">
567
775
 
568
- <mat-label class="fs-16 fc-black">
569
- <ng-content select="label"></ng-content>
570
- </mat-label>
776
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
777
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
571
778
  <mat-date-range-input
572
779
  [formGroup]="range"
573
780
  [rangePicker]="picker"
@@ -577,23 +784,23 @@ class DateRangePickerControl extends ControlBase {
577
784
  >
578
785
  <input
579
786
  matStartDate
580
- formControlName="start"
581
- [readonly]="readonly()"
787
+ formControlName="start"
788
+ [readonly]="readonly()"
582
789
  placeholder="dd/mm/yyyy"
583
- (click)="openPicker(picker)"
790
+ (click)="openPicker(picker)"
584
791
  />
585
792
  <input
586
793
  matEndDate
587
- formControlName="end"
588
- [readonly]="readonly()"
794
+ formControlName="end"
795
+ [readonly]="readonly()"
589
796
  placeholder="dd/mm/yyyy"
590
- (click)="openPicker(picker)"
797
+ (click)="openPicker(picker)"
591
798
  />
592
799
  </mat-date-range-input>
593
800
  @if (range.getRawValue().start || range.getRawValue().end) {
594
801
  <mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
595
802
  }
596
- <mat-datepicker-toggle matSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
803
+ <mat-datepicker-toggle matSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
597
804
  <mat-date-range-picker #picker></mat-date-range-picker>
598
805
 
599
806
  </mat-form-field>
@@ -617,9 +824,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
617
824
  template: `
618
825
  <mat-form-field floatLabel="auto" class="">
619
826
 
620
- <mat-label class="fs-16 fc-black">
621
- <ng-content select="label"></ng-content>
622
- </mat-label>
827
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
828
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
623
829
  <mat-date-range-input
624
830
  [formGroup]="range"
625
831
  [rangePicker]="picker"
@@ -629,23 +835,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
629
835
  >
630
836
  <input
631
837
  matStartDate
632
- formControlName="start"
633
- [readonly]="readonly()"
838
+ formControlName="start"
839
+ [readonly]="readonly()"
634
840
  placeholder="dd/mm/yyyy"
635
- (click)="openPicker(picker)"
841
+ (click)="openPicker(picker)"
636
842
  />
637
843
  <input
638
844
  matEndDate
639
- formControlName="end"
640
- [readonly]="readonly()"
845
+ formControlName="end"
846
+ [readonly]="readonly()"
641
847
  placeholder="dd/mm/yyyy"
642
- (click)="openPicker(picker)"
848
+ (click)="openPicker(picker)"
643
849
  />
644
850
  </mat-date-range-input>
645
851
  @if (range.getRawValue().start || range.getRawValue().end) {
646
852
  <mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
647
853
  }
648
- <mat-datepicker-toggle matSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
854
+ <mat-datepicker-toggle matSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
649
855
  <mat-date-range-picker #picker></mat-date-range-picker>
650
856
 
651
857
  </mat-form-field>
@@ -653,9 +859,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
653
859
  }]
654
860
  }], propDecorators: { disabledDays: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDays", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], onDateRangeObjectChange: [{ type: i0.Output, args: ["onDateRangeObjectChange"] }] } });
655
861
 
862
+ /**
863
+ * `<iss-ctrl-time-picker>` — time of day, picked from a list generated at a fixed interval.
864
+ *
865
+ * @example
866
+ * ```html
867
+ * <iss-ctrl-time-picker formControlName="startsAt" interval="15min" minTime="08:00" maxTime="17:00">
868
+ * <label>Starts at</label>
869
+ * </iss-ctrl-time-picker>
870
+ * ```
871
+ *
872
+ * ### Own inputs
873
+ * | Property | Type | Default | Description |
874
+ * | --- | --- | --- | --- |
875
+ * | `interval` | `string` | `"30min"` | Step between the offered times. |
876
+ * | `minTime` | `string \| null` | `null` | Earliest offered time, `HH:mm`. |
877
+ * | `maxTime` | `string \| null` | `null` | Latest offered time, `HH:mm`. |
878
+ *
879
+ * ### Inherited from {@link ControlBase}
880
+ * `formControlName` · `readonly` · `className` · `(onChange)`
881
+ *
882
+ * Projects `<label>` into the floating label; omit it to render the control without one.
883
+ */
656
884
  class TimePickerControl extends ControlBase {
885
+ /**
886
+ * Step between the offered times, for example `"15min"` or `"30min"`.
887
+ */
657
888
  interval = input("30min", ...(ngDevMode ? [{ debugName: "interval" }] : /* istanbul ignore next */ []));
889
+ /**
890
+ * Earliest offered time of day, as `HH:mm`.
891
+ */
658
892
  minTime = input(null, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
893
+ /**
894
+ * Latest offered time of day, as `HH:mm`.
895
+ */
659
896
  maxTime = input(null, ...(ngDevMode ? [{ debugName: "maxTime" }] : /* istanbul ignore next */ []));
660
897
  emit(evt) {
661
898
  if (this.readonly()) {
@@ -705,22 +942,21 @@ class TimePickerControl extends ControlBase {
705
942
  { provide: NG_VALIDATORS, useExisting: TimePickerControl, multi: true },
706
943
  ], usesInheritance: true, ngImport: i0, template: `
707
944
  <mat-form-field floatLabel="auto" class="">
708
- <mat-label class="fs-16 fc-black">
709
- <ng-content select="label"></ng-content>
710
- </mat-label>
945
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
946
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
711
947
  <input
712
948
  matInput
713
949
  [formControl]="ctrl"
714
950
  [matTimepicker]="picker"
715
951
  [matTimepickerMin]="minTime()"
716
- [matTimepickerMax]="maxTime()"
717
- [readonly]="readonly()"
952
+ [matTimepickerMax]="maxTime()"
953
+ [readonly]="readonly()"
718
954
  readonly
719
955
  />
720
956
  @if (ctrl.getRawValue()) {
721
957
  <mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
722
958
  }
723
- <mat-timepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"/>
959
+ <mat-timepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"/>
724
960
  <mat-timepicker (selected)="emit($event)" [interval]="interval()" #picker/>
725
961
 
726
962
  </mat-form-field>
@@ -741,22 +977,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
741
977
  ],
742
978
  template: `
743
979
  <mat-form-field floatLabel="auto" class="">
744
- <mat-label class="fs-16 fc-black">
745
- <ng-content select="label"></ng-content>
746
- </mat-label>
980
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
981
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
747
982
  <input
748
983
  matInput
749
984
  [formControl]="ctrl"
750
985
  [matTimepicker]="picker"
751
986
  [matTimepickerMin]="minTime()"
752
- [matTimepickerMax]="maxTime()"
753
- [readonly]="readonly()"
987
+ [matTimepickerMax]="maxTime()"
988
+ [readonly]="readonly()"
754
989
  readonly
755
990
  />
756
991
  @if (ctrl.getRawValue()) {
757
992
  <mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
758
993
  }
759
- <mat-timepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"/>
994
+ <mat-timepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"/>
760
995
  <mat-timepicker (selected)="emit($event)" [interval]="interval()" #picker/>
761
996
 
762
997
  </mat-form-field>
@@ -764,15 +999,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
764
999
  }]
765
1000
  }], propDecorators: { interval: [{ type: i0.Input, args: [{ isSignal: true, alias: "interval", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }] } });
766
1001
 
1002
+ /**
1003
+ * `<iss-ctrl-datetime-picker>` — a date and a time in a single field.
1004
+ *
1005
+ * Combines the calendar of the date picker with the time list of the time picker; both parts
1006
+ * must be set before a value is emitted.
1007
+ *
1008
+ * @example
1009
+ * ```html
1010
+ * <iss-ctrl-datetime-picker formControlName="scheduledAt" [minDate]="today" minTime="08:00" maxTime="17:00">
1011
+ * <label>Scheduled at</label>
1012
+ * </iss-ctrl-datetime-picker>
1013
+ * ```
1014
+ *
1015
+ * ### Own inputs
1016
+ * | Property | Type | Default | Description |
1017
+ * | --- | --- | --- | --- |
1018
+ * | `minDate` | `Date \| null` | `null` | Earliest selectable date. |
1019
+ * | `maxDate` | `Date \| null` | `null` | Latest selectable date. |
1020
+ * | `minTime` | `string \| null` | `null` | Earliest selectable time, `HH:mm`. |
1021
+ * | `maxTime` | `string \| null` | `null` | Latest selectable time, `HH:mm`. |
1022
+ * | `disabledDays` | `number[]` | `[]` | Week days to block, `0` = Sunday … `6` = Saturday. |
1023
+ *
1024
+ * ### Inherited from {@link ControlBase}
1025
+ * `formControlName` · `readonly` · `className` · `(onChange)`
1026
+ *
1027
+ * Projects `<label>` into the floating label; omit it to render the control without one.
1028
+ */
767
1029
  class DatetimePickerControl extends ControlBase {
768
1030
  datetimeForm = new FormGroup({
769
1031
  date: new FormControl(null),
770
1032
  time: new FormControl(null),
771
1033
  });
1034
+ /**
1035
+ * Week days that cannot be selected — `0` is Sunday through `6` for Saturday.
1036
+ */
772
1037
  disabledDays = input([], ...(ngDevMode ? [{ debugName: "disabledDays" }] : /* istanbul ignore next */ []));
1038
+ /**
1039
+ * Earliest selectable date.
1040
+ */
773
1041
  minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
1042
+ /**
1043
+ * Latest selectable date.
1044
+ */
774
1045
  maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
1046
+ /**
1047
+ * Earliest selectable time of day, as `HH:mm`.
1048
+ */
775
1049
  minTime = input(null, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
1050
+ /**
1051
+ * Latest selectable time of day, as `HH:mm`.
1052
+ */
776
1053
  maxTime = input(null, ...(ngDevMode ? [{ debugName: "maxTime" }] : /* istanbul ignore next */ []));
777
1054
  setDisabledState(isDisabled) {
778
1055
  super.setDisabledState(isDisabled);
@@ -839,16 +1116,16 @@ class DatetimePickerControl extends ControlBase {
839
1116
  { provide: NG_VALIDATORS, useExisting: DatetimePickerControl, multi: true },
840
1117
  ], usesInheritance: true, ngImport: i0, template: `
841
1118
  <form [formGroup]="datetimeForm" class="d-flex flex-row gap-1">
842
- <iss-ctrl-date-picker (focusout)="markAsTouched()" [disabledDays]="disabledDays()" [maxDate]="maxDate()" [minDate]="minDate()" [readonly]="readonly()" formControlName="date" (onChange)="emit()">
843
- <label>
844
- <ng-content select="label"></ng-content>
845
- </label>
1119
+ <iss-ctrl-date-picker (focusout)="markAsTouched()" [disabledDays]="disabledDays()" [maxDate]="maxDate()" [minDate]="minDate()" [readonly]="readonly()" formControlName="date" (onChange)="emit()">
1120
+ <!-- Re-projected with ngProjectAs so it still matches the date picker's own select="label";
1121
+ wrapping it in a second <label> instead would hide an empty label from the :empty rule in upgrade.scss. -->
1122
+ <ng-content select="label" ngProjectAs="label"></ng-content>
846
1123
  </iss-ctrl-date-picker>
847
1124
  <iss-ctrl-time-picker
848
1125
  (focusout)="markAsTouched()"
849
1126
  [maxTime]="maxTime()"
850
- [minTime]="minTime()"
851
- [readonly]="readonly()"
1127
+ [minTime]="minTime()"
1128
+ [readonly]="readonly()"
852
1129
  formControlName="time"
853
1130
  (onChange)="emit()"
854
1131
  />
@@ -874,16 +1151,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
874
1151
  ],
875
1152
  template: `
876
1153
  <form [formGroup]="datetimeForm" class="d-flex flex-row gap-1">
877
- <iss-ctrl-date-picker (focusout)="markAsTouched()" [disabledDays]="disabledDays()" [maxDate]="maxDate()" [minDate]="minDate()" [readonly]="readonly()" formControlName="date" (onChange)="emit()">
878
- <label>
879
- <ng-content select="label"></ng-content>
880
- </label>
1154
+ <iss-ctrl-date-picker (focusout)="markAsTouched()" [disabledDays]="disabledDays()" [maxDate]="maxDate()" [minDate]="minDate()" [readonly]="readonly()" formControlName="date" (onChange)="emit()">
1155
+ <!-- Re-projected with ngProjectAs so it still matches the date picker's own select="label";
1156
+ wrapping it in a second <label> instead would hide an empty label from the :empty rule in upgrade.scss. -->
1157
+ <ng-content select="label" ngProjectAs="label"></ng-content>
881
1158
  </iss-ctrl-date-picker>
882
1159
  <iss-ctrl-time-picker
883
1160
  (focusout)="markAsTouched()"
884
1161
  [maxTime]="maxTime()"
885
- [minTime]="minTime()"
886
- [readonly]="readonly()"
1162
+ [minTime]="minTime()"
1163
+ [readonly]="readonly()"
887
1164
  formControlName="time"
888
1165
  (onChange)="emit()"
889
1166
  />
@@ -988,12 +1265,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
988
1265
  args: ["drop", ["$event"]]
989
1266
  }] } });
990
1267
 
1268
+ /**
1269
+ * `<iss-ctrl-file-picker>` — attachment upload with a per-file progress and error state.
1270
+ *
1271
+ * Uploading is done by the host: the control emits the picked files and renders whatever is
1272
+ * fed back through `uploadedFiles`, `uploading` and `uploadingError`.
1273
+ *
1274
+ * @example
1275
+ * ```html
1276
+ * <iss-ctrl-file-picker
1277
+ * formControlName="attachments"
1278
+ * [multiple]="true"
1279
+ * accept=".pdf,.png"
1280
+ * [uploading]="uploading()"
1281
+ * [uploadedFiles]="uploaded()"
1282
+ * />
1283
+ * ```
1284
+ *
1285
+ * ### Own inputs
1286
+ * | Property | Type | Default | Description |
1287
+ * | --- | --- | --- | --- |
1288
+ * | `accept` | `string \| undefined` | `undefined` | Accepted extensions or MIME types for the native picker. |
1289
+ * | `showDownloadButton` | `boolean` | `true` | Shows the download action on each attachment. |
1290
+ * | `showDeleteButton` | `boolean` | `true` | Shows the remove action on each attachment. |
1291
+ * | `uploading` | `boolean` | `false` | Renders the in-progress state. |
1292
+ * | `uploadedFiles` | `IssAttachment[]` | `[]` | Files already stored on the server. |
1293
+ * | `uploadingError` | `string \| undefined` | `undefined` | Error message attached to the failed upload. |
1294
+ *
1295
+ * ### Inherited from {@link ControlBase}
1296
+ * `formControlName` · `readonly` · `className` · `(onChange)` · `multiple` · `hints`
1297
+ *
1298
+ * Does not project a label — the field label is rendered by the wrapping `iss-field-*`.
1299
+ */
991
1300
  class FilePickerControl extends ControlBase {
1301
+ /**
1302
+ * Accepted extensions or MIME types, passed straight to the native file input.
1303
+ */
992
1304
  accept = input(...(ngDevMode ? [undefined, { debugName: "accept" }] : /* istanbul ignore next */ []));
1305
+ /**
1306
+ * Shows the download action on each listed attachment.
1307
+ */
993
1308
  showDownloadButton = input(true, ...(ngDevMode ? [{ debugName: "showDownloadButton" }] : /* istanbul ignore next */ []));
1309
+ /**
1310
+ * Shows the remove action on each listed attachment.
1311
+ */
994
1312
  showDeleteButton = input(true, ...(ngDevMode ? [{ debugName: "showDeleteButton" }] : /* istanbul ignore next */ []));
1313
+ /**
1314
+ * Renders the upload-in-progress state; set by the host that performs the upload.
1315
+ */
995
1316
  uploading = input(false, ...(ngDevMode ? [{ debugName: "uploading" }] : /* istanbul ignore next */ []));
1317
+ /**
1318
+ * Attachments already stored on the server, merged into the rendered list.
1319
+ */
996
1320
  uploadedFiles = input([], ...(ngDevMode ? [{ debugName: "uploadedFiles" }] : /* istanbul ignore next */ []));
1321
+ /**
1322
+ * Error message shown on the attachment whose upload failed.
1323
+ */
997
1324
  uploadingError = input(undefined, ...(ngDevMode ? [{ debugName: "uploadingError" }] : /* istanbul ignore next */ []));
998
1325
  filesValue = computed(() => this.#returnAttachmentViewObject(), ...(ngDevMode ? [{ debugName: "filesValue" }] : /* istanbul ignore next */ []));
999
1326
  attachments = signal([], ...(ngDevMode ? [{ debugName: "attachments" }] : /* istanbul ignore next */ []));
@@ -1163,13 +1490,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1163
1490
  `, styles: [".file-uploader{--uploader-height: 150px;--uploader-width: 100%;--uploader-bg: var(--off-white);--uploader-border: 1px dashed var(--dark-gray);--uploader-radius: var(--box-radius);--uploader-padding: 1rem;height:var(--uploader-height);background-color:var(--uploader-bg);border:var(--uploader-border);border-radius:var(--uploader-radius);padding:var(--uploader-padding);text-align:center;cursor:pointer}.file-uploader --input{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:.75rem}\n"] }]
1164
1491
  }], propDecorators: { accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], showDownloadButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDownloadButton", required: false }] }], showDeleteButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDeleteButton", required: false }] }], uploading: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploading", required: false }] }], uploadedFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadedFiles", required: false }] }], uploadingError: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadingError", required: false }] }] } });
1165
1492
 
1493
+ /**
1494
+ * `<iss-ctrl-input>` — single line text input, the base for every scalar text field.
1495
+ *
1496
+ * `type` is forwarded to the native input, so `number`, `email` and `password` variants all
1497
+ * come from this one control.
1498
+ *
1499
+ * @example
1500
+ * ```html
1501
+ * <iss-ctrl-input formControlName="amount" type="number" [min]="0" suffixText="SAR">
1502
+ * <label>Amount</label>
1503
+ * </iss-ctrl-input>
1504
+ * ```
1505
+ *
1506
+ * ### Own inputs
1507
+ * | Property | Type | Default | Description |
1508
+ * | --- | --- | --- | --- |
1509
+ * | `type` | `string` | `"text"` | Native input type: `text`, `number`, `email`, `password`, … |
1510
+ * | `prefixIcon` | `string` | `""` | Icon rendered before the value. |
1511
+ * | `prefixText` | `string` | `""` | Text rendered before the value. |
1512
+ * | `suffixIcon` | `string` | `""` | Icon rendered after the value. |
1513
+ * | `suffixText` | `string` | `""` | Text rendered after the value. |
1514
+ *
1515
+ * ### Inherited from {@link ControlBase}
1516
+ * `formControlName` · `readonly` · `className` · `(onChange)` · `placeholder` · `min` · `max` · `minLength` · `maxLength` · `hints`
1517
+ *
1518
+ * ### Outputs
1519
+ * - `(onPrefixClick)` — `string`, the prefix affix was clicked.
1520
+ * - `(onSuffixClick)` — `string`, the suffix affix was clicked.
1521
+ *
1522
+ * Projects `<label>` into the floating label; omit it to render the control without one.
1523
+ *
1524
+ * Also projects `[issPrefix]` and `[issSuffix]` for fully custom affixes.
1525
+ */
1166
1526
  class InputControl extends ControlBase {
1527
+ /**
1528
+ * Native input type — `text`, `number`, `email`, `password`, and so on.
1529
+ */
1167
1530
  type = input("text", ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
1531
+ /**
1532
+ * Icon name rendered before the value.
1533
+ */
1168
1534
  prefixIcon = input("", ...(ngDevMode ? [{ debugName: "prefixIcon" }] : /* istanbul ignore next */ []));
1535
+ /**
1536
+ * Static text rendered before the value.
1537
+ */
1169
1538
  prefixText = input("", ...(ngDevMode ? [{ debugName: "prefixText" }] : /* istanbul ignore next */ []));
1539
+ /**
1540
+ * Icon name rendered after the value.
1541
+ */
1170
1542
  suffixIcon = input("", ...(ngDevMode ? [{ debugName: "suffixIcon" }] : /* istanbul ignore next */ []));
1543
+ /**
1544
+ * Static text rendered after the value, a unit or currency for example.
1545
+ */
1171
1546
  suffixText = input("", ...(ngDevMode ? [{ debugName: "suffixText" }] : /* istanbul ignore next */ []));
1547
+ /**
1548
+ * Emits when the prefix affix is clicked.
1549
+ */
1172
1550
  onPrefixClick = output();
1551
+ /**
1552
+ * Emits when the suffix affix is clicked.
1553
+ */
1173
1554
  onSuffixClick = output();
1174
1555
  #disabledEffect = effect(() => {
1175
1556
  if (this.disabled()) {
@@ -1194,9 +1575,8 @@ class InputControl extends ControlBase {
1194
1575
  { provide: NG_VALIDATORS, useExisting: InputControl, multi: true }
1195
1576
  ], usesInheritance: true, ngImport: i0, template: `
1196
1577
  <mat-form-field floatLabel="auto" class="">
1197
- <mat-label class="fs-16 fc-black">
1198
- <ng-content select="label"></ng-content>
1199
- </mat-label>
1578
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
1579
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
1200
1580
  <ng-content select="[issPrefix]"></ng-content>
1201
1581
  <div (click)="emitPrefixClick()" class="cursor-pointer">
1202
1582
  @if (prefixText()) {
@@ -1215,8 +1595,8 @@ class InputControl extends ControlBase {
1215
1595
  [attr.minlength]="minLength()"
1216
1596
  [attr.max]="max()"
1217
1597
  [attr.min]="min()"
1218
- [placeholder]="placeholder()"
1219
- [readonly]="readonly()"
1598
+ [placeholder]="placeholder()"
1599
+ [readonly]="readonly()"
1220
1600
  [type]="type()"
1221
1601
  />
1222
1602
  <ng-content select="[issSuffix]"></ng-content>
@@ -1251,9 +1631,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1251
1631
  ],
1252
1632
  template: `
1253
1633
  <mat-form-field floatLabel="auto" class="">
1254
- <mat-label class="fs-16 fc-black">
1255
- <ng-content select="label"></ng-content>
1256
- </mat-label>
1634
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
1635
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
1257
1636
  <ng-content select="[issPrefix]"></ng-content>
1258
1637
  <div (click)="emitPrefixClick()" class="cursor-pointer">
1259
1638
  @if (prefixText()) {
@@ -1272,8 +1651,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1272
1651
  [attr.minlength]="minLength()"
1273
1652
  [attr.max]="max()"
1274
1653
  [attr.min]="min()"
1275
- [placeholder]="placeholder()"
1276
- [readonly]="readonly()"
1654
+ [placeholder]="placeholder()"
1655
+ [readonly]="readonly()"
1277
1656
  [type]="type()"
1278
1657
  />
1279
1658
  <ng-content select="[issSuffix]"></ng-content>
@@ -3427,10 +3806,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3427
3806
  args: [{ providedIn: "root" }]
3428
3807
  }] });
3429
3808
 
3809
+ /**
3810
+ * `<iss-ctrl-mobile>` — international phone number with a country selector.
3811
+ *
3812
+ * The number is validated against the selected country and stored in its international form.
3813
+ *
3814
+ * @example
3815
+ * ```html
3816
+ * <iss-ctrl-mobile formControlName="mobile" [preferredCountries]="['SA', 'AE']">
3817
+ * <label>Mobile</label>
3818
+ * </iss-ctrl-mobile>
3819
+ * ```
3820
+ *
3821
+ * ### Own inputs
3822
+ * | Property | Type | Default | Description |
3823
+ * | --- | --- | --- | --- |
3824
+ * | `preferredCountries` | `ISO2[]` | `["SA"]` | Countries pinned to the top of the country list. |
3825
+ *
3826
+ * ### Inherited from {@link ControlBase}
3827
+ * `formControlName` · `readonly` · `className` · `(onChange)`
3828
+ *
3829
+ * Projects `<label>` into the floating label; omit it to render the control without one.
3830
+ */
3430
3831
  class MobileControl extends ControlBase {
3431
3832
  phoneService = inject(Phone);
3432
3833
  isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
3433
3834
  selectedCountry = signal(DEFAULT_COUNTRY, ...(ngDevMode ? [{ debugName: "selectedCountry" }] : /* istanbul ignore next */ []));
3835
+ /**
3836
+ * ISO-2 country codes pinned to the top of the country list; the first one is preselected.
3837
+ */
3434
3838
  preferredCountries = input(["SA"], ...(ngDevMode ? [{ debugName: "preferredCountries" }] : /* istanbul ignore next */ []));
3435
3839
  searchInput = new FormControl("");
3436
3840
  filteredCountries = computed(() => this.#searchInCountries(), ...(ngDevMode ? [{ debugName: "filteredCountries" }] : /* istanbul ignore next */ []));
@@ -3561,9 +3965,8 @@ class MobileControl extends ControlBase {
3561
3965
  { provide: NG_VALIDATORS, useExisting: MobileControl, multi: true }
3562
3966
  ], usesInheritance: true, ngImport: i0, template: `
3563
3967
  <mat-form-field floatLabel="auto" cdkOverlayOrigin #trigger="cdkOverlayOrigin">
3564
- <mat-label class="fs-16 fc-black">
3565
- <ng-content select="label"></ng-content>
3566
- </mat-label>
3968
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
3969
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
3567
3970
  <div class="d-inline-flex align-items-center gap-1 country-flag" matPrefix (click)="toggleCountryCodeMenu()">
3568
3971
  <img
3569
3972
  ngSrc="./flags/{{selectedCountry().code.toLowerCase()}}.svg"
@@ -3582,8 +3985,8 @@ class MobileControl extends ControlBase {
3582
3985
  (blur)="markAsTouched()"
3583
3986
  (keydown)="onInput($event)"
3584
3987
  (input)="emit()"
3585
- [formControl]="ctrl"
3586
- [readonly]="readonly()"
3988
+ [formControl]="ctrl"
3989
+ [readonly]="readonly()"
3587
3990
  [placeholder]="selectedCountry().placeholder"
3588
3991
  />
3589
3992
  </mat-form-field>
@@ -3638,9 +4041,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3638
4041
  { provide: NG_VALIDATORS, useExisting: MobileControl, multi: true }
3639
4042
  ], template: `
3640
4043
  <mat-form-field floatLabel="auto" cdkOverlayOrigin #trigger="cdkOverlayOrigin">
3641
- <mat-label class="fs-16 fc-black">
3642
- <ng-content select="label"></ng-content>
3643
- </mat-label>
4044
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
4045
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
3644
4046
  <div class="d-inline-flex align-items-center gap-1 country-flag" matPrefix (click)="toggleCountryCodeMenu()">
3645
4047
  <img
3646
4048
  ngSrc="./flags/{{selectedCountry().code.toLowerCase()}}.svg"
@@ -3659,8 +4061,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3659
4061
  (blur)="markAsTouched()"
3660
4062
  (keydown)="onInput($event)"
3661
4063
  (input)="emit()"
3662
- [formControl]="ctrl"
3663
- [readonly]="readonly()"
4064
+ [formControl]="ctrl"
4065
+ [readonly]="readonly()"
3664
4066
  [placeholder]="selectedCountry().placeholder"
3665
4067
  />
3666
4068
  </mat-form-field>
@@ -3719,6 +4121,26 @@ const PLATE_LETTERS = [
3719
4121
  { label: { ar: "ي", en: "V" }, value: "V" }
3720
4122
  ];
3721
4123
 
4124
+ /**
4125
+ * `<iss-ctrl-plate-number>` — Saudi vehicle plate, entered as digits and letters in both
4126
+ * Arabic and English.
4127
+ *
4128
+ * Typing into one script fills the matching cell in the other automatically, and letters are
4129
+ * validated against the allowed plate alphabet.
4130
+ *
4131
+ * @example
4132
+ * ```html
4133
+ * <iss-ctrl-plate-number formControlName="plate" [readonly]="false"/>
4134
+ * ```
4135
+ *
4136
+ * ### Own inputs
4137
+ * None — the control is configured entirely through the inherited properties.
4138
+ *
4139
+ * ### Inherited from {@link ControlBase}
4140
+ * `formControlName` · `readonly` · `className` · `(onChange)`
4141
+ *
4142
+ * Does not project a label — the field label is rendered by the wrapping `iss-field-*`.
4143
+ */
3722
4144
  class PlateControl extends ControlBase {
3723
4145
  numbersAr = signal(Array(4).fill(""), ...(ngDevMode ? [{ debugName: "numbersAr" }] : /* istanbul ignore next */ []));
3724
4146
  numbersEn = signal(Array(4).fill(""), ...(ngDevMode ? [{ debugName: "numbersEn" }] : /* istanbul ignore next */ []));
@@ -3951,8 +4373,8 @@ class PlateControl extends ControlBase {
3951
4373
  class="plate-input number-input"
3952
4374
  maxlength="1"
3953
4375
  [attr.data-plate-input]="'num-ar-' + $index"
3954
- [value]="num"
3955
- [readonly]="readonly()"
4376
+ [value]="num"
4377
+ [readonly]="readonly()"
3956
4378
  placeholder="١"
3957
4379
  (keydown)="preventNonDigits($event, 'ar')"
3958
4380
  (keyup)="preventNonDigits($event, 'ar')"
@@ -3968,8 +4390,8 @@ class PlateControl extends ControlBase {
3968
4390
  class="plate-input number-input"
3969
4391
  maxlength="1"
3970
4392
  [attr.data-plate-input]="'num-en-' + $index"
3971
- [value]="num"
3972
- [readonly]="readonly()"
4393
+ [value]="num"
4394
+ [readonly]="readonly()"
3973
4395
  placeholder="1"
3974
4396
  (keydown)="preventNonDigits($event, 'en')"
3975
4397
  (keyup)="preventNonDigits($event, 'en')"
@@ -4000,8 +4422,8 @@ class PlateControl extends ControlBase {
4000
4422
  maxlength="1"
4001
4423
  [attr.data-plate-input]="'let-ar-' + $index"
4002
4424
  [class.invalid]="letterErrors()[$index]"
4003
- [value]="letter"
4004
- [readonly]="readonly()"
4425
+ [value]="letter"
4426
+ [readonly]="readonly()"
4005
4427
  placeholder="س"
4006
4428
  (input)="onLetterInput($index, $event, 'ar')"
4007
4429
  />
@@ -4021,8 +4443,8 @@ class PlateControl extends ControlBase {
4021
4443
  maxlength="1"
4022
4444
  [attr.data-plate-input]="'let-en-' + $index"
4023
4445
  [class.invalid]="letterErrors()[$index]"
4024
- [value]="letter"
4025
- [readonly]="readonly()"
4446
+ [value]="letter"
4447
+ [readonly]="readonly()"
4026
4448
  placeholder="S"
4027
4449
  (input)="onLetterInput($index, $event, 'en')"
4028
4450
  />
@@ -4061,8 +4483,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4061
4483
  class="plate-input number-input"
4062
4484
  maxlength="1"
4063
4485
  [attr.data-plate-input]="'num-ar-' + $index"
4064
- [value]="num"
4065
- [readonly]="readonly()"
4486
+ [value]="num"
4487
+ [readonly]="readonly()"
4066
4488
  placeholder="١"
4067
4489
  (keydown)="preventNonDigits($event, 'ar')"
4068
4490
  (keyup)="preventNonDigits($event, 'ar')"
@@ -4078,8 +4500,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4078
4500
  class="plate-input number-input"
4079
4501
  maxlength="1"
4080
4502
  [attr.data-plate-input]="'num-en-' + $index"
4081
- [value]="num"
4082
- [readonly]="readonly()"
4503
+ [value]="num"
4504
+ [readonly]="readonly()"
4083
4505
  placeholder="1"
4084
4506
  (keydown)="preventNonDigits($event, 'en')"
4085
4507
  (keyup)="preventNonDigits($event, 'en')"
@@ -4110,8 +4532,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4110
4532
  maxlength="1"
4111
4533
  [attr.data-plate-input]="'let-ar-' + $index"
4112
4534
  [class.invalid]="letterErrors()[$index]"
4113
- [value]="letter"
4114
- [readonly]="readonly()"
4535
+ [value]="letter"
4536
+ [readonly]="readonly()"
4115
4537
  placeholder="س"
4116
4538
  (input)="onLetterInput($index, $event, 'ar')"
4117
4539
  />
@@ -4131,8 +4553,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4131
4553
  maxlength="1"
4132
4554
  [attr.data-plate-input]="'let-en-' + $index"
4133
4555
  [class.invalid]="letterErrors()[$index]"
4134
- [value]="letter"
4135
- [readonly]="readonly()"
4556
+ [value]="letter"
4557
+ [readonly]="readonly()"
4136
4558
  placeholder="S"
4137
4559
  (input)="onLetterInput($index, $event, 'en')"
4138
4560
  />
@@ -4156,7 +4578,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4156
4578
  `, styles: [".plate-container{width:600px;height:130px;border:4px solid #1D252D;border-radius:10px;background:#fff;display:flex;box-shadow:0 4px 10px #0003;overflow:hidden;position:relative}.section{display:flex;flex-direction:column;justify-content:center;align-items:center}.numbers-section{flex:2;padding:0 10px}.digit-row{display:flex;justify-content:space-between;width:80%;font-size:38px;line-height:1;color:#1d252d;margin:2px 0}.emblem-section{flex:1.2;padding:10px}.emblem-svg{width:100%;height:100%;max-height:90px}.letters-section{flex:1.8;border-right:2px solid #1D252D;padding:0 10px}.arabic-row{font-family:Noto Sans Arabic,sans-serif;font-size:32px;display:flex;justify-content:space-around;width:100%;margin-bottom:5px;color:#1d252d}.english-row{font-size:38px;display:flex;justify-content:space-around;width:100%;color:#1d252d}.ksa-strip{width:50px;display:flex;flex-direction:column;justify-content:space-between;align-items:center;padding:10px 0;background-color:#fff}.mini-emblem{width:25px;height:auto}.ksa-text{writing-mode:vertical-rl;text-orientation:upright;font-weight:900;font-size:16px;letter-spacing:2px;color:#1d252d;margin-top:auto;margin-bottom:5px}.plate-input{background:transparent;border:none;text-align:center;font-family:inherit;font-size:inherit;font-weight:700;color:#1d252d;width:100%;padding:0;margin:0;outline:none}.plate-input:focus{border-bottom:2px solid #1D252D}.digit-row,.arabic-row,.english-row{display:flex;justify-content:space-between;width:100%}.number-input,.letter-input{flex:1}.plate-input::placeholder{color:#ccc;opacity:1}.input-wrapper{position:relative;display:flex;flex-direction:column;align-items:center;flex:1}.error-tooltip{position:absolute;bottom:-15px;font-size:10px;color:red;white-space:nowrap}.plate-input.invalid{color:red}\n"] }]
4157
4579
  }] });
4158
4580
 
4581
+ /**
4582
+ * `<iss-ctrl-radio>` — one choice out of a fixed set of options.
4583
+ *
4584
+ * @example
4585
+ * ```html
4586
+ * <iss-ctrl-radio formControlName="gender" [options]="genders"/>
4587
+ * ```
4588
+ *
4589
+ * ### Own inputs
4590
+ * | Property | Type | Default | Description |
4591
+ * | --- | --- | --- | --- |
4592
+ * | `options` | `Option[]` | **required** | The selectable choices. |
4593
+ *
4594
+ * ### Inherited from {@link ControlBase}
4595
+ * `formControlName` · `readonly` · `className` · `(onChange)`
4596
+ *
4597
+ * Does not project a label — the field label is rendered by the wrapping `iss-field-*`.
4598
+ */
4159
4599
  class RadioControl extends ControlBase {
4600
+ /**
4601
+ * Selectable choices, each a `{ value, label }` pair. Required.
4602
+ */
4160
4603
  options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
4161
4604
  writeValue(value) {
4162
4605
  if (!value) {
@@ -4182,7 +4625,7 @@ class RadioControl extends ControlBase {
4182
4625
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: RadioControl, isStandalone: true, selector: "iss-ctrl-radio", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, providers: [
4183
4626
  { provide: NG_VALUE_ACCESSOR, useExisting: RadioControl, multi: true }
4184
4627
  ], usesInheritance: true, ngImport: i0, template: `
4185
- <mat-button-toggle-group [hideSingleSelectionIndicator]="true" [disabled]="disabled() || readonly()">
4628
+ <mat-button-toggle-group [hideSingleSelectionIndicator]="true" [disabled]="disabled() || readonly()">
4186
4629
  @for (option of options(); track option.value) {
4187
4630
  <mat-button-toggle
4188
4631
  [value]="option.value"
@@ -4207,7 +4650,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4207
4650
  { provide: NG_VALUE_ACCESSOR, useExisting: RadioControl, multi: true }
4208
4651
  ],
4209
4652
  template: `
4210
- <mat-button-toggle-group [hideSingleSelectionIndicator]="true" [disabled]="disabled() || readonly()">
4653
+ <mat-button-toggle-group [hideSingleSelectionIndicator]="true" [disabled]="disabled() || readonly()">
4211
4654
  @for (option of options(); track option.value) {
4212
4655
  <mat-button-toggle
4213
4656
  [value]="option.value"
@@ -4221,13 +4664,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4221
4664
  }]
4222
4665
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }] } });
4223
4666
 
4667
+ /**
4668
+ * `<iss-ctrl-select>` — dropdown selection, single or multiple, with a search box.
4669
+ *
4670
+ * Typing in the search box emits `(onQueryChange)`, so options can be loaded remotely; set
4671
+ * `loading` while that request is in flight.
4672
+ *
4673
+ * @example
4674
+ * ```html
4675
+ * <iss-ctrl-select
4676
+ * formControlName="city"
4677
+ * [options]="cities()"
4678
+ * [multiple]="false"
4679
+ * [loading]="loading()"
4680
+ * (onQueryChange)="search($event)"
4681
+ * >
4682
+ * <label>City</label>
4683
+ * </iss-ctrl-select>
4684
+ * ```
4685
+ *
4686
+ * ### Own inputs
4687
+ * | Property | Type | Default | Description |
4688
+ * | --- | --- | --- | --- |
4689
+ * | `options` | `Option[]` | **required** | The selectable choices. |
4690
+ * | `height` | `string` | `"150px"` | Max height of the open panel. |
4691
+ * | `loading` | `boolean` | `false` | Shows the loading state inside the panel. |
4692
+ *
4693
+ * ### Inherited from {@link ControlBase}
4694
+ * `formControlName` · `readonly` · `className` · `(onChange)` · `placeholder` · `multiple`
4695
+ *
4696
+ * ### Outputs
4697
+ * - `(onQueryChange)` — `string`, the current search text.
4698
+ *
4699
+ * Projects `<label>` into the floating label; omit it to render the control without one.
4700
+ */
4224
4701
  class SelectControl extends ControlBase {
4225
4702
  selectedOptions = signal(new Map(), ...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
4703
+ /**
4704
+ * Selectable choices, each a `{ value, label }` pair. Required.
4705
+ */
4226
4706
  options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
4707
+ /**
4708
+ * Maximum height of the open options panel, as a CSS length.
4709
+ */
4227
4710
  height = input("150px", ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
4228
4711
  query = toSignal(this.ctrl.valueChanges);
4229
4712
  filteredOptions = computed(() => this.#filter(this.query()), ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
4713
+ /**
4714
+ * Shows the loading state inside the panel while options are being fetched.
4715
+ */
4230
4716
  loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
4717
+ /**
4718
+ * Emits the search text so the host can load matching options.
4719
+ */
4231
4720
  onQueryChange = output();
4232
4721
  optionTemplate = contentChild("optionTemplate", ...(ngDevMode ? [{ debugName: "optionTemplate" }] : /* istanbul ignore next */ []));
4233
4722
  cardViewerTemplate = contentChild("cardViewerTemplate", ...(ngDevMode ? [{ debugName: "cardViewerTemplate" }] : /* istanbul ignore next */ []));
@@ -4370,10 +4859,9 @@ class SelectControl extends ControlBase {
4370
4859
  { provide: NG_VALUE_ACCESSOR, useExisting: SelectControl, multi: true },
4371
4860
  ], queries: [{ propertyName: "optionTemplate", first: true, predicate: ["optionTemplate"], descendants: true, isSignal: true }, { propertyName: "cardViewerTemplate", first: true, predicate: ["cardViewerTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
4372
4861
  <mat-form-field floatLabel="auto" class="">
4373
- <mat-label class="fs-16 fc-black">
4374
- <ng-content select="label"></ng-content>
4375
- </mat-label>
4376
- <input [formControl]="ctrl" [matAutocomplete]="auto" [matChipInputFor]="chipGrid" [placeholder]="placeholder()" [readonly]="readonly()" (blur)="markAsTouched()" class="m-0" matInput/>
4862
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
4863
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
4864
+ <input [formControl]="ctrl" [matAutocomplete]="auto" [matChipInputFor]="chipGrid" [placeholder]="placeholder()" [readonly]="readonly()" (blur)="markAsTouched()" class="m-0" matInput/>
4377
4865
  @if (!disabled()) {
4378
4866
  @if (selectedOptions().size) {
4379
4867
  <span matSuffix class="sfi sfi-close fs-18 fc-black cursor-pointer" (click)="clearSelection()"></span>
@@ -4421,7 +4909,7 @@ class SelectControl extends ControlBase {
4421
4909
  } @else {
4422
4910
  {{ chip[1].label }}
4423
4911
  }
4424
- <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + chip[1].label">
4912
+ <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + chip[1].label">
4425
4913
  <ds-icon icon="trash" class="fc-red"></ds-icon>
4426
4914
  </button>
4427
4915
  </mat-chip-row>
@@ -4449,10 +4937,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4449
4937
  { provide: NG_VALUE_ACCESSOR, useExisting: SelectControl, multi: true },
4450
4938
  ], template: `
4451
4939
  <mat-form-field floatLabel="auto" class="">
4452
- <mat-label class="fs-16 fc-black">
4453
- <ng-content select="label"></ng-content>
4454
- </mat-label>
4455
- <input [formControl]="ctrl" [matAutocomplete]="auto" [matChipInputFor]="chipGrid" [placeholder]="placeholder()" [readonly]="readonly()" (blur)="markAsTouched()" class="m-0" matInput/>
4940
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
4941
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
4942
+ <input [formControl]="ctrl" [matAutocomplete]="auto" [matChipInputFor]="chipGrid" [placeholder]="placeholder()" [readonly]="readonly()" (blur)="markAsTouched()" class="m-0" matInput/>
4456
4943
  @if (!disabled()) {
4457
4944
  @if (selectedOptions().size) {
4458
4945
  <span matSuffix class="sfi sfi-close fs-18 fc-black cursor-pointer" (click)="clearSelection()"></span>
@@ -4500,7 +4987,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4500
4987
  } @else {
4501
4988
  {{ chip[1].label }}
4502
4989
  }
4503
- <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + chip[1].label">
4990
+ <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + chip[1].label">
4504
4991
  <ds-icon icon="trash" class="fc-red"></ds-icon>
4505
4992
  </button>
4506
4993
  </mat-chip-row>
@@ -4510,6 +4997,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4510
4997
  `, schemas: [CUSTOM_ELEMENTS_SCHEMA] }]
4511
4998
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], onQueryChange: [{ type: i0.Output, args: ["onQueryChange"] }], optionTemplate: [{ type: i0.ContentChild, args: ["optionTemplate", { isSignal: true }] }], cardViewerTemplate: [{ type: i0.ContentChild, args: ["cardViewerTemplate", { isSignal: true }] }] } });
4512
4999
 
5000
+ /**
5001
+ * `<iss-ctrl-slide-toggle>` — an on/off switch for a boolean value.
5002
+ *
5003
+ * @example
5004
+ * ```html
5005
+ * <iss-ctrl-slide-toggle formControlName="active" (onChange)="save($event)"/>
5006
+ * ```
5007
+ *
5008
+ * ### Own inputs
5009
+ * None — the control is configured entirely through the inherited properties.
5010
+ *
5011
+ * ### Inherited from {@link ControlBase}
5012
+ * `formControlName` · `readonly` · `className` · `(onChange)`
5013
+ *
5014
+ * Does not project a label — the field label is rendered by the wrapping `iss-field-*`.
5015
+ */
4513
5016
  class SlideToggleControl extends ControlBase {
4514
5017
  onSlideToggleChange(checked) {
4515
5018
  if (this.readonly()) {
@@ -4523,8 +5026,8 @@ class SlideToggleControl extends ControlBase {
4523
5026
  { provide: NG_VALUE_ACCESSOR, useExisting: SlideToggleControl, multi: true }
4524
5027
  ], usesInheritance: true, ngImport: i0, template: `
4525
5028
  <mat-slide-toggle
4526
- class="d-block" [formControl]="ctrl"
4527
- [disabled]="readonly()"
5029
+ class="d-block" [formControl]="ctrl"
5030
+ [disabled]="readonly()"
4528
5031
  (change)="onSlideToggleChange($event.checked)"
4529
5032
  >
4530
5033
  </mat-slide-toggle>
@@ -4540,8 +5043,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4540
5043
  ],
4541
5044
  template: `
4542
5045
  <mat-slide-toggle
4543
- class="d-block" [formControl]="ctrl"
4544
- [disabled]="readonly()"
5046
+ class="d-block" [formControl]="ctrl"
5047
+ [disabled]="readonly()"
4545
5048
  (change)="onSlideToggleChange($event.checked)"
4546
5049
  >
4547
5050
  </mat-slide-toggle>
@@ -4549,6 +5052,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4549
5052
  }]
4550
5053
  }] });
4551
5054
 
5055
+ /**
5056
+ * `<iss-ctrl-textarea>` — multi line free text.
5057
+ *
5058
+ * @example
5059
+ * ```html
5060
+ * <iss-ctrl-textarea formControlName="notes" [maxLength]="500" placeholder="Add a note">
5061
+ * <label>Notes</label>
5062
+ * </iss-ctrl-textarea>
5063
+ * ```
5064
+ *
5065
+ * ### Own inputs
5066
+ * None — the control is configured entirely through the inherited properties.
5067
+ *
5068
+ * ### Inherited from {@link ControlBase}
5069
+ * `formControlName` · `readonly` · `className` · `(onChange)` · `placeholder` · `minLength` · `maxLength` · `hints`
5070
+ *
5071
+ * Projects `<label>` into the floating label; omit it to render the control without one.
5072
+ */
4552
5073
  class TextareaControl extends ControlBase {
4553
5074
  #disabledEffect = effect(() => {
4554
5075
  if (this.disabled()) {
@@ -4567,16 +5088,15 @@ class TextareaControl extends ControlBase {
4567
5088
  { provide: NG_VALIDATORS, useExisting: TextareaControl, multi: true }
4568
5089
  ], usesInheritance: true, ngImport: i0, template: `
4569
5090
  <mat-form-field floatLabel="auto" class="custom-textarea">
4570
- <mat-label class="fs-16 fc-black">
4571
- <ng-content select="label"></ng-content>
4572
- </mat-label>
5091
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
5092
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
4573
5093
  <textarea
4574
5094
  matInput
4575
5095
  [placeholder]="placeholder()"
4576
5096
  [formControl]="ctrl"
4577
5097
  [attr.maxlength]="maxLength()"
4578
- [attr.minlength]="minLength()"
4579
- [readonly]="readonly()"
5098
+ [attr.minlength]="minLength()"
5099
+ [readonly]="readonly()"
4580
5100
  (input)="emitValue()"
4581
5101
  (focusout)="markAsTouched()"
4582
5102
  >
@@ -4604,16 +5124,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4604
5124
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
4605
5125
  template: `
4606
5126
  <mat-form-field floatLabel="auto" class="custom-textarea">
4607
- <mat-label class="fs-16 fc-black">
4608
- <ng-content select="label"></ng-content>
4609
- </mat-label>
5127
+ <!-- Kept on one line: an omitted or empty label must leave <mat-label> :empty so upgrade.scss can collapse the floating-label space. -->
5128
+ <mat-label class="fs-16 fc-black"><ng-content select="label"></ng-content></mat-label>
4610
5129
  <textarea
4611
5130
  matInput
4612
5131
  [placeholder]="placeholder()"
4613
5132
  [formControl]="ctrl"
4614
5133
  [attr.maxlength]="maxLength()"
4615
- [attr.minlength]="minLength()"
4616
- [readonly]="readonly()"
5134
+ [attr.minlength]="minLength()"
5135
+ [readonly]="readonly()"
4617
5136
  (input)="emitValue()"
4618
5137
  (focusout)="markAsTouched()"
4619
5138
  >
@@ -4624,7 +5143,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4624
5143
  }]
4625
5144
  }] });
4626
5145
 
5146
+ /**
5147
+ * `<iss-ctrl-toggle-button>` — options rendered as a button group instead of a dropdown.
5148
+ *
5149
+ * With `multiple` set, several buttons can be active at once.
5150
+ *
5151
+ * @example
5152
+ * ```html
5153
+ * <iss-ctrl-toggle-button formControlName="priority" [options]="priorities" [multiple]="false"/>
5154
+ * ```
5155
+ *
5156
+ * ### Own inputs
5157
+ * | Property | Type | Default | Description |
5158
+ * | --- | --- | --- | --- |
5159
+ * | `options` | `Option[]` | **required** | The selectable choices. |
5160
+ *
5161
+ * ### Inherited from {@link ControlBase}
5162
+ * `formControlName` · `readonly` · `className` · `(onChange)` · `multiple`
5163
+ *
5164
+ * Does not project a label — the field label is rendered by the wrapping `iss-field-*`.
5165
+ */
4627
5166
  class ToggleButtonControl extends ControlBase {
5167
+ /**
5168
+ * Selectable choices, each a `{ value, label }` pair. Required.
5169
+ */
4628
5170
  options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
4629
5171
  selectedOptions = signal(new Map(), ...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
4630
5172
  writeValue(value) {
@@ -4705,8 +5247,8 @@ class ToggleButtonControl extends ControlBase {
4705
5247
  { provide: NG_VALUE_ACCESSOR, useExisting: ToggleButtonControl, multi: true }
4706
5248
  ], usesInheritance: true, ngImport: i0, template: `
4707
5249
  <mat-button-toggle-group
4708
- [formControl]="ctrl"
4709
- [disabled]="readonly()"
5250
+ [formControl]="ctrl"
5251
+ [disabled]="readonly()"
4710
5252
  [multiple]=multiple()
4711
5253
  [hideMultipleSelectionIndicator]="true"
4712
5254
  [hideSingleSelectionIndicator]="true"
@@ -4723,8 +5265,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4723
5265
  type: Component,
4724
5266
  args: [{ selector: "iss-ctrl-toggle-button", imports: [MatButtonToggleModule, ReactiveFormsModule], template: `
4725
5267
  <mat-button-toggle-group
4726
- [formControl]="ctrl"
4727
- [disabled]="readonly()"
5268
+ [formControl]="ctrl"
5269
+ [disabled]="readonly()"
4728
5270
  [multiple]=multiple()
4729
5271
  [hideMultipleSelectionIndicator]="true"
4730
5272
  [hideSingleSelectionIndicator]="true"
@@ -4747,32 +5289,131 @@ class FieldAsyncValidation {
4747
5289
  }
4748
5290
  }
4749
5291
 
5292
+ /**
5293
+ * Per-field configuration, reachable as `field.config` and consumed by the `iss-field-*`
5294
+ * components. Every entry is a signal, so it can be changed at runtime by field events.
5295
+ *
5296
+ * Not every key applies to every field — the class doc of each `iss-field-*` component
5297
+ * lists exactly which of these it reads.
5298
+ *
5299
+ * ### Keys by area
5300
+ * - **Common:** `type` · `disabled` · `readonly` · `placeholder` · `suffix` · `hideLabel` · `multiple`
5301
+ * - **Bounds:** `min` · `max` · `minLength` · `maxLength`
5302
+ * - **Dates:** `minDate` · `maxDate` · `dateFilter`
5303
+ * - **Attachments:** `allowedFileSize` · `allowedFileTypes` · `minFilesCount` · `maxFilesCount` · `templateId` · `templateUrl`
5304
+ * - **Users:** `minUsersCount` · `maxUsersCount`
5305
+ * - **Table:** `showInTableColumns` · `tableWithFilter` · `tableWithSort` · `tableWithPagination`
5306
+ *
5307
+ * @example
5308
+ * ```json
5309
+ * { "name": "email", "type": "text_input", "config": { "type": "email", "maxLength": 120 } }
5310
+ * ```
5311
+ */
4750
5312
  class FieldConfig {
5313
+ /**
5314
+ * Native input type for `text_input` (`text`, `email`, `number`, `password`, …).
5315
+ */
4751
5316
  type = signal(undefined, ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
5317
+ /**
5318
+ * Disables the control; the underlying `FormControl` is disabled on init.
5319
+ */
4752
5320
  disabled = signal(undefined, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
5321
+ /**
5322
+ * Shows the value but blocks interaction. Unlike `disabled`, the value is still submitted.
5323
+ */
4753
5324
  readonly = signal(undefined, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
5325
+ /**
5326
+ * Placeholder text shown while the field is empty.
5327
+ */
4754
5328
  placeholder = signal(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
5329
+ /**
5330
+ * Text rendered after the value (a unit or currency, for example).
5331
+ */
4755
5332
  suffix = signal(undefined, ...(ngDevMode ? [{ debugName: "suffix" }] : /* istanbul ignore next */ []));
5333
+ /**
5334
+ * Hides the field label without removing it from the accessibility tree.
5335
+ */
4756
5336
  hideLabel = signal(undefined, ...(ngDevMode ? [{ debugName: "hideLabel" }] : /* istanbul ignore next */ []));
5337
+ /**
5338
+ * Allows more than one value — multi select, multi file upload, multi toggle.
5339
+ */
4757
5340
  multiple = signal(undefined, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
5341
+ /**
5342
+ * Minimum number of characters. Source: `config.minLength`.
5343
+ */
4758
5344
  minLength = signal(undefined, ...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
5345
+ /**
5346
+ * Maximum number of characters. Source: `config.maxLength`.
5347
+ */
4759
5348
  maxLength = signal(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
5349
+ /**
5350
+ * Minimum numeric value (also the minimum user count for the user picker).
5351
+ */
4760
5352
  min = signal(undefined, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
5353
+ /**
5354
+ * Maximum numeric value (also the maximum user count for the user picker).
5355
+ */
4761
5356
  max = signal(undefined, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
5357
+ /**
5358
+ * Earliest selectable date for date, datetime and date-range fields.
5359
+ */
4762
5360
  minDate = signal(undefined, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
5361
+ /**
5362
+ * Latest selectable date for date, datetime and date-range fields.
5363
+ */
4763
5364
  maxDate = signal(undefined, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
5365
+ /**
5366
+ * Restricts the calendar to working days. Source: `config.acceptWorkDaysOnly`.
5367
+ */
4764
5368
  dateFilter = signal(undefined, ...(ngDevMode ? [{ debugName: "dateFilter" }] : /* istanbul ignore next */ []));
5369
+ /**
5370
+ * Id of a downloadable template offered next to an attachment field.
5371
+ */
4765
5372
  templateId = signal(undefined, ...(ngDevMode ? [{ debugName: "templateId" }] : /* istanbul ignore next */ []));
5373
+ /**
5374
+ * Direct URL of the downloadable template for an attachment field.
5375
+ */
4766
5376
  templateUrl = signal(undefined, ...(ngDevMode ? [{ debugName: "templateUrl" }] : /* istanbul ignore next */ []));
5377
+ /**
5378
+ * Maximum size per uploaded file. Source: `config.allowedSize`.
5379
+ */
4767
5380
  allowedFileSize = signal(undefined, ...(ngDevMode ? [{ debugName: "allowedFileSize" }] : /* istanbul ignore next */ []));
5381
+ /**
5382
+ * Comma separated list of accepted file extensions or MIME types.
5383
+ */
4768
5384
  allowedFileTypes = signal(undefined, ...(ngDevMode ? [{ debugName: "allowedFileTypes" }] : /* istanbul ignore next */ []));
5385
+ /**
5386
+ * Maximum number of files that may be attached.
5387
+ */
4769
5388
  maxFilesCount = signal(undefined, ...(ngDevMode ? [{ debugName: "maxFilesCount" }] : /* istanbul ignore next */ []));
5389
+ /**
5390
+ * Minimum number of files required.
5391
+ */
4770
5392
  minFilesCount = signal(undefined, ...(ngDevMode ? [{ debugName: "minFilesCount" }] : /* istanbul ignore next */ []));
5393
+ /**
5394
+ * Maximum number of users selectable in a user picker.
5395
+ */
4771
5396
  maxUsersCount = signal(undefined, ...(ngDevMode ? [{ debugName: "maxUsersCount" }] : /* istanbul ignore next */ []));
5397
+ /**
5398
+ * Minimum number of users required in a user picker.
5399
+ */
4772
5400
  minUsersCount = signal(undefined, ...(ngDevMode ? [{ debugName: "minUsersCount" }] : /* istanbul ignore next */ []));
5401
+ /**
5402
+ * Parsed from the field definition but not consumed yet — table columns currently come
5403
+ * from `field.children`.
5404
+ */
4773
5405
  showInTableColumns = signal(undefined, ...(ngDevMode ? [{ debugName: "showInTableColumns" }] : /* istanbul ignore next */ []));
5406
+ /**
5407
+ * Enables the filter row on a `table` field.
5408
+ */
4774
5409
  tableWithFilter = signal(undefined, ...(ngDevMode ? [{ debugName: "tableWithFilter" }] : /* istanbul ignore next */ []));
5410
+ /**
5411
+ * Enables column sorting on a `table` field.
5412
+ */
4775
5413
  tableWithSort = signal(undefined, ...(ngDevMode ? [{ debugName: "tableWithSort" }] : /* istanbul ignore next */ []));
5414
+ /**
5415
+ * Enables the paginator on a `table` field.
5416
+ */
4776
5417
  tableWithPagination = signal(undefined, ...(ngDevMode ? [{ debugName: "tableWithPagination" }] : /* istanbul ignore next */ []));
4777
5418
  constructor(config) {
4778
5419
  this.type.set(config?.type);
@@ -4877,6 +5518,38 @@ class FieldEvent {
4877
5518
  }
4878
5519
  }
4879
5520
 
5521
+ /**
5522
+ * Runtime model of a single form field, built from the JSON definition returned by the API.
5523
+ *
5524
+ * It is what `iss-field-*` components inject through the `FIELD_DATA` token, and the object
5525
+ * field events read from and write to. Signal-valued members can be changed at runtime and
5526
+ * the rendered field reacts immediately.
5527
+ *
5528
+ * ### Properties
5529
+ * | Property | Type | Description |
5530
+ * | --- | --- | --- |
5531
+ * | `id` | `number` | Unique field id. |
5532
+ * | `name` | `string` | Control name inside the form group. |
5533
+ * | `type` | `string` | Key into the `COMPONENTS` index (`text_input`, `dropdown_list`, …). |
5534
+ * | `base` | `string` | Underlying data type of the field. |
5535
+ * | `label()` | `string` | Visible label. |
5536
+ * | `hint()` | `string` | Helper text under the field. |
5537
+ * | `options()` | `Option[]` | Choices for select, radio, checkbox and toggle fields. |
5538
+ * | `api()` | `string` | Endpoint used to load options or lookups. |
5539
+ * | `mode()` | `"edit" \| "view"` | Renders the control or the read-only viewer. |
5540
+ * | `visible()` | `boolean` | Whether the field is rendered at all. |
5541
+ * | `loading()` | `boolean` | Shows the field's own loading state. |
5542
+ * | `config` | `FieldConfig` | Per-type configuration — see {@link FieldConfig}. |
5543
+ * | `validation` | `any` | Synchronous validation rules. |
5544
+ * | `asyncValidation` | `FieldAsyncValidation` | Remote validation rules. |
5545
+ * | `events` | `FieldEvent[]` | Cross-field reactions (show, hide, set value, …). |
5546
+ * | `children` | `IssField[]` | Nested fields, used by table and group fields. |
5547
+ * | `value` / `defaultValue` | `string` | Initial and fallback raw values. |
5548
+ * | `jsonValue` | `any` | Initial resolved value for controls with a rich payload. |
5549
+ * | `ctrlValue()` | `string \| null` | Live raw value of the control. |
5550
+ * | `ctrlJsonValue()` | `any` | Live resolved value (selected options, files, users, …). |
5551
+ * | `response()` / `apiResponse` | `any` | Latest payload returned for this field. |
5552
+ */
4880
5553
  class IssField {
4881
5554
  id;
4882
5555
  name;
@@ -5162,38 +5835,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
5162
5835
  args: [{ providedIn: "root" }]
5163
5836
  }] });
5164
5837
 
5838
+ /**
5839
+ * Maps a field's `type` to the `iss-field-*` component that renders it.
5840
+ *
5841
+ * The outlet looks the field up here and lazy-loads the component, so a `type` that is not
5842
+ * a key of this object renders nothing. Hover a field class for the `config` keys it reads.
5843
+ *
5844
+ * | `type` | Component | Control | Renders |
5845
+ * | --- | --- | --- | --- |
5846
+ * | `text_input` | `InputField` | `iss-ctrl-input` | Single line text, number, email, password. |
5847
+ * | `textarea` | `TextareaField` | `iss-ctrl-textarea` | Multi line free text. |
5848
+ * | `dropdown_list` | `SelectField` | `iss-ctrl-select` | Searchable single/multi select. |
5849
+ * | `toggle_button` | `ToggleButtonField` | `iss-ctrl-toggle-button` | Options as a button group. |
5850
+ * | `checkbox` | `CheckboxField` | `iss-ctrl-checkbox` | Multi choice checkbox list. |
5851
+ * | `radio` | `RadioField` | `iss-ctrl-radio` | Single choice radio list. |
5852
+ * | `date` | `DatePickerField` | `iss-ctrl-date-picker` | A single date. |
5853
+ * | `time` | `TimePickerField` | `iss-ctrl-time-picker` | A time of day. |
5854
+ * | `datetime` | `DatetimePickerField` | `iss-ctrl-datetime-picker` | Date and time together. |
5855
+ * | `date_range` | `DateRangePickerField` | `iss-ctrl-date-range-picker` | A start/end date range. |
5856
+ * | `attachment` | `FilePickerField` | `iss-ctrl-file-picker` | File upload. |
5857
+ * | `userPicker` | `UserPickerField` | `iss-ctrl-select` | Employee lookup. |
5858
+ * | `vehicle_plate` | `PlateField` | `iss-ctrl-plate-number` | Saudi vehicle plate. |
5859
+ * | `enrichment` | `NoteField` | — | Read-only explanatory text. |
5860
+ * | `mobile` | `MobileField` | `iss-ctrl-mobile` | International phone number. |
5861
+ * | `table` | `TableField` | `iss-ctrl-table` | Repeatable rows built from `children`. |
5862
+ * | `chips` | `ChipsField` | `iss-ctrl-chips` | Free text as removable chips. |
5863
+ * | `switch` | `SlideToggleField` | `iss-ctrl-slide-toggle` | Boolean on/off switch. |
5864
+ */
5165
5865
  const COMPONENTS = {
5166
- date: () => Promise.resolve().then(function () { return datePicker_field; }).then((c) => c.DatePickerField),
5167
- datetime: () => Promise.resolve().then(function () { return datetimePicker_field; }).then((c) => c.DatetimePickerField),
5168
- dateRange: () => Promise.resolve().then(function () { return dateRangePicker_field; }).then((c) => c.DateRangePickerField),
5169
- date_range: () => Promise.resolve().then(function () { return dateRangePicker_field; }).then((c) => c.DateRangePickerField),
5170
- select: () => Promise.resolve().then(function () { return select_field; }).then((c) => c.SelectField),
5171
- input: () => Promise.resolve().then(function () { return input_field; }).then((c) => c.InputField),
5172
- text: () => Promise.resolve().then(function () { return input_field; }).then((c) => c.InputField),
5866
+ text_input: () => Promise.resolve().then(function () { return input_field; }).then((c) => c.InputField),
5867
+ textarea: () => Promise.resolve().then(function () { return textarea_field; }).then((c) => c.TextareaField),
5868
+ dropdown_list: () => Promise.resolve().then(function () { return select_field; }).then((c) => c.SelectField),
5869
+ toggle_button: () => Promise.resolve().then(function () { return toggleButton_field; }).then((c) => c.ToggleButtonField),
5173
5870
  checkbox: () => Promise.resolve().then(function () { return checkbox_field; }).then((c) => c.CheckboxField),
5174
- file: () => Promise.resolve().then(function () { return filePicker_field; }).then((c) => c.FilePickerField),
5175
- file2: () => Promise.resolve().then(function () { return filePicker_field; }).then((c) => c.FilePickerField),
5176
5871
  radio: () => Promise.resolve().then(function () { return radio_field; }).then((c) => c.RadioField),
5177
- textarea: () => Promise.resolve().then(function () { return textarea_field; }).then((c) => c.TextareaField),
5178
- chips: () => Promise.resolve().then(function () { return chips_field; }).then((c) => c.ChipsField),
5179
- plate: () => Promise.resolve().then(function () { return plate_field; }).then((c) => c.PlateField),
5180
- note: () => import('./iss-ctrl-note.field-4uLl0oS_.mjs').then((c) => c.NoteField),
5181
- slideToggle: () => Promise.resolve().then(function () { return slideToggle_field; }).then((c) => c.SlideToggleField),
5182
- toggle: () => Promise.resolve().then(function () { return toggleButton_field; }).then((c) => c.ToggleButtonField),
5872
+ date: () => Promise.resolve().then(function () { return datePicker_field; }).then((c) => c.DatePickerField),
5183
5873
  time: () => Promise.resolve().then(function () { return timePicker_field; }).then((c) => c.TimePickerField),
5874
+ datetime: () => Promise.resolve().then(function () { return datetimePicker_field; }).then((c) => c.DatetimePickerField),
5875
+ date_range: () => Promise.resolve().then(function () { return dateRangePicker_field; }).then((c) => c.DateRangePickerField),
5876
+ attachment: () => Promise.resolve().then(function () { return filePicker_field; }).then((c) => c.FilePickerField),
5877
+ userPicker: () => import('./iss-ctrl-user-picker.field-8Jb1325c.mjs').then((c) => c.UserPickerField),
5878
+ vehicle_plate: () => Promise.resolve().then(function () { return plate_field; }).then((c) => c.PlateField),
5879
+ enrichment: () => import('./iss-ctrl-note.field-C9cVaAz0.mjs').then((c) => c.NoteField),
5184
5880
  mobile: () => Promise.resolve().then(function () { return mobile_field; }).then((c) => c.MobileField),
5185
- table: () => import('./iss-ctrl-table.field-kPIwve-M.mjs').then((c) => c.TableField),
5186
- userPicker: () => import('./iss-ctrl-user-picker.field-l-0bW6lP.mjs').then((c) => c.UserPickerField),
5187
- userPicker2: () => import('./iss-ctrl-user-picker.field-l-0bW6lP.mjs').then((c) => c.UserPickerField),
5881
+ table: () => import('./iss-ctrl-table.field-BP-HMKO3.mjs').then((c) => c.TableField),
5882
+ chips: () => Promise.resolve().then(function () { return chips_field; }).then((c) => c.ChipsField),
5883
+ switch: () => Promise.resolve().then(function () { return slideToggle_field; }).then((c) => c.SlideToggleField),
5188
5884
  };
5189
5885
 
5190
5886
  const SERVICES = {
5191
- setValue: () => import('./iss-ctrl-set-value-event-BbEYFBe3.mjs').then((s) => s.SetValueEvent),
5887
+ setValue: () => import('./iss-ctrl-set-value-event-CrpzRR6X.mjs').then((s) => s.SetValueEvent),
5192
5888
  show: () => import('./iss-ctrl-show-event-BcRCwAfo.mjs').then((s) => s.ShowEvent),
5193
- load: () => import('./iss-ctrl-load-value-event-DThpI9BA.mjs').then((s) => s.LoadValueEvent),
5194
- loadOptions: () => import('./iss-ctrl-load-options-event-ClX9TiiD.mjs').then((s) => s.LoadOptionsEvent),
5195
- triggerBasedOnJsonValue: () => import('./iss-ctrl-trigger-based-on-json-value-DuLD4SOS.mjs').then((s) => s.TriggerBasedOnJsonValue),
5196
- replaceApiKeyDefaultImpl: () => import('./iss-ctrl-replace-api-keys-BQL9zimJ.mjs').then((s) => s.ReplaceApiKeys),
5889
+ load: () => import('./iss-ctrl-load-value-event-CDAKsE_O.mjs').then((s) => s.LoadValueEvent),
5890
+ loadOptions: () => import('./iss-ctrl-load-options-event-ClQPHNBO.mjs').then((s) => s.LoadOptionsEvent),
5891
+ triggerBasedOnJsonValue: () => import('./iss-ctrl-trigger-based-on-json-value-DS4TR38v.mjs').then((s) => s.TriggerBasedOnJsonValue),
5892
+ replaceApiKeyDefaultImpl: () => import('./iss-ctrl-replace-api-keys-CvhCKvNB.mjs').then((s) => s.ReplaceApiKeys),
5197
5893
  };
5198
5894
 
5199
5895
  // Read-only counterpart of COMPONENTS: the component used to render a field's value
@@ -5308,7 +6004,7 @@ class Outlet {
5308
6004
  #formEngine = inject(FormEngine);
5309
6005
  #loader = inject(Loader);
5310
6006
  #effectRef = effect((onCleanup) => {
5311
- // Dynamic imports cannot be cancelled, but an old result must never replace
6007
+ // Dynamic imports cannot be canceled, but an old result must never replace
5312
6008
  // the components produced for a newer fields input (or a destroyed outlet).
5313
6009
  let active = true;
5314
6010
  onCleanup(() => {
@@ -5738,14 +6434,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
5738
6434
  args: [{ providedIn: "root" }]
5739
6435
  }] });
5740
6436
 
6437
+ /**
6438
+ * Base class for every `iss-field-*` field.
6439
+ *
6440
+ * A field is the form-engine layer around a control: it reads its whole configuration from
6441
+ * the injected {@link IssField} (label, options, config, validation, events), registers its
6442
+ * `FormControl` on the parent `FormGroup` on init and removes it again on destroy, and
6443
+ * switches between the control (`mode() === "edit"`) and the viewer (`mode() === "view"`).
6444
+ *
6445
+ * ### Inputs
6446
+ * | Property | Type | Description |
6447
+ * | --- | --- | --- |
6448
+ * | `issField` | `IssField` | **Required.** The field definition; also provided through the `FIELD_DATA` token. |
6449
+ * | `formReady` | `boolean \| undefined` | Set by the outlet once the whole form exists; gates event wiring. |
6450
+ *
6451
+ * ### Properties available on `field`
6452
+ * `name` · `type` · `base` · `label()` · `hint()` · `options()` · `api()` · `mode()` ·
6453
+ * `visible()` · `loading()` · `value` · `jsonValue` · `defaultValue` · `ctrlValue()` ·
6454
+ * `ctrlJsonValue()` · `events` · `validation` · `asyncValidation` · `children` ·
6455
+ * `response()` · `config` — see {@link IssField} and {@link FieldConfig}.
6456
+ *
6457
+ * Fields are not used directly in templates; the outlet resolves them from the field `type`
6458
+ * through the `COMPONENTS` index.
6459
+ */
5741
6460
  class FieldBase {
6461
+ /**
6462
+ * The field definition rendered by this component. Required.
6463
+ */
5742
6464
  issField = input.required(...(ngDevMode ? [{ debugName: "issField" }] : /* istanbul ignore next */ []));
6465
+ /**
6466
+ * Set by the outlet once every field is registered; field events start only after it turns true.
6467
+ */
5743
6468
  formReady = input(...(ngDevMode ? [undefined, { debugName: "formReady" }] : /* istanbul ignore next */ []));
6469
+ /**
6470
+ * The {@link IssField} for this instance, injected through the `FIELD_DATA` token.
6471
+ */
5744
6472
  field = inject(FIELD_DATA);
5745
6473
  parentFormGroup = inject(ControlContainer);
5746
6474
  formEngine = inject(FormEngine);
5747
6475
  eventHandler = inject(EventHandler);
5748
6476
  destroyRef = inject(DestroyRef);
6477
+ /**
6478
+ * The `FormControl` this field registers on the parent form under `field.name`.
6479
+ */
5749
6480
  ctrl = new FormControl(null);
5750
6481
  ctrlValueChange = toSignal(this.ctrl.valueChanges, { initialValue: this.ctrl.getRawValue() });
5751
6482
  #valueChangeEffectRef = effect(() => {
@@ -5852,6 +6583,34 @@ var input_viewer = /*#__PURE__*/Object.freeze({
5852
6583
  InputViewer: InputViewer
5853
6584
  });
5854
6585
 
6586
+ /**
6587
+ * `<iss-field-input>` — single line text, number, email or password entry.
6588
+ *
6589
+ * Rendered by the outlet for fields of type `text_input`. In `edit` mode it renders
6590
+ * {@link InputControl} plus the validation message; in `view` mode the matching viewer.
6591
+ *
6592
+ * ### Supported `config` keys
6593
+ * | Key | Type | Description |
6594
+ * | --- | --- | --- |
6595
+ * | `type` | `string` | Native input type — `text`, `number`, `email`, `password`, … |
6596
+ * | `placeholder` | `string` | Placeholder shown while empty. |
6597
+ * | `min` | `number` | Minimum numeric value. |
6598
+ * | `max` | `number` | Maximum numeric value. |
6599
+ * | `minLength` | `number` | Minimum number of characters. |
6600
+ * | `maxLength` | `number` | Maximum number of characters. |
6601
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
6602
+ *
6603
+ * ### Other field members used
6604
+ * `label()`
6605
+ *
6606
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
6607
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
6608
+ *
6609
+ * @example
6610
+ * ```json
6611
+ * { "name": "email", "type": "text_input", "label": "Email", "config": { "type": "email", "maxLength": 120 } }
6612
+ * ```
6613
+ */
5855
6614
  class InputField extends FieldBase {
5856
6615
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: InputField, deps: null, target: i0.ɵɵFactoryTarget.Component });
5857
6616
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: InputField, isStandalone: true, selector: "iss-field-input", usesInheritance: true, ngImport: i0, template: `
@@ -5862,8 +6621,8 @@ class InputField extends FieldBase {
5862
6621
  [type]="field.config.type() ?? ''"
5863
6622
  [placeholder]="field.config.placeholder() ?? ''"
5864
6623
  [min]="field.config.min() ?? null"
5865
- [max]="field.config.max() ?? null"
5866
- [readonly]="field.config.readonly() ?? false"
6624
+ [max]="field.config.max() ?? null"
6625
+ [readonly]="field.config.readonly() ?? false"
5867
6626
  [minLength]="field.config.minLength() ?? null"
5868
6627
  [maxLength]="field.config.maxLength() ?? null"
5869
6628
  >
@@ -5895,8 +6654,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
5895
6654
  [type]="field.config.type() ?? ''"
5896
6655
  [placeholder]="field.config.placeholder() ?? ''"
5897
6656
  [min]="field.config.min() ?? null"
5898
- [max]="field.config.max() ?? null"
5899
- [readonly]="field.config.readonly() ?? false"
6657
+ [max]="field.config.max() ?? null"
6658
+ [readonly]="field.config.readonly() ?? false"
5900
6659
  [minLength]="field.config.minLength() ?? null"
5901
6660
  [maxLength]="field.config.maxLength() ?? null"
5902
6661
  >
@@ -5937,12 +6696,36 @@ var textarea_viewer = /*#__PURE__*/Object.freeze({
5937
6696
  TextareaViewer: TextareaViewer
5938
6697
  });
5939
6698
 
6699
+ /**
6700
+ * `<iss-field-textarea>` — multi line free text.
6701
+ *
6702
+ * Rendered by the outlet for fields of type `textarea`. In `edit` mode it renders
6703
+ * {@link TextareaControl} plus the validation message; in `view` mode the matching viewer.
6704
+ *
6705
+ * ### Supported `config` keys
6706
+ * | Key | Type | Description |
6707
+ * | --- | --- | --- |
6708
+ * | `minLength` | `number` | Minimum number of characters. |
6709
+ * | `maxLength` | `number` | Maximum number of characters. |
6710
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
6711
+ *
6712
+ * ### Other field members used
6713
+ * `label()`
6714
+ *
6715
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
6716
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
6717
+ *
6718
+ * @example
6719
+ * ```json
6720
+ * { "name": "notes", "type": "textarea", "label": "Notes", "config": { "maxLength": 500 } }
6721
+ * ```
6722
+ */
5940
6723
  class TextareaField extends FieldBase {
5941
6724
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: TextareaField, deps: null, target: i0.ɵɵFactoryTarget.Component });
5942
6725
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: TextareaField, isStandalone: true, selector: "iss-field-textarea", usesInheritance: true, ngImport: i0, template: `
5943
6726
  @if (field.visible()) {
5944
6727
  @if (field.mode() === "edit") {
5945
- <iss-ctrl-textarea [formControlName]="field.name" [minLength]="field.config.minLength() ?? null" [maxLength]="field.config.maxLength() ?? null" [readonly]="field.config.readonly() ?? false">
6728
+ <iss-ctrl-textarea [formControlName]="field.name" [minLength]="field.config.minLength() ?? null" [maxLength]="field.config.maxLength() ?? null" [readonly]="field.config.readonly() ?? false">
5946
6729
  <label>{{ field.label() }}</label>
5947
6730
  </iss-ctrl-textarea>
5948
6731
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -5966,7 +6749,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
5966
6749
  template: `
5967
6750
  @if (field.visible()) {
5968
6751
  @if (field.mode() === "edit") {
5969
- <iss-ctrl-textarea [formControlName]="field.name" [minLength]="field.config.minLength() ?? null" [maxLength]="field.config.maxLength() ?? null" [readonly]="field.config.readonly() ?? false">
6752
+ <iss-ctrl-textarea [formControlName]="field.name" [minLength]="field.config.minLength() ?? null" [maxLength]="field.config.maxLength() ?? null" [readonly]="field.config.readonly() ?? false">
5970
6753
  <label>{{ field.label() }}</label>
5971
6754
  </iss-ctrl-textarea>
5972
6755
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -6019,12 +6802,34 @@ var chips_viewer = /*#__PURE__*/Object.freeze({
6019
6802
  ChipsViewer: ChipsViewer
6020
6803
  });
6021
6804
 
6805
+ /**
6806
+ * `<iss-field-chips>` — free text entered as removable chips.
6807
+ *
6808
+ * Rendered by the outlet for fields of type `chips`. In `edit` mode it renders
6809
+ * {@link ChipsControl} plus the validation message; in `view` mode the matching viewer.
6810
+ *
6811
+ * ### Supported `config` keys
6812
+ * | Key | Type | Description |
6813
+ * | --- | --- | --- |
6814
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
6815
+ *
6816
+ * ### Other field members used
6817
+ * `label()`
6818
+ *
6819
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
6820
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
6821
+ *
6822
+ * @example
6823
+ * ```json
6824
+ * { "name": "tags", "type": "chips", "label": "Tags" }
6825
+ * ```
6826
+ */
6022
6827
  class ChipsField extends FieldBase {
6023
6828
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ChipsField, deps: null, target: i0.ɵɵFactoryTarget.Component });
6024
6829
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ChipsField, isStandalone: true, selector: "iss-field-chips", usesInheritance: true, ngImport: i0, template: `
6025
6830
  @if (field.visible()) {
6026
6831
  @if (field.mode() === "edit") {
6027
- <iss-ctrl-chips [formControlName]="field.name" [readonly]="field.config.readonly() ?? false"><label>{{ field.label() }}</label></iss-ctrl-chips>
6832
+ <iss-ctrl-chips [formControlName]="field.name" [readonly]="field.config.readonly() ?? false"><label>{{ field.label() }}</label></iss-ctrl-chips>
6028
6833
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6029
6834
  } @else {
6030
6835
  <iss-viewer-chips [field]="field"/>
@@ -6046,7 +6851,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6046
6851
  template: `
6047
6852
  @if (field.visible()) {
6048
6853
  @if (field.mode() === "edit") {
6049
- <iss-ctrl-chips [formControlName]="field.name" [readonly]="field.config.readonly() ?? false"><label>{{ field.label() }}</label></iss-ctrl-chips>
6854
+ <iss-ctrl-chips [formControlName]="field.name" [readonly]="field.config.readonly() ?? false"><label>{{ field.label() }}</label></iss-ctrl-chips>
6050
6855
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6051
6856
  } @else {
6052
6857
  <iss-viewer-chips [field]="field"/>
@@ -6090,6 +6895,29 @@ var radio_viewer = /*#__PURE__*/Object.freeze({
6090
6895
  RadioViewer: RadioViewer
6091
6896
  });
6092
6897
 
6898
+ /**
6899
+ * `<iss-field-radio>` — one choice out of a fixed set of options.
6900
+ *
6901
+ * Rendered by the outlet for fields of type `radio`. In `edit` mode it renders
6902
+ * {@link RadioControl} plus the validation message; in `view` mode the matching viewer.
6903
+ *
6904
+ * ### Supported `config` keys
6905
+ * | Key | Type | Description |
6906
+ * | --- | --- | --- |
6907
+ * | `hideLabel` | `boolean` | Hides the field label. |
6908
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
6909
+ *
6910
+ * ### Other field members used
6911
+ * `label()` · `options()`
6912
+ *
6913
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
6914
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
6915
+ *
6916
+ * @example
6917
+ * ```json
6918
+ * { "name": "gender", "type": "radio", "label": "Gender", "options": [{ "value": "m", "label": "Male" }] }
6919
+ * ```
6920
+ */
6093
6921
  class RadioField extends FieldBase {
6094
6922
  onChange($event) {
6095
6923
  this.field.ctrlJsonValue.set($event);
@@ -6103,7 +6931,7 @@ class RadioField extends FieldBase {
6103
6931
  }
6104
6932
 
6105
6933
  @if (field.mode() === "edit") {
6106
- <iss-ctrl-radio [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
6934
+ <iss-ctrl-radio [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
6107
6935
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6108
6936
  } @else {
6109
6937
  <iss-viewer-radio [field]="field"/>
@@ -6132,7 +6960,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6132
6960
  }
6133
6961
 
6134
6962
  @if (field.mode() === "edit") {
6135
- <iss-ctrl-radio [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
6963
+ <iss-ctrl-radio [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
6136
6964
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6137
6965
  } @else {
6138
6966
  <iss-viewer-radio [field]="field"/>
@@ -6177,6 +7005,32 @@ var select_viewer = /*#__PURE__*/Object.freeze({
6177
7005
  SelectViewer: SelectViewer
6178
7006
  });
6179
7007
 
7008
+ /**
7009
+ * `<iss-field-select>` — single or multiple selection from a dropdown.
7010
+ *
7011
+ * Rendered by the outlet for fields of type `dropdown_list`. In `edit` mode it renders
7012
+ * {@link SelectControl} plus the validation message; in `view` mode the matching viewer.
7013
+ *
7014
+ * ### Supported `config` keys
7015
+ * | Key | Type | Description |
7016
+ * | --- | --- | --- |
7017
+ * | `multiple` | `boolean` | Allows selecting more than one option. |
7018
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
7019
+ *
7020
+ * ### Other field members used
7021
+ * `label()` · `options()` · `ctrlJsonValue()`
7022
+ *
7023
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
7024
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
7025
+ *
7026
+ * The raw form value holds the selected option values; the resolved options are written
7027
+ * back to `field.ctrlJsonValue`.
7028
+ *
7029
+ * @example
7030
+ * ```json
7031
+ * { "name": "city", "type": "dropdown_list", "label": "City", "options": [{ "value": "1", "label": "Riyadh" }] }
7032
+ * ```
7033
+ */
6180
7034
  class SelectField extends FieldBase {
6181
7035
  onChange($event) {
6182
7036
  this.field.ctrlJsonValue.set($event);
@@ -6185,7 +7039,7 @@ class SelectField extends FieldBase {
6185
7039
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: SelectField, isStandalone: true, selector: "iss-field-select", usesInheritance: true, ngImport: i0, template: `
6186
7040
  @if (field.visible()) {
6187
7041
  @if (field.mode() === "edit") {
6188
- <iss-ctrl-select [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
7042
+ <iss-ctrl-select [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
6189
7043
  <label>{{ field.label() }}</label>
6190
7044
  </iss-ctrl-select>
6191
7045
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -6209,7 +7063,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6209
7063
  template: `
6210
7064
  @if (field.visible()) {
6211
7065
  @if (field.mode() === "edit") {
6212
- <iss-ctrl-select [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
7066
+ <iss-ctrl-select [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
6213
7067
  <label>{{ field.label() }}</label>
6214
7068
  </iss-ctrl-select>
6215
7069
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -6247,6 +7101,28 @@ var mobile_viewer = /*#__PURE__*/Object.freeze({
6247
7101
  MobileViewer: MobileViewer
6248
7102
  });
6249
7103
 
7104
+ /**
7105
+ * `<iss-field-mobile>` — an international phone number with a country selector.
7106
+ *
7107
+ * Rendered by the outlet for fields of the type `mobile`. In `edit` mode it renders
7108
+ * {@link MobileControl} plus the validation message; in `view` mode the matching viewer.
7109
+ *
7110
+ * ### Supported `config` keys
7111
+ * | Key | Type | Description |
7112
+ * | --- | --- | --- |
7113
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
7114
+ *
7115
+ * ### Other field members used
7116
+ * `label()`
7117
+ *
7118
+ * Every field also honors `visible`, `mode`, `validation`, `asyncValidation` and
7119
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
7120
+ *
7121
+ * @example
7122
+ * ```json
7123
+ * { "name": "mobile", "type": "mobile", "label": "Mobile" }
7124
+ * ```
7125
+ */
6250
7126
  class MobileField extends FieldBase {
6251
7127
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MobileField, deps: null, target: i0.ɵɵFactoryTarget.Component });
6252
7128
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MobileField, isStandalone: true, selector: "iss-field-mobile", usesInheritance: true, ngImport: i0, template: `
@@ -6320,6 +7196,29 @@ var checkbox_viewer = /*#__PURE__*/Object.freeze({
6320
7196
  CheckboxViewer: CheckboxViewer
6321
7197
  });
6322
7198
 
7199
+ /**
7200
+ * `<iss-field-checkbox>` — a list of checkboxes over a fixed set of options.
7201
+ *
7202
+ * Rendered by the outlet for fields of type `checkbox`. In `edit` mode it renders
7203
+ * {@link CheckboxControl} plus the validation message; in `view` mode the matching viewer.
7204
+ *
7205
+ * ### Supported `config` keys
7206
+ * | Key | Type | Description |
7207
+ * | --- | --- | --- |
7208
+ * | `hideLabel` | `boolean` | Hides the field label. |
7209
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
7210
+ *
7211
+ * ### Other field members used
7212
+ * `label()` · `options()`
7213
+ *
7214
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
7215
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
7216
+ *
7217
+ * @example
7218
+ * ```json
7219
+ * { "name": "days", "type": "checkbox", "label": "Days", "options": [{ "value": "sun", "label": "Sunday" }] }
7220
+ * ```
7221
+ */
6323
7222
  class CheckboxField extends FieldBase {
6324
7223
  updateField($event) {
6325
7224
  this.field.ctrlJsonValue.set($event);
@@ -6328,7 +7227,7 @@ class CheckboxField extends FieldBase {
6328
7227
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CheckboxField, isStandalone: true, selector: "iss-field-checkbox", usesInheritance: true, ngImport: i0, template: `
6329
7228
  @if (field.visible()) {
6330
7229
  @if (field.mode() === "edit") {
6331
- <iss-ctrl-checkbox [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)">
7230
+ <iss-ctrl-checkbox [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)">
6332
7231
  @if (!field.config.hideLabel()) {
6333
7232
  <label>{{ field.label() }}</label>
6334
7233
  }
@@ -6354,7 +7253,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6354
7253
  template: `
6355
7254
  @if (field.visible()) {
6356
7255
  @if (field.mode() === "edit") {
6357
- <iss-ctrl-checkbox [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)">
7256
+ <iss-ctrl-checkbox [formControlName]="field.name" [options]="field.options()" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)">
6358
7257
  @if (!field.config.hideLabel()) {
6359
7258
  <label>{{ field.label() }}</label>
6360
7259
  }
@@ -6402,6 +7301,30 @@ var toggleButton_viewer = /*#__PURE__*/Object.freeze({
6402
7301
  ToggleButtonViewer: ToggleButtonViewer
6403
7302
  });
6404
7303
 
7304
+ /**
7305
+ * `<iss-field-toggle-button>` — options rendered as a button group.
7306
+ *
7307
+ * Rendered by the outlet for fields of type `toggle_button`. In `edit` mode it renders
7308
+ * {@link ToggleButtonControl} plus the validation message; in `view` mode the matching viewer.
7309
+ *
7310
+ * ### Supported `config` keys
7311
+ * | Key | Type | Description |
7312
+ * | --- | --- | --- |
7313
+ * | `multiple` | `boolean` | Allows more than one active button. |
7314
+ * | `hideLabel` | `boolean` | Hides the field label. |
7315
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
7316
+ *
7317
+ * ### Other field members used
7318
+ * `label()` · `options()`
7319
+ *
7320
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
7321
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
7322
+ *
7323
+ * @example
7324
+ * ```json
7325
+ * { "name": "priority", "type": "toggle_button", "label": "Priority", "options": [{ "value": "high", "label": "High" }] }
7326
+ * ```
7327
+ */
6405
7328
  class ToggleButtonField extends FieldBase {
6406
7329
  onChange($event) {
6407
7330
  this.field.ctrlJsonValue.set($event);
@@ -6415,9 +7338,9 @@ class ToggleButtonField extends FieldBase {
6415
7338
  @if (field.mode() === "edit") {
6416
7339
  <iss-ctrl-toggle-button
6417
7340
  [formControlName]="field.name"
6418
- [options]="field.options()"
6419
- [multiple]="field.config.multiple()"
6420
- [readonly]="field.config.readonly() ?? false"
7341
+ [options]="field.options()"
7342
+ [multiple]="field.config.multiple()"
7343
+ [readonly]="field.config.readonly() ?? false"
6421
7344
  (onChange)="onChange($event)"
6422
7345
  />
6423
7346
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -6447,9 +7370,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6447
7370
  @if (field.mode() === "edit") {
6448
7371
  <iss-ctrl-toggle-button
6449
7372
  [formControlName]="field.name"
6450
- [options]="field.options()"
6451
- [multiple]="field.config.multiple()"
6452
- [readonly]="field.config.readonly() ?? false"
7373
+ [options]="field.options()"
7374
+ [multiple]="field.config.multiple()"
7375
+ [readonly]="field.config.readonly() ?? false"
6453
7376
  (onChange)="onChange($event)"
6454
7377
  />
6455
7378
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -6499,6 +7422,29 @@ var slideToggle_viewer = /*#__PURE__*/Object.freeze({
6499
7422
  SlideToggleViewer: SlideToggleViewer
6500
7423
  });
6501
7424
 
7425
+ /**
7426
+ * `<iss-field-slide-toggle>` — an on/off switch for a boolean value.
7427
+ *
7428
+ * Rendered by the outlet for fields of type `switch`. In `edit` mode it renders
7429
+ * {@link SlideToggleControl} plus the validation message; in `view` mode the matching viewer.
7430
+ *
7431
+ * ### Supported `config` keys
7432
+ * | Key | Type | Description |
7433
+ * | --- | --- | --- |
7434
+ * | `hideLabel` | `boolean` | Hides the field label. |
7435
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
7436
+ *
7437
+ * ### Other field members used
7438
+ * `label()`
7439
+ *
7440
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
7441
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
7442
+ *
7443
+ * @example
7444
+ * ```json
7445
+ * { "name": "active", "type": "switch", "label": "Active" }
7446
+ * ```
7447
+ */
6502
7448
  class SlideToggleField extends FieldBase {
6503
7449
  onChange($event) {
6504
7450
  this.field.ctrlJsonValue.set($event);
@@ -6511,7 +7457,7 @@ class SlideToggleField extends FieldBase {
6511
7457
  }
6512
7458
 
6513
7459
  @if (field.mode() === "edit") {
6514
- <iss-ctrl-slide-toggle [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
7460
+ <iss-ctrl-slide-toggle [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
6515
7461
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6516
7462
  } @else {
6517
7463
  <iss-viewer-slide-toggle [field]="field"/>
@@ -6532,7 +7478,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6532
7478
  }
6533
7479
 
6534
7480
  @if (field.mode() === "edit") {
6535
- <iss-ctrl-slide-toggle [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
7481
+ <iss-ctrl-slide-toggle [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)"/>
6536
7482
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6537
7483
  } @else {
6538
7484
  <iss-viewer-slide-toggle [field]="field"/>
@@ -6724,6 +7670,29 @@ var plate_viewer = /*#__PURE__*/Object.freeze({
6724
7670
  PlateViewer: PlateViewer
6725
7671
  });
6726
7672
 
7673
+ /**
7674
+ * `<iss-field-plate-number>` — a Saudi vehicle plate in Arabic and English.
7675
+ *
7676
+ * Rendered by the outlet for fields of type `vehicle_plate`. In `edit` mode it renders
7677
+ * {@link PlateControl} plus the validation message; in `view` mode the matching viewer.
7678
+ *
7679
+ * ### Supported `config` keys
7680
+ * | Key | Type | Description |
7681
+ * | --- | --- | --- |
7682
+ * | `hideLabel` | `boolean` | Hides the field label. |
7683
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
7684
+ *
7685
+ * ### Other field members used
7686
+ * `label()`
7687
+ *
7688
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
7689
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
7690
+ *
7691
+ * @example
7692
+ * ```json
7693
+ * { "name": "plate", "type": "vehicle_plate", "label": "Plate number" }
7694
+ * ```
7695
+ */
6727
7696
  class PlateField extends FieldBase {
6728
7697
  updateField($event) {
6729
7698
  this.field.ctrlJsonValue.set($event);
@@ -6736,7 +7705,7 @@ class PlateField extends FieldBase {
6736
7705
  }
6737
7706
 
6738
7707
  @if (field.mode() === "edit") {
6739
- <iss-ctrl-plate-number [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)"/>
7708
+ <iss-ctrl-plate-number [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)"/>
6740
7709
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6741
7710
  } @else {
6742
7711
  <iss-viewer-plate [field]="field"/>
@@ -6763,7 +7732,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6763
7732
  }
6764
7733
 
6765
7734
  @if (field.mode() === "edit") {
6766
- <iss-ctrl-plate-number [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)"/>
7735
+ <iss-ctrl-plate-number [formControlName]="field.name" [readonly]="field.config.readonly() ?? false" (onChange)="updateField($event)"/>
6767
7736
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
6768
7737
  } @else {
6769
7738
  <iss-viewer-plate [field]="field"/>
@@ -6997,6 +7966,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
6997
7966
  args: [{ providedIn: "root" }]
6998
7967
  }] });
6999
7968
 
7969
+ /**
7970
+ * `<iss-field-file-picker>` — attachment upload.
7971
+ *
7972
+ * Rendered by the outlet for fields of type `attachment`. In `edit` mode it renders
7973
+ * {@link FilePickerControl} plus the validation message; in `view` mode the matching viewer.
7974
+ *
7975
+ * ### Supported `config` keys
7976
+ * | Key | Type | Description |
7977
+ * | --- | --- | --- |
7978
+ * | `multiple` | `boolean` | Allows attaching more than one file. |
7979
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
7980
+ *
7981
+ * ### Other field members used
7982
+ * `label()` · `value` · `validation` · `ctrlJsonValue()`
7983
+ *
7984
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
7985
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
7986
+ *
7987
+ * The field uploads the picked files itself, stores the returned ids as the control value
7988
+ * and keeps the resolved attachments in `field.ctrlJsonValue`.
7989
+ *
7990
+ * Accepted extensions come from the `fileType` **validation** rule, not from `config`; the
7991
+ * `allowedFileSize`, `allowedFileTypes`, `minFilesCount`, `maxFilesCount`, `templateId` and
7992
+ * `templateUrl` config keys exist on {@link FieldConfig} but are not read here yet.
7993
+ *
7994
+ * @example
7995
+ * ```json
7996
+ * { "name": "attachments", "type": "attachment", "label": "Attachments", "config": { "multiple": true }, "validation": { "fileType": ["pdf", "png"] } }
7997
+ * ```
7998
+ */
7000
7999
  class FilePickerField extends FieldBase {
7001
8000
  picker = new FormControl();
7002
8001
  fileHandlerService = inject(FileHandler);
@@ -7107,8 +8106,8 @@ class FilePickerField extends FieldBase {
7107
8106
  [formControl]="picker"
7108
8107
  [accept]="accept"
7109
8108
  (onChange)="captureFile($event)"
7110
- [multiple]="field.config.multiple()"
7111
- [readonly]="field.config.readonly() ?? false"
8109
+ [multiple]="field.config.multiple()"
8110
+ [readonly]="field.config.readonly() ?? false"
7112
8111
  [uploading]="uploading()"
7113
8112
  [uploadedFiles]="attachments()"
7114
8113
  [uploadingError]="uploadingError()"
@@ -7142,8 +8141,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
7142
8141
  [formControl]="picker"
7143
8142
  [accept]="accept"
7144
8143
  (onChange)="captureFile($event)"
7145
- [multiple]="field.config.multiple()"
7146
- [readonly]="field.config.readonly() ?? false"
8144
+ [multiple]="field.config.multiple()"
8145
+ [readonly]="field.config.readonly() ?? false"
7147
8146
  [uploading]="uploading()"
7148
8147
  [uploadedFiles]="attachments()"
7149
8148
  [uploadingError]="uploadingError()"
@@ -7183,6 +8182,28 @@ var timePicker_viewer = /*#__PURE__*/Object.freeze({
7183
8182
  TimePickerViewer: TimePickerViewer
7184
8183
  });
7185
8184
 
8185
+ /**
8186
+ * `<iss-field-time-picker>` — a time of day, picked from a generated list.
8187
+ *
8188
+ * Rendered by the outlet for fields of type `time`. In `edit` mode it renders
8189
+ * {@link TimePickerControl} plus the validation message; in `view` mode the matching viewer.
8190
+ *
8191
+ * ### Supported `config` keys
8192
+ * | Key | Type | Description |
8193
+ * | --- | --- | --- |
8194
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
8195
+ *
8196
+ * ### Other field members used
8197
+ * `label()`
8198
+ *
8199
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
8200
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
8201
+ *
8202
+ * @example
8203
+ * ```json
8204
+ * { "name": "startsAt", "type": "time", "label": "Starts at" }
8205
+ * ```
8206
+ */
7186
8207
  class TimePickerField extends FieldBase {
7187
8208
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: TimePickerField, deps: null, target: i0.ɵɵFactoryTarget.Component });
7188
8209
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: TimePickerField, isStandalone: true, selector: "iss-field-time-picker", usesInheritance: true, ngImport: i0, template: `
@@ -7250,12 +8271,36 @@ var datePicker_viewer = /*#__PURE__*/Object.freeze({
7250
8271
  DatePickerViewer: DatePickerViewer
7251
8272
  });
7252
8273
 
8274
+ /**
8275
+ * `<iss-field-date-picker>` — a single date, picked from a calendar.
8276
+ *
8277
+ * Rendered by the outlet for fields of type `date`. In `edit` mode it renders
8278
+ * {@link DatePickerControl} plus the validation message; in `view` mode the matching viewer.
8279
+ *
8280
+ * ### Supported `config` keys
8281
+ * | Key | Type | Description |
8282
+ * | --- | --- | --- |
8283
+ * | `minDate` | `Date` | Earliest selectable date. |
8284
+ * | `maxDate` | `Date` | Latest selectable date. |
8285
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
8286
+ *
8287
+ * ### Other field members used
8288
+ * `label()`
8289
+ *
8290
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
8291
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
8292
+ *
8293
+ * @example
8294
+ * ```json
8295
+ * { "name": "startsOn", "type": "date", "label": "Start date", "config": { "minDate": "2026-01-01" } }
8296
+ * ```
8297
+ */
7253
8298
  class DatePickerField extends FieldBase {
7254
8299
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatePickerField, deps: null, target: i0.ɵɵFactoryTarget.Component });
7255
8300
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DatePickerField, isStandalone: true, selector: "iss-field-date-picker", usesInheritance: true, ngImport: i0, template: `
7256
8301
  @if (field.visible()) {
7257
8302
  @if (field.mode() === "edit") {
7258
- <iss-ctrl-date-picker [formControlName]="field.name" [minDate]="field.config.minDate() ?? null" [maxDate]="field.config.maxDate() ?? null" [readonly]="field.config.readonly() ?? false">
8303
+ <iss-ctrl-date-picker [formControlName]="field.name" [minDate]="field.config.minDate() ?? null" [maxDate]="field.config.maxDate() ?? null" [readonly]="field.config.readonly() ?? false">
7259
8304
  <label>{{ field.label() }}</label>
7260
8305
  </iss-ctrl-date-picker>
7261
8306
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -7279,7 +8324,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
7279
8324
  template: `
7280
8325
  @if (field.visible()) {
7281
8326
  @if (field.mode() === "edit") {
7282
- <iss-ctrl-date-picker [formControlName]="field.name" [minDate]="field.config.minDate() ?? null" [maxDate]="field.config.maxDate() ?? null" [readonly]="field.config.readonly() ?? false">
8327
+ <iss-ctrl-date-picker [formControlName]="field.name" [minDate]="field.config.minDate() ?? null" [maxDate]="field.config.maxDate() ?? null" [readonly]="field.config.readonly() ?? false">
7283
8328
  <label>{{ field.label() }}</label>
7284
8329
  </iss-ctrl-date-picker>
7285
8330
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
@@ -7321,6 +8366,30 @@ var datetimePicker_viewer = /*#__PURE__*/Object.freeze({
7321
8366
  DatePickerTimeViewer: DatePickerTimeViewer
7322
8367
  });
7323
8368
 
8369
+ /**
8370
+ * `<iss-field-datetime-picker>` — a date and a time in one field.
8371
+ *
8372
+ * Rendered by the outlet for fields of type `datetime`. In `edit` mode it renders
8373
+ * {@link DatetimePickerControl} plus the validation message; in `view` mode the matching viewer.
8374
+ *
8375
+ * ### Supported `config` keys
8376
+ * | Key | Type | Description |
8377
+ * | --- | --- | --- |
8378
+ * | `minDate` | `Date` | Earliest selectable date. |
8379
+ * | `maxDate` | `Date` | Latest selectable date. |
8380
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
8381
+ *
8382
+ * ### Other field members used
8383
+ * `label()`
8384
+ *
8385
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
8386
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
8387
+ *
8388
+ * @example
8389
+ * ```json
8390
+ * { "name": "scheduledAt", "type": "datetime", "label": "Scheduled at" }
8391
+ * ```
8392
+ */
7324
8393
  class DatetimePickerField extends FieldBase {
7325
8394
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatetimePickerField, deps: null, target: i0.ɵɵFactoryTarget.Component });
7326
8395
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DatetimePickerField, isStandalone: true, selector: "iss-field-datetime-picker", usesInheritance: true, ngImport: i0, template: `
@@ -7399,6 +8468,32 @@ var dateRangePicker_viewer = /*#__PURE__*/Object.freeze({
7399
8468
  DateRangePickerViewer: DateRangePickerViewer
7400
8469
  });
7401
8470
 
8471
+ /**
8472
+ * `<iss-field-date-range-picker>` — a start and end date in one field.
8473
+ *
8474
+ * Rendered by the outlet for fields of type `date_range`. In `edit` mode it renders
8475
+ * {@link DateRangePickerControl} plus the validation message; in `view` mode the matching viewer.
8476
+ *
8477
+ * ### Supported `config` keys
8478
+ * | Key | Type | Description |
8479
+ * | --- | --- | --- |
8480
+ * | `minDate` | `Date` | Earliest selectable date. |
8481
+ * | `maxDate` | `Date` | Latest selectable date. |
8482
+ * | `readonly` | `boolean` | Shows the value but blocks interaction. |
8483
+ *
8484
+ * ### Other field members used
8485
+ * `label()`
8486
+ *
8487
+ * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
8488
+ * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
8489
+ *
8490
+ * A half-filled range is treated as no value at all.
8491
+ *
8492
+ * @example
8493
+ * ```json
8494
+ * { "name": "period", "type": "date_range", "label": "Period" }
8495
+ * ```
8496
+ */
7402
8497
  class DateRangePickerField extends FieldBase {
7403
8498
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DateRangePickerField, deps: null, target: i0.ɵɵFactoryTarget.Component });
7404
8499
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DateRangePickerField, isStandalone: true, selector: "iss-field-date-range-picker", usesInheritance: true, ngImport: i0, template: `
@@ -7756,5 +8851,5 @@ var time_validator = /*#__PURE__*/Object.freeze({
7756
8851
  * Generated bundle index. Do not edit.
7757
8852
  */
7758
8853
 
7759
- export { PlateViewer as $, TimePickerField as A, DatePickerField as B, ControlBase as C, DatePickerControl as D, Employee as E, FieldBase as F, DatetimePickerField as G, HOST as H, IssField as I, DateRangePickerField as J, InputViewer as K, Loader as L, MobileControl as M, TextareaViewer as N, Outlet as O, PLACEHOLDER_REGEX as P, ChipsViewer as Q, RadioControl as R, SelectControl as S, TextareaControl as T, RadioViewer as U, VIEW_PROVIDER as V, SelectViewer as W, MobileViewer as X, CheckboxViewer as Y, ToggleButtonViewer as Z, SlideToggleViewer as _, ViewerBase as a, AttachmentViewer as a0, TimePickerViewer as a1, DatePickerViewer as a2, DatePickerTimeViewer as a3, DateRangePickerViewer as a4, DEFAULT_COUNTRY as a5, COUNTRIES as a6, DATE_FORMAT_ADAPTER as a7, DATETIME_FORMAT as a8, PLATE_LETTERS as a9, VALIDATION_MESSAGES as aa, COMPONENTS as ab, SERVICES as ac, VALIDATORS as ad, FIELD_DATA as ae, UI_LANGUAGE as af, ATTACHMENT_UPLOAD_URL as ag, ATTACHMENT_UPLOAD_RESPONSE_MAPPER as ah, ATTACHMENT_DOWNLOAD_URL as ai, USER_SEARCH_API as aj, HintsComponent as ak, Droppable as al, ArabicNumberPipe as am, FieldDataInjector as an, PlateLetterPipe as ao, SelectStatusPipe as ap, TranslatePipe as aq, FileHandler as ar, Phone as as, arrayFrom as at, formatFileSize as au, IssValidators as av, FileValidators as aw, TimeValidator as ax, FormEngine as b, ValidationMessageComponent as c, CheckboxControl as d, ChipsControl as e, DateRangePickerControl as f, getPropertyByPath as g, DatetimePickerControl as h, FilePickerControl as i, InputControl as j, PlateControl as k, SlideToggleControl as l, TimePickerControl as m, ToggleButtonControl as n, InputField as o, TextareaField as p, ChipsField as q, replacePlaceholders as r, RadioField as s, SelectField as t, MobileField as u, CheckboxField as v, ToggleButtonField as w, SlideToggleField as x, PlateField as y, FilePickerField as z };
7760
- //# sourceMappingURL=iss-ctrl-iss-ctrl-hz0ibyPg.mjs.map
8854
+ export { PlateViewer as $, TimePickerField as A, DatePickerField as B, ControlBase as C, DatePickerControl as D, Employee as E, FieldBase as F, DatetimePickerField as G, HOST as H, IssField as I, DateRangePickerField as J, InputViewer as K, Loader as L, MobileControl as M, TextareaViewer as N, Outlet as O, PLACEHOLDER_REGEX as P, ChipsViewer as Q, RadioControl as R, SelectControl as S, TextareaControl as T, RadioViewer as U, VIEW_PROVIDER as V, SelectViewer as W, MobileViewer as X, CheckboxViewer as Y, ToggleButtonViewer as Z, SlideToggleViewer as _, ValidationMessageComponent as a, AttachmentViewer as a0, TimePickerViewer as a1, DatePickerViewer as a2, DatePickerTimeViewer as a3, DateRangePickerViewer as a4, DEFAULT_COUNTRY as a5, COUNTRIES as a6, DATE_FORMAT_ADAPTER as a7, DATETIME_FORMAT as a8, PLATE_LETTERS as a9, VALIDATION_MESSAGES as aa, COMPONENTS as ab, SERVICES as ac, VALIDATORS as ad, FIELD_DATA as ae, UI_LANGUAGE as af, ATTACHMENT_UPLOAD_URL as ag, ATTACHMENT_UPLOAD_RESPONSE_MAPPER as ah, ATTACHMENT_DOWNLOAD_URL as ai, USER_SEARCH_API as aj, HintsComponent as ak, Droppable as al, ArabicNumberPipe as am, FieldDataInjector as an, PlateLetterPipe as ao, SelectStatusPipe as ap, TranslatePipe as aq, FileHandler as ar, Phone as as, arrayFrom as at, formatFileSize as au, IssValidators as av, FileValidators as aw, TimeValidator as ax, ViewerBase as b, FormEngine as c, CheckboxControl as d, ChipsControl as e, DateRangePickerControl as f, getPropertyByPath as g, DatetimePickerControl as h, FilePickerControl as i, InputControl as j, PlateControl as k, SlideToggleControl as l, TimePickerControl as m, ToggleButtonControl as n, InputField as o, TextareaField as p, ChipsField as q, replacePlaceholders as r, RadioField as s, SelectField as t, MobileField as u, CheckboxField as v, ToggleButtonField as w, SlideToggleField as x, PlateField as y, FilePickerField as z };
8855
+ //# sourceMappingURL=iss-ctrl-iss-ctrl-BN9rcLt2.mjs.map