@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,79 @@
1
+ # Choosing a Component Type and Subtype
2
+
3
+ Use this when the request is not a plain "make a <subtype> field": a custom control (a star rating, a signature pad), a block you cannot name a subtype for (a kanban board), or something that may not be a custom component at all. The CLI accepts a fixed set of subtypes, and `validate-schema` rejects any other, so every idea has to land on one of them or be declared out of scope. Never invent a subtype.
4
+
5
+ ## 1. Fit check
6
+
7
+ A custom DX component is one of four things:
8
+
9
+ | Type | It is |
10
+ | --- | --- |
11
+ | Field | One control bound to **one case property** |
12
+ | Widget | A standalone block that loads and shows its own data |
13
+ | Template | A layout that arranges child views and fields |
14
+ | Presentation | A replacement for the whole case view page |
15
+
16
+ If the request is none of these, say so plainly, name the closest option, and let the user decide. Do not stretch a type to fit. Examples that do not fit as stated:
17
+
18
+ - Changing the app shell, navigation, theme or portal frame.
19
+ - Adding or intercepting the buttons and flow actions of an assignment.
20
+ - Business logic, validation rules or data models. Those live in the Pega application, not in a DX component.
21
+ - A control that stores a **list** of values or **several properties** at once. No Field subtype binds more than one scalar property. Offer instead: a Template that arranges existing fields; a Widget that writes back to the property (confirm the stored shape with the app designer and flag it as a risk); or a delimited string in a Text field if the user accepts that.
22
+
23
+ If you are unsure whether something is possible on the platform, say that you are unsure instead of building a guess.
24
+
25
+ ## 2. Pick the type
26
+
27
+ Ask in this order and stop at the first yes:
28
+
29
+ 1. Does it replace how the whole case view page is rendered? **Presentation** (`CASEVIEW` or `WSSCASEVIEW`).
30
+ 2. Does it edit or show **one** case property? **Field**.
31
+ 3. Does its main job arrange other components that the app designer places inside it? **Template**.
32
+ 4. Does it show its own data (chart, list, KPI, board, timeline)? **Widget**.
33
+
34
+ A read-only badge, pill, icon or formatted value bound to a property is a Field that handles `DISPLAY_ONLY`. If it loads its own data instead, it is a Widget.
35
+
36
+ ## 3. Pick the subtype
37
+
38
+ **Field: choose by the type of the stored value, not by how the control looks.** The control can be anything Cosmos or the browser can render.
39
+
40
+ | Stored value | Subtype |
41
+ | --- | --- |
42
+ | Short or free text | `Text`, `Text-Input` (single line), `Text-Paragraph` (multi-line) |
43
+ | Email, phone, web address | `Text-Email`, `Text-Phone`, `Text-URL`; `Icon-Button-URL` for a link shown as an icon button |
44
+ | Whole number | `Integer` |
45
+ | Fractional number | `Decimal`; `Decimal-Currency` for money; `Decimal-Percentage` for a percent |
46
+ | True or false | `Boolean` |
47
+ | Date, date and time, time of day | `Date`, `DateTime`, `TimeOfDay` |
48
+ | One choice from a list | `Picklist` (dropdown), `Picklist-RadioButtons`, `Picklist-Autocomplete` (searchable) |
49
+
50
+ **Template:** `FORM` (editable fields), `DETAILS` (read-only label/value pairs), `PAGE` (whole-page regions). `FORM-region` and `DETAILS-region` are the multi-region variants. `PAGE` is the template to use for an app-level layout with named regions.
51
+
52
+ **Widget:** `CASE` when it belongs inside a case view and uses the current case, `PAGE` when it sits on a portal page or dashboard with no case, and, if the same widget must work in both, the `config.json` subtype can be the array `["PAGE", "CASE"]` (shown as "PAGE & CASE"). The `create` argument for that combination is not documented in [cli-workflow.md](./cli-workflow.md), so pick `CASE` or `PAGE` unless the user needs both, and then check the CLI help first.
53
+
54
+ **Presentation:** `CASEVIEW`, or `WSSCASEVIEW` for the Web Self Service portal.
55
+
56
+ ## 4. Worked examples
57
+
58
+ | The user wants | Type and subtype | Notes |
59
+ | --- | --- | --- |
60
+ | A star rating (1 to 5) | Field `Integer` | Custom control over a whole number. The Cosmos `Rating` component in the build checked takes `value`, `maxRating` and `readOnly` and has no change callback, so use it for the `DISPLAY_ONLY` view and build the editable control from a Cosmos radio group so it stays keyboard and screen-reader operable. Check `Rating.d.ts` in the installed version |
61
+ | A slider for a quantity | Field `Integer` | Cosmos has a slider; check its `.d.ts` first |
62
+ | A status pill or badge for a property | Field `Text` with `DISPLAY_ONLY` | See [the status badge recipe](../cookbooks/status-badge-field.md) |
63
+ | A color picker | Field `Text` | Store a hex string such as `#1A2B3C` |
64
+ | A signature pad | Field `Text-Paragraph` | Stores a data URL, which can be large; confirm the property's size limit with the user. Try the browser canvas before asking to add a library |
65
+ | A time picker | Field `TimeOfDay` | |
66
+ | A searchable customer lookup | Field `Picklist-Autocomplete` | The options come from the property's configured source |
67
+ | Tag input or multi-select | Not a Field | See the fit check: it stores a list |
68
+ | An address block | Not a Field | It binds several properties. Offer a Template that arranges the existing address fields |
69
+ | A kanban board, timeline, chart, KPI tile, map, org chart | Widget `CASE` or `PAGE` | `CASE` if it shows the current case's data, otherwise `PAGE`. Data comes from a data page. Check Cosmos for a ready component before proposing a charting or map library |
70
+ | A tabbed or stepper layout of fields | Template `FORM-region` or `PAGE` | One region per tab or step. Use Cosmos `Tabs`; editable steps must all stay mounted so validation sees every field (see [template-patterns.md](./template-patterns.md)) |
71
+ | A read-only summary panel | Template `DETAILS` | Must force read-only on its children |
72
+ | A sidebar layout or dashboard grid | Template `PAGE` | Regions `A` and `B` |
73
+ | A custom case header with tabs on the left | Presentation `CASEVIEW` | Props only; no PCore or PConnect |
74
+
75
+ ## 5. Decide, then say what you decided
76
+
77
+ - If two types or subtypes both fit, take the narrowest, state the assumption in one sentence, and ask once. The ambiguity rule in [AGENTS.md](../../../../AGENTS.md) applies.
78
+ - Say which subtype you chose and **why** (for a Field, the stored value type). The user can then correct a wrong storage assumption before any code exists.
79
+ - If the idea needs a third-party library, first check whether Cosmos or the browser already does it. Propose a library only when neither does, and follow the consent rule in [AGENTS.md](../../../../AGENTS.md).
@@ -0,0 +1,125 @@
1
+ # Custom Component Project Workflow (CLI, Build, Test)
2
+
3
+ > Part of the [create-dx-component skill](../SKILL.md). PCore/PConnect signatures are in the [API catalog](./pcore-pconnect-apis.md).
4
+
5
+ This file explains how a custom component project is laid out and which commands an AI assistant can run **without interactive prompts** to scaffold, check and build components. Every command form below was run against a generated project.
6
+
7
+ ## Project layout
8
+
9
+ ```text
10
+ <project>/
11
+ tasks.config.json # CLI configuration (library, version, server settings)
12
+ src/components/
13
+ shared/ # PConnProps.d.ts, create-nonce.ts (shared by library components)
14
+ <Org>_<Library>_<Name>/ # one folder per component
15
+ config.json # design-time definition: properties, defaults
16
+ index.tsx # the React component
17
+ styles.ts # styled-components wrapper
18
+ mock.ts # sample props/state props for stories and tests
19
+ demo.stories.tsx # Storybook story (supplies a mocked getPConnect)
20
+ demo.test.tsx # Jest test built on the story
21
+ src/globals.d.ts # declares the global `PCore` type
22
+ setupTests.ts, jest.config.cjs, tsconfig.json, eslint.config.mjs
23
+ ```
24
+
25
+ Some component types add helper files (for example `DetailsRender.tsx`, `utils.ts`, `localizations.json`).
26
+
27
+ ## Library mode: create a library first
28
+
29
+ New projects run in **library mode**. Until a library exists, almost every command fails with a message to run `createLib`. Create one once per project:
30
+
31
+ ```bash
32
+ npm run createLib -- <LibraryName> <version> Y Current
33
+ # example
34
+ npm run createLib -- Lib 1.0.0 Y Current
35
+ ```
36
+
37
+ Arguments: library name (alphanumeric, starts with a letter), semver version, `Y`/`N` for a permanent build (library mode always treats it as permanent), and `Current` or `Original` (only relevant when archives already exist).
38
+
39
+ ## One-command check
40
+
41
+ `node .claude/skills/validate-component/scripts/check-component.mjs <Org>_<Library>_<Name>` runs the whole loop below for one component and prints a PASS/FAIL/WARN/NOT RUN table. The schema check, `tsc`, ESLint and Jest run in parallel; `tsc` covers only this component, `src/components/shared/` and the global declarations, and is incremental. The build starts only when the schema and ESLint checks pass, because it repeats both and would fail anyway.
42
+
43
+ While fixing failures, rerun it with `--no-build` (or the single command for the failing row). Run it once without `--no-build` for the final table.
44
+
45
+ ## Non-interactive commands
46
+
47
+ The `npm run` scripts forward everything after `--` to the CLI. Without arguments each command prompts interactively, which an AI assistant cannot answer, so **always pass the arguments**.
48
+
49
+ | Goal | Command |
50
+ | ------------------------- | ------------------------------------------------------------------------------------------------------------- |
51
+ | Create a library | `npm run createLib -- <Library> <version> Y Current` |
52
+ | Scaffold a component | `npm run create -- <type> <subtype> <Name> "<Label>" <version> <Library> "<description>" <Organization>` |
53
+ | Validate `config.json` | `npm run validate-schema -- <Org>_<Library>_<Name>` |
54
+ | Lint, validate and bundle | `npm run buildComponent -- <Org>_<Library>_<Name> N N` (the last two are source map `Y/N` and dev build `Y/N`) |
55
+ | Build every component | `npm run buildAllComponents` |
56
+ | List components | `npm run list` (safe). `npm run listLib` prompts and crashes when run without a terminal |
57
+ | Aliases | `npm run validate` is `buildComponent` and `npm run validateAll` is `buildAllComponents`; they take the same arguments |
58
+
59
+ Scaffold example:
60
+
61
+ ```bash
62
+ npm run create -- Field Text-Email ContactEmail "Contact email" 1.0.0 Lib "Email field" Acme
63
+ # creates src/components/Acme_Lib_ContactEmail
64
+ ```
65
+
66
+ Valid `<type>` and `<subtype>` values:
67
+
68
+ | Type | Subtypes |
69
+ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
+ | `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` |
71
+ | `Template` | `DETAILS`, `DETAILS-region`, `FORM`, `FORM-region`, `PAGE` |
72
+ | `Widget` | `CASE`, `PAGE` |
73
+ | `Presentation` | `CASEVIEW`, `WSSCASEVIEW` |
74
+
75
+ Use these values exactly, including casing (for example `TimeOfDay`, not `TimeofDay`). With arguments supplied, `create` does not validate the subtype up front: an unknown subtype either fails with a missing-template error or generates a `config.json` that then fails `validate-schema` with `data/subtype must be equal to one of the allowed values`. The authoritative list is `COMPONENT_SCHEMA` in the installed `@pega/custom-dx-components` package.
76
+
77
+ ## Naming rules
78
+
79
+ - The component key is `<Organization>_<Library>_<Name>`: exactly three alphanumeric segments separated by underscores. `config.json` `name` and `componentKey` must match this pattern (`validate-schema` enforces it).
80
+ - `<Name>`, `<Library>` and `<Organization>` must be alphanumeric, start with a letter and contain no spaces.
81
+ - The component's React function name is the PascalCase form of the key (for example `Acme_Lib_ContactEmail` becomes `AcmeLibContactEmail`).
82
+ - Keep names short. The CLI rejects names that exceed the length limit for the server.
83
+
84
+ ## Check loop (run after every change)
85
+
86
+ Run from the project root, in this order, and fix failures before moving on:
87
+
88
+ ```bash
89
+ npx tsc --noEmit 2>&1 | grep -v "demo.stories.tsx" # types in your own files
90
+ npm test # Jest (coverage thresholds apply)
91
+ npm run lint # ESLint
92
+ npm run validate-schema -- <Org>_<Library>_<Name> # config.json against the schema
93
+ npm run buildComponent -- <Org>_<Library>_<Name> N N # lint + validate + bundle
94
+ ```
95
+
96
+ Notes:
97
+
98
+ - `npm run lint` lints `src/` and the project config; the `.claude/` skill assets are ignored.
99
+ - `npm test` and the build create `coverage/` and `dist/` in the project root. Both are git-ignored in projects made by `init`.
100
+ - Freshly scaffolded Widget, Template and Presentation `demo.stories.tsx` files can produce `tsc` errors such as `Property 'PCore' does not exist on type 'Window'`. Stories are excluded from lint and the bundle, so filter them out as shown. Do not edit those scaffolded stories only to silence the error. Any error in `index.tsx`, `config.json` or your own files is real and must be fixed.
101
+ - `npm test` runs every `demo.test.tsx`. To run one, use `npx jest <path>` (add `--coverage=false` to skip the coverage thresholds).
102
+ - `buildComponent` runs schema validation, then lint, then the bundle. A lint failure stops the build before bundling.
103
+ - Storybook (`npm run startStorybook`) is a long-running dev server. Do not start it from an automated check loop unless the user asks.
104
+
105
+ ## Commands that need the user
106
+
107
+ Do not run these unless the user explicitly asks, because they need credentials, a Pega server, or change or delete data:
108
+
109
+ - `authenticate`, `publish`, `publishAll`, `publishLibVersion`, `exportRC`: use the server settings and credentials in `tasks.config.json`.
110
+ - `delete`, `deleteAll`, `deleteLib`, `deletePublishedLib`, `deleteLibVersion`, `restoreLibVersion`: destructive.
111
+ - `rename`, `move`, `switchLib`, `createLibVersion`, `importLibVersion`: change the project structure or library state.
112
+
113
+ Never write secrets (client secrets, passwords, tokens) into `tasks.config.json` or source files, and never commit the `keys/` directory contents or `.npmrc` credentials.
114
+
115
+ ## Troubleshooting
116
+
117
+ | Symptom | Likely cause and fix |
118
+ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
119
+ | "All commands will NOT work until a library is created" | No library yet. Run `npm run createLib -- <Library> <version> Y Current`. |
120
+ | A command hangs or prints a prompt | Arguments were omitted. Re-run with every positional argument. |
121
+ | `Cannot find package '@eslint-react/eslint-plugin'` or other missing packages | Dependencies are not installed. Run `npm install` in the project, then retry. |
122
+ | Jest fails with `ReferenceError: Highlight is not defined` | `setupTests.ts` is missing the `Highlight` stub that `@pega/cosmos-react-core` needs under jsdom. Add the stub. |
123
+ | `Invalid: data/properties/N must have required property ...` from `validate-schema` | Property N (zero-based) in `config.json` lacks `name`, `label` or `format`. |
124
+ | `Invalid: data/subtype must be equal to one of the allowed values` | The subtype has the wrong value or casing. Use a value from the table above. |
125
+ | `Property 'PCore' does not exist on type 'Window'` in `demo.stories.tsx` | Known noise in scaffolded stories; not part of the bundle. |
@@ -0,0 +1,241 @@
1
+ # Component Implementation Patterns
2
+
3
+ ## Field Component Pattern
4
+
5
+ Field components bind to a single case property and handle input/display with validation.
6
+
7
+ ```typescript
8
+ import { Input, withConfiguration } from '@pega/cosmos-react-core';
9
+ import type { PConnFieldProps } from '../shared/PConnProps';
10
+ import '../shared/create-nonce';
11
+ import handleEvent from './event-utils';
12
+ import StyledWrapper from './styles';
13
+
14
+ interface Props extends PConnFieldProps {
15
+ // Additional props from config.json
16
+ hasSuggestions?: boolean;
17
+ variant?: any;
18
+ formatter?: string;
19
+ }
20
+
21
+ interface StateProps {
22
+ value: string;
23
+ hasSuggestions: boolean;
24
+ }
25
+
26
+ function AcmeLibMyField(props: Props) {
27
+ const {
28
+ getPConnect,
29
+ value = '',
30
+ label = '',
31
+ helperText = '',
32
+ validatemessage,
33
+ hideLabel,
34
+ testId,
35
+ additionalProps = {},
36
+ displayMode,
37
+ placeholder
38
+ } = props;
39
+
40
+ const pConn = getPConnect();
41
+ const actions = pConn.getActionsApi();
42
+ const stateProps = pConn.getStateProps() as StateProps;
43
+ const propName: string = stateProps.value;
44
+
45
+ let { readOnly = false, required = false, disabled = false } = props;
46
+ [readOnly, required, disabled] = [readOnly, required, disabled].map(
47
+ (prop) => prop === true || (typeof prop === 'string' && prop === 'true')
48
+ );
49
+
50
+ let status: 'error' | 'success' | 'warning' | 'pending' | undefined;
51
+ if (validatemessage) {
52
+ status = 'error';
53
+ }
54
+
55
+ // Display mode (required for all Field components)
56
+ if (displayMode === 'DISPLAY_ONLY') {
57
+ return <StyledWrapper>{value}</StyledWrapper>;
58
+ }
59
+
60
+ // Edit mode
61
+ return (
62
+ <StyledWrapper>
63
+ <Input
64
+ {...additionalProps}
65
+ label={label}
66
+ labelHidden={hideLabel}
67
+ info={validatemessage || helperText}
68
+ status={status}
69
+ value={value}
70
+ placeholder={placeholder}
71
+ disabled={disabled}
72
+ readOnly={readOnly}
73
+ required={required}
74
+ testId={testId}
75
+ onChange={(event: any) => {
76
+ handleEvent(actions, 'change', propName, event.target.value);
77
+ }}
78
+ onBlur={(event: any) => {
79
+ handleEvent(actions, 'blur', propName, value);
80
+ pConn.getValidationApi().validate(value);
81
+ }}
82
+ />
83
+ </StyledWrapper>
84
+ );
85
+ }
86
+
87
+ export default withConfiguration(AcmeLibMyField);
88
+ ```
89
+
90
+ ### event-utils.ts (Field Components)
91
+
92
+ ```typescript
93
+ const handleEvent = (actions: any, eventType: string, propName: string, value: any) => {
94
+ switch (eventType) {
95
+ case 'change':
96
+ actions.updateFieldValue(propName, value);
97
+ break;
98
+ case 'blur':
99
+ actions.triggerFieldChange(propName, value);
100
+ break;
101
+ case 'changeNblur':
102
+ actions.updateFieldValue(propName, value);
103
+ actions.triggerFieldChange(propName, value);
104
+ break;
105
+ default:
106
+ break;
107
+ }
108
+ };
109
+
110
+ export default handleEvent;
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Template Component Pattern
116
+
117
+ Templates arrange child components in layouts (forms, details views, pages). `children` holds one element per **region**; fields are one level down. This skeleton is the editable-layout starting point only. For read-only rendering, per-field layout, responsive columns and hidden children read [template-patterns.md](./template-patterns.md).
118
+
119
+ ```typescript
120
+ import { Grid, Flex, FieldGroup, withConfiguration } from '@pega/cosmos-react-core';
121
+ import type { PConnFieldProps } from '../shared/PConnProps';
122
+ import '../shared/create-nonce';
123
+ import StyledWrapper from './styles';
124
+
125
+ interface Props extends PConnFieldProps {
126
+ children: any[];
127
+ NumCols?: string;
128
+ showLabel?: boolean;
129
+ }
130
+
131
+ function AcmeLibMyTemplate(props: Props) {
132
+ const { children = [], NumCols = '1', label, showLabel, getPConnect, readOnly, displayMode } = props;
133
+ const propsToUse = { label, showLabel, ...getPConnect().getInheritedProps() };
134
+ const nCols = parseInt(NumCols, 10);
135
+
136
+ return (
137
+ <StyledWrapper>
138
+ <FieldGroup name={propsToUse.showLabel ? propsToUse.label : ''}>
139
+ <Grid container={{ cols: `repeat(${nCols}, minmax(0, 1fr))`, gap: 2 }}>
140
+ {children}
141
+ </Grid>
142
+ </FieldGroup>
143
+ </StyledWrapper>
144
+ );
145
+ }
146
+
147
+ export default withConfiguration(AcmeLibMyTemplate);
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Widget Component Pattern
153
+
154
+ Widgets are standalone UI blocks that fetch their own data.
155
+
156
+ ```typescript
157
+ import { useState, useEffect } from 'react';
158
+ import { Table, Card, CardHeader, CardContent, Text, withConfiguration } from '@pega/cosmos-react-core';
159
+ import type { PConnFieldProps } from '../shared/PConnProps';
160
+ import '../shared/create-nonce';
161
+ import StyledWrapper from './styles';
162
+
163
+ interface Props extends PConnFieldProps {
164
+ // Widget-specific props
165
+ }
166
+
167
+ function AcmeLibMyWidget(props: Props) {
168
+ const { getPConnect, label } = props;
169
+ const pConn = getPConnect();
170
+ const [data, setData] = useState<any[]>([]);
171
+ const [isLoading, setIsLoading] = useState(true);
172
+ const context = pConn.getContextName();
173
+
174
+ useEffect(() => {
175
+ const caseProp: string = PCore.getConstants().CASE_INFO.CASE_INFO_ID;
176
+ const caseID = pConn.getValue(caseProp, '');
177
+ const payload = { dataViewParameters: { CaseInstanceKey: caseID } };
178
+
179
+ PCore.getDataApiUtils()
180
+ .getData('D_DataPageName', payload, context)
181
+ .then((response: any) => {
182
+ setIsLoading(false);
183
+ if (response.data.data !== null) {
184
+ setData(response.data.data);
185
+ }
186
+ })
187
+ .catch(() => {
188
+ setData([]);
189
+ setIsLoading(false);
190
+ });
191
+ }, [context]);
192
+
193
+ return (
194
+ <StyledWrapper>
195
+ <Card>
196
+ <CardHeader>
197
+ <Text variant="h2">{label}</Text>
198
+ </CardHeader>
199
+ <CardContent>
200
+ {/* Render data */}
201
+ </CardContent>
202
+ </Card>
203
+ </StyledWrapper>
204
+ );
205
+ }
206
+
207
+ export default withConfiguration(AcmeLibMyWidget);
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Presentation Component Pattern
213
+
214
+ Presentation components (`CASEVIEW`, `WSSCASEVIEW`) replace how a whole case view is rendered. They receive everything as props and cannot use PCore or PConnect.
215
+
216
+ ```typescript
217
+ import { withConfiguration } from '@pega/cosmos-react-core';
218
+ import type { CaseViewProps } from '@pega/cosmos-react-work';
219
+ import '../shared/create-nonce';
220
+ import StyledWrapper from './styles';
221
+
222
+ function AcmeLibMyCaseView(props: CaseViewProps) {
223
+ const { caseId, heading, caseType, tabs, tabContent } = props;
224
+ const activeTab = tabContent?.find((tab) => tab.id === tabs.currentTabId);
225
+
226
+ return (
227
+ <StyledWrapper>
228
+ <header>
229
+ <span>{caseType}</span>
230
+ <h1>{typeof heading === 'string' ? heading : heading?.text}</h1>
231
+ <span>{caseId}</span>
232
+ </header>
233
+ {activeTab?.content}
234
+ </StyledWrapper>
235
+ );
236
+ }
237
+
238
+ export default withConfiguration(AcmeLibMyCaseView);
239
+ ```
240
+
241
+ Always start from the scaffolded `index.tsx` (`npm run create -- Presentation CASEVIEW ...`) and read the prop types in `node_modules/@pega/cosmos-react-work/lib/components/CaseView/CaseView.types.d.ts` before using a prop. For `WSSCASEVIEW` the type comes from `@pega/cosmos-react-wss`.