@pega/custom-dx-components 26.1.11 → 26.1.12-alpha.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/README.md +6 -2
  2. package/package.json +48 -64
  3. package/src/ai/README.md +44 -0
  4. package/src/ai/catalog/README.md +133 -0
  5. package/src/ai/catalog/best-practices/README.md +24 -0
  6. package/src/ai/catalog/best-practices/accessibility-for-async-components.md +53 -0
  7. package/src/ai/catalog/best-practices/error-handling-and-resiliency.md +116 -0
  8. package/src/ai/catalog/best-practices/genai-assistant-integration-patterns.md +49 -0
  9. package/src/ai/catalog/best-practices/performance-and-efficiency.md +109 -0
  10. package/src/ai/catalog/best-practices/security-considerations.md +93 -0
  11. package/src/ai/catalog/best-practices/testing-pconnect-components.md +245 -0
  12. package/src/ai/catalog/best-practices/troubleshooting-common-pitfalls.md +132 -0
  13. package/src/ai/catalog/pconnect-assignment-lifecycle/SKILL.md +44 -0
  14. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/README.md +39 -0
  15. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/approval-workflow-decision.md +47 -0
  16. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/attachment-upload.md +45 -0
  17. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/bulk-action-submit.md +50 -0
  18. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/confirm-before-destructive-action.md +43 -0
  19. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/create-and-stage-new-case.md +45 -0
  20. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/graceful-submit-failure.md +39 -0
  21. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/modal-assignment-submit.md +58 -0
  22. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/multi-step-wizard.md +44 -0
  23. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/resolve-or-ignore-duplicate.md +47 -0
  24. package/src/ai/catalog/pconnect-assignment-lifecycle/cookbooks/safe-case-deletion.md +36 -0
  25. package/src/ai/catalog/pconnect-case-collaboration/SKILL.md +42 -0
  26. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/README.md +36 -0
  27. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/look-up-user-details.md +43 -0
  28. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/manage-case-attachments.md +51 -0
  29. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/manage-case-participants.md +52 -0
  30. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/participant-and-follower.md +40 -0
  31. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/post-and-manage-feed.md +50 -0
  32. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/relate-cases.md +35 -0
  33. package/src/ai/catalog/pconnect-case-collaboration/cookbooks/tag-case-and-find-related.md +44 -0
  34. package/src/ai/catalog/pconnect-data-subscriptions/SKILL.md +42 -0
  35. package/src/ai/catalog/pconnect-data-subscriptions/cookbooks/README.md +35 -0
  36. package/src/ai/catalog/pconnect-data-subscriptions/cookbooks/data-page-subscription-cleanup.md +41 -0
  37. package/src/ai/catalog/pconnect-data-subscriptions/cookbooks/publish-and-subscribe-events.md +40 -0
  38. package/src/ai/catalog/pconnect-data-subscriptions/cookbooks/pubsub-cleanup.md +38 -0
  39. package/src/ai/catalog/pconnect-data-subscriptions/cookbooks/query-paginated-list-data.md +44 -0
  40. package/src/ai/catalog/pconnect-data-subscriptions/cookbooks/realtime-case-subscription.md +46 -0
  41. package/src/ai/catalog/pconnect-data-subscriptions/cookbooks/refresh-and-update-data.md +41 -0
  42. package/src/ai/catalog/pconnect-forms-and-fields/SKILL.md +44 -0
  43. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/README.md +36 -0
  44. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/autosave-tracking.md +45 -0
  45. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/cascading-dependent-fields.md +51 -0
  46. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/collect-form-changes-for-manual-save.md +45 -0
  47. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/custom-field-validators.md +44 -0
  48. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/discard-changes-and-reset-form.md +41 -0
  49. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/full-form-validation.md +38 -0
  50. package/src/ai/catalog/pconnect-forms-and-fields/cookbooks/persist-widget-ui-state.md +41 -0
  51. package/src/ai/catalog/pconnect-lists-and-views/SKILL.md +44 -0
  52. package/src/ai/catalog/pconnect-lists-and-views/cookbooks/README.md +35 -0
  53. package/src/ai/catalog/pconnect-lists-and-views/cookbooks/activate-and-switch-container-items.md +52 -0
  54. package/src/ai/catalog/pconnect-lists-and-views/cookbooks/container-item-lifecycle.md +61 -0
  55. package/src/ai/catalog/pconnect-lists-and-views/cookbooks/insert-delete-list-rows.md +40 -0
  56. package/src/ai/catalog/pconnect-lists-and-views/cookbooks/reorder-list-rows.md +39 -0
  57. package/src/ai/catalog/pconnect-lists-and-views/cookbooks/repeating-row-edit.md +39 -0
  58. package/src/ai/catalog/pconnect-lists-and-views/cookbooks/view-personalization.md +60 -0
  59. package/src/ai/catalog/pconnect-navigation-locale-genai/SKILL.md +45 -0
  60. package/src/ai/catalog/pconnect-navigation-locale-genai/cookbooks/README.md +35 -0
  61. package/src/ai/catalog/pconnect-navigation-locale-genai/cookbooks/agent-conversation-for-tasks.md +54 -0
  62. package/src/ai/catalog/pconnect-navigation-locale-genai/cookbooks/bookmarkable-filter-state.md +40 -0
  63. package/src/ai/catalog/pconnect-navigation-locale-genai/cookbooks/deep-link-semantic-url.md +39 -0
  64. package/src/ai/catalog/pconnect-navigation-locale-genai/cookbooks/genai-assistant-conversation.md +43 -0
  65. package/src/ai/catalog/pconnect-navigation-locale-genai/cookbooks/locale-switch-and-relocalize.md +38 -0
  66. package/src/ai/catalog/pconnect-navigation-locale-genai/cookbooks/persist-operator-preferences.md +40 -0
  67. package/src/ai/catalog/references/architecture-overview.md +52 -0
  68. package/src/ai/catalog/references/pconnect-actions-api.md +948 -0
  69. package/src/ai/catalog/references/pconnect-case-info-data-info-localization.md +618 -0
  70. package/src/ai/catalog/references/pconnect-case-validation-utilities.md +238 -0
  71. package/src/ai/catalog/references/pconnect-container-manager.md +215 -0
  72. package/src/ai/catalog/references/pconnect-list-actions.md +250 -0
  73. package/src/ai/catalog/references/pconnect-misc-suggestions-creation.md +231 -0
  74. package/src/ai/catalog/references/pconnect-reference-context-component.md +471 -0
  75. package/src/ai/catalog/references/pconnect-state-config.md +316 -0
  76. package/src/ai/catalog/references/pconnect-validation-api.md +45 -0
  77. package/src/ai/catalog/references/pcore-analytics-genai-details.md +50 -0
  78. package/src/ai/catalog/references/pcore-bootstrap-init-details.md +121 -0
  79. package/src/ai/catalog/references/pcore-bootstrap-registry-routing.md +253 -0
  80. package/src/ai/catalog/references/pcore-case-collaboration-details.md +191 -0
  81. package/src/ai/catalog/references/pcore-case-collaboration-genai.md +264 -0
  82. package/src/ai/catalog/references/pcore-environment-info-details.md +96 -0
  83. package/src/ai/catalog/references/pcore-environment-locale-namespace.md +175 -0
  84. package/src/ai/catalog/references/pcore-messaging-details.md +99 -0
  85. package/src/ai/catalog/references/pcore-misc-details.md +207 -0
  86. package/src/ai/catalog/references/pcore-misc-utilities.md +325 -0
  87. package/src/ai/catalog/references/pcore-rest-data-details.md +164 -0
  88. package/src/ai/catalog/references/pcore-rest-data-messaging.md +308 -0
  89. package/src/ai/catalog/references/pcore-store-context-details.md +40 -0
  90. package/src/ai/catalog/references/pcore-store-context-state.md +130 -0
  91. package/src/ai/index.js +154 -0
  92. package/src/ai/project/.claude/skills/boolean/SKILL.md +43 -0
  93. package/src/ai/project/.claude/skills/case/SKILL.md +58 -0
  94. package/src/ai/project/.claude/skills/create-dx-component/SKILL.md +98 -0
  95. package/src/ai/project/.claude/skills/create-dx-component/assets/PConnProps.d.ts +24 -0
  96. package/src/ai/project/.claude/skills/create-dx-component/assets/create-nonce.ts +5 -0
  97. package/src/ai/project/.claude/skills/create-dx-component/assets/event-utils.ts +18 -0
  98. package/src/ai/project/.claude/skills/create-dx-component/assets/styles.ts +7 -0
  99. package/src/ai/project/.claude/skills/create-dx-component/cookbooks/README.md +28 -0
  100. package/src/ai/project/.claude/skills/create-dx-component/cookbooks/build-a-data-widget.md +281 -0
  101. package/src/ai/project/.claude/skills/create-dx-component/cookbooks/field-with-limits-and-validation.md +156 -0
  102. package/src/ai/project/.claude/skills/create-dx-component/cookbooks/status-badge-field.md +97 -0
  103. package/src/ai/project/.claude/skills/create-dx-component/references/accessibility.md +71 -0
  104. package/src/ai/project/.claude/skills/create-dx-component/references/choosing-type-and-subtype.md +79 -0
  105. package/src/ai/project/.claude/skills/create-dx-component/references/cli-workflow.md +125 -0
  106. package/src/ai/project/.claude/skills/create-dx-component/references/component-patterns.md +241 -0
  107. package/src/ai/project/.claude/skills/create-dx-component/references/config-schema.md +296 -0
  108. package/src/ai/project/.claude/skills/create-dx-component/references/cosmos-components.md +137 -0
  109. package/src/ai/project/.claude/skills/create-dx-component/references/field-behavior.md +155 -0
  110. package/src/ai/project/.claude/skills/create-dx-component/references/field-essentials.md +90 -0
  111. package/src/ai/project/.claude/skills/create-dx-component/references/field-subtypes-extra.md +68 -0
  112. package/src/ai/project/.claude/skills/create-dx-component/references/localization.md +30 -0
  113. package/src/ai/project/.claude/skills/create-dx-component/references/pcore-pconnect-apis.md +77 -0
  114. package/src/ai/project/.claude/skills/create-dx-component/references/presentation-essentials.md +57 -0
  115. package/src/ai/project/.claude/skills/create-dx-component/references/props-contract.md +182 -0
  116. package/src/ai/project/.claude/skills/create-dx-component/references/state-matrix.md +102 -0
  117. package/src/ai/project/.claude/skills/create-dx-component/references/storybook-pattern.md +262 -0
  118. package/src/ai/project/.claude/skills/create-dx-component/references/styles-pattern.md +54 -0
  119. package/src/ai/project/.claude/skills/create-dx-component/references/template-essentials.md +87 -0
  120. package/src/ai/project/.claude/skills/create-dx-component/references/template-patterns.md +131 -0
  121. package/src/ai/project/.claude/skills/create-dx-component/references/test-pattern.md +215 -0
  122. package/src/ai/project/.claude/skills/create-dx-component/references/ui-gallery-reuse.md +93 -0
  123. package/src/ai/project/.claude/skills/create-dx-component/references/widget-essentials.md +84 -0
  124. package/src/ai/project/.claude/skills/create-dx-component/references/widget-patterns.md +164 -0
  125. package/src/ai/project/.claude/skills/currency/SKILL.md +46 -0
  126. package/src/ai/project/.claude/skills/date/SKILL.md +46 -0
  127. package/src/ai/project/.claude/skills/decimal/SKILL.md +49 -0
  128. package/src/ai/project/.claude/skills/details/SKILL.md +60 -0
  129. package/src/ai/project/.claude/skills/email/SKILL.md +42 -0
  130. package/src/ai/project/.claude/skills/field/SKILL.md +68 -0
  131. package/src/ai/project/.claude/skills/form/SKILL.md +51 -0
  132. package/src/ai/project/.claude/skills/generate-component-set/SKILL.md +80 -0
  133. package/src/ai/project/.claude/skills/generate-component-set/component-manifest.json +161 -0
  134. package/src/ai/project/.claude/skills/identify-components/SKILL.md +76 -0
  135. package/src/ai/project/.claude/skills/integer/SKILL.md +45 -0
  136. package/src/ai/project/.claude/skills/page/SKILL.md +60 -0
  137. package/src/ai/project/.claude/skills/page-widget/SKILL.md +55 -0
  138. package/src/ai/project/.claude/skills/percentage/SKILL.md +52 -0
  139. package/src/ai/project/.claude/skills/phone/SKILL.md +44 -0
  140. package/src/ai/project/.claude/skills/picklist/SKILL.md +50 -0
  141. package/src/ai/project/.claude/skills/plan-dx-component/SKILL.md +51 -0
  142. package/src/ai/project/.claude/skills/plan-dx-component/references/design-system-mapping.md +108 -0
  143. package/src/ai/project/.claude/skills/plan-dx-component/references/intake.md +146 -0
  144. package/src/ai/project/.claude/skills/plan-dx-component/references/plan-template.md +76 -0
  145. package/src/ai/project/.claude/skills/plan-dx-component/references/requirements-template.md +88 -0
  146. package/src/ai/project/.claude/skills/presentation/SKILL.md +61 -0
  147. package/src/ai/project/.claude/skills/publish-library/SKILL.md +106 -0
  148. package/src/ai/project/.claude/skills/radiobuttons/SKILL.md +51 -0
  149. package/src/ai/project/.claude/skills/review-component/SKILL.md +49 -0
  150. package/src/ai/project/.claude/skills/review-component/references/checklist.md +77 -0
  151. package/src/ai/project/.claude/skills/template/SKILL.md +60 -0
  152. package/src/ai/project/.claude/skills/text/SKILL.md +45 -0
  153. package/src/ai/project/.claude/skills/update-dx-component/SKILL.md +56 -0
  154. package/src/ai/project/.claude/skills/update-dx-component/references/maintenance.md +43 -0
  155. package/src/ai/project/.claude/skills/url/SKILL.md +46 -0
  156. package/src/ai/project/.claude/skills/validate-component/SKILL.md +78 -0
  157. package/src/ai/project/.claude/skills/validate-component/references/runtime-troubleshooting.md +56 -0
  158. package/src/ai/project/.claude/skills/validate-component/scripts/check-component.mjs +327 -0
  159. package/src/ai/project/.claude/skills/widget/SKILL.md +59 -0
  160. package/src/ai/project/.gemini/settings.json +5 -0
  161. package/src/ai/project/AGENTS.md +74 -0
  162. package/src/ai/readme-section.md +91 -0
  163. package/src/cli.js +48 -7
  164. package/src/constants.js +54 -53
  165. package/src/internal-tests.js +27 -0
  166. package/src/tasks/ai-toggle/index.js +46 -0
  167. package/src/tasks/authenticate/helper.js +38 -38
  168. package/src/tasks/authenticate/index.js +17 -15
  169. package/src/tasks/build-all/helper.js +4 -4
  170. package/src/tasks/build-all/index.js +7 -7
  171. package/src/tasks/build-comp/helper.js +17 -17
  172. package/src/tasks/build-comp/index.js +10 -10
  173. package/src/tasks/build-jest-assets/index.js +7 -9
  174. package/src/tasks/build-lib/helper.js +8 -8
  175. package/src/tasks/build-lib/index.js +8 -8
  176. package/src/tasks/bundle/builder/index.js +9 -12
  177. package/src/tasks/bundle/builder/modules.js +8 -9
  178. package/src/tasks/bundle/builder/paths.js +2 -19
  179. package/src/tasks/bundle/builder/webpack.config.js +60 -77
  180. package/src/tasks/bundle/index.js +8 -8
  181. package/src/tasks/create/index.js +35 -35
  182. package/src/tasks/create/templates/Constellation/Field/Boolean/index.tsx.mustache +1 -36
  183. package/src/tasks/create/templates/Constellation/Field/Date/date.ts.mustache +2 -2
  184. package/src/tasks/create/templates/Constellation/Field/Date/index.tsx.mustache +2 -27
  185. package/src/tasks/create/templates/Constellation/Field/DateTime/date-utils.ts.mustache +2 -2
  186. package/src/tasks/create/templates/Constellation/Field/DateTime/date.ts.mustache +2 -2
  187. package/src/tasks/create/templates/Constellation/Field/DateTime/index.tsx.mustache +2 -35
  188. package/src/tasks/create/templates/Constellation/Field/Decimal/index.tsx.mustache +3 -36
  189. package/src/tasks/create/templates/Constellation/Field/Decimal-Currency/index.tsx.mustache +4 -39
  190. package/src/tasks/create/templates/Constellation/Field/Decimal-Percentage/index.tsx.mustache +4 -53
  191. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/index.tsx.mustache +5 -5
  192. package/src/tasks/create/templates/Constellation/Field/Integer/index.tsx.mustache +3 -36
  193. package/src/tasks/create/templates/Constellation/Field/Picklist/index.tsx.mustache +7 -42
  194. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/component-constants.ts +1 -1
  195. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/date.ts.mustache +0 -2
  196. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/embed-utils.ts.mustache +1 -1
  197. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/index.tsx.mustache +11 -11
  198. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/repeat-utils.ts.mustache +3 -13
  199. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/textformat-utils.tsx.mustache +2 -3
  200. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/utils.ts.mustache +28 -28
  201. package/src/tasks/create/templates/Constellation/Field/Picklist-RadioButtons/index.tsx.mustache +2 -2
  202. package/src/tasks/create/templates/Constellation/Field/Picklist-RadioButtons/textformat-utils.tsx.mustache +2 -3
  203. package/src/tasks/create/templates/Constellation/Field/Text/index.tsx.mustache +4 -33
  204. package/src/tasks/create/templates/Constellation/Field/Text-Email/index.tsx.mustache +3 -33
  205. package/src/tasks/create/templates/Constellation/Field/Text-Input/index.tsx.mustache +3 -31
  206. package/src/tasks/create/templates/Constellation/Field/Text-Paragraph/index.tsx.mustache +3 -31
  207. package/src/tasks/create/templates/Constellation/Field/Text-Phone/index.tsx.mustache +3 -35
  208. package/src/tasks/create/templates/Constellation/Field/Text-URL/index.tsx.mustache +3 -33
  209. package/src/tasks/create/templates/Constellation/Field/Text-URL/text-url.tsx.mustache +2 -3
  210. package/src/tasks/create/templates/Constellation/Field/TimeofDay/index.tsx.mustache +2 -35
  211. package/src/tasks/create/templates/Constellation/Field/TimeofDay/time-of-day.ts.mustache +2 -2
  212. package/src/tasks/create/templates/Constellation/Template/DETAILS/Avatar.tsx.mustache +19 -15
  213. package/src/tasks/create/templates/Constellation/Template/DETAILS/Operator.tsx.mustache +6 -6
  214. package/src/tasks/create/templates/Constellation/Template/DETAILS/demo.stories.tsx.mustache +1 -1
  215. package/src/tasks/create/templates/Constellation/Template/DETAILS/index.tsx.mustache +4 -8
  216. package/src/tasks/create/templates/Constellation/Template/DETAILS/mock.ts.mustache +9 -9
  217. package/src/tasks/create/templates/Constellation/Template/DETAILS/utils.js.mustache +4 -8
  218. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/Avatar.tsx.mustache +19 -15
  219. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/Operator.tsx.mustache +6 -6
  220. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/demo.stories.tsx.mustache +1 -1
  221. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/index.tsx.mustache +1 -1
  222. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/mock.ts.mustache +9 -9
  223. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/utils.ts.mustache +4 -8
  224. package/src/tasks/create/templates/Constellation/Template/FORM/demo.stories.tsx.mustache +8 -8
  225. package/src/tasks/create/templates/Constellation/Template/FORM-region/demo.stories.tsx.mustache +8 -8
  226. package/src/tasks/create/templates/Constellation/Template/PAGE/utils.ts.mustache +4 -9
  227. package/src/tasks/create/templates/Constellation/Widget/CASE/demo.test.tsx.mustache +3 -3
  228. package/src/tasks/create/templates/Constellation/Widget/PAGE-CASE/Avatar.tsx.mustache +19 -14
  229. package/src/tasks/create/templates/Constellation/Widget/PAGE-CASE/Operator.tsx.mustache +6 -6
  230. package/src/tasks/create/templates/Constellation/Widget/PAGE-CASE/index.tsx.mustache +1 -1
  231. package/src/tasks/create/templates/Constellation/Widget/PAGE-CASE/mock.ts.mustache +1 -1
  232. package/src/tasks/create/templates/Launchpad/Field/Icon-Button-URL/index.tsx.mustache +5 -5
  233. package/src/tasks/create/templates/Launchpad/Field/Text-Phone/index.tsx.mustache +3 -35
  234. package/src/tasks/create/templates/Launchpad/Field/__components.md +1 -1
  235. package/src/tasks/create/templates/Launchpad/Template/FORM/demo.stories.tsx.mustache +8 -8
  236. package/src/tasks/create/templates/Launchpad/Template/FORM-region/demo.stories.tsx.mustache +8 -8
  237. package/src/tasks/create/templates/Launchpad/Widget/CASE/demo.test.tsx.mustache +3 -3
  238. package/src/tasks/create/templates/Launchpad/Widget/PAGE-CASE/index.tsx.mustache +1 -1
  239. package/src/tasks/create/templates/Launchpad/Widget/PAGE-CASE/mock.ts.mustache +1 -1
  240. package/src/tasks/create-all/index.js +42 -41
  241. package/src/tasks/create-lib/helper.js +13 -13
  242. package/src/tasks/create-lib/index.js +5 -5
  243. package/src/tasks/create-version/helper.js +10 -10
  244. package/src/tasks/create-version/index.js +3 -4
  245. package/src/tasks/delete/helper.js +20 -19
  246. package/src/tasks/delete/index.js +2 -2
  247. package/src/tasks/delete-all/helper.js +26 -25
  248. package/src/tasks/delete-all/index.js +2 -2
  249. package/src/tasks/delete-lib/helper.js +6 -6
  250. package/src/tasks/delete-lib/index.js +6 -6
  251. package/src/tasks/delete-pub/helper.js +18 -18
  252. package/src/tasks/delete-pub/index.js +8 -8
  253. package/src/tasks/delete-version/index.js +2 -2
  254. package/src/tasks/dev-server/index.js +1 -1
  255. package/src/tasks/export-archive/helper.js +21 -21
  256. package/src/tasks/export-archive/index.js +27 -40
  257. package/src/tasks/export-rc/helper.js +34 -34
  258. package/src/tasks/export-rc/index.js +21 -31
  259. package/src/tasks/import-archive/helper.js +39 -39
  260. package/src/tasks/import-archive/index.js +69 -89
  261. package/src/tasks/import-comp/helper.js +8 -8
  262. package/src/tasks/import-comp/index.js +30 -42
  263. package/src/tasks/index.js +5 -0
  264. package/src/tasks/init/Node.gitignore +149 -0
  265. package/src/tasks/init/helper.js +15 -8
  266. package/src/tasks/init/index.js +115 -35
  267. package/src/tasks/init/template/.prettierrc.json +4 -1
  268. package/src/tasks/init/template/.storybook/main.ts +1 -4
  269. package/src/tasks/init/template/.storybook/manager.ts +1 -1
  270. package/src/tasks/init/template/.storybook/preview.tsx +2 -2
  271. package/src/tasks/init/template/.storybook/theme.js +1 -1
  272. package/src/tasks/init/template/.vscode/extensions.json +0 -1
  273. package/src/tasks/init/template/README.md +2 -2
  274. package/src/tasks/init/template/eslint.config.mjs +13 -155
  275. package/src/tasks/init/template/jest.config.cjs +2 -0
  276. package/src/tasks/init/template/package-lock.json +26864 -0
  277. package/src/tasks/init/template/package.json.mustache +19 -74
  278. package/src/tasks/init/template/setupTests.ts +10 -4
  279. package/src/tasks/init/template/tsconfig.json +14 -6
  280. package/src/tasks/internal-test/index.js +21 -0
  281. package/src/tasks/internal-test-full/index.js +15 -0
  282. package/src/tasks/internal-test-functional/index.js +15 -0
  283. package/src/tasks/internal-test-unit/index.js +13 -0
  284. package/src/tasks/linter/index.js +2 -2
  285. package/src/tasks/list/helper.js +41 -40
  286. package/src/tasks/list/index.js +3 -3
  287. package/src/tasks/list-lib/helper.js +5 -5
  288. package/src/tasks/list-lib/index.js +8 -8
  289. package/src/tasks/list-pub/helper.js +23 -16
  290. package/src/tasks/list-pub/index.js +24 -21
  291. package/src/tasks/move/helper.js +8 -8
  292. package/src/tasks/move/index.js +19 -23
  293. package/src/tasks/promote-webpack/index.js +4 -4
  294. package/src/tasks/promote-webpack/webpack.config.js +62 -93
  295. package/src/tasks/publish/helper.js +21 -21
  296. package/src/tasks/publish/index.js +16 -16
  297. package/src/tasks/publish-all/helper.js +20 -20
  298. package/src/tasks/publish-all/index.js +11 -12
  299. package/src/tasks/publish-archive/helper.js +9 -9
  300. package/src/tasks/publish-archive/index.js +12 -14
  301. package/src/tasks/publish-lib/helper.js +3 -3
  302. package/src/tasks/publish-lib/index.js +28 -34
  303. package/src/tasks/quarantine/index.js +8 -8
  304. package/src/tasks/rename/index.js +26 -30
  305. package/src/tasks/rename-lib/index.js +21 -25
  306. package/src/tasks/restore/index.js +8 -8
  307. package/src/tasks/restore-config/index.js +3 -5
  308. package/src/tasks/set-perm/index.js +8 -8
  309. package/src/tasks/show-help/index.js +17 -9
  310. package/src/tasks/show-status/index.js +2 -2
  311. package/src/tasks/store/index.js +8 -8
  312. package/src/tasks/switch-lib/helper.js +7 -7
  313. package/src/tasks/switch-lib/index.js +7 -7
  314. package/src/tasks/switch-version/helper.js +6 -6
  315. package/src/tasks/switch-version/index.js +7 -7
  316. package/src/tasks/update/index.js +1 -1
  317. package/src/tasks/upgrade/index.js +7 -7
  318. package/src/tasks/validator/index.js +49 -203
  319. package/src/util.js +169 -186
  320. package/src/rules/no-pcore-pconnect-in-presentation.js +0 -103
  321. package/src/tasks/init/template/.stylelintrc.json +0 -4
  322. package/src/tasks/init/template/babel.config.cjs +0 -22
  323. package/src/tasks/init/template/cspell.json +0 -14
@@ -0,0 +1,296 @@
1
+ # Config.json Schema Reference
2
+
3
+ The `config.json` file defines component metadata and configurable properties that appear in the Pega Constellation authoring environment.
4
+
5
+ ## Base Structure
6
+
7
+ ```json
8
+ {
9
+ "name": "<Org>_<Library>_ComponentName",
10
+ "label": "Human Readable Label",
11
+ "description": "Brief description of the component",
12
+ "organization": "<Org>",
13
+ "version": "1.0.0",
14
+ "library": "<Library>",
15
+ "componentKey": "<Org>_<Library>_ComponentName",
16
+ "type": "Field|Template|Widget|Presentation",
17
+ "subtype": "Text|Boolean|FORM|DETAILS|CASE|PAGE|CASEVIEW",
18
+ "subtypeLabel": "Human readable subtype",
19
+ "icon": "optional-icon.svg",
20
+ "properties": [],
21
+ "defaultConfig": {}
22
+ }
23
+ ```
24
+
25
+ ## Type-Specific Configurations
26
+
27
+ ### Field Component
28
+ ```json
29
+ {
30
+ "type": "Field",
31
+ "subtype": "Text",
32
+ "subtypeLabel": "Text",
33
+ "properties": [
34
+ { "name": "label", "label": "Field label", "format": "TEXT" },
35
+ { "name": "hideLabel", "label": "Hide Label", "format": "BOOLEAN" },
36
+ { "name": "readOnly", "label": "Edit mode", "format": "READONLY" },
37
+ {
38
+ "label": "Input settings",
39
+ "format": "GROUP",
40
+ "visibility": "(!readOnly = true)",
41
+ "properties": [
42
+ { "name": "helperText", "label": "Helper text", "format": "TEXT" },
43
+ { "name": "placeholder", "label": "Placeholder", "format": "TEXT" }
44
+ ]
45
+ },
46
+ {
47
+ "label": "Conditions",
48
+ "format": "GROUP",
49
+ "properties": [
50
+ { "name": "required", "label": "Required", "format": "REQUIRED", "visibility": "(!readOnly = true)" },
51
+ { "name": "disabled", "label": "Disabled", "format": "DISABLED" },
52
+ { "name": "visibility", "label": "Visibility", "format": "VISIBILITY" }
53
+ ]
54
+ },
55
+ {
56
+ "label": "Advanced",
57
+ "format": "GROUP",
58
+ "collapsible": true,
59
+ "properties": [
60
+ { "name": "testId", "label": "Test ID", "format": "TEXT", "includeAnnotations": false }
61
+ ]
62
+ }
63
+ ]
64
+ }
65
+ ```
66
+
67
+ ### Template Component
68
+ ```json
69
+ {
70
+ "type": "Template",
71
+ "subtype": "FORM",
72
+ "subtypeLabel": "FORM",
73
+ "properties": [
74
+ {
75
+ "format": "SELECT",
76
+ "name": "NumCols",
77
+ "label": "Number of columns",
78
+ "defaultValue": "1",
79
+ "source": [
80
+ { "key": "1", "value": "One" },
81
+ { "key": "2", "value": "Two" },
82
+ { "key": "3", "value": "Three" }
83
+ ]
84
+ },
85
+ { "format": "INSTRUCTIONS" },
86
+ {
87
+ "name": "Fields",
88
+ "label": "Fields",
89
+ "format": "CONTENTPICKER",
90
+ "allowCreatingGroup": true
91
+ }
92
+ ]
93
+ }
94
+ ```
95
+
96
+ ### Widget Component
97
+ ```json
98
+ {
99
+ "type": "Widget",
100
+ "subtype": "CASE",
101
+ "subtypeLabel": "CASE",
102
+ "properties": [
103
+ { "name": "label", "label": "Label value", "format": "TEXT" }
104
+ ],
105
+ "defaultConfig": {
106
+ "label": "@L My Widget Label"
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Property Format Reference
112
+
113
+ | Format | Description | Additional Fields |
114
+ |--------|-------------|-------------------|
115
+ | `TEXT` | Free text input | — |
116
+ | `SELECT` | Dropdown | `source: [{key, value}]`, `defaultValue` |
117
+ | `BOOLEAN` | Toggle | `defaultValue: true/false` |
118
+ | `NUMBER` | Numeric | — |
119
+ | `READONLY` | Edit mode toggle | — |
120
+ | `REQUIRED` | Required toggle | — |
121
+ | `DISABLED` | Disabled toggle | — |
122
+ | `VISIBILITY` | Condition expression | — |
123
+ | `CONTENTPICKER` | Add fields/views | `addTypeList`, `allowCreatingGroup`, `saveToConfig` |
124
+ | `DATASOURCE` | Data page binding | — |
125
+ | `GROUP` | Nested property group | `properties: [...]` |
126
+ | `INSTRUCTIONS` | Help text | — |
127
+ | `VALUEINPUT` | Value with rule type | `ruleType` |
128
+
129
+ ## Visibility Expressions
130
+
131
+ Properties can be conditionally shown. Forms seen in shipped configs:
132
+
133
+ - `"visibility": "(!readOnly = true)"` — a bare sibling property name with a single `=`, in parentheses
134
+ - `"visibility": "$this.columnWidth == 'custom'"` — `$this.` prefix with `==` (also `!=`, `!==`)
135
+ - `"visibility": "!($this.readOnly == true)"` — negation
136
+ - `"visibility": "hideLabel == false || hideLabel IS_NULL"` — combine with `&&` and `||`
137
+ - `"visibility": "$this.mode CONTAINS 'single'"` — `CONTAINS`, `STARTS_WITH`, `IS_NULL`, `IS_NOT_NULL`, `IS_IN_LIST`
138
+ - `"visibility": "@PLATFORMNAME != 'launchpad'"` — platform-specific; the one `@` context variable proven for custom components
139
+
140
+ Prefer `$this.<prop>` or the parenthesized bare name over a bare `$prop`; no shipped config uses `$prop`. Other `@` variables (`@VIEWTYPE`, `@VIEWTEMPLATESUBTYPE`, `@RULEVIEWTYPE`, `@ISHYBRIDAPP`, and so on) appear in Pega's own configs, but there is no evidence they are available to custom components. Do not invent a variable because its name sounds right. Compare to the correct type: do not compare a boolean to the string `'true'` unless a shipped example does.
141
+
142
+ ## DefaultConfig
143
+
144
+ Use `defaultConfig` to set initial values when the component is first added:
145
+ ```json
146
+ {
147
+ "defaultConfig": {
148
+ "label": "@L Default Label",
149
+ "NumCols": "2"
150
+ }
151
+ }
152
+ ```
153
+
154
+ The `@L` prefix marks the value as localizable.
155
+
156
+ ## What `validate-schema` checks
157
+
158
+ `npm run validate-schema -- <Org>_<Library>_<Name>` (also the first step of `buildComponent`) checks the structure of the file, **not** whether the platform understands a `format`. The rules, from the CLI validator:
159
+
160
+ - Required top-level keys: `componentKey`, `name`, `description`, `type`, `subtype`, `properties`. `label`, `icon` and `organization` are not required by the schema (library mode still enforces `organization` and `library`; see Key and property rules). Extra top-level keys are allowed.
161
+ - `name` and `componentKey` match `^[A-Za-z0-9]+_[A-Za-z0-9]+_[A-Za-z0-9]+$`.
162
+ - `description` is not blank.
163
+ - `type` is one of `Field`, `Template`, `Widget`, `Presentation`. `subtype` is one of the values in [Valid `subtype` values](#valid-subtype-values), with exact casing (for example `TimeOfDay`). The Presentation subtypes (`CASEVIEW`, `WSSCASEVIEW`) are valid only on `Presentation`, and `Presentation` accepts only those.
164
+ - `properties` is an array with **unique** entries. Each entry must match one of three shapes:
165
+ 1. `name`, `label` and `format` (the normal control).
166
+ 2. A `CASCADE`: `format`, plus a `source` object (`name`, `label`, `format`) and `cascadeElements` where each element has `key`, `name`, `label` and `format`. Only `format` is required.
167
+ 3. A `GROUP`: `label` and `format`, with a nested `properties` array whose entries are a normal control, a `LABEL` (`variant`, `label`, `format`) or an `INLINE` (`format` and `elements`, each element with `key`, `format` and `label`). `GROUP` has no `name`.
168
+ - A bare `{ "format": "INSTRUCTIONS" }` passes (through the `CASCADE` shape, which only requires `format`).
169
+
170
+ **`format` is only checked to be a string.** A misspelled or unsupported format passes `validate-schema` and `buildComponent` and then fails (or silently does nothing) in App Studio. Use only formats from the tables below, and check any other against a scaffold of the same type.
171
+
172
+ Typical errors: `Invalid: data/properties/N must have required property 'label'` (property N, zero-based, is incomplete), `data/properties must NOT have duplicate items` (two identical entries), and `Invalid: data/subtype must be equal to one of the allowed values`.
173
+
174
+ ## More formats and members
175
+
176
+ **Scaffold-proven.** The CLI scaffolds use exactly these 17 formats, so they are safe for custom components: `GROUP`, `TEXT`, `SELECT`, `NUMBER`, `BOOLEAN`, `VISIBILITY`, `REQUIRED`, `DISABLED`, `READONLY`, `VALUEINPUT`, `LABEL`, `CONTENTPICKER`, `CASCADE`, `PROPERTY`, `INLINE`, `DATASOURCE`, `INSTRUCTIONS`.
177
+
178
+ | Format | Notes and members |
179
+ | --- | --- |
180
+ | `TEXT` | `helperText`, `helperTextVisibility` (same grammar as `visibility`), `placeholder`, `ignorePattern` (characters stripped from input), `includeAnnotations` (default true), `allowsDynamicText`, `multiline` |
181
+ | `NUMBER` | `min`, `max` (min defaults to 0), `showDecimal`, `numberOfDecimals`. Store a number, not a string |
182
+ | `BOOLEAN` | `defaultValue`; give it a positive label such as `Show profile` and set the default explicitly when absent and false differ |
183
+ | `SELECT` | `source: [{ key, value }]`, `defaultValue`, `placeholder`, `helperText`, `localize`. Persist the stable `key`; `value` is the display text |
184
+ | `GROUP` | Nested `properties`, `collapsible`, `defaultCollapsed`, `visibility`. A group is not a runtime property and is never serialized |
185
+ | `CONTENTPICKER` | Templates only. `addTypeList` (values seen: `Fields`, `Views`, `Widgets`, `Insights`, `Associations`), `allowCreatingGroup`, `saveToConfig`, `source`, `itemTypes` |
186
+ | `PROPERTY` | Property picker. `ofContextClass`, `filter` (for example `"$this.typeKey == 'Pega-Fields-Scalar-Integer'"`), `useAnnotation`, `inheritedProp` |
187
+ | `CASCADE` | One property controls which dependent control is shown. `source` is a full property object, `cascadeElements` each carry a `match` value, `clearElementsOnSwitch` clears hidden values on a switch |
188
+ | `LABEL`, `INLINE` | Layout in the property panel. `LABEL` takes `variant` (`primary`, `secondary`, `h1` to `h6`); `INLINE` has an `elements` array |
189
+ | `VALUEINPUT` | Value with a rule type (`ruleType`, for example `"Paragraph"`), `allowsDynamicText` |
190
+ | `DATASOURCE` | Data page binding; has a nested `properties` array of the fields to read from the source |
191
+ | `VISIBILITY`, `REQUIRED`, `DISABLED`, `READONLY` | Platform-aware condition editors, not plain booleans. `REQUIRED` and `DISABLED` also take `inheritedProp` |
192
+
193
+ **Seen in Pega's own components, support for custom components unconfirmed:** `FIELDLABELINPUT`, `EXPRESSION`, `DEFAULTVALUE`, `CASELINK`, `VIEWPICKER`, `DATAPAGE`, `PARAMETERS`, `GROUPBY`, `ACTIONPICKER`, `COLUMNFILTER`, `COLUMNSORT`, `COLUMNFORMATTER`, `FILLCOLUMNWIDTH`, `PRESETPICKER`, `CONTENTPICKERSOURCE`, `RENDERMODE`, `EDITMODE`, `MULTIRECORDDISPLAYAS`, `AUTOGENERATED`. Because `validate-schema` accepts any string, a format from this list will pass validation even if App Studio ignores it. Do not use one unless the user supplies a working example, and say so when you do.
194
+
195
+ If you need a format that is not listed, copy a similar property from a scaffolded component of the same type (`node_modules/@pega/custom-dx-components/src/tasks/create/templates/Constellation/<Type>/<Subtype>/config.json.mustache`) rather than inventing one.
196
+
197
+ ## Standard Field property layout
198
+
199
+ Pega's own Fields follow one order, and so do the scaffolds. Keep it so the property panel feels familiar:
200
+
201
+ 1. `label`, `hideLabel`, `readOnly` at the top level.
202
+ 2. A `GROUP` "Input settings" (edit-only settings such as `placeholder`, `helperText`), gated by `"visibility": "(!readOnly = true)"`.
203
+ 3. A `GROUP` "Read-only settings" for display formatting, when there is any.
204
+ 4. A `GROUP` "Conditions" with `REQUIRED` (edit-only), `DISABLED` and `VISIBILITY`.
205
+ 5. A collapsible `GROUP` "Advanced" with a `testId` property:
206
+
207
+ ```json
208
+ {
209
+ "label": "Advanced",
210
+ "format": "GROUP",
211
+ "collapsible": true,
212
+ "properties": [
213
+ {
214
+ "name": "testId",
215
+ "label": "Test ID",
216
+ "format": "TEXT",
217
+ "ignorePattern": "[^-_\\p{N}\\p{L}]",
218
+ "includeAnnotations": false
219
+ }
220
+ ]
221
+ }
222
+ ```
223
+
224
+ Property `name` is camelCase for Fields and Widgets. Template region and layout names are PascalCase or a single letter (`NumCols`, `Fields`, `A`, `B`); do not rename them in a copied scaffold. `label` text is sentence case and is never prefixed with `@L`; only default values are localized that way. Keep `helperText` to one short sentence about a consequence or constraint; use `additionalInfo: { heading?, content }` for anything longer.
225
+
226
+ ## Authoring design rules
227
+
228
+ - **Persist a stable key, not a label.** A `SELECT` stores its `key`; the `value` can be translated. Changing a `key` breaks every saved view.
229
+ - **Hidden does not mean deleted.** When a visibility condition or `CASCADE` hides a property, its old value stays in the saved metadata. Decide for each conditional property whether the component ignores, clears or still honors it, and make `index.tsx` safe against a stale value. Use `clearElementsOnSwitch` when a stale value would change meaning.
230
+ - **Defaults apply only when the key is absent.** They do not repair a malformed saved value. The precedence is saved value, then `defaultConfig` / `defaultValue`, then the fallback in the component. Treat absent, `null`, `''`, `0` and `false` as different inputs and say which the component accepts.
231
+ - **Keep authoring settings separate from runtime state.** Focus, hover, open menus, request status and filter text never belong in `config.json`. Secrets, endpoints and data page names that vary per environment do not either.
232
+ - **Fewer properties is better.** Every property adds persisted surface, test cases and migration cost. Start with the smallest set that makes the component usable.
233
+ - **Do not expose two controls for one runtime key** unless their visibility conditions are mutually exclusive.
234
+
235
+ ### Property ledger
236
+
237
+ Keep this table in the plan for any component with more than a couple of properties. A key is unfinished until every column is known; mismatches (`readOnly` in JSON but `readonly` in code, a string default for a number, a picker that persists objects while the code expects strings) are the usual bugs.
238
+
239
+ | Config key | Format | Default | Prop in `index.tsx` | Hidden or legacy behavior | Test |
240
+ | --- | --- | --- | --- | --- | --- |
241
+ | `maxLength` | `NUMBER` | none | `maxLength?: number` | ignored when not a positive number | boundary story and test |
242
+
243
+ ### Safe and risky changes to an existing component
244
+
245
+ Adding an optional property is low risk when it has a backward-compatible default, existing metadata renders identically when the key is absent, and it does not hide or reinterpret an existing control. Test both the absent key and an explicit value.
246
+
247
+ These need an explicit compatibility decision from the user, because saved views already use the old shape: renaming `name` or a property key or region name, changing the type of a saved value, changing a `SELECT` `key`, changing a `CONTENTPICKER` from scalars to objects, removing a property or region, and changing `defaultConfig` so existing components behave differently. Prefer adding the new shape and keeping the old one.
248
+
249
+ ## `defaultConfig` bindings
250
+
251
+ Besides literals, scaffolds use these bindings in `defaultConfig`:
252
+
253
+ | Binding | Meaning |
254
+ | ------------------------------------------- | ------------------------------------------------------------- |
255
+ | `"@P .pyLabel"` | Value of a property on the current page |
256
+ | `"@L $this.label"`, `"@L Select..."` | Localized text (the field's own label, or a literal) |
257
+ | `"@DATASOURCE D_pyAnnouncements.pxResults"` | A data page and the result list to bind to |
258
+ | `"@ASSOCIATED .$this.name"` | The associated (list-of-values) source for the bound property |
259
+ | `"@FL .$this.name"` | The bound property's field label (the most common default for a Field `caption`) |
260
+
261
+ Scaffolded fields also carry layout flags in `defaultConfig` (for example `detailFVLItem`, `isFormWidth`). Leave them as generated.
262
+
263
+ ## Keep `config.json` and `index.tsx` in sync
264
+
265
+ - Add a property: add the entry to `properties`, add the prop (with its type) to the props interface in `index.tsx`, and use it in the component. Give it a safe default in the destructuring (`const { max = 100 } = props;`) because a designer may leave it empty.
266
+ - Remove a property: remove it from all three places.
267
+ - Rename a property: it is a breaking change for any view that already configures it. Prefer adding a new property and keeping the old one until the user confirms.
268
+ - Boolean and numeric properties can reach the component as strings. Normalize them before use, as the scaffolded fields do for `readOnly`, `required` and `disabled` (and `parseInt` for numeric settings such as `decimalPrecision`).
269
+ - After editing, run `npm run validate-schema -- <Org>_<Library>_<Name>`.
270
+
271
+ ## Key and property rules
272
+
273
+ - `name` must match the folder name exactly, and `componentKey` must equal `name`.
274
+ - `library` must match `component.library` in [tasks.config.json](../../../../tasks.config.json), and `organization` must match the organization there (library mode enforces both).
275
+ - `icon` is optional and names an SVG in the component folder.
276
+ - `SELECT` requires a `source` array of `{ "key", "value" }` pairs. `GROUP` carries a nested `properties` array and has no `name`. `INSTRUCTIONS` renders help text and has no `name`. `CONTENTPICKER` is for Templates: it lets App Studio authors add child fields and views.
277
+ - Every `name` must match a prop consumed in `index.tsx`. Do not declare properties the component ignores.
278
+
279
+ ## Valid `subtype` values
280
+
281
+
282
+ Use these exact values (the CLI `create` argument and `config.json` `subtype`). A wrong value or casing fails `validate-schema` with `data/subtype must be equal to one of the allowed values`.
283
+
284
+ | type | subtype |
285
+ | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
286
+ | `Field` | `Text`, `Text-Input`, `Text-Paragraph`, `Text-Email`, `Text-Phone`, `Text-URL`, `Icon-Button-URL`, `Integer`, `Decimal`, `Decimal-Currency`, `Decimal-Percentage`, `Boolean`, `Date`, `DateTime`, `TimeOfDay`, `Picklist`, `Picklist-Autocomplete`, `Picklist-RadioButtons` |
287
+ | `Template` | `FORM`, `FORM-region`, `DETAILS`, `DETAILS-region`, `PAGE` |
288
+ | `Widget` | `CASE`, `PAGE`, or the array `["PAGE", "CASE"]` (shown in the picker as "PAGE & CASE") |
289
+ | `Presentation` | `CASEVIEW`, `WSSCASEVIEW` |
290
+
291
+ [component-manifest.json](../../generate-component-set/component-manifest.json) maps each friendly subtype name to its `cliSubtype`.
292
+
293
+ ## Grouping convention
294
+
295
+
296
+ Put `label`, `hideLabel`, and `readOnly` at the top level. Group the rest by concern with `GROUP`, and gate edit-only settings behind `"visibility": "(!readOnly = true)"`.
@@ -0,0 +1,137 @@
1
+ # Cosmos React Core - Available Components
2
+
3
+ Every name below was checked against the barrel in `node_modules/@pega/cosmos-react-core/lib/index.d.ts`. **Verify any name that is not on this list before you import it** — several plausible-sounding components (`Divider`, `Badge`, `DataGrid`, `IconButton`, `Tab`) do **not** exist.
4
+
5
+ ## Layout Components
6
+ - `Grid` — CSS Grid layout container
7
+ - `Flex` — Flexbox layout container
8
+ - `Card` — Card container with shadow/border
9
+ - `CardHeader` — Card header section
10
+ - `CardContent` — Card content section
11
+ - `FieldGroup` — Group of fields with optional label
12
+ - `FormField` — Label + control + info + actions wrapper
13
+
14
+ ## Input Components
15
+ - `Input` — Text input field
16
+ - `TextArea` — Multi-line text input
17
+ - `Checkbox` — Single checkbox
18
+ - `CheckboxGroup` — Group of checkboxes
19
+ - `RadioButtonGroup` — Radio button selection
20
+ - `Select` — Dropdown select
21
+ - `DateInput` — Date picker input
22
+ - `TimeInput` — Time picker input
23
+ - `NumberInput` — Numeric input
24
+ - `CurrencyInput` — Currency input with formatting
25
+ - `PhoneInput` — Phone number input
26
+ - `SearchInput` — Search input with icon
27
+
28
+ ## Display Components
29
+ - `Text` — Typography component (variants: h1-h6, body, caption)
30
+ - `FieldValueList` — Label-value pair display (variants: inline, stacked)
31
+ - `BooleanDisplay` — True/false display
32
+ - `DateTimeDisplay` — Formatted date/time
33
+ - `CurrencyDisplay` — Formatted currency
34
+ - `PhoneDisplay` — Formatted phone number
35
+ - `EmailDisplay` — Email with link
36
+ - `URLDisplay` — URL with link
37
+ - `Icon` — SVG icon display
38
+ - `Avatar` — User avatar
39
+ - `Progress` — Progress bar/indicator
40
+ - `EmptyState` — Empty view placeholder
41
+
42
+ ## Badges (all from `./components/Badges`)
43
+ - `Status` — Status badge/indicator
44
+ - `Tag` — Label chip
45
+ - `Count` — Numeric badge
46
+ - `Alert` — Alert badge
47
+ - `Selectable`, `Keyboard`
48
+
49
+ ## Data Components
50
+ - `Table` — Data table with columns, sorting, pagination
51
+
52
+ ## Feedback Components
53
+ - `Banner` — Banner notification
54
+ - `Toaster` — Toast notifications
55
+ - `Modal` — Modal dialog (see gotchas)
56
+ - `FormDialog` / `InfoDialog` — Anchored dialogs
57
+
58
+ ## Navigation Components
59
+ - `Link` — Hyperlink
60
+ - `Button` — Action button
61
+ - `Tabs` — Tabbed navigation (**not** `Tab`)
62
+
63
+ ## HOCs & Utilities
64
+ - `withConfiguration` — **Required wrapper** for all DX components
65
+ - `ShortcutManager` — Keyboard shortcut handling
66
+ - `PopoverManager` — Popover positioning
67
+ - `ModalManager` — Modal dialog management
68
+ - `useTheme` — Cosmos theme access (see gotchas)
69
+ - `useModalManager` — Imperative modal creation
70
+
71
+ ## Additional components used by Pega's own widgets and templates
72
+
73
+ These are exported by `@pega/cosmos-react-core` (or `@pega/cosmos-react-work` where noted) in recent builds. Check the export and prop names in the installed `.d.ts` before use; several came from a newer Cosmos than a customer project may have.
74
+
75
+ | Need | Component or helper | Notes |
76
+ | --- | --- | --- |
77
+ | Summary list with loading, count, per-item actions and focus after delete | `SummaryList`, `ViewAll` | `loading`, `count` (pass `undefined` while loading), `noItemsText`, `onViewAll`, item `contextualLabel`, and `deletedItemId` + `onDeleteFocusComplete` + `fallbackFocusRef` |
78
+ | Error with retry | `ErrorState` | props are `message` and `onRetry` only; its retry button reads "Try again" |
79
+ | Destructive confirm | `Modal`, `DangerButton`, `useModalManager`, `useModalContext` | see [widget-patterns.md](./widget-patterns.md) |
80
+ | Focus an error summary | `Banner` with a `handle` | `handle.current.focus()`; `messages` must be an array |
81
+ | Progress placement | `Progress` | `placement` is `'block'`, `'local'` (needs a positioned parent) or `'inline'`; `variant` is `'ring'`, `'bar'` or `'ellipsis'` |
82
+ | Grouped fields | `FieldGroup`, `FieldGroupList` | `fieldset`/`legend`; `collapsed`, `status='error'`, `headingTag` |
83
+ | Tabs | `Tabs`, `TabPanel` | ARIA and arrow keys are built in; do not reimplement |
84
+ | Page layouts | `OneColumnPage`, `TwoColumnPage`, `ThreeColumnPage`, `NarrowWidePage`, `WideNarrowPage`, `TabbedPage` | slots `a`, `b`, `c`; they own scrolling and heading focus |
85
+ | Read-only label/value lists | `FieldValueList`; `Details`, `DetailsList`, `DetailsContext` from `@pega/cosmos-react-work` | `Details` handles column fitting and label alignment |
86
+ | Display formatting | `DateTimeDisplay`, `CurrencyDisplay`, `NumberDisplay`, `EmailDisplay`, `PhoneDisplay`, `BooleanDisplay`, `ParagraphDisplay`, `URLDisplay`, `NoValue` | prefer to hand formatting |
87
+ | Utilities | `useBreakpoint`, `useTheme`, `useConfiguration`, `createUID`, `debounce`, `createStringMatcher`, `formatNumber`, `useElement`, `LocaleOverride`, `getPhoneNumberParts` | create a `debounce` once (`useMemo`), never in the render body |
88
+ | Safe links | `disallowedURI` | present in some builds; keep your own protocol allow-list as well |
89
+
90
+ ## Verified Gotchas
91
+
92
+ Each of these was confirmed by reading the installed package. They are the opposite of what the prop names suggest.
93
+
94
+ | Component | Trap |
95
+ | --- | --- |
96
+ | `Banner` | `messages` must be an **array**. Passing a string throws `messages.flatMap is not a function`. |
97
+ | `EmptyState` | The prop is `message`, **not** `title`. A `title` prop is silently ignored. |
98
+ | `Tag` | Requires `children`. There is **no** `label` prop. |
99
+ | `Input` | Does **not** render a character counter. `maxLength` only sets the native attribute. Only `TextArea` has `displayCharCount`. |
100
+ | `Input` | Renders its own `FormField` when `label` is passed. Composing it inside your own `FormField` while also passing `label` nests two of them. |
101
+ | `FormField` | `onClear` is gated behind `isRadioCheck` — it renders **only** for radio/checkbox groups. For a text input, use the `actions` array. |
102
+ | `FormField` / `Input` | Pass the **same explicit `id`** to both, or the label's `htmlFor` will point at a different generated id. |
103
+ | `Modal` | Needs a `ModalManager` ancestor. Without one, `useModalManager().create()` is a silent no-op and `dismiss` does nothing. |
104
+ | — | There is **no floating-label** API anywhere in Cosmos. Build it in `styles.ts`. |
105
+
106
+ ### styled-components theme does not cross the boundary
107
+
108
+ `@pega/cosmos-react-core` bundles its **own nested copy** of `styled-components`. Its `ThemeProvider` therefore does not populate the `ThemeContext` used by a component's own `styles.ts`, and `theme.base` is `undefined` there.
109
+
110
+ Read the theme in `index.tsx` and pass the values down as props:
111
+
112
+ ```typescript
113
+ import { useTheme } from '@pega/cosmos-react-core';
114
+
115
+ const palette = useTheme().base.palette;
116
+ // palette['primary-background'] | palette['foreground-color'] | palette.urgent | palette.success
117
+ <StyledWrapper $error={palette.urgent} />
118
+ ```
119
+
120
+ ## Import Pattern
121
+ ```typescript
122
+ import {
123
+ Grid,
124
+ Flex,
125
+ Card,
126
+ CardContent,
127
+ Text,
128
+ Input,
129
+ Table,
130
+ withConfiguration
131
+ } from '@pega/cosmos-react-core';
132
+ ```
133
+
134
+ ## Additional Cosmos Libraries
135
+ - `@pega/cosmos-react-work` — Work-related components (assignments, cases)
136
+ - `@pega/cosmos-react-wss` — Workspace components
137
+ - `@pega/cosmos-react-condition-builder` — Condition/filter builder
@@ -0,0 +1,155 @@
1
+ # Field Behavior
2
+
3
+ How production Constellation Fields commit values, handle empty and zero, and report status. This is the shared contract behind every Field subtype skill; the subtype skills only add what differs. Props and display modes are in [props-contract.md](./props-contract.md), states in [state-matrix.md](./state-matrix.md).
4
+
5
+ The behaviors below were observed in Pega's own Field components. Cosmos callback shapes can differ between Cosmos versions, so check the control's `.d.ts` in the installed `@pega/cosmos-react-core` before relying on a shape (see Verified Gotchas in [cosmos-components.md](./cosmos-components.md)).
6
+
7
+ ## Commit protocol
8
+
9
+ `handleEvent(actions, type, propName, value, options?)` from `shared/event-utils` maps to the PConnect actions API:
10
+
11
+ | `type` | Calls |
12
+ | --- | --- |
13
+ | `'change'` | `updateFieldValue(prop, value, options)` |
14
+ | `'blur'` | `triggerFieldChange(prop, value)` |
15
+ | `'changeNblur'` | both, in that order |
16
+
17
+ Which event commits depends on the control. Follow the contract for the subtype instead of committing on every keystroke:
18
+
19
+ | Family | While typing | On blur |
20
+ | --- | --- | --- |
21
+ | Text, TextArea, Email, URL | keep a local draft, clear the field error, `pConn.updateDirtyCheckChangeList(propName, draft)` | commit with `changeNblur` only if the value differs from the stored one |
22
+ | Integer, Decimal, Percentage, Currency | validate the draft, keep it local, clear the field error | convert to a number (or `''`), compare, `changeNblur` if different |
23
+ | Date, DateTime, Time | pickers commit when a complete valid date is entered (see Dates) | same helper |
24
+ | Dropdown, RadioButtons, Checkbox | `changeNblur` straight from the change event | `validate(value)` (RadioButtons only when there is no value) |
25
+ | Stepper or slider variants | `changeNblur` on change, because they may never fire blur | none |
26
+
27
+ Rules that apply to every family:
28
+
29
+ - **Read the value from the control's blur callback argument, not from React state.** State may not have updated yet; a decimal point inserted into `805` to make `8.05` must still commit.
30
+ - **Do nothing when the value is unchanged.** If the draft equals the stored value, do not commit. If both are empty, call `getValidationApi().validate('')` only, so a required field still reports its error.
31
+ - **Zero is a value.** Never write `if (!value)` for a number. Typing `0` over an empty field commits `0`; clearing a stored `0` commits `''`.
32
+ - **Compare as strings (or the parsed form), never with epsilon.** Compare `value.toString()` with the parsed text, so `1.600` redisplays as `1.6` after commit.
33
+ - **Clear means `''`.** Production numeric fields send `''` (not `null`, not `0`) when the user clears the input. See [Empty and null](#empty-and-null).
34
+ - **Guard blur with `!readOnly`** so a read-only control cannot commit.
35
+ - **Wire error clearing and the dirty list.** On change call `pConn.clearErrorMessages({ property: propName })` (documented), so a stale error disappears as soon as the user edits. Pega's own fields that keep a local draft also call `pConn.updateDirtyCheckChangeList(propName, value)`. That method is in the PConnect typedefs but **not in the API catalog**: confirm it in `node_modules/@pega/pcore-pconnect-typedefs`, and tell the user you are using it, before adding it.
36
+ - **Local draft state needs a sync effect.** Keep `useState(String(value))` for the control and an effect on `[value]` that overwrites it when the store changes (a reset, a cascade, a suggestion accepted).
37
+
38
+ ## Empty and null
39
+
40
+ `value` can be `null` for a property that was never set. A destructure default (`value = ''`) does not cover `null`; use `const value = valueProp ?? ''`.
41
+
42
+ Test these inputs for every numeric and text field: `null`, `''`, `0`, a stored value, and a typed value over `null`.
43
+
44
+ | Subtype | `null` mounts as | Notes |
45
+ | --- | --- | --- |
46
+ | Text, Integer, Decimal, Currency, Percentage | empty input | display mode shows `NoValue` (Text shows `0` for a real zero) |
47
+ | Boolean checkbox | unchecked | writes `false` with `{ skipDirtyValidation: true }` so the form is not dirtied; no `triggerFieldChange` |
48
+ | Boolean as two radios | neither selected | skip the null-to-false write so "unset" stays distinct from "false" |
49
+ | Picklist | first option, or `''` when a placeholder exists | see [picklist](../../picklist/SKILL.md) |
50
+
51
+ ## Message precedence
52
+
53
+ - `info` shown under the control is `validatemessage` if non-empty, else the field warning content, else `helperText`. A validation message **replaces** the helper text.
54
+ - `status` passed to the Cosmos control: `'error'` when `validatemessage` is non-empty, `'pending'` while a suggestion is available, `'warning'` for a field warning, otherwise `undefined`. Never pass the internal value `'suggestion-accepted'` to a Cosmos control; map it to `undefined`.
55
+ - **Field warning.** `showFieldMessage` plus `messageConfig: { visibility, content }` shows a non-blocking warning when `showFieldMessage && messageConfig.visibility && !readOnly`. It is suppressed in read-only mode and when the condition is false.
56
+ - `hideLabel` hides the label (`labelHidden`) but helper text still renders.
57
+ - `fieldMetadata` may carry `maxLength`, `additionalInformation` (render as the control's `additionalInfo={{ content }}`) and `inputFormat.pattern` (a mask). `pConn.getFieldMetadata(prop)` returns it; the scaffolds already receive it as a prop. The method is typed in the PConnect typedefs but is not in the API catalog, so prefer the prop, and confirm the method in the typedefs before calling it.
58
+
59
+ ## Boolean-like props arrive as strings
60
+
61
+ `readOnly`, `required` and `disabled` can arrive as `true`, `'true'` or anything else. Normalize each with `p === true || p === 'true'`. Numeric config such as `decimalPrecision` or `pickerInterval` arrives as a string too; `parseInt` it and fall back deliberately when it is `NaN`.
62
+
63
+ ## `additionalProps`
64
+
65
+ Spread `{...additionalProps}` **first** on the Cosmos control so explicit props win. `autoFocus` and similar platform props arrive this way. Give the control `testId={testId ?? label}` so tests and test automation have a stable hook.
66
+
67
+ ## Suggestions (AI-assisted values)
68
+
69
+ When the platform proposes a value, `pConn.acceptSuggestion()` and `pConn.ignoreSuggestion()` (both in the catalog) accept or reject it. Pass `suggestion={{ onAccept, onReject }}` to the Cosmos control, and keep a local `status` that becomes `'suggestion-accepted'` on accept and is cleared on reject, on user edit and after the blur commit. For a Checkbox or radio, call `onAccept` when the click changes the suggested value, otherwise `onReject`. Show the pending status only when the suggested value is among the options.
70
+
71
+ ## Display only
72
+
73
+ `DISPLAY_ONLY` returns early, after all hooks, with no label or input. An empty value renders `NoValue`. Numeric displays pass `undefined` (not `''`) to `NumberDisplay` or `CurrencyDisplay`. The Cosmos `*Display` components (`DateTimeDisplay`, `CurrencyDisplay`, `NumberDisplay`, `EmailDisplay`, `PhoneDisplay`, `BooleanDisplay`, `ParagraphDisplay`, `URLDisplay`) format values for you; prefer them to formatting by hand. The optional `formatter` prop maps to display variants (for example `Currency`, `Decimal`, `Percentage`, `DateTime-Long`); read it from `pConn.getConfigProps()` at render time.
74
+
75
+ ## Dates, times and time zones
76
+
77
+ - **Date** values are `YYYY-MM-DD` strings. Never run them through a time zone: parsing `2024-03-01` as local midnight can shift the day. Take the year with `value.slice(0, 4)` and format date-only values with `timeZone: 'UTC'`.
78
+ - **DateTime** values are UTC instants (`YYYY-MM-DDTHH:mm:ss.000Z`). Convert to the operator's zone for the input and back to UTC on commit. The zone comes from `PCore.getEnvironmentInfo().getTimeZone()`; when that is empty and the feature flag `pyEnableDateTimeSystemTimezoneFallback` is on in `getEnvironmentInfo().getFeatureMap()`, fall back to `PCore.getLocaleUtils().getTimeZoneInUse()`.
79
+ - **Time** values are `HH:mm:ss` and commit on blur.
80
+ - **Year range.** Defaults are 100 years back and 20 years forward from today, widened to include the year of the stored value. `min` is `${year}-01-01` and `max` is `${year}-12-31`.
81
+ - **Invalid and incomplete input.** Cosmos date inputs report an error state alongside the value. While the state is invalid or incomplete, keep the draft and call `validate(...)`; do not call `triggerFieldChange`, and do not clear what the user typed. Only a complete valid date is committed.
82
+ - **DateTime options.** `pickerInterval` accepts only 5, 10, 15, 20, 30 or 60 (fall back to 30). `clockFormat` accepts 12 or 24 (fall back to the locale default).
83
+ - Use `LocaleOverride` from Cosmos for a calendar override, and read the locale from `PCore.getEnvironmentInfo().getLocale()`.
84
+
85
+ ## Numbers
86
+
87
+ - Integer: accept `''`, `'-'`, or text where `Number(s).toString() === s`. That rejects `1.0`, `01` and `1e3` while typing. `showGroupSeparators` defaults to true.
88
+ - Decimal: `numberOfDecimals` is `parseInt(decimalPrecision)`. `NaN` from `''` means unlimited, any other `NaN` means 2. Intermediate drafts such as `-`, `-0`, `-0.` and `-0.0` must survive typing, which is why a draft is validated by its trimmed form rather than by `Number()`. Cosmos `NumberInput` already caps the length.
89
+ - Currency: use the authored `currencyISOCode` prop. Fall back to `PCore.getFieldDefaultUtils().fieldDefaults.Currency.currencyISOCode`, then `'USD'`. Check that a code is valid with `new Intl.NumberFormat('en', { style: 'currency', currency: code })` in a try/catch.
90
+ - Percentage: a platform default (`PCore.getFieldDefaultUtils().fieldDefaults.Percentage.storePercentageAsDecimal`) decides whether `0.25` or `25` is stored. When it is on, display is `value * 100` and commit is `value / 100` rounded to `precision + 2` decimals. Watch the precision fallback: a stored `0.123456` with an empty precision displays as `12.35`.
91
+
92
+ ## Pickers and radios
93
+
94
+ - Compare option keys as strings: `` `${value}` === `${item.key}` ``. Never key a radio by array index; use the key, and name the group `pageReference.propName` so groups on different pages do not collide.
95
+ - A placeholder is an option with value `''`. With no placeholder and an empty value, production selects the first option and commits it; if the stored value is not among the options it resets to the first option (or `''` with a placeholder). Decide on purpose whether your picker does this, and test it.
96
+ - Dependent options: register through the cascade APIs and cancel stale option requests with an `AbortController` before each search.
97
+ - A single-select combo box keeps the typed filter text separate from the selected item, and clearing the text deselects.
98
+ - A picker that also writes other properties from the selected row calls `updateFieldValue(prop, v)` then `triggerFieldChange(prop, v, true)` for each extra property; the third argument skips validation.
99
+ - Radio deselect is an opt-in (`allowClear`), not the default.
100
+
101
+ ## URL, email and phone
102
+
103
+ - A display link built by Cosmos `URLDisplay` is not a security boundary. In the Cosmos build checked here, `Link` only drops hrefs that match `javascript:`; `data:`, `vbscript:` and `file:` pass through. Validate scheme yourself (allow `http:`, `https:` and `mailto:` as needed) and test `disallowedURI` from Cosmos where it exists. Open external links with `rel='noopener noreferrer'`.
104
+ - Phone: `PhoneInput` emits country code plus number. A value holding only a country code is junk: on mount write `''` and remember the code locally, and make `required` reject it. Use `getPhoneNumberParts` from Cosmos to split a value.
105
+ - Email and URL commit the raw string like Text. Trimming or lowercasing is your design choice, not platform behavior; say so in the contract.
106
+
107
+ ## Handler shapes
108
+
109
+ Reference examples for the rules above. Adapt them; do not paste them over the scaffold.
110
+
111
+ A numeric blur handler (Integer, Decimal, Currency, Percentage):
112
+
113
+ ```typescript
114
+ const onBlur = (event) => {
115
+ const entered = event.target.value; // read from the event, not from state
116
+ const next = entered !== '' ? Number(entered) : '';
117
+ if (String(valueProp ?? '') !== String(next)) {
118
+ handleEvent(actions, 'changeNblur', propName, next);
119
+ } else {
120
+ pConn.getValidationApi().validate(entered); // unchanged or still empty: validate only
121
+ }
122
+ };
123
+ ```
124
+
125
+ A date callback (Cosmos `DateInput`; verify the shape in the installed `.d.ts`):
126
+
127
+ ```typescript
128
+ const { valueAsISOString, state } = callbackValue;
129
+ const date = valueAsISOString ? valueAsISOString.split('T')[0] : '';
130
+ // state is 'invalid' or 'incomplete' while the user is mid-entry: keep the draft and validate; commit only a complete date
131
+ ```
132
+
133
+ A URL allow-list:
134
+
135
+ ```typescript
136
+ const isSafe = (raw: string) => {
137
+ try {
138
+ return ['http:', 'https:'].includes(new URL(raw).protocol);
139
+ } catch {
140
+ return false;
141
+ }
142
+ };
143
+ ```
144
+
145
+ An email normalizer (only if the user agrees to normalize stored data):
146
+
147
+ ```typescript
148
+ const normalized = (value ?? '').trim().toLowerCase();
149
+ handleEvent(actions, 'blur', propName, normalized);
150
+ pConn.getValidationApi().validate(normalized);
151
+ ```
152
+
153
+ ## Verification checklist
154
+
155
+ For every Field, the matching story and test should cover: label, required, disabled, read-only, display only, helper text, validation message replacing helper text, zero, `null`, empty, typing over `null`, unchanged blur (no commit), empty blur (validate only), the commit arguments, and a long value. Details in [test-pattern.md](./test-pattern.md).