iss-ctrl 0.0.22 → 0.0.23

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 (88) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/iss-ctrl-base.mjs +20 -1
  3. package/fesm2022/iss-ctrl-base.mjs.map +1 -1
  4. package/fesm2022/{iss-ctrl-checkbox.field-Dj5EGLUr.mjs → iss-ctrl-checkbox.field-CILXADas.mjs} +25 -29
  5. package/fesm2022/iss-ctrl-checkbox.field-CILXADas.mjs.map +1 -0
  6. package/fesm2022/iss-ctrl-checkbox.mjs +10 -7
  7. package/fesm2022/iss-ctrl-checkbox.mjs.map +1 -1
  8. package/fesm2022/{iss-ctrl-chips.field-BLLAjBbP.mjs → iss-ctrl-chips.field-445Ds3V7.mjs} +2 -2
  9. package/fesm2022/{iss-ctrl-chips.field-BLLAjBbP.mjs.map → iss-ctrl-chips.field-445Ds3V7.mjs.map} +1 -1
  10. package/fesm2022/{iss-ctrl-date-picker.field-BSpXukpO.mjs → iss-ctrl-date-picker.field-Djhh1FsR.mjs} +2 -2
  11. package/fesm2022/{iss-ctrl-date-picker.field-BSpXukpO.mjs.map → iss-ctrl-date-picker.field-Djhh1FsR.mjs.map} +1 -1
  12. package/fesm2022/{iss-ctrl-date-range-picker.field-CjNHU1RW.mjs → iss-ctrl-date-range-picker.field-Dv636SAm.mjs} +2 -2
  13. package/fesm2022/{iss-ctrl-date-range-picker.field-CjNHU1RW.mjs.map → iss-ctrl-date-range-picker.field-Dv636SAm.mjs.map} +1 -1
  14. package/fesm2022/{iss-ctrl-datetime-picker.field-DGMY9PaU.mjs → iss-ctrl-datetime-picker.field-DldY8vke.mjs} +2 -2
  15. package/fesm2022/{iss-ctrl-datetime-picker.field-DGMY9PaU.mjs.map → iss-ctrl-datetime-picker.field-DldY8vke.mjs.map} +1 -1
  16. package/fesm2022/{iss-ctrl-select.field-DoU4G_8t.mjs → iss-ctrl-dropdownlist.field-DikBAtc_.mjs} +21 -21
  17. package/fesm2022/iss-ctrl-dropdownlist.field-DikBAtc_.mjs.map +1 -0
  18. package/fesm2022/{iss-ctrl-select.mjs → iss-ctrl-dropdownlist.mjs} +36 -25
  19. package/fesm2022/iss-ctrl-dropdownlist.mjs.map +1 -0
  20. package/fesm2022/{iss-ctrl-select.viewer-Dv9M-lG-.mjs → iss-ctrl-dropdownlist.viewer-OWJxDpr8.mjs} +7 -7
  21. package/fesm2022/iss-ctrl-dropdownlist.viewer-OWJxDpr8.mjs.map +1 -0
  22. package/fesm2022/{iss-ctrl-file-picker.field-CbepZaX6.mjs → iss-ctrl-file-picker.field-BMZaJxvj.mjs} +2 -2
  23. package/fesm2022/{iss-ctrl-file-picker.field-CbepZaX6.mjs.map → iss-ctrl-file-picker.field-BMZaJxvj.mjs.map} +1 -1
  24. package/fesm2022/iss-ctrl-file-picker.mjs +3 -1
  25. package/fesm2022/iss-ctrl-file-picker.mjs.map +1 -1
  26. package/fesm2022/{iss-ctrl-input.field-Ctlf3OCN.mjs → iss-ctrl-input.field-BiwBFYx3.mjs} +2 -2
  27. package/fesm2022/{iss-ctrl-input.field-Ctlf3OCN.mjs.map → iss-ctrl-input.field-BiwBFYx3.mjs.map} +1 -1
  28. package/fesm2022/{iss-ctrl-iss-ctrl-DvnkwSMG.mjs → iss-ctrl-iss-ctrl-BG-QWWdq.mjs} +51 -70
  29. package/fesm2022/iss-ctrl-iss-ctrl-BG-QWWdq.mjs.map +1 -0
  30. package/fesm2022/{iss-ctrl-load-event-CuZ7pMjk.mjs → iss-ctrl-load-event-T4L3k9XO.mjs} +3 -3
  31. package/fesm2022/{iss-ctrl-load-event-CuZ7pMjk.mjs.map → iss-ctrl-load-event-T4L3k9XO.mjs.map} +1 -1
  32. package/fesm2022/{iss-ctrl-load-options-event-B10rhdqh.mjs → iss-ctrl-load-options-event-tG258cbP.mjs} +3 -3
  33. package/fesm2022/{iss-ctrl-load-options-event-B10rhdqh.mjs.map → iss-ctrl-load-options-event-tG258cbP.mjs.map} +1 -1
  34. package/fesm2022/{iss-ctrl-load-value-event-C-aRgKLx.mjs → iss-ctrl-load-value-event--7zt90Dl.mjs} +3 -3
  35. package/fesm2022/{iss-ctrl-load-value-event-C-aRgKLx.mjs.map → iss-ctrl-load-value-event--7zt90Dl.mjs.map} +1 -1
  36. package/fesm2022/{iss-ctrl-mobile.field-DXVYT3q-.mjs → iss-ctrl-mobile.field-DLccnWKX.mjs} +2 -2
  37. package/fesm2022/{iss-ctrl-mobile.field-DXVYT3q-.mjs.map → iss-ctrl-mobile.field-DLccnWKX.mjs.map} +1 -1
  38. package/fesm2022/{iss-ctrl-note.field-C8X9-mgD.mjs → iss-ctrl-note.field-CT1wVmfF.mjs} +2 -2
  39. package/fesm2022/{iss-ctrl-note.field-C8X9-mgD.mjs.map → iss-ctrl-note.field-CT1wVmfF.mjs.map} +1 -1
  40. package/fesm2022/{iss-ctrl-plate.field-aI81tAOV.mjs → iss-ctrl-plate.field-CQQY8rnE.mjs} +2 -2
  41. package/fesm2022/{iss-ctrl-plate.field-aI81tAOV.mjs.map → iss-ctrl-plate.field-CQQY8rnE.mjs.map} +1 -1
  42. package/fesm2022/iss-ctrl-plate.mjs +3 -1
  43. package/fesm2022/iss-ctrl-plate.mjs.map +1 -1
  44. package/fesm2022/{iss-ctrl-radio.field-B_JjPIlb.mjs → iss-ctrl-radio.field-Dp5D-AXQ.mjs} +11 -19
  45. package/fesm2022/iss-ctrl-radio.field-Dp5D-AXQ.mjs.map +1 -0
  46. package/fesm2022/iss-ctrl-radio.mjs +9 -6
  47. package/fesm2022/iss-ctrl-radio.mjs.map +1 -1
  48. package/fesm2022/{iss-ctrl-replace-api-keys-DLnagkOr.mjs → iss-ctrl-replace-api-keys-COUv4Kin.mjs} +2 -2
  49. package/fesm2022/{iss-ctrl-replace-api-keys-DLnagkOr.mjs.map → iss-ctrl-replace-api-keys-COUv4Kin.mjs.map} +1 -1
  50. package/fesm2022/{iss-ctrl-set-value-event-Dhw0Vj5J.mjs → iss-ctrl-set-value-event-D0-_qIyS.mjs} +2 -2
  51. package/fesm2022/{iss-ctrl-set-value-event-Dhw0Vj5J.mjs.map → iss-ctrl-set-value-event-D0-_qIyS.mjs.map} +1 -1
  52. package/fesm2022/{iss-ctrl-slide-toggle.field-TVVbAr6p.mjs → iss-ctrl-slide-toggle.field-vCJHOiSG.mjs} +2 -2
  53. package/fesm2022/{iss-ctrl-slide-toggle.field-TVVbAr6p.mjs.map → iss-ctrl-slide-toggle.field-vCJHOiSG.mjs.map} +1 -1
  54. package/fesm2022/iss-ctrl-slide-toggle.mjs +5 -11
  55. package/fesm2022/iss-ctrl-slide-toggle.mjs.map +1 -1
  56. package/fesm2022/{iss-ctrl-table.field-E0r9w0os.mjs → iss-ctrl-table.field-DdFjH-D8.mjs} +2 -2
  57. package/fesm2022/{iss-ctrl-table.field-E0r9w0os.mjs.map → iss-ctrl-table.field-DdFjH-D8.mjs.map} +1 -1
  58. package/fesm2022/{iss-ctrl-textarea.field-CmHPDpk-.mjs → iss-ctrl-textarea.field-Dqhhu2m4.mjs} +2 -2
  59. package/fesm2022/{iss-ctrl-textarea.field-CmHPDpk-.mjs.map → iss-ctrl-textarea.field-Dqhhu2m4.mjs.map} +1 -1
  60. package/fesm2022/{iss-ctrl-time-picker.field-Cb0I5Ut1.mjs → iss-ctrl-time-picker.field-CdmxRiH8.mjs} +2 -2
  61. package/fesm2022/{iss-ctrl-time-picker.field-Cb0I5Ut1.mjs.map → iss-ctrl-time-picker.field-CdmxRiH8.mjs.map} +1 -1
  62. package/fesm2022/{iss-ctrl-toggle-button.field-Bj8WrkB-.mjs → iss-ctrl-toggle-button.field-rAT7dVFC.mjs} +39 -43
  63. package/fesm2022/iss-ctrl-toggle-button.field-rAT7dVFC.mjs.map +1 -0
  64. package/fesm2022/iss-ctrl-toggle-button.mjs +9 -7
  65. package/fesm2022/iss-ctrl-toggle-button.mjs.map +1 -1
  66. package/fesm2022/{iss-ctrl-trigger-based-on-json-value-D9rTXVD1.mjs → iss-ctrl-trigger-based-on-json-value-I92SNsv9.mjs} +2 -2
  67. package/fesm2022/{iss-ctrl-trigger-based-on-json-value-D9rTXVD1.mjs.map → iss-ctrl-trigger-based-on-json-value-I92SNsv9.mjs.map} +1 -1
  68. package/fesm2022/{iss-ctrl-user-picker.field-BIzB5ZX6.mjs → iss-ctrl-user-picker.field-DpmYCfpD.mjs} +10 -10
  69. package/fesm2022/iss-ctrl-user-picker.field-DpmYCfpD.mjs.map +1 -0
  70. package/fesm2022/iss-ctrl.mjs +1 -1
  71. package/package.json +5 -5
  72. package/types/iss-ctrl-base.d.ts +15 -3
  73. package/types/iss-ctrl-checkbox.d.ts +4 -3
  74. package/types/{iss-ctrl-select.d.ts → iss-ctrl-dropdownlist.d.ts} +11 -8
  75. package/types/iss-ctrl-file-picker.d.ts +2 -2
  76. package/types/iss-ctrl-plate.d.ts +2 -2
  77. package/types/iss-ctrl-radio.d.ts +3 -3
  78. package/types/iss-ctrl-slide-toggle.d.ts +2 -2
  79. package/types/iss-ctrl-toggle-button.d.ts +3 -3
  80. package/types/iss-ctrl.d.ts +5 -17
  81. package/fesm2022/iss-ctrl-checkbox.field-Dj5EGLUr.mjs.map +0 -1
  82. package/fesm2022/iss-ctrl-iss-ctrl-DvnkwSMG.mjs.map +0 -1
  83. package/fesm2022/iss-ctrl-radio.field-B_JjPIlb.mjs.map +0 -1
  84. package/fesm2022/iss-ctrl-select.field-DoU4G_8t.mjs.map +0 -1
  85. package/fesm2022/iss-ctrl-select.mjs.map +0 -1
  86. package/fesm2022/iss-ctrl-select.viewer-Dv9M-lG-.mjs.map +0 -1
  87. package/fesm2022/iss-ctrl-toggle-button.field-Bj8WrkB-.mjs.map +0 -1
  88. package/fesm2022/iss-ctrl-user-picker.field-BIzB5ZX6.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"iss-ctrl-date-range-picker.field-CjNHU1RW.mjs","sources":["../../../projects/iss/src/components/controls/date-range-picker/date-range-picker.field.ts"],"sourcesContent":["import { Component } from \"@angular/core\";\nimport { ReactiveFormsModule } from \"@angular/forms\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { FieldBase } from \"../base/field-base\";\nimport { DateRangePickerControl } from \"iss-ctrl/date-range-picker\";\nimport { DateRangePickerViewer } from \"./date-range-picker.viewer\";\n\n/**\n * `<iss-field-date-range-picker>` — a start and end date in one field.\n *\n * Rendered by the outlet for fields of type `date_range`. In `edit` mode it renders\n * {@link DateRangePickerControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `minDate` | `Date` | Earliest selectable date. |\n * | `maxDate` | `Date` | Latest selectable date. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n * | `hijriCalendar` | `boolean` | Renders an Umm al-Qura Hijri calendar while the emitted value stays Gregorian. |\n * | `emitHijri` | `boolean` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |\n *\n * ### Other field members used\n * `label()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * A half-filled range is treated as no value at all.\n *\n * @example\n * ```json\n * { \"name\": \"period\", \"type\": \"date_range\", \"label\": \"Period\" }\n * ```\n */\n@Component({\n selector: \"iss-field-date-range-picker\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n DateRangePickerControl,\n DateRangePickerViewer,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <iss-ctrl-date-range-picker\n [formControlName]=\"field.name\"\n [minDate]=\"field.config.minDate() ?? null\"\n [maxDate]=\"field.config.maxDate() ?? null\"\n [readonly]=\"field.config.readonly() ?? false\"\n [hijriCalendar]=\"field.config.hijriCalendar() ?? false\"\n [emitHijri]=\"field.config.emitHijri() ?? false\"\n >\n <label>{{ field.label() }}</label>\n </iss-ctrl-date-range-picker>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-date-range-picker [field]=\"field\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class DateRangePickerField extends FieldBase {}\n"],"names":[],"mappings":";;;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;AAgCG,MAAO,oBAAqB,SAAQ,SAAS,CAAA;uGAAtC,oBAAoB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAtBrB;;;;;;;;;;;;;;;;;;;;GAoBT,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAzBC,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,sBAAsB,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,SAAA,EAAA,SAAA,EAAA,eAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,yBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,qBAAqB,yEACrB,WAAW,EAAA,QAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,aAAA,EALE,CAAC,aAAa,CAAC,EAAA,CAAA;;2FA6BnB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBA/BhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,6BAA6B;oBACvC,aAAa,EAAE,CAAC,aAAa,CAAC;AAC9B,oBAAA,OAAO,EAAE;wBACP,mBAAmB;wBACnB,sBAAsB;wBACtB,qBAAqB;wBACrB;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;AAoBT,EAAA;AACF,iBAAA;;;;;"}
1
+ {"version":3,"file":"iss-ctrl-date-range-picker.field-Dv636SAm.mjs","sources":["../../../projects/iss/src/components/controls/date-range-picker/date-range-picker.field.ts"],"sourcesContent":["import { Component } from \"@angular/core\";\nimport { ReactiveFormsModule } from \"@angular/forms\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { FieldBase } from \"../base/field-base\";\nimport { DateRangePickerControl } from \"iss-ctrl/date-range-picker\";\nimport { DateRangePickerViewer } from \"./date-range-picker.viewer\";\n\n/**\n * `<iss-field-date-range-picker>` — a start and end date in one field.\n *\n * Rendered by the outlet for fields of type `date_range`. In `edit` mode it renders\n * {@link DateRangePickerControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `minDate` | `Date` | Earliest selectable date. |\n * | `maxDate` | `Date` | Latest selectable date. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n * | `hijriCalendar` | `boolean` | Renders an Umm al-Qura Hijri calendar while the emitted value stays Gregorian. |\n * | `emitHijri` | `boolean` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |\n *\n * ### Other field members used\n * `label()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * A half-filled range is treated as no value at all.\n *\n * @example\n * ```json\n * { \"name\": \"period\", \"type\": \"date_range\", \"label\": \"Period\" }\n * ```\n */\n@Component({\n selector: \"iss-field-date-range-picker\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n DateRangePickerControl,\n DateRangePickerViewer,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <iss-ctrl-date-range-picker\n [formControlName]=\"field.name\"\n [minDate]=\"field.config.minDate() ?? null\"\n [maxDate]=\"field.config.maxDate() ?? null\"\n [readonly]=\"field.config.readonly() ?? false\"\n [hijriCalendar]=\"field.config.hijriCalendar() ?? false\"\n [emitHijri]=\"field.config.emitHijri() ?? false\"\n >\n <label>{{ field.label() }}</label>\n </iss-ctrl-date-range-picker>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-date-range-picker [field]=\"field\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class DateRangePickerField extends FieldBase {}\n"],"names":[],"mappings":";;;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;AAgCG,MAAO,oBAAqB,SAAQ,SAAS,CAAA;uGAAtC,oBAAoB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAtBrB;;;;;;;;;;;;;;;;;;;;GAoBT,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAzBC,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,sBAAsB,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,SAAA,EAAA,SAAA,EAAA,eAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,yBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,qBAAqB,yEACrB,WAAW,EAAA,QAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,aAAA,EALE,CAAC,aAAa,CAAC,EAAA,CAAA;;2FA6BnB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBA/BhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,6BAA6B;oBACvC,aAAa,EAAE,CAAC,aAAa,CAAC;AAC9B,oBAAA,OAAO,EAAE;wBACP,mBAAmB;wBACnB,sBAAsB;wBACtB,qBAAqB;wBACrB;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;AAoBT,EAAA;AACF,iBAAA;;;;;"}
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { Component } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { ReactiveFormsModule } from '@angular/forms';
5
- import { F as FieldBase, V as VIEW_PROVIDER, a as ValidationMessage, b as FieldViewer } from './iss-ctrl-iss-ctrl-DvnkwSMG.mjs';
5
+ import { F as FieldBase, V as VIEW_PROVIDER, a as ValidationMessage, b as FieldViewer } from './iss-ctrl-iss-ctrl-BG-QWWdq.mjs';
6
6
  import { DatetimePickerControl } from 'iss-ctrl/datetime-picker';
7
7
  import { DatePickerTimeViewer } from './iss-ctrl-datetime-picker.viewer-BeUyEBKo.mjs';
8
8
 
@@ -95,4 +95,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
95
95
  }] });
96
96
 
97
97
  export { DatetimePickerField };
98
- //# sourceMappingURL=iss-ctrl-datetime-picker.field-DGMY9PaU.mjs.map
98
+ //# sourceMappingURL=iss-ctrl-datetime-picker.field-DldY8vke.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"iss-ctrl-datetime-picker.field-DGMY9PaU.mjs","sources":["../../../projects/iss/src/components/controls/datetime-picker/datetime-picker.field.ts"],"sourcesContent":["import { Component } from \"@angular/core\";\nimport { ReactiveFormsModule } from \"@angular/forms\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { ValidationMessage } from \"../../shared/validation-message\";\nimport { FieldBase } from \"../base/field-base\";\nimport { DatetimePickerControl } from \"iss-ctrl/datetime-picker\";\nimport { DatePickerTimeViewer } from \"./datetime-picker.viewer\";\n\n/**\n * `<iss-field-datetime-picker>` — a date and a time in one field.\n *\n * Rendered by the outlet for fields of type `datetime`. In `edit` mode it renders\n * {@link DatetimePickerControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `minDate` | `Date` | Earliest selectable date. |\n * | `maxDate` | `Date` | Latest selectable date. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n * | `hijriCalendar` | `boolean` | Renders an Umm al-Qura Hijri calendar while the emitted value stays Gregorian. |\n * | `emitHijri` | `boolean` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |\n *\n * ### Other field members used\n * `label()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * @example\n * ```json\n * { \"name\": \"scheduledAt\", \"type\": \"datetime\", \"label\": \"Scheduled at\" }\n * ```\n */\n@Component({\n selector: \"iss-field-datetime-picker\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n DatetimePickerControl,\n ValidationMessage,\n DatePickerTimeViewer,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <iss-ctrl-datetime-picker\n [formControlName]=\"field.name\"\n [minDate]=\"field.config.minDate() ?? null\"\n [maxDate]=\"field.config.maxDate() ?? null\"\n [readonly]=\"field.config.readonly() ?? false\"\n [hijriCalendar]=\"field.config.hijriCalendar() ?? false\"\n [emitHijri]=\"field.config.emitHijri() ?? false\"\n >\n <label>{{ field.label() }}</label>\n </iss-ctrl-datetime-picker>\n <iss-validation-message-viewer [errors]=\"ctrl.errors\" [showMessage]=\"!ctrl.untouched\"/>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-datetime-picker [field]=\"field\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class DatetimePickerField extends FieldBase {}\n"],"names":[],"mappings":";;;;;;;;AASA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;AAkCG,MAAO,mBAAoB,SAAQ,SAAS,CAAA;uGAArC,mBAAmB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,2BAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvBpB;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA3BC,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,qBAAqB,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,SAAA,EAAA,SAAA,EAAA,SAAA,EAAA,SAAA,EAAA,eAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,iBAAiB,EAAA,QAAA,EAAA,+BAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,oBAAoB,EAAA,QAAA,EAAA,4BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACpB,WAAW,EAAA,QAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,aAAA,EANE,CAAC,aAAa,CAAC,EAAA,CAAA;;2FA+BnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAjC/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,2BAA2B;oBACrC,aAAa,EAAE,CAAC,aAAa,CAAC;AAC9B,oBAAA,OAAO,EAAE;wBACP,mBAAmB;wBACnB,qBAAqB;wBACrB,iBAAiB;wBACjB,oBAAoB;wBACpB;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA;AACF,iBAAA;;;;;"}
1
+ {"version":3,"file":"iss-ctrl-datetime-picker.field-DldY8vke.mjs","sources":["../../../projects/iss/src/components/controls/datetime-picker/datetime-picker.field.ts"],"sourcesContent":["import { Component } from \"@angular/core\";\nimport { ReactiveFormsModule } from \"@angular/forms\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { ValidationMessage } from \"../../shared/validation-message\";\nimport { FieldBase } from \"../base/field-base\";\nimport { DatetimePickerControl } from \"iss-ctrl/datetime-picker\";\nimport { DatePickerTimeViewer } from \"./datetime-picker.viewer\";\n\n/**\n * `<iss-field-datetime-picker>` — a date and a time in one field.\n *\n * Rendered by the outlet for fields of type `datetime`. In `edit` mode it renders\n * {@link DatetimePickerControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `minDate` | `Date` | Earliest selectable date. |\n * | `maxDate` | `Date` | Latest selectable date. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n * | `hijriCalendar` | `boolean` | Renders an Umm al-Qura Hijri calendar while the emitted value stays Gregorian. |\n * | `emitHijri` | `boolean` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |\n *\n * ### Other field members used\n * `label()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * @example\n * ```json\n * { \"name\": \"scheduledAt\", \"type\": \"datetime\", \"label\": \"Scheduled at\" }\n * ```\n */\n@Component({\n selector: \"iss-field-datetime-picker\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n DatetimePickerControl,\n ValidationMessage,\n DatePickerTimeViewer,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <iss-ctrl-datetime-picker\n [formControlName]=\"field.name\"\n [minDate]=\"field.config.minDate() ?? null\"\n [maxDate]=\"field.config.maxDate() ?? null\"\n [readonly]=\"field.config.readonly() ?? false\"\n [hijriCalendar]=\"field.config.hijriCalendar() ?? false\"\n [emitHijri]=\"field.config.emitHijri() ?? false\"\n >\n <label>{{ field.label() }}</label>\n </iss-ctrl-datetime-picker>\n <iss-validation-message-viewer [errors]=\"ctrl.errors\" [showMessage]=\"!ctrl.untouched\"/>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-datetime-picker [field]=\"field\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class DatetimePickerField extends FieldBase {}\n"],"names":[],"mappings":";;;;;;;;AASA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;AAkCG,MAAO,mBAAoB,SAAQ,SAAS,CAAA;uGAArC,mBAAmB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,2BAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvBpB;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA3BC,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,qBAAqB,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,SAAA,EAAA,SAAA,EAAA,SAAA,EAAA,SAAA,EAAA,eAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,iBAAiB,EAAA,QAAA,EAAA,+BAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,oBAAoB,EAAA,QAAA,EAAA,4BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACpB,WAAW,EAAA,QAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,aAAA,EANE,CAAC,aAAa,CAAC,EAAA,CAAA;;2FA+BnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAjC/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,2BAA2B;oBACrC,aAAa,EAAE,CAAC,aAAa,CAAC;AAC9B,oBAAA,OAAO,EAAE;wBACP,mBAAmB;wBACnB,qBAAqB;wBACrB,iBAAiB;wBACjB,oBAAoB;wBACpB;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA;AACF,iBAAA;;;;;"}
@@ -2,15 +2,15 @@ import * as i0 from '@angular/core';
2
2
  import { Component } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { ReactiveFormsModule } from '@angular/forms';
5
- import { F as FieldBase, V as VIEW_PROVIDER, a as ValidationMessage, b as FieldViewer } from './iss-ctrl-iss-ctrl-DvnkwSMG.mjs';
6
- import { SelectControl } from 'iss-ctrl/select';
7
- import { SelectViewer } from './iss-ctrl-select.viewer-Dv9M-lG-.mjs';
5
+ import { F as FieldBase, V as VIEW_PROVIDER, a as ValidationMessage, b as FieldViewer } from './iss-ctrl-iss-ctrl-BG-QWWdq.mjs';
6
+ import { DropdownlistControl } from 'iss-ctrl/dropdownlist';
7
+ import { DropdownlistViewer } from './iss-ctrl-dropdownlist.viewer-OWJxDpr8.mjs';
8
8
 
9
9
  /**
10
- * `<iss-field-select>` — single or multiple selection from a dropdown.
10
+ * `<iss-field-dropdownlist>` — single or multiple selection from a dropdown.
11
11
  *
12
12
  * Rendered by the outlet for fields of type `dropdown_list`. In `edit` mode it renders
13
- * {@link SelectControl} plus the validation message; in `view` mode the matching viewer.
13
+ * {@link DropdownlistControl} plus the validation message; in `view` mode the matching viewer.
14
14
  *
15
15
  * ### Supported `config` keys
16
16
  * | Key | Type | Description |
@@ -32,50 +32,50 @@ import { SelectViewer } from './iss-ctrl-select.viewer-Dv9M-lG-.mjs';
32
32
  * { "name": "city", "type": "dropdown_list", "label": "City", "options": [{ "value": "1", "label": "Riyadh" }] }
33
33
  * ```
34
34
  */
35
- class SelectField extends FieldBase {
35
+ class DropdownlistField extends FieldBase {
36
36
  onChange($event) {
37
37
  this.field.ctrlJsonValue.set($event);
38
38
  }
39
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SelectField, deps: null, target: i0.ɵɵFactoryTarget.Component });
40
- 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: `
39
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownlistField, deps: null, target: i0.ɵɵFactoryTarget.Component });
40
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DropdownlistField, isStandalone: true, selector: "iss-field-dropdownlist", usesInheritance: true, ngImport: i0, template: `
41
41
  @if (field.visible()) {
42
42
  @if (field.mode() === "edit") {
43
- <iss-ctrl-select [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
43
+ <iss-ctrl-dropdownlist [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
44
44
  <label>{{ field.label() }}</label>
45
- </iss-ctrl-select>
45
+ </iss-ctrl-dropdownlist>
46
46
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
47
47
  } @else {
48
48
  <iss-field-viewer>
49
49
  <label>{{ field.label() }}</label>
50
- <iss-viewer-select [field]="field"/>
50
+ <iss-viewer-dropdownlist [field]="field"/>
51
51
  </iss-field-viewer>
52
52
  }
53
53
  }
54
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: SelectControl, selector: "iss-ctrl-select", inputs: ["options", "height", "loading"], outputs: ["onQueryChange"] }, { kind: "component", type: ValidationMessage, selector: "iss-validation-message-viewer", inputs: ["errors", "showMessage"] }, { kind: "component", type: SelectViewer, selector: "iss-viewer-select" }, { kind: "component", type: FieldViewer, selector: "iss-field-viewer" }], viewProviders: [VIEW_PROVIDER] });
54
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DropdownlistControl, selector: "iss-ctrl-dropdownlist", inputs: ["options", "height", "loading"], outputs: ["onQueryChange"] }, { kind: "component", type: ValidationMessage, selector: "iss-validation-message-viewer", inputs: ["errors", "showMessage"] }, { kind: "component", type: DropdownlistViewer, selector: "iss-viewer-dropdownlist" }, { kind: "component", type: FieldViewer, selector: "iss-field-viewer" }], viewProviders: [VIEW_PROVIDER] });
55
55
  }
56
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SelectField, decorators: [{
56
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownlistField, decorators: [{
57
57
  type: Component,
58
58
  args: [{
59
- selector: "iss-field-select",
59
+ selector: "iss-field-dropdownlist",
60
60
  viewProviders: [VIEW_PROVIDER],
61
61
  imports: [
62
62
  ReactiveFormsModule,
63
- SelectControl,
63
+ DropdownlistControl,
64
64
  ValidationMessage,
65
- SelectViewer,
65
+ DropdownlistViewer,
66
66
  FieldViewer
67
67
  ],
68
68
  template: `
69
69
  @if (field.visible()) {
70
70
  @if (field.mode() === "edit") {
71
- <iss-ctrl-select [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
71
+ <iss-ctrl-dropdownlist [formControlName]="field.name" [options]="field.options()" [multiple]="field.config.multiple()" [readonly]="field.config.readonly() ?? false" (onChange)="onChange($event)">
72
72
  <label>{{ field.label() }}</label>
73
- </iss-ctrl-select>
73
+ </iss-ctrl-dropdownlist>
74
74
  <iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
75
75
  } @else {
76
76
  <iss-field-viewer>
77
77
  <label>{{ field.label() }}</label>
78
- <iss-viewer-select [field]="field"/>
78
+ <iss-viewer-dropdownlist [field]="field"/>
79
79
  </iss-field-viewer>
80
80
  }
81
81
  }
@@ -83,5 +83,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
83
83
  }]
84
84
  }] });
85
85
 
86
- export { SelectField };
87
- //# sourceMappingURL=iss-ctrl-select.field-DoU4G_8t.mjs.map
86
+ export { DropdownlistField };
87
+ //# sourceMappingURL=iss-ctrl-dropdownlist.field-DikBAtc_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iss-ctrl-dropdownlist.field-DikBAtc_.mjs","sources":["../../../projects/iss/src/components/controls/dropdownlist/dropdownlist.field.ts"],"sourcesContent":["import { Component } from \"@angular/core\";\nimport { ReactiveFormsModule } from \"@angular/forms\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { ValidationMessage } from \"../../shared/validation-message\";\nimport { FieldBase } from \"../base/field-base\";\nimport { DropdownlistControl } from \"iss-ctrl/dropdownlist\";\nimport { DropdownlistViewer } from \"./dropdownlist.viewer\";\n\n/**\n * `<iss-field-dropdownlist>` — single or multiple selection from a dropdown.\n *\n * Rendered by the outlet for fields of type `dropdown_list`. In `edit` mode it renders\n * {@link DropdownlistControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `multiple` | `boolean` | Allows selecting more than one option. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n *\n * ### Other field members used\n * `label()` · `options()` · `ctrlJsonValue()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * The raw form value holds the selected option values; the resolved options are written\n * back to `field.ctrlJsonValue`.\n *\n * @example\n * ```json\n * { \"name\": \"city\", \"type\": \"dropdown_list\", \"label\": \"City\", \"options\": [{ \"value\": \"1\", \"label\": \"Riyadh\" }] }\n * ```\n */\n@Component({\n selector: \"iss-field-dropdownlist\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n DropdownlistControl,\n ValidationMessage,\n DropdownlistViewer,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <iss-ctrl-dropdownlist [formControlName]=\"field.name\" [options]=\"field.options()\" [multiple]=\"field.config.multiple()\" [readonly]=\"field.config.readonly() ?? false\" (onChange)=\"onChange($event)\">\n <label>{{ field.label() }}</label>\n </iss-ctrl-dropdownlist>\n <iss-validation-message-viewer [errors]=\"ctrl.errors\" [showMessage]=\"!ctrl.untouched\"/>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-dropdownlist [field]=\"field\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class DropdownlistField extends FieldBase {\n onChange($event: string | FormData) {\n this.field.ctrlJsonValue.set($event);\n }\n}\n"],"names":[],"mappings":";;;;;;;;AASA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;AA2BG,MAAO,iBAAkB,SAAQ,SAAS,CAAA;AAC9C,IAAA,QAAQ,CAAC,MAAyB,EAAA;QAChC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;IACtC;uGAHW,iBAAiB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhBlB;;;;;;;;;;;;;;AAcT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EApBC,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,mBAAmB,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,iBAAiB,EAAA,QAAA,EAAA,+BAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,kBAAkB,EAAA,QAAA,EAAA,yBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,WAAW,EAAA,QAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,aAAA,EANE,CAAC,aAAa,CAAC,EAAA,CAAA;;2FAwBnB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBA1B7B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,wBAAwB;oBAClC,aAAa,EAAE,CAAC,aAAa,CAAC;AAC9B,oBAAA,OAAO,EAAE;wBACP,mBAAmB;wBACnB,mBAAmB;wBACnB,iBAAiB;wBACjB,kBAAkB;wBAClB;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;AAcT,EAAA;AACF,iBAAA;;;;;"}
@@ -1,7 +1,7 @@
1
1
  import { CdkVirtualForOf, CdkVirtualScrollViewport, CdkFixedSizeVirtualScroll } from '@angular/cdk/scrolling';
2
2
  import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { signal, input, computed, output, contentChild, effect, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
4
+ import { inject, signal, input, computed, output, contentChild, effect, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
5
5
  import { toSignal } from '@angular/core/rxjs-interop';
6
6
  import * as i1 from '@angular/forms';
7
7
  import { ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
@@ -12,17 +12,18 @@ import { MatChipsModule } from '@angular/material/chips';
12
12
  import { MatIconModule } from '@angular/material/icon';
13
13
  import * as i3 from '@angular/material/input';
14
14
  import { MatInputModule } from '@angular/material/input';
15
- import { ControlBase, SelectStatusPipe } from 'iss-ctrl/base';
15
+ import { ControlBase, SelectStatusPipe, TranslatePipe } from 'iss-ctrl/base';
16
+ import { UI_LANGUAGE } from 'iss-ctrl/tokens';
16
17
 
17
18
  /**
18
- * `<iss-ctrl-select>` — dropdown selection, single or multiple, with a search box.
19
+ * `<iss-ctrl-dropdownlist>` — dropdown selection, single or multiple, with a search box.
19
20
  *
20
21
  * Typing in the search box emits `(onQueryChange)`, so options can be loaded remotely; set
21
22
  * `loading` while that request is in flight.
22
23
  *
23
24
  * @example
24
25
  * ```html
25
- * <iss-ctrl-select
26
+ * <iss-ctrl-dropdownlist
26
27
  * formControlName="city"
27
28
  * [options]="cities()"
28
29
  * [multiple]="false"
@@ -30,7 +31,7 @@ import { ControlBase, SelectStatusPipe } from 'iss-ctrl/base';
30
31
  * (onQueryChange)="search($event)"
31
32
  * >
32
33
  * <label>City</label>
33
- * </iss-ctrl-select>
34
+ * </iss-ctrl-dropdownlist>
34
35
  * ```
35
36
  *
36
37
  * ### Own inputs
@@ -48,10 +49,11 @@ import { ControlBase, SelectStatusPipe } from 'iss-ctrl/base';
48
49
  *
49
50
  * Projects `<label>` into the floating label; omit it to render the control without one.
50
51
  */
51
- class SelectControl extends ControlBase {
52
+ class DropdownlistControl extends ControlBase {
53
+ UI_LANGUAGE = inject(UI_LANGUAGE);
52
54
  selectedOptions = signal(new Map(), ...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
53
55
  /**
54
- * Selectable choices, each a `{ value, label }` pair. Required.
56
+ * Selectable choices, each a `{ value, title }` pair. Required.
55
57
  */
56
58
  options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
57
59
  /**
@@ -86,10 +88,18 @@ class SelectControl extends ControlBase {
86
88
  }, ...(ngDevMode ? [{ debugName: "#disabledEffectRef" }] : /* istanbul ignore next */ []));
87
89
  displayFn = (options) => {
88
90
  if (Array.isArray(options) && !this.multiple()) {
89
- return options[0]?.label;
91
+ return this.titleOf(options[0]);
90
92
  }
91
93
  return "";
92
94
  };
95
+ /** Resolves an option title to plain text for the active UI language. */
96
+ titleOf(option) {
97
+ const title = option?.title;
98
+ if (!title) {
99
+ return "";
100
+ }
101
+ return typeof title === "string" ? title : title[this.UI_LANGUAGE] ?? "";
102
+ }
93
103
  /*todo: add pagination for async options*/
94
104
  writeValue(value) {
95
105
  this.#reset();
@@ -194,7 +204,7 @@ class SelectControl extends ControlBase {
194
204
  }
195
205
  const query = queryString.toLowerCase();
196
206
  return this.options().filter((option) => {
197
- return (option.value.toLowerCase().includes(query) || option.label.toLowerCase().includes(query));
207
+ return (option.value.toLowerCase().includes(query) || this.titleOf(option).toLowerCase().includes(query));
198
208
  });
199
209
  }
200
210
  #emit() {
@@ -209,9 +219,9 @@ class SelectControl extends ControlBase {
209
219
  const selectedOptionsArr = Array.from(this.selectedOptions(), ([_, option]) => option);
210
220
  return selectedOptionsArr.length ? selectedOptionsArr : null;
211
221
  }
212
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SelectControl, deps: null, target: i0.ɵɵFactoryTarget.Component });
213
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: SelectControl, isStandalone: true, selector: "iss-ctrl-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onQueryChange: "onQueryChange" }, providers: [
214
- { provide: NG_VALUE_ACCESSOR, useExisting: SelectControl, multi: true },
222
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownlistControl, deps: null, target: i0.ɵɵFactoryTarget.Component });
223
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DropdownlistControl, isStandalone: true, selector: "iss-ctrl-dropdownlist", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onQueryChange: "onQueryChange" }, providers: [
224
+ { provide: NG_VALUE_ACCESSOR, useExisting: DropdownlistControl, multi: true },
215
225
  ], 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: `
216
226
  <mat-form-field floatLabel="auto" class="">
217
227
  <!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->
@@ -254,7 +264,7 @@ class SelectControl extends ControlBase {
254
264
  @if (optionTemplate()) {
255
265
  <ng-container *ngTemplateOutlet="optionTemplate(); context: { $implicit: option}"/>
256
266
  } @else {
257
- {{ option.label }}
267
+ {{ option?.title | translate }}
258
268
  }
259
269
  </mat-option>
260
270
  </cdk-virtual-scroll-viewport>
@@ -274,20 +284,20 @@ class SelectControl extends ControlBase {
274
284
  *ngTemplateOutlet="cardViewerTemplate(); context: { $implicit: chip[1]}"
275
285
  />
276
286
  } @else {
277
- {{ chip[1].label }}
287
+ {{ chip[1]?.title | translate }}
278
288
  }
279
- <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + chip[1].label">
289
+ <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + titleOf(chip[1])">
280
290
  <ds-icon icon="trash" class="fc-red"></ds-icon>
281
291
  </button>
282
292
  </mat-chip-row>
283
293
  }
284
294
  }
285
295
  </mat-chip-grid>
286
- `, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i4.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i4.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: SelectStatusPipe, name: "selectStatus" }] });
296
+ `, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i4.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i4.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: SelectStatusPipe, name: "selectStatus" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
287
297
  }
288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SelectControl, decorators: [{
298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownlistControl, decorators: [{
289
299
  type: Component,
290
- args: [{ selector: "iss-ctrl-select", imports: [
300
+ args: [{ selector: "iss-ctrl-dropdownlist", imports: [
291
301
  ReactiveFormsModule,
292
302
  MatAutocompleteModule,
293
303
  MatInputModule,
@@ -295,13 +305,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
295
305
  MatIconModule,
296
306
  NgClass,
297
307
  SelectStatusPipe,
308
+ TranslatePipe,
298
309
  CdkVirtualForOf,
299
310
  CdkVirtualScrollViewport,
300
311
  CdkFixedSizeVirtualScroll,
301
312
  NgStyle,
302
313
  NgTemplateOutlet,
303
314
  ], providers: [
304
- { provide: NG_VALUE_ACCESSOR, useExisting: SelectControl, multi: true },
315
+ { provide: NG_VALUE_ACCESSOR, useExisting: DropdownlistControl, multi: true },
305
316
  ], template: `
306
317
  <mat-form-field floatLabel="auto" class="">
307
318
  <!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->
@@ -344,7 +355,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
344
355
  @if (optionTemplate()) {
345
356
  <ng-container *ngTemplateOutlet="optionTemplate(); context: { $implicit: option}"/>
346
357
  } @else {
347
- {{ option.label }}
358
+ {{ option?.title | translate }}
348
359
  }
349
360
  </mat-option>
350
361
  </cdk-virtual-scroll-viewport>
@@ -364,9 +375,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
364
375
  *ngTemplateOutlet="cardViewerTemplate(); context: { $implicit: chip[1]}"
365
376
  />
366
377
  } @else {
367
- {{ chip[1].label }}
378
+ {{ chip[1]?.title | translate }}
368
379
  }
369
- <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + chip[1].label">
380
+ <button matChipRemove [disabled]="readonly()" [attr.aria-label]="'remove ' + titleOf(chip[1])">
370
381
  <ds-icon icon="trash" class="fc-red"></ds-icon>
371
382
  </button>
372
383
  </mat-chip-row>
@@ -376,12 +387,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
376
387
  `, schemas: [CUSTOM_ELEMENTS_SCHEMA] }]
377
388
  }], 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 }] }] } });
378
389
 
379
- // The select control. Its field and viewer stay in the primary entry point and reach it
390
+ // The dropdownlist control. Its field and viewer stay in the primary entry point and reach it
380
391
  // from there, so the control ships only to an app that renders it or imports it directly.
381
392
 
382
393
  /**
383
394
  * Generated bundle index. Do not edit.
384
395
  */
385
396
 
386
- export { SelectControl };
387
- //# sourceMappingURL=iss-ctrl-select.mjs.map
397
+ export { DropdownlistControl };
398
+ //# sourceMappingURL=iss-ctrl-dropdownlist.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iss-ctrl-dropdownlist.mjs","sources":["../../../projects/iss/dropdownlist/src/dropdownlist.control.ts","../../../projects/iss/dropdownlist/src/public-api.ts","../../../projects/iss/dropdownlist/src/iss-ctrl-dropdownlist.ts"],"sourcesContent":["import { CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualScrollViewport } from \"@angular/cdk/scrolling\";\nimport { NgClass, NgStyle, NgTemplateOutlet } from \"@angular/common\";\nimport { Component, computed, contentChild, CUSTOM_ELEMENTS_SCHEMA, effect, inject, input, InputSignal, OnDestroy, output, OutputEmitterRef, signal, Signal, WritableSignal } from \"@angular/core\";\nimport { toSignal } from \"@angular/core/rxjs-interop\";\nimport { NG_VALUE_ACCESSOR, ReactiveFormsModule } from \"@angular/forms\";\nimport { MatAutocompleteModule } from \"@angular/material/autocomplete\";\nimport { MatChipsModule } from \"@angular/material/chips\";\nimport { MatIconModule } from \"@angular/material/icon\";\nimport { MatInputModule } from \"@angular/material/input\";\nimport { ControlBase, I18n, Option, SelectStatusPipe, TranslatePipe } from \"iss-ctrl/base\";\nimport { UI_LANGUAGE } from \"iss-ctrl/tokens\";\n\n/**\n * `<iss-ctrl-dropdownlist>` — dropdown selection, single or multiple, with a search box.\n *\n * Typing in the search box emits `(onQueryChange)`, so options can be loaded remotely; set\n * `loading` while that request is in flight.\n *\n * @example\n * ```html\n * <iss-ctrl-dropdownlist\n * formControlName=\"city\"\n * [options]=\"cities()\"\n * [multiple]=\"false\"\n * [loading]=\"loading()\"\n * (onQueryChange)=\"search($event)\"\n * >\n * <label>City</label>\n * </iss-ctrl-dropdownlist>\n * ```\n *\n * ### Own inputs\n * | Property | Type | Default | Description |\n * | --- | --- | --- | --- |\n * | `options` | `Option[]` | **required** | The selectable choices. |\n * | `height` | `string` | `\"150px\"` | Max height of the open panel. |\n * | `loading` | `boolean` | `false` | Shows the loading state inside the panel. |\n *\n * ### Inherited from {@link ControlBase}\n * `formControlName` · `readonly` · `className` · `(onChange)` · `placeholder` · `multiple`\n *\n * ### Outputs\n * - `(onQueryChange)` — `string`, the current search text.\n *\n * Projects `<label>` into the floating label; omit it to render the control without one.\n */\n@Component({\n selector: \"iss-ctrl-dropdownlist\",\n imports: [\n ReactiveFormsModule,\n MatAutocompleteModule,\n MatInputModule,\n MatChipsModule,\n MatIconModule,\n NgClass,\n SelectStatusPipe,\n TranslatePipe,\n CdkVirtualForOf,\n CdkVirtualScrollViewport,\n CdkFixedSizeVirtualScroll,\n NgStyle,\n NgTemplateOutlet,\n ],\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: DropdownlistControl, multi: true },\n ],\n template: `\n <mat-form-field floatLabel=\"auto\" class=\"\">\n <!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->\n <mat-label class=\"fs-16 fc-dark-gray\">\n <ng-content select=\"label\"></ng-content>\n </mat-label>\n <input\n [formControl]=\"ctrl\"\n [matAutocomplete]=\"auto\"\n [matChipInputFor]=\"chipGrid\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [errorStateMatcher]=\"errorStateMatcher\"\n (blur)=\"markAsTouched()\"\n class=\"m-0\"\n matInput\n />\n @if (!disabled()) {\n @if (selectedOptions().size) {\n <span matSuffix class=\"sfi sfi-close fs-18 fc-black cursor-pointer\" (click)=\"clearSelection()\"></span>\n } @else {\n <span matSuffix class=\"sfi sfi-arrow-down fs-18 fc-black cursor-pointer\"></span>\n }\n }\n\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"captureValue($event)\" [displayWith]=\"displayFn\" autoActiveFirstOption hideSingleSelectionIndicator>\n @if (loading()) {\n <mat-option disabled=\"true\">\n <ds-icon icon=\"spinner\" class=\"spin fc-coral fs-20\"></ds-icon>\n </mat-option>\n } @else {\n @if (filteredOptions().length) {\n @if (multiple()) {\n <mat-option (click)=\"toggleAllSelection()\" value=\"_SELECT_ALL_OPTIONS_\">\n {{ allSelected() ? \"deselect all\" : \"Select All\" }}\n </mat-option>\n }\n <cdk-virtual-scroll-viewport itemSize=\"5\" [ngStyle]=\"{'height': height()}\">\n <mat-option *cdkVirtualFor=\"let option of filteredOptions()\" [value]=\"option\" [ngClass]=\"{'mdc-list-item__selected': option | selectStatus: selectedOptions()}\">\n @if (optionTemplate()) {\n <ng-container *ngTemplateOutlet=\"optionTemplate(); context: { $implicit: option}\"/>\n } @else {\n {{ option?.title | translate }}\n }\n </mat-option>\n </cdk-virtual-scroll-viewport>\n } @else {\n <mat-option disabled=\"true\">No Result Found</mat-option>\n }\n }\n </mat-autocomplete>\n </mat-form-field>\n\n <mat-chip-grid #chipGrid>\n @if (multiple()) {\n @for (chip of selectedOptions(); track chip[0]) {\n <mat-chip-row (removed)=\"removeFromSelectedOptionsMap(chip[1])\">\n @if (cardViewerTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"cardViewerTemplate(); context: { $implicit: chip[1]}\"\n />\n } @else {\n {{ chip[1]?.title | translate }}\n }\n <button matChipRemove [disabled]=\"readonly()\" [attr.aria-label]=\"'remove ' + titleOf(chip[1])\">\n <ds-icon icon=\"trash\" class=\"fc-red\"></ds-icon>\n </button>\n </mat-chip-row>\n }\n }\n </mat-chip-grid>\n `,\n styles: `\n ::ng-deep {\n .mat-mdc-option.mdc-list-item__selected:not(.mdc-list-item--disabled) .mdc-list-item__primary-text {\n --mat-option-selected-state-label-text-color: var(--green);\n color: var(--green);\n }\n }\n `,\n schemas: [CUSTOM_ELEMENTS_SCHEMA]\n})\nexport class DropdownlistControl extends ControlBase implements OnDestroy {\n UI_LANGUAGE = inject(UI_LANGUAGE);\n selectedOptions: WritableSignal<Map<string, Option>> = signal(new Map<string, Option>());\n /**\n * Selectable choices, each a `{ value, title }` pair. Required.\n */\n options: InputSignal<Option[]> = input.required();\n /**\n * Maximum height of the open options panel, as a CSS length.\n */\n height: InputSignal<string> = input(\"150px\");\n query: Signal<string> = toSignal(this.ctrl.valueChanges);\n readonly filteredOptions: Signal<Option[]> = computed(() => this.#filter(this.query()));\n /**\n * Shows the loading state inside the panel while options are being fetched.\n */\n loading: InputSignal<boolean> = input(false);\n /**\n * Emits the search text so the host can load matching options.\n */\n onQueryChange: OutputEmitterRef<string> = output();\n protected optionTemplate: any = contentChild(\"optionTemplate\");\n protected cardViewerTemplate: any = contentChild(\"cardViewerTemplate\");\n protected allSelected: WritableSignal<boolean> = signal(false);\n #queryEffectRef = effect(() => {\n if (typeof this.query() === \"string\") {\n this.onQueryChange.emit(this.query());\n }\n });\n #disabledEffectRef = effect(() => {\n if (this.disabled()) {\n this.ctrl.disable();\n } else {\n this.ctrl.enable();\n }\n });\n\n displayFn = (options: Option | Option[]): string => {\n if (Array.isArray(options) && !this.multiple()) {\n return this.titleOf(options[0]);\n }\n return \"\";\n };\n\n /** Resolves an option title to plain text for the active UI language. */\n titleOf(option: Option | undefined): string {\n const title = option?.title;\n if (!title) {\n return \"\";\n }\n return typeof title === \"string\" ? title : title[this.UI_LANGUAGE as keyof I18n] ?? \"\";\n }\n\n /*todo: add pagination for async options*/\n\n override writeValue(value: string | null) {\n this.#reset();\n if (value === null || value === undefined) {\n return;\n }\n const values: string[] = value.split(\",\").map(val => val.trim());\n let selectedOptions: Option[] = this.options().filter((option: Option) => values.includes(option.value));\n if (!this.multiple()) {\n // single selection mode, only the first matching option is honoured\n selectedOptions = selectedOptions.slice(0, 1);\n }\n const next: Map<string, Option> = new Map<string, Option>();\n for (let i = 0; i < selectedOptions.length; i++) {\n const val: Option = selectedOptions[i];\n next.set(val.value, val);\n }\n this.selectedOptions.set(next);\n this.ctrl.setValue(selectedOptions);\n }\n\n captureValue($event: any) {\n if (this.readonly()) {\n return;\n }\n if ($event?.option.value === \"_SELECT_ALL_OPTIONS_\") {\n return;\n }\n this.#addToSelectedOptionsMap($event?.option.value);\n this.#emit();\n }\n\n removeFromSelectedOptionsMap(option: Option) {\n if (this.readonly()) {\n return;\n }\n this.selectedOptions.update((selected: Map<string, Option>) => {\n const next: Map<string, Option> = new Map(selected);\n next.delete(option.value);\n return next;\n });\n this.allSelected.set(false);\n this.#emit();\n }\n\n clearSelection() {\n if (this.readonly()) {\n return;\n }\n this.#reset();\n this.allSelected.set(false);\n this.#emit();\n }\n\n toggleAllSelection() {\n if (this.readonly()) {\n return;\n }\n if (this.selectedOptions().size === this.options().length) {\n this.#reset();\n this.#emit();\n this.allSelected.set(false);\n return;\n }\n const next: Map<string, Option> = new Map<string, Option>();\n for (let i = 0; i < this.options().length; i++) {\n const option: Option = this.options()[i];\n next.set(option.value, option);\n }\n this.selectedOptions.set(next);\n this.ctrl.setValue(this.#convertSelectedMapToArray());\n this.allSelected.set(true);\n this.#emit();\n }\n\n ngOnDestroy(): void {\n this.#queryEffectRef.destroy();\n this.#disabledEffectRef.destroy();\n }\n\n // the selection is the value here; `ctrl` doubles as the autocomplete's search box, so while\n // the user is typing a query it holds that string rather than the chosen options.\n protected override isEmpty(): boolean {\n return this.selectedOptions().size === 0;\n }\n\n #addToSelectedOptionsMap(option: any) {\n if (option) {\n const selectedOption = option;\n this.selectedOptions.update((selected: Map<string, Option>) => {\n // single selection replaces the map instead of adding to it\n const next: Map<string, Option> = this.multiple() ? new Map(selected) : new Map<string, Option>();\n next.set(selectedOption.value, selectedOption);\n return next;\n });\n this.ctrl.setValue(this.#convertSelectedMapToArray());\n }\n }\n\n #stringifySelectedOptions(): string | null {\n const selectedOptionsArr: Option[] | null = this.#convertSelectedMapToArray();\n if (selectedOptionsArr) {\n return selectedOptionsArr.map((o) => o.value).join();\n }\n return null;\n }\n\n #filter(queryString: string | Option): Option[] {\n if (queryString === null || queryString === undefined || typeof queryString !== \"string\") {\n return this.options();\n }\n const query: string = queryString.toLowerCase();\n return this.options().filter((option: Option) => {\n return (option.value.toLowerCase().includes(query) || this.titleOf(option).toLowerCase().includes(query));\n });\n }\n\n #emit() {\n this.propagateValue(this.#stringifySelectedOptions());\n this.emitOnChangeEvent(this.#convertSelectedMapToArray());\n }\n\n #reset() {\n this.selectedOptions.set(new Map<string, Option>());\n this.ctrl.setValue(null);\n }\n\n #convertSelectedMapToArray(): Option[] | null {\n const selectedOptionsArr: Option[] = Array.from(this.selectedOptions(), ([_, option]) => option);\n return selectedOptionsArr.length ? selectedOptionsArr : null;\n }\n}\n","// The dropdownlist control. Its field and viewer stay in the primary entry point and reach it\n// from there, so the control ships only to an app that renders it or imports it directly.\n\nexport * from \"./dropdownlist.control\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -2,9 +2,9 @@ import * as i0 from '@angular/core';
2
2
  import { Component } from '@angular/core';
3
3
  import { ViewerBase } from 'iss-ctrl/base';
4
4
 
5
- class SelectViewer extends ViewerBase {
6
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SelectViewer, deps: null, target: i0.ɵɵFactoryTarget.Component });
7
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: SelectViewer, isStandalone: true, selector: "iss-viewer-select", usesInheritance: true, ngImport: i0, template: `
5
+ class DropdownlistViewer extends ViewerBase {
6
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownlistViewer, deps: null, target: i0.ɵɵFactoryTarget.Component });
7
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DropdownlistViewer, isStandalone: true, selector: "iss-viewer-dropdownlist", usesInheritance: true, ngImport: i0, template: `
8
8
  <p>
9
9
  @for (item of field().ctrlJsonValue(); track item?.value; let last = $last) {
10
10
  <span>{{ item.label }} {{ last ? '' : ', ' }}</span>
@@ -12,10 +12,10 @@ class SelectViewer extends ViewerBase {
12
12
  </p>
13
13
  `, isInline: true });
14
14
  }
15
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SelectViewer, decorators: [{
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownlistViewer, decorators: [{
16
16
  type: Component,
17
17
  args: [{
18
- selector: "iss-viewer-select",
18
+ selector: "iss-viewer-dropdownlist",
19
19
  template: `
20
20
  <p>
21
21
  @for (item of field().ctrlJsonValue(); track item?.value; let last = $last) {
@@ -26,5 +26,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
26
26
  }]
27
27
  }] });
28
28
 
29
- export { SelectViewer };
30
- //# sourceMappingURL=iss-ctrl-select.viewer-Dv9M-lG-.mjs.map
29
+ export { DropdownlistViewer };
30
+ //# sourceMappingURL=iss-ctrl-dropdownlist.viewer-OWJxDpr8.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iss-ctrl-dropdownlist.viewer-OWJxDpr8.mjs","sources":["../../../projects/iss/src/components/controls/dropdownlist/dropdownlist.viewer.ts"],"sourcesContent":["import { Component } from \"@angular/core\";\nimport { ViewerBase } from \"iss-ctrl/base\";\n\n@Component({\n selector: \"iss-viewer-dropdownlist\",\n template: `\n <p>\n @for (item of field().ctrlJsonValue(); track item?.value; let last = $last) {\n <span>{{ item.label }} {{ last ? '' : ', ' }}</span>\n }\n </p>\n `,\n})\nexport class DropdownlistViewer extends ViewerBase {}\n"],"names":[],"mappings":";;;;AAaM,MAAO,kBAAmB,SAAQ,UAAU,CAAA;uGAArC,kBAAkB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EARnB;;;;;;AAMT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA;;2FAEU,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAV9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,yBAAyB;AACnC,oBAAA,QAAQ,EAAE;;;;;;AAMT,EAAA,CAAA;AACF,iBAAA;;;;;"}
@@ -5,7 +5,7 @@ import * as i1 from '@angular/forms';
5
5
  import { FormControl, ReactiveFormsModule } from '@angular/forms';
6
6
  import { MatLabel } from '@angular/material/input';
7
7
  import { catchError, EMPTY } from 'rxjs';
8
- import { F as FieldBase, c as FileHandler, V as VIEW_PROVIDER, a as ValidationMessage, b as FieldViewer } from './iss-ctrl-iss-ctrl-DvnkwSMG.mjs';
8
+ import { F as FieldBase, c as FileHandler, V as VIEW_PROVIDER, a as ValidationMessage, b as FieldViewer } from './iss-ctrl-iss-ctrl-BG-QWWdq.mjs';
9
9
  import { AttachmentViewer } from './iss-ctrl-attachment.viewer-DVUL39xd.mjs';
10
10
  import { FilePickerControl } from 'iss-ctrl/file-picker';
11
11
 
@@ -207,4 +207,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
207
207
  }] });
208
208
 
209
209
  export { FilePickerField };
210
- //# sourceMappingURL=iss-ctrl-file-picker.field-CbepZaX6.mjs.map
210
+ //# sourceMappingURL=iss-ctrl-file-picker.field-BMZaJxvj.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"iss-ctrl-file-picker.field-CbepZaX6.mjs","sources":["../../../projects/iss/src/components/controls/file-picker/file-picker.field.ts"],"sourcesContent":["import { Component, computed, effect, inject, OnDestroy, Signal, signal, WritableSignal, } from \"@angular/core\";\nimport { takeUntilDestroyed } from \"@angular/core/rxjs-interop\";\nimport { FormControl, ReactiveFormsModule } from \"@angular/forms\";\nimport { MatLabel } from \"@angular/material/input\";\nimport { catchError, EMPTY } from \"rxjs\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { ValidationMessage } from \"../../shared/validation-message\";\nimport { FieldBase } from \"../base/field-base\";\nimport { IssAttachment } from \"iss-ctrl/tokens\";\nimport { AttachmentViewer } from \"./attachment.viewer\";\nimport { IssFile } from \"iss-ctrl/file-picker\";\nimport { FileHandler } from \"./file-handler\";\nimport { FilePickerControl } from \"iss-ctrl/file-picker\";\n\n/**\n * `<iss-field-file-picker>` — attachment upload.\n *\n * Rendered by the outlet for fields of type `attachment`. In `edit` mode it renders\n * {@link FilePickerControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `multiple` | `boolean` | Allows attaching more than one file. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n *\n * ### Other field members used\n * `label()` · `value` · `validation` · `ctrlJsonValue()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * The field uploads the picked files itself, stores the returned ids as the control value\n * and keeps the resolved attachments in `field.ctrlJsonValue`.\n *\n * Accepted extensions come from the `fileType` **validation** rule, not from `config`; the\n * `allowedFileSize`, `allowedFileTypes`, `minFilesCount`, `maxFilesCount`, `templateId` and\n * `templateUrl` config keys exist on {@link FieldConfig} but are not read here yet.\n *\n * @example\n * ```json\n * { \"name\": \"attachments\", \"type\": \"attachment\", \"label\": \"Attachments\", \"config\": { \"multiple\": true }, \"validation\": { \"fileType\": [\"pdf\", \"png\"] } }\n * ```\n */\n@Component({\n selector: \"iss-field-file-picker\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n FilePickerControl,\n ValidationMessage,\n AttachmentViewer,\n MatLabel,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <mat-label>{{ field.label() }}</mat-label>\n <input type=\"hidden\" [formControlName]=\"field.name\">\n <!-- [showDeleteButton]=\"field.config.showDeleteButton\" [showDownloadButton]=\"field.config.showDownloadButton\"-->\n <iss-ctrl-file-picker\n [formControl]=\"picker\"\n [accept]=\"accept\"\n (onChange)=\"captureFile($event)\"\n [multiple]=\"field.config.multiple()\"\n [readonly]=\"field.config.readonly() ?? false\"\n [uploading]=\"uploading()\"\n [uploadedFiles]=\"attachments()\"\n [uploadingError]=\"uploadingError()\"\n />\n <iss-validation-message-viewer [errors]=\"ctrl.errors\" [showMessage]=\"ctrl.touched\"/>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-attachment [uploading]=\"uploading()\" [field]=\"viewField()\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class FilePickerField extends FieldBase implements OnDestroy {\n picker = new FormControl();\n fileHandlerService = inject(FileHandler);\n uploading: WritableSignal<boolean> = signal(false);\n viewField: Signal<any> = computed(() => this.#generateViewField(this.field.ctrlJsonValue()));\n attachments: WritableSignal<IssAttachment[]> = signal([]);\n uploadingError = signal<string | undefined>(undefined);\n accept: string = this.#acceptFactory();\n // the ids the picker already holds files for; without it the effect would re-download\n // the very files captureFile just uploaded, since it writes them back into ctrl\n #hydratedValue: string | null = null;\n #valueEffect = effect(() => {\n const value = this.ctrlValueChange();\n if (!value || !this.field.value || value === this.#hydratedValue) {\n return;\n }\n\n this.#hydratedValue = value;\n this.fileHandlerService.fetchFiles(value)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((res: any) => {\n const filesOnly = res.map((attachment: any) => attachment.file);\n const formDataValue: FormData | null = this.fileHandlerService.formDataFactory(filesOnly, !!this.field.config.multiple());\n this.attachments.set(res);\n this.picker.setValue(formDataValue);\n this.field.ctrlJsonValue.set(res);\n });\n });\n\n captureFile(formData: FormData | null) {\n if (!formData) {\n return;\n }\n\n this.uploading.set(true);\n const notUploadedFiles: FormData = this.#getNotUploadedFiles(formData);\n if (this.fileHandlerService.formDataHasValue(notUploadedFiles)) {\n this.fileHandlerService.upload(notUploadedFiles).pipe(\n catchError((err) => {\n this.uploading.set(false);\n this.uploadingError.set(err?.message ?? \"Uploading Failed!\");\n console.error(err);\n return EMPTY;\n }),\n ).subscribe((res: any) => {\n this.attachments.update((attachments: IssAttachment[]): IssAttachment[] => {\n if (!this.field.config.multiple()) {\n return res;\n }\n return [...attachments, ...res];\n });\n const stringifiedValue = this.stringifyIssAttachment(this.attachments());\n this.#hydratedValue = stringifiedValue;\n this.ctrl.setValue(stringifiedValue);\n this.field.ctrlJsonValue.set(this.attachments());\n this.uploading.set(false);\n });\n } else {\n this.uploading.set(false);\n }\n }\n\n stringifyIssAttachment(attachments: IssAttachment[]): string {\n return attachments.map((attachment: IssAttachment) => attachment.id).join(\",\");\n }\n\n override ngOnDestroy() {\n super.ngOnDestroy();\n this.#valueEffect.destroy();\n }\n\n // The accepted extensions are the `fileType` rule's own value, the same one its validator is\n // built from — a list, or the comma-separated string an older definition wrote it as.\n #acceptFactory(): string {\n const extensions: any = this.field.validation?.[\"fileType\"];\n if (!extensions) {\n return \"\";\n }\n const list: string[] = Array.isArray(extensions) ? extensions : String(extensions).split(\",\");\n return list\n .map((extension: string) => extension.trim())\n .filter((extension: string) => !!extension)\n .map((extension: string) => extension.startsWith(\".\") ? extension : `.${extension}`)\n .join(\",\");\n }\n\n #generateViewField(value: IssFile[]) {\n return {\n config: {\n showDownloadButton: true,\n showDeleteButton: false\n },\n ctrlJsonValue: signal(value ?? [])\n };\n }\n\n #getNotUploadedFiles(formData: FormData): FormData {\n const fd: FormData = new FormData();\n if (formData) {\n for (const pair of formData.entries()) {\n const file: IssFile = pair[1] as unknown as IssFile;\n if (!file.id) {\n fd.append(pair[0], pair[1]);\n }\n }\n }\n return fd;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"iss-ctrl-file-picker.field-BMZaJxvj.mjs","sources":["../../../projects/iss/src/components/controls/file-picker/file-picker.field.ts"],"sourcesContent":["import { Component, computed, effect, inject, OnDestroy, Signal, signal, WritableSignal, } from \"@angular/core\";\nimport { takeUntilDestroyed } from \"@angular/core/rxjs-interop\";\nimport { FormControl, ReactiveFormsModule } from \"@angular/forms\";\nimport { MatLabel } from \"@angular/material/input\";\nimport { catchError, EMPTY } from \"rxjs\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { ValidationMessage } from \"../../shared/validation-message\";\nimport { FieldBase } from \"../base/field-base\";\nimport { IssAttachment } from \"iss-ctrl/tokens\";\nimport { AttachmentViewer } from \"./attachment.viewer\";\nimport { IssFile } from \"iss-ctrl/file-picker\";\nimport { FileHandler } from \"./file-handler\";\nimport { FilePickerControl } from \"iss-ctrl/file-picker\";\n\n/**\n * `<iss-field-file-picker>` — attachment upload.\n *\n * Rendered by the outlet for fields of type `attachment`. In `edit` mode it renders\n * {@link FilePickerControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `multiple` | `boolean` | Allows attaching more than one file. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n *\n * ### Other field members used\n * `label()` · `value` · `validation` · `ctrlJsonValue()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * The field uploads the picked files itself, stores the returned ids as the control value\n * and keeps the resolved attachments in `field.ctrlJsonValue`.\n *\n * Accepted extensions come from the `fileType` **validation** rule, not from `config`; the\n * `allowedFileSize`, `allowedFileTypes`, `minFilesCount`, `maxFilesCount`, `templateId` and\n * `templateUrl` config keys exist on {@link FieldConfig} but are not read here yet.\n *\n * @example\n * ```json\n * { \"name\": \"attachments\", \"type\": \"attachment\", \"label\": \"Attachments\", \"config\": { \"multiple\": true }, \"validation\": { \"fileType\": [\"pdf\", \"png\"] } }\n * ```\n */\n@Component({\n selector: \"iss-field-file-picker\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n FilePickerControl,\n ValidationMessage,\n AttachmentViewer,\n MatLabel,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <mat-label>{{ field.label() }}</mat-label>\n <input type=\"hidden\" [formControlName]=\"field.name\">\n <!-- [showDeleteButton]=\"field.config.showDeleteButton\" [showDownloadButton]=\"field.config.showDownloadButton\"-->\n <iss-ctrl-file-picker\n [formControl]=\"picker\"\n [accept]=\"accept\"\n (onChange)=\"captureFile($event)\"\n [multiple]=\"field.config.multiple()\"\n [readonly]=\"field.config.readonly() ?? false\"\n [uploading]=\"uploading()\"\n [uploadedFiles]=\"attachments()\"\n [uploadingError]=\"uploadingError()\"\n />\n <iss-validation-message-viewer [errors]=\"ctrl.errors\" [showMessage]=\"ctrl.touched\"/>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-attachment [uploading]=\"uploading()\" [field]=\"viewField()\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class FilePickerField extends FieldBase implements OnDestroy {\n picker = new FormControl();\n fileHandlerService = inject(FileHandler);\n uploading: WritableSignal<boolean> = signal(false);\n viewField: Signal<any> = computed(() => this.#generateViewField(this.field.ctrlJsonValue()));\n attachments: WritableSignal<IssAttachment[]> = signal([]);\n uploadingError = signal<string | undefined>(undefined);\n accept: string = this.#acceptFactory();\n // the ids the picker already holds files for; without it the effect would re-download\n // the very files captureFile just uploaded, since it writes them back into ctrl\n #hydratedValue: string | null = null;\n #valueEffect = effect(() => {\n const value = this.ctrlValueChange();\n if (!value || !this.field.value || value === this.#hydratedValue) {\n return;\n }\n\n this.#hydratedValue = value;\n this.fileHandlerService.fetchFiles(value)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((res: any) => {\n const filesOnly = res.map((attachment: any) => attachment.file);\n const formDataValue: FormData | null = this.fileHandlerService.formDataFactory(filesOnly, !!this.field.config.multiple());\n this.attachments.set(res);\n this.picker.setValue(formDataValue);\n this.field.ctrlJsonValue.set(res);\n });\n });\n\n captureFile(formData: FormData | null) {\n if (!formData) {\n return;\n }\n\n this.uploading.set(true);\n const notUploadedFiles: FormData = this.#getNotUploadedFiles(formData);\n if (this.fileHandlerService.formDataHasValue(notUploadedFiles)) {\n this.fileHandlerService.upload(notUploadedFiles).pipe(\n catchError((err) => {\n this.uploading.set(false);\n this.uploadingError.set(err?.message ?? \"Uploading Failed!\");\n console.error(err);\n return EMPTY;\n }),\n ).subscribe((res: any) => {\n this.attachments.update((attachments: IssAttachment[]): IssAttachment[] => {\n if (!this.field.config.multiple()) {\n return res;\n }\n return [...attachments, ...res];\n });\n const stringifiedValue = this.stringifyIssAttachment(this.attachments());\n this.#hydratedValue = stringifiedValue;\n this.ctrl.setValue(stringifiedValue);\n this.field.ctrlJsonValue.set(this.attachments());\n this.uploading.set(false);\n });\n } else {\n this.uploading.set(false);\n }\n }\n\n stringifyIssAttachment(attachments: IssAttachment[]): string {\n return attachments.map((attachment: IssAttachment) => attachment.id).join(\",\");\n }\n\n override ngOnDestroy() {\n super.ngOnDestroy();\n this.#valueEffect.destroy();\n }\n\n // The accepted extensions are the `fileType` rule's own value, the same one its validator is\n // built from — a list, or the comma-separated string an older definition wrote it as.\n #acceptFactory(): string {\n const extensions: any = this.field.validation?.[\"fileType\"];\n if (!extensions) {\n return \"\";\n }\n const list: string[] = Array.isArray(extensions) ? extensions : String(extensions).split(\",\");\n return list\n .map((extension: string) => extension.trim())\n .filter((extension: string) => !!extension)\n .map((extension: string) => extension.startsWith(\".\") ? extension : `.${extension}`)\n .join(\",\");\n }\n\n #generateViewField(value: IssFile[]) {\n return {\n config: {\n showDownloadButton: true,\n showDeleteButton: false\n },\n ctrlJsonValue: signal(value ?? [])\n };\n }\n\n #getNotUploadedFiles(formData: FormData): FormData {\n const fd: FormData = new FormData();\n if (formData) {\n for (const pair of formData.entries()) {\n const file: IssFile = pair[1] as unknown as IssFile;\n if (!file.id) {\n fd.append(pair[0], pair[1]);\n }\n }\n }\n return fd;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -66,7 +66,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
66
66
  * ### Inherited from {@link ControlBase}
67
67
  * `formControlName` · `readonly` · `className` · `(onChange)` · `multiple` · `hints`
68
68
  *
69
- * Does not project a label the field label is rendered by the wrapping `iss-field-*`.
69
+ * Projects a `<label>` above the control the wrapping `iss-field-*` passes the field label in that way.
70
70
  */
71
71
  class FilePickerControl extends ControlBase {
72
72
  /**
@@ -215,6 +215,7 @@ class FilePickerControl extends ControlBase {
215
215
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: FilePickerControl, isStandalone: true, selector: "iss-ctrl-file-picker", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, showDownloadButton: { classPropertyName: "showDownloadButton", publicName: "showDownloadButton", isSignal: true, isRequired: false, transformFunction: null }, showDeleteButton: { classPropertyName: "showDeleteButton", publicName: "showDeleteButton", isSignal: true, isRequired: false, transformFunction: null }, uploading: { classPropertyName: "uploading", publicName: "uploading", isSignal: true, isRequired: false, transformFunction: null }, uploadedFiles: { classPropertyName: "uploadedFiles", publicName: "uploadedFiles", isSignal: true, isRequired: false, transformFunction: null }, uploadingError: { classPropertyName: "uploadingError", publicName: "uploadingError", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
216
216
  { provide: NG_VALUE_ACCESSOR, useExisting: FilePickerControl, multi: true }
217
217
  ], usesInheritance: true, ngImport: i0, template: `
218
+ <ng-content select="label"></ng-content>
218
219
  <ds-file-picker (click)="openFilePicker(inputFile)" (onDrop)="captureFile($event)" droppable>
219
220
  <input
220
221
  #inputFile
@@ -242,6 +243,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
242
243
  ], providers: [
243
244
  { provide: NG_VALUE_ACCESSOR, useExisting: FilePickerControl, multi: true }
244
245
  ], template: `
246
+ <ng-content select="label"></ng-content>
245
247
  <ds-file-picker (click)="openFilePicker(inputFile)" (onDrop)="captureFile($event)" droppable>
246
248
  <input
247
249
  #inputFile