@vc-shell/vc-app-skill 2.0.0-alpha.33 → 2.0.0-alpha.34

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 (195) hide show
  1. package/CHANGELOG.md +78 -54
  2. package/README.md +42 -12
  3. package/package.json +4 -4
  4. package/runtime/VERSION +1 -1
  5. package/runtime/agents/api-analyzer.md +31 -16
  6. package/runtime/agents/blade-enhancer.md +15 -9
  7. package/runtime/agents/details-blade-generator.md +47 -31
  8. package/runtime/agents/list-blade-generator.md +21 -37
  9. package/runtime/agents/locales-generator.md +3 -0
  10. package/runtime/agents/migration-agent.md +18 -7
  11. package/runtime/agents/module-analyzer.md +2 -0
  12. package/runtime/agents/module-assembler.md +15 -0
  13. package/runtime/agents/promote-agent.md +15 -4
  14. package/runtime/agents/type-checker.md +11 -0
  15. package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
  16. package/runtime/knowledge/docs/core/api/platform.docs.md +30 -30
  17. package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +41 -41
  18. package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +12 -10
  19. package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +11 -14
  20. package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +35 -35
  21. package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +35 -35
  22. package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +15 -15
  23. package/runtime/knowledge/docs/core/composables/useAssets/useAssets.docs.md +21 -18
  24. package/runtime/knowledge/docs/core/composables/useAssetsManager/useAssetsManager.docs.md +28 -24
  25. package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +90 -61
  26. package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +19 -18
  27. package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +89 -68
  28. package/runtime/knowledge/docs/core/composables/useBladeForm/useBladeForm.docs.md +27 -25
  29. package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +15 -15
  30. package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +43 -47
  31. package/runtime/knowledge/docs/core/composables/useBreadcrumbs/useBreadcrumbs.docs.md +11 -11
  32. package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md +27 -15
  33. package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +30 -30
  34. package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +34 -36
  35. package/runtime/knowledge/docs/core/composables/useErrorHandler/useErrorHandler.docs.md +44 -23
  36. package/runtime/knowledge/docs/core/composables/useFunctions/useFunctions.docs.md +14 -11
  37. package/runtime/knowledge/docs/core/composables/useKeyboardNavigation/useKeyboardNavigation.docs.md +47 -38
  38. package/runtime/knowledge/docs/core/composables/useLanguages/useLanguages.docs.md +37 -28
  39. package/runtime/knowledge/docs/core/composables/useLoading/useLoading.docs.md +23 -17
  40. package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +9 -9
  41. package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +42 -42
  42. package/runtime/knowledge/docs/core/composables/useModificationTracker/useModificationTracker.docs.md +22 -12
  43. package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +33 -41
  44. package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +16 -16
  45. package/runtime/knowledge/docs/core/composables/usePlatformLocaleSync/usePlatformLocaleSync.docs.md +28 -0
  46. package/runtime/knowledge/docs/core/composables/usePopup/usePopup.docs.md +32 -24
  47. package/runtime/knowledge/docs/core/composables/useResponsive/useResponsive.docs.md +32 -11
  48. package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +22 -13
  49. package/runtime/knowledge/docs/core/composables/useSettingsMenu/useSettingsMenu.docs.md +7 -7
  50. package/runtime/knowledge/docs/core/composables/useSidebarState/useSidebarState.docs.md +32 -24
  51. package/runtime/knowledge/docs/core/composables/useSlowNetworkDetection/useSlowNetworkDetection.docs.md +21 -17
  52. package/runtime/knowledge/docs/core/composables/useTheme/useTheme.docs.md +24 -24
  53. package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +28 -31
  54. package/runtime/knowledge/docs/core/composables/useUser/useUser.docs.md +43 -24
  55. package/runtime/knowledge/docs/core/composables/useUserManagement/useUserManagement.docs.md +68 -48
  56. package/runtime/knowledge/docs/core/composables/useWebVitals/useWebVitals.docs.md +19 -19
  57. package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +42 -47
  58. package/runtime/knowledge/docs/core/directives/autofocus/autofocus.docs.md +10 -4
  59. package/runtime/knowledge/docs/core/directives/loading/loading.docs.md +35 -20
  60. package/runtime/knowledge/docs/core/notifications/notifications.docs.md +36 -35
  61. package/runtime/knowledge/docs/core/plugins/ai-agent/ai-agent.docs.md +38 -38
  62. package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +79 -62
  63. package/runtime/knowledge/docs/core/plugins/global-error-handler/global-error-handler.docs.md +10 -10
  64. package/runtime/knowledge/docs/core/plugins/i18n/i18n.docs.md +21 -23
  65. package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +91 -83
  66. package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +10 -16
  67. package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +9 -9
  68. package/runtime/knowledge/docs/core/plugins/validation/validation.docs.md +65 -22
  69. package/runtime/knowledge/docs/core/services/services.docs.md +19 -22
  70. package/runtime/knowledge/docs/core/types/types.docs.md +40 -40
  71. package/runtime/knowledge/docs/core/utilities/date/date-utilities.docs.md +27 -27
  72. package/runtime/knowledge/docs/core/utilities/shared-utilities.docs.md +23 -23
  73. package/runtime/knowledge/docs/core/utilities/thumbnail/thumbnail.docs.md +22 -25
  74. package/runtime/knowledge/docs/core/utilities/utilities.docs.md +64 -64
  75. package/runtime/knowledge/docs/injection-keys.docs.md +52 -51
  76. package/runtime/knowledge/docs/modules/assets-manager/assets-manager.docs.md +9 -9
  77. package/runtime/knowledge/docs/shell/_internal/popup/common/popup-common.docs.md +23 -43
  78. package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +5 -5
  79. package/runtime/knowledge/docs/shell/auth/ForgotPasswordPage/forgot-password-page.docs.md +5 -5
  80. package/runtime/knowledge/docs/shell/auth/InvitePage/invite-page.docs.md +8 -7
  81. package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +7 -7
  82. package/runtime/knowledge/docs/shell/auth/ResetPasswordPage/reset-password-page.docs.md +8 -7
  83. package/runtime/knowledge/docs/shell/auth/sign-in/sign-in.docs.md +29 -13
  84. package/runtime/knowledge/docs/shell/components/change-password/change-password.docs.md +13 -16
  85. package/runtime/knowledge/docs/shell/components/change-password-button/change-password-button.docs.md +1 -7
  86. package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +5 -5
  87. package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +1 -1
  88. package/runtime/knowledge/docs/shell/components/logout-button/logout-button.docs.md +1 -1
  89. package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +17 -9
  90. package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +11 -17
  91. package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +34 -65
  92. package/runtime/knowledge/docs/shell/components/sidebar/sidebar.docs.md +16 -26
  93. package/runtime/knowledge/docs/shell/components/theme-selector/theme-selector.docs.md +2 -2
  94. package/runtime/knowledge/docs/shell/components/user-dropdown-button/user-dropdown-button.docs.md +7 -9
  95. package/runtime/knowledge/docs/shell/dashboard/dashboard-charts/dashboard-charts.docs.md +30 -40
  96. package/runtime/knowledge/docs/shell/dashboard/dashboard-widget-card/dashboard-widget-card.docs.md +26 -19
  97. package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +15 -12
  98. package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +15 -26
  99. package/runtime/knowledge/docs/ui/components/atoms/vc-banner/vc-banner.docs.md +21 -19
  100. package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +83 -67
  101. package/runtime/knowledge/docs/ui/components/atoms/vc-card/vc-card.docs.md +100 -59
  102. package/runtime/knowledge/docs/ui/components/atoms/vc-col/vc-col.docs.md +28 -11
  103. package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +20 -17
  104. package/runtime/knowledge/docs/ui/components/atoms/vc-hint/vc-hint.docs.md +26 -17
  105. package/runtime/knowledge/docs/ui/components/atoms/vc-icon/vc-icon.docs.md +30 -32
  106. package/runtime/knowledge/docs/ui/components/atoms/vc-image/vc-image.docs.md +25 -48
  107. package/runtime/knowledge/docs/ui/components/atoms/vc-label/vc-label.docs.md +29 -24
  108. package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +23 -15
  109. package/runtime/knowledge/docs/ui/components/atoms/vc-loading/vc-loading.docs.md +22 -13
  110. package/runtime/knowledge/docs/ui/components/atoms/vc-progress/vc-progress.docs.md +33 -18
  111. package/runtime/knowledge/docs/ui/components/atoms/vc-row/vc-row.docs.md +56 -15
  112. package/runtime/knowledge/docs/ui/components/atoms/vc-scrollable-container/vc-scrollable-container.docs.md +28 -15
  113. package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +40 -20
  114. package/runtime/knowledge/docs/ui/components/atoms/vc-status/vc-status.docs.md +25 -14
  115. package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +40 -14
  116. package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +54 -42
  117. package/runtime/knowledge/docs/ui/components/atoms/vc-video/vc-video.docs.md +17 -17
  118. package/runtime/knowledge/docs/ui/components/atoms/vc-widget/vc-widget.docs.md +21 -21
  119. package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +23 -10
  120. package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +55 -44
  121. package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +23 -20
  122. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +92 -65
  123. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +22 -36
  124. package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +65 -23
  125. package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +52 -73
  126. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown/vc-dropdown.docs.md +91 -85
  127. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +38 -42
  128. package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +56 -73
  129. package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +61 -27
  130. package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +42 -50
  131. package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +35 -64
  132. package/runtime/knowledge/docs/ui/components/molecules/vc-image-tile/vc-image-tile.docs.md +38 -41
  133. package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +109 -131
  134. package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +47 -88
  135. package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +50 -64
  136. package/runtime/knowledge/docs/ui/components/molecules/vc-input-group/vc-input-group.docs.md +29 -24
  137. package/runtime/knowledge/docs/ui/components/molecules/vc-menu/vc-menu.docs.md +32 -28
  138. package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +57 -65
  139. package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +28 -26
  140. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +55 -20
  141. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +21 -35
  142. package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +38 -33
  143. package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +72 -83
  144. package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +21 -16
  145. package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +55 -64
  146. package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +51 -70
  147. package/runtime/knowledge/docs/ui/components/molecules/vc-toast/vc-toast.docs.md +58 -57
  148. package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +49 -26
  149. package/runtime/knowledge/docs/ui/components/organisms/vc-auth-layout/vc-auth-layout.docs.md +82 -28
  150. package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +90 -75
  151. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +99 -48
  152. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +548 -367
  153. package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +35 -52
  154. package/runtime/knowledge/docs/ui/components/organisms/vc-gallery/vc-gallery.docs.md +33 -62
  155. package/runtime/knowledge/docs/ui/components/organisms/vc-image-upload/vc-image-upload.docs.md +17 -23
  156. package/runtime/knowledge/docs/ui/components/organisms/vc-popup/vc-popup.docs.md +109 -68
  157. package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +82 -44
  158. package/runtime/knowledge/docs/ui/composables/ui-composables.docs.md +8 -8
  159. package/runtime/knowledge/docs/ui/composables/useDataTablePagination.docs.md +164 -0
  160. package/runtime/knowledge/docs/ui/composables/useDataTableSort.docs.md +34 -26
  161. package/runtime/knowledge/docs/ui/composables/useTableSelection.docs.md +48 -40
  162. package/runtime/knowledge/docs/ui/composables/useTableSort.docs.md +30 -17
  163. package/runtime/knowledge/docs/ui/types/ui-types.docs.md +40 -29
  164. package/runtime/knowledge/examples/offers-module.md +15 -13
  165. package/runtime/knowledge/examples/team-module.md +82 -119
  166. package/runtime/knowledge/examples/videos-module.md +44 -17
  167. package/runtime/knowledge/index.md +22 -0
  168. package/runtime/knowledge/migration-prompts/blade-form-migration.md +17 -8
  169. package/runtime/knowledge/migration-prompts/blade-props-migration.md +1 -2
  170. package/runtime/knowledge/migration-prompts/datatable-migration.md +801 -0
  171. package/runtime/knowledge/migration-prompts/icon-migration.md +97 -0
  172. package/runtime/knowledge/migration-prompts/manual-migration-audit.md +117 -0
  173. package/runtime/knowledge/migration-prompts/notifications-migration.md +8 -3
  174. package/runtime/knowledge/migration-prompts/nswag-migration.md +25 -29
  175. package/runtime/knowledge/migration-prompts/use-assets-migration.md +164 -0
  176. package/runtime/knowledge/migration-prompts/use-data-table-pagination-migration.md +176 -0
  177. package/runtime/knowledge/migration-prompts/widgets-migration.md +48 -27
  178. package/runtime/knowledge/patterns/assets-management.md +20 -20
  179. package/runtime/knowledge/patterns/blade-navigation.md +7 -14
  180. package/runtime/knowledge/patterns/blade-widget.md +19 -17
  181. package/runtime/knowledge/patterns/child-blade-flow.md +19 -7
  182. package/runtime/knowledge/patterns/composable-details.md +20 -50
  183. package/runtime/knowledge/patterns/composable-list.md +43 -31
  184. package/runtime/knowledge/patterns/dashboard-widget.md +14 -16
  185. package/runtime/knowledge/patterns/datatable-pattern.md +521 -0
  186. package/runtime/knowledge/patterns/details-blade-pattern.md +78 -116
  187. package/runtime/knowledge/patterns/extension-points-usage.md +53 -44
  188. package/runtime/knowledge/patterns/form-validation.md +28 -64
  189. package/runtime/knowledge/patterns/list-blade-pattern.md +33 -21
  190. package/runtime/knowledge/patterns/module-structure.md +7 -1
  191. package/runtime/knowledge/patterns/multilanguage-fields.md +8 -14
  192. package/runtime/knowledge/patterns/notification-template.md +21 -14
  193. package/runtime/knowledge/patterns/signalr-notifications.md +30 -32
  194. package/runtime/knowledge/patterns/toolbar-pattern.md +18 -20
  195. package/runtime/vc-app.md +241 -62
@@ -1,7 +1,6 @@
1
1
  # Details Blade Pattern
2
2
 
3
- Reference source: `apps/vendor-portal/src/modules/team/pages/team-member-details.vue`
4
- Secondary source: `apps/vendor-portal/src/modules/offers/pages/offers-details.vue`
3
+ Generic worked example for a typical details blade (form-based, validation, modification tracking).
5
4
 
6
5
  ## Overview
7
6
 
@@ -202,7 +201,7 @@ A details blade is a form-based panel opened from a list blade (or navigation) t
202
201
  v-model="entity.agreeTerms"
203
202
  class="tw-p-3"
204
203
  >
205
- {{ $t('MODULE.FIELDS.AGREE_TERMS.LABEL') }}
204
+ {{ $t("MODULE.FIELDS.AGREE_TERMS.LABEL") }}
206
205
  </VcCheckbox>
207
206
 
208
207
  <!-- Radio group: for enum fields with 2-5 options -->
@@ -320,24 +319,10 @@ const { showConfirmation, showError } = usePopup();
320
319
  const { meta } = useForm({ validateOnMount: false });
321
320
 
322
321
  // --- Details composable (entity + CRUD + modification tracking) ---
323
- const {
324
- entity,
325
- loading,
326
- modified,
327
- getXxx,
328
- createXxx,
329
- updateXxx,
330
- deleteXxx,
331
- resetEntries,
332
- resetModificationState,
333
- } = useXxx();
322
+ const { entity, loading, modified, getXxx, createXxx, updateXxx, deleteXxx, resetEntries, resetModificationState } = useXxx();
334
323
 
335
324
  // --- Derived state ---
336
- const title = computed(() =>
337
- param.value
338
- ? entity.value?.name ?? t("MODULE.PAGES.DETAILS.TITLE_EDIT")
339
- : t("MODULE.PAGES.DETAILS.TITLE_NEW"),
340
- );
325
+ const title = computed(() => (param.value ? (entity.value?.name ?? t("MODULE.PAGES.DETAILS.TITLE_EDIT")) : t("MODULE.PAGES.DETAILS.TITLE_NEW")));
341
326
 
342
327
  // Disabled when form is pristine/invalid
343
328
  const isDisabled = computed(() => !meta.value.dirty || !meta.value.valid);
@@ -388,12 +373,7 @@ const bladeToolbar = ref<IBladeToolbar[]>([
388
373
  title: computed(() => t("MODULE.PAGES.DETAILS.TOOLBAR.DELETE")),
389
374
  icon: "lucide-trash-2",
390
375
  async clickHandler() {
391
- if (
392
- param.value &&
393
- (await showConfirmation(
394
- computed(() => t("MODULE.PAGES.DETAILS.POPUP.ALERT.DELETE")),
395
- ))
396
- ) {
376
+ if (param.value && (await showConfirmation(computed(() => t("MODULE.PAGES.DETAILS.POPUP.ALERT.DELETE"))))) {
397
377
  await deleteXxx({ id: param.value });
398
378
  callParent("reload");
399
379
  closeSelf();
@@ -427,9 +407,7 @@ onMounted(async () => {
427
407
  // --- Close guard ---
428
408
  onBeforeClose(async () => {
429
409
  if (modified.value) {
430
- return !(await showConfirmation(
431
- unref(computed(() => t("MODULE.PAGES.ALERTS.CLOSE_CONFIRMATION"))),
432
- ));
410
+ return !(await showConfirmation(unref(computed(() => t("MODULE.PAGES.ALERTS.CLOSE_CONFIRMATION")))));
433
411
  }
434
412
  return false;
435
413
  });
@@ -440,15 +418,15 @@ onBeforeClose(async () => {
440
418
 
441
419
  ## Field Type Mapping
442
420
 
443
- | TypeScript/API type | Component | Notes |
444
- |-------------------------|------------------------|--------------------------------------------|
445
- | `string` | `VcInput` | Default; add `rules="required"` if needed |
446
- | `boolean` | `VcSwitch` | No `Field` wrapper needed |
447
- | enum / reference type | `VcSelect` | Supply `:options`, `option-value`, `option-label` |
448
- | `Date` / `DateTime` | `VcInput type="datetime-local"` | Or `VcDatePicker` if available in project |
449
- | `number` / `bigint` | `VcInput type="number"` | Add `rules="bigint|min_value:0"` for integers |
450
- | `string[]` / array | `VcDataTable` | Inline read-only table (see Nested Collections) |
451
- | nested object array | `VcDataTable` | Inline read-only table (see Nested Collections) |
421
+ | TypeScript/API type | Component | Notes |
422
+ | --------------------- | ------------------------------- | ------------------------------------------------- | -------------------------- |
423
+ | `string` | `VcInput` | Default; add `rules="required"` if needed |
424
+ | `boolean` | `VcSwitch` | No `Field` wrapper needed |
425
+ | enum / reference type | `VcSelect` | Supply `:options`, `option-value`, `option-label` |
426
+ | `Date` / `DateTime` | `VcInput type="datetime-local"` | Or `VcDatePicker` if available in project |
427
+ | `number` / `bigint` | `VcInput type="number"` | Add `rules="bigint | min_value:0"` for integers |
428
+ | `string[]` / array | `VcDataTable` | Inline read-only table (see Nested Collections) |
429
+ | nested object array | `VcDataTable` | Inline read-only table (see Nested Collections) |
452
430
 
453
431
  ---
454
432
 
@@ -456,15 +434,16 @@ onBeforeClose(async () => {
456
434
 
457
435
  Rules are composed with `|` (pipe) separator:
458
436
 
459
- | Rule | Example | Description |
460
- |---------------|------------------------------------|--------------------------------|
461
- | `required` | `rules="required"` | Field must have a value |
462
- | `email` | `rules="required|email"` | Valid email format |
463
- | `min:N` | `rules="required|min:3"` | Minimum string length |
464
- | `min_value:N` | `rules="required|min_value:0"` | Minimum numeric value |
465
- | `bigint` | `rules="bigint|min_value:0"` | Integer (no decimals) |
437
+ | Rule | Example | Description |
438
+ | ------------- | ------------------ | ----------------------- | --------------------- |
439
+ | `required` | `rules="required"` | Field must have a value |
440
+ | `email` | `rules="required | email"` | Valid email format |
441
+ | `min:N` | `rules="required | min:3"` | Minimum string length |
442
+ | `min_value:N` | `rules="required | min_value:0"` | Minimum numeric value |
443
+ | `bigint` | `rules="bigint | min_value:0"` | Integer (no decimals) |
466
444
 
467
445
  **Dynamic rules** via `:rules` binding:
446
+
468
447
  ```vue
469
448
  <Field
470
449
  :rules="entity.trackInventory ? 'required|bigint|min_value:0' : 'bigint|min_value:0'"
@@ -494,8 +473,8 @@ Define columns as a computed from the nested type's fields:
494
473
  ```ts
495
474
  const lineItemColumns = computed<ITableColumns[]>(() => [
496
475
  { id: "productName", title: t("MODULE.LINE_ITEMS.PRODUCT"), alwaysVisible: true },
497
- { id: "quantity", title: t("MODULE.LINE_ITEMS.QUANTITY") },
498
- { id: "price", title: t("MODULE.LINE_ITEMS.PRICE") },
476
+ { id: "quantity", title: t("MODULE.LINE_ITEMS.QUANTITY") },
477
+ { id: "price", title: t("MODULE.LINE_ITEMS.PRICE") },
499
478
  ]);
500
479
  ```
501
480
 
@@ -507,8 +486,6 @@ The `VcDataTable` here is read-only — no toolbar, no selection, no pagination
507
486
 
508
487
  For details blades that display data without editing (e.g., order details, transaction history), use `VcField` instead of `VcInput`. This is a common pattern for view-only pages.
509
488
 
510
- Source: `apps/vendor-portal/src/modules/orders/pages/order-details.vue`
511
-
512
489
  ```vue
513
490
  <VcCard :header="$t('MODULE.SECTIONS.INFO.TITLE')">
514
491
  <div class="tw-p-4 tw-space-y-4">
@@ -541,12 +518,14 @@ Source: `apps/vendor-portal/src/modules/orders/pages/order-details.vue`
541
518
  ```
542
519
 
543
520
  Key `VcField` props:
521
+
544
522
  - `orientation="horizontal"` — label left, value right (default is vertical)
545
523
  - `:aspect-ratio="[1, 2]"` — label takes 1/3, value takes 2/3
546
524
  - `copyable` — adds a copy-to-clipboard button
547
525
  - `:tooltip` — adds an info icon with hover text
548
526
 
549
527
  Use `VcField` when:
528
+
550
529
  - The blade is read-only (order details, audit log, transaction view)
551
530
  - Showing summary/computed data that users don't edit
552
531
  - Displaying key-value pairs in a structured layout
@@ -557,17 +536,9 @@ Use `VcField` when:
557
536
 
558
537
  Use `VcBanner` at the top of a form to show contextual alerts, warnings, or informational messages based on entity state.
559
538
 
560
- Source: `apps/vendor-portal/src/modules/offers/pages/offers-details.vue`, `seller-details-edit.vue`
561
-
562
539
  ```vue
563
540
  <!-- Error banner (shown conditionally) -->
564
- <VcBanner
565
- v-if="errorMessage"
566
- variant="danger"
567
- icon="lucide-alert-circle"
568
- icon-size="l"
569
- icon-variant="danger"
570
- >
541
+ <VcBanner v-if="errorMessage" variant="danger" icon="lucide-alert-circle" icon-size="l" icon-variant="danger">
571
542
  <template #title>
572
543
  {{ $t("MODULE.ALERTS.ERROR") }}
573
544
  </template>
@@ -577,22 +548,12 @@ Source: `apps/vendor-portal/src/modules/offers/pages/offers-details.vue`, `selle
577
548
  </VcBanner>
578
549
 
579
550
  <!-- Info banner with action button -->
580
- <VcBanner
581
- v-if="!entity.id"
582
- variant="info"
583
- icon="lucide-lightbulb"
584
- icon-size="l"
585
- >
551
+ <VcBanner v-if="!entity.id" variant="info" icon="lucide-lightbulb" icon-size="l">
586
552
  {{ $t("MODULE.ALERTS.CREATE_NEW_HINT") }}
587
553
  </VcBanner>
588
554
 
589
555
  <!-- Warning banner with inline action -->
590
- <VcBanner
591
- v-if="entity.id && !entity.priceLists?.length"
592
- variant="info"
593
- icon="lucide-lightbulb"
594
- icon-size="l"
595
- >
556
+ <VcBanner v-if="entity.id && !entity.priceLists?.length" variant="info" icon="lucide-lightbulb" icon-size="l">
596
557
  <div class="tw-flex tw-flex-row tw-justify-between tw-items-center">
597
558
  <span>{{ $t("MODULE.ALERTS.MISSING_PRICES") }}</span>
598
559
  <VcButton
@@ -609,6 +570,7 @@ Source: `apps/vendor-portal/src/modules/offers/pages/offers-details.vue`, `selle
609
570
  Banner variants: `"info"`, `"warning"`, `"danger"`, `"success"`.
610
571
 
611
572
  Use banners when:
573
+
612
574
  - Entity is in a special state (new, error, incomplete)
613
575
  - User needs to take action (missing required data)
614
576
  - Showing validation errors at form level
@@ -619,27 +581,25 @@ Use banners when:
619
581
 
620
582
  Blade widgets appear as icon buttons in the blade sidebar, showing related entities with badge counts. Clicking a widget opens a child blade.
621
583
 
622
- Source: `apps/vendor-portal/src/modules/products/widgets/useProductWidgets.ts`
623
-
624
584
  ```ts
625
585
  import { useBladeWidgets, type UseBladeWidgetsReturn } from "@vc-shell/framework";
626
586
 
627
- export function useProductWidgets(options: { item: Ref<Product | undefined> }): UseBladeWidgetsReturn {
587
+ export function useEntityWidgets(options: { item: Ref<Entity | undefined> }): UseBladeWidgetsReturn {
628
588
  const { item } = options;
629
589
  const { openBlade } = useBlade();
630
590
 
631
- const { count: offersCount, loading: offersLoading, refresh: refreshOffers } = useOfferCount(item);
591
+ const { count: childCount, loading: childLoading, refresh: refreshChildren } = useChildCount(item);
632
592
 
633
593
  const widgets = useBladeWidgets([
634
594
  {
635
- id: "OffersWidget",
595
+ id: "ChildListWidget",
636
596
  icon: "lucide-tag",
637
- title: "PRODUCTS.PAGES.DETAILS.WIDGETS.OFFERS",
638
- badge: offersCount,
639
- loading: offersLoading,
597
+ title: "MODULE.PAGES.DETAILS.WIDGETS.CHILD_LIST",
598
+ badge: childCount,
599
+ loading: childLoading,
640
600
  isVisible: computed(() => !!item.value?.id),
641
- onClick: () => openBlade({ name: "Offers", options: { product: item.value } }),
642
- onRefresh: refreshOffers,
601
+ onClick: () => openBlade({ name: "ChildList", options: { entity: item.value } }),
602
+ onRefresh: refreshChildren,
643
603
  },
644
604
  // ... more widgets
645
605
  ]);
@@ -649,12 +609,14 @@ export function useProductWidgets(options: { item: Ref<Product | undefined> }):
649
609
  ```
650
610
 
651
611
  Use in the blade:
612
+
652
613
  ```ts
653
- const { widgets } = useProductWidgets({ item: entity });
614
+ const { widgets } = useEntityWidgets({ item: entity });
654
615
  ```
655
616
 
656
617
  Use widgets when:
657
- - Entity has related sub-entities (product → offers, videos, assets)
618
+
619
+ - Entity has related sub-entities (parent → children, attachments, history)
658
620
  - You want sidebar navigation with counts
659
621
  - Each widget opens a different child blade
660
622
 
@@ -676,46 +638,46 @@ Use widgets when:
676
638
 
677
639
  Use this table to choose the correct component for each field type during generation. The `formField.type` value comes from the design prompt analysis (Phase 2 of `/vc-app design`) or from API type inference.
678
640
 
679
- | Field Type | Component | When to Use | Notes |
680
- |---|---|---|---|
681
- | `string` | `VcInput` | Default for short text (name, title, email, phone, URL) | Use `type="number"` for numeric strings, `rules="email"` for emails |
682
- | `text` | `VcTextarea` | Long text: description, notes, comments, bio | Multi-line input, no formatting |
683
- | `rich-text` | `VcEditor` | HTML content: article body, email template, product description | WYSIWYG HTML editor |
684
- | `number` | `VcInput` | Plain numbers: quantity, count, age, priority | Set `type="number"`, use `rules="bigint\|min_value:0"` |
685
- | `currency` | `VcInputCurrency` | Money: price, cost, amount, salary, budget | Formatted with currency symbol and decimals |
686
- | `boolean` | `VcSwitch` | Toggle: isActive, isEnabled, isPublished | No `Field` wrapper needed |
687
- | `boolean` | `VcCheckbox` | Consent/agree: agreeTerms, acceptPolicy | Use when "agree/accept" semantics, not toggle |
688
- | `date-time` | `VcDatePicker` | Date/datetime: createdDate, deadline, startDate, birthday | Calendar picker, preferred over `VcInput type="datetime-local"` |
689
- | `enum` | `VcSelect` | Dropdown: status, type, category (6+ options or dynamic) | Use `option-value` + `option-label` |
690
- | `enum` | `VcRadioGroup` | Radio: priority, type (2-5 static options) | More visual for small option sets |
691
- | `multi-select` | `VcMultivalue` | Tags/multi-pick: tags, categories, permissions, roles | Tag-style chips with add/remove |
692
- | `multi-select` | `VcCheckboxGroup` | Multi-check: features, capabilities (few static options) | Vertical checkbox list |
693
- | `rating` | `VcRating` | Star rating: rating, score, quality | 1-5 star picker |
694
- | `range` | `VcSlider` | Range: discount, opacity, volume, percentage | Numeric slider with min/max |
695
- | `color` | `VcColorInput` | Color: brandColor, backgroundColor, themeColor | Color picker with hex input |
696
- | `image` | `VcImageUpload` | Single image: avatar, logo, thumbnail, banner | Upload with preview |
697
- | `gallery` | `VcGallery` | Multiple images: productPhotos, screenshots | Multi-image management grid |
698
- | `file` | `VcFileUpload` | Attachment: document, contract, certificate | File upload with accept filter |
641
+ | Field Type | Component | When to Use | Notes |
642
+ | -------------- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------- |
643
+ | `string` | `VcInput` | Default for short text (name, title, email, phone, URL) | Use `type="number"` for numeric strings, `rules="email"` for emails |
644
+ | `text` | `VcTextarea` | Long text: description, notes, comments, bio | Multi-line input, no formatting |
645
+ | `rich-text` | `VcEditor` | HTML content: article body, email template, product description | WYSIWYG HTML editor |
646
+ | `number` | `VcInput` | Plain numbers: quantity, count, age, priority | Set `type="number"`, use `rules="bigint\|min_value:0"` |
647
+ | `currency` | `VcInputCurrency` | Money: price, cost, amount, salary, budget | Formatted with currency symbol and decimals |
648
+ | `boolean` | `VcSwitch` | Toggle: isActive, isEnabled, isPublished | No `Field` wrapper needed |
649
+ | `boolean` | `VcCheckbox` | Consent/agree: agreeTerms, acceptPolicy | Use when "agree/accept" semantics, not toggle |
650
+ | `date-time` | `VcDatePicker` | Date/datetime: createdDate, deadline, startDate, birthday | Calendar picker, preferred over `VcInput type="datetime-local"` |
651
+ | `enum` | `VcSelect` | Dropdown: status, type, category (6+ options or dynamic) | Use `option-value` + `option-label` |
652
+ | `enum` | `VcRadioGroup` | Radio: priority, type (2-5 static options) | More visual for small option sets |
653
+ | `multi-select` | `VcMultivalue` | Tags/multi-pick: tags, categories, permissions, roles | Tag-style chips with add/remove |
654
+ | `multi-select` | `VcCheckboxGroup` | Multi-check: features, capabilities (few static options) | Vertical checkbox list |
655
+ | `rating` | `VcRating` | Star rating: rating, score, quality | 1-5 star picker |
656
+ | `range` | `VcSlider` | Range: discount, opacity, volume, percentage | Numeric slider with min/max |
657
+ | `color` | `VcColorInput` | Color: brandColor, backgroundColor, themeColor | Color picker with hex input |
658
+ | `image` | `VcImageUpload` | Single image: avatar, logo, thumbnail, banner | Upload with preview |
659
+ | `gallery` | `VcGallery` | Multiple images: productPhotos, screenshots | Multi-image management grid |
660
+ | `file` | `VcFileUpload` | Attachment: document, contract, certificate | File upload with accept filter |
699
661
 
700
662
  ### Selection heuristics (when type is ambiguous)
701
663
 
702
664
  When the field type from prompt analysis is plain `"string"`, use field name patterns to upgrade:
703
665
 
704
- | Field name pattern | Upgrade to |
705
- |---|---|
706
- | `description`, `notes`, `comment`, `bio`, `summary`, `about` | `text` → `VcTextarea` |
707
- | `body`, `content`, `html`, `template`, `article` | `rich-text` → `VcEditor` |
708
- | `price`, `cost`, `amount`, `total`, `salary`, `budget`, `fee` | `currency` → `VcInputCurrency` |
709
- | `avatar`, `logo`, `photo`, `thumbnail`, `banner`, `icon` | `image` → `VcImageUpload` |
710
- | `photos`, `images`, `screenshots`, `gallery` | `gallery` → `VcGallery` |
711
- | `file`, `attachment`, `document`, `contract`, `certificate` | `file` → `VcFileUpload` |
712
- | `tags`, `labels`, `categories`, `roles`, `permissions` | `multi-select` → `VcMultivalue` |
713
- | `rating`, `score`, `stars` | `rating` → `VcRating` |
714
- | `color`, `colour`, `brandColor`, `backgroundColor` | `color` → `VcColorInput` |
715
- | `discount`, `opacity`, `volume`, `percentage`, `progress` | `range` → `VcSlider` |
716
- | `email` | `string` → `VcInput` with `rules="required\|email"` |
717
- | `phone`, `tel` | `string` → `VcInput` with `type="tel"` |
718
- | `url`, `website`, `link` | `string` → `VcInput` with `type="url"` |
666
+ | Field name pattern | Upgrade to |
667
+ | ------------------------------------------------------------- | --------------------------------------------------- |
668
+ | `description`, `notes`, `comment`, `bio`, `summary`, `about` | `text` → `VcTextarea` |
669
+ | `body`, `content`, `html`, `template`, `article` | `rich-text` → `VcEditor` |
670
+ | `price`, `cost`, `amount`, `total`, `salary`, `budget`, `fee` | `currency` → `VcInputCurrency` |
671
+ | `avatar`, `logo`, `photo`, `thumbnail`, `banner`, `icon` | `image` → `VcImageUpload` |
672
+ | `photos`, `images`, `screenshots`, `gallery` | `gallery` → `VcGallery` |
673
+ | `file`, `attachment`, `document`, `contract`, `certificate` | `file` → `VcFileUpload` |
674
+ | `tags`, `labels`, `categories`, `roles`, `permissions` | `multi-select` → `VcMultivalue` |
675
+ | `rating`, `score`, `stars` | `rating` → `VcRating` |
676
+ | `color`, `colour`, `brandColor`, `backgroundColor` | `color` → `VcColorInput` |
677
+ | `discount`, `opacity`, `volume`, `percentage`, `progress` | `range` → `VcSlider` |
678
+ | `email` | `string` → `VcInput` with `rules="required\|email"` |
679
+ | `phone`, `tel` | `string` → `VcInput` with `type="tel"` |
680
+ | `url`, `website`, `link` | `string` → `VcInput` with `type="url"` |
719
681
 
720
682
  ### Layout heuristics
721
683
 
@@ -17,10 +17,10 @@ Cross-module UI composition without compile-time dependencies. One module declar
17
17
 
18
18
  ### Two Roles
19
19
 
20
- | Role | API | Purpose |
21
- |------|-----|---------|
22
- | **Host** | `<ExtensionPoint>` or `defineExtensionPoint()` | Declares a named region that accepts plugins |
23
- | **Plugin** | `useExtensionPoint()` | Registers components into a named region |
20
+ | Role | API | Purpose |
21
+ | ---------- | ---------------------------------------------- | -------------------------------------------- |
22
+ | **Host** | `<ExtensionPoint>` or `defineExtensionPoint()` | Declares a named region that accepts plugins |
23
+ | **Plugin** | `useExtensionPoint()` | Registers components into a named region |
24
24
 
25
25
  Neither side imports the other. They communicate through a shared **name string**.
26
26
 
@@ -50,7 +50,7 @@ The simplest approach -- declares the point and renders registered components in
50
50
 
51
51
  <ExtensionPoint
52
52
  v-if="sellerDetails?.id"
53
- name="seller:commissions"
53
+ name="entity:custom-fields"
54
54
  wrapper-class="tw-p-2"
55
55
  />
56
56
  </VcBlade>
@@ -63,14 +63,14 @@ import { ExtensionPoint } from "@vc-shell/framework";
63
63
 
64
64
  **Props:**
65
65
 
66
- | Prop | Type | Default | Description |
67
- |------|------|---------|-------------|
68
- | `name` | `string` | required | Extension point name |
69
- | `separator` | `boolean` | `false` | Adds `<hr>` before components |
70
- | `separatorClass` | `string` | built-in | Custom CSS class for `<hr>` |
71
- | `wrapperClass` | `string` | none | CSS class for wrapper div |
72
- | `gap` | `string` | none | CSS gap (e.g. `"1rem"`) |
73
- | `filter` | `Record<string, unknown>` | none | Filter by meta field equality |
66
+ | Prop | Type | Default | Description |
67
+ | ---------------- | ------------------------- | -------- | ----------------------------- |
68
+ | `name` | `string` | required | Extension point name |
69
+ | `separator` | `boolean` | `false` | Adds `<hr>` before components |
70
+ | `separatorClass` | `string` | built-in | Custom CSS class for `<hr>` |
71
+ | `wrapperClass` | `string` | none | CSS class for wrapper div |
72
+ | `gap` | `string` | none | CSS gap (e.g. `"1rem"`) |
73
+ | `filter` | `Record<string, unknown>` | none | Filter by meta field equality |
74
74
 
75
75
  ### Composable: `defineExtensionPoint()`
76
76
 
@@ -118,17 +118,19 @@ A module registers components into an extension point declared by another module
118
118
  ```typescript
119
119
  // commissions-module/index.ts
120
120
  import { defineAppModule, useExtensionPoint } from "@vc-shell/framework";
121
- import CommissionFields from "./components/CommissionFields.vue";
121
+ import CustomFields from "./components/CustomFields.vue";
122
122
 
123
- const { add } = useExtensionPoint("seller:commissions");
123
+ const { add } = useExtensionPoint("entity:custom-fields");
124
124
  add({
125
- id: "marketplace:commission-fields",
126
- component: CommissionFields,
125
+ id: "module:custom-fields",
126
+ component: CustomFields,
127
127
  props: { editable: true },
128
128
  priority: 10,
129
129
  });
130
130
 
131
- export default defineAppModule({ /* locales, blades, etc. */ });
131
+ export default defineAppModule({
132
+ /* locales, blades, etc. */
133
+ });
132
134
  ```
133
135
 
134
136
  ### Using Framework Constants
@@ -149,14 +151,14 @@ add({
149
151
 
150
152
  Currently defined framework constants:
151
153
 
152
- | Constant | Value | Location |
153
- |----------|-------|----------|
154
+ | Constant | Value | Location |
155
+ | --------------------------------- | ------------------- | ------------------------------ |
154
156
  | `ExtensionPoints.AUTH_AFTER_FORM` | `"auth:after-form"` | Login page, below sign-in form |
155
157
 
156
158
  ### Removing a Registration
157
159
 
158
160
  ```typescript
159
- const { add, remove } = useExtensionPoint("seller:commissions");
161
+ const { add, remove } = useExtensionPoint("entity:custom-fields");
160
162
  add({ id: "my-fields", component: MyFields });
161
163
 
162
164
  // Later (e.g., during cleanup):
@@ -172,8 +174,8 @@ Props are passed via the `props` field in `add()` and bound with `v-bind`:
172
174
  ```typescript
173
175
  add({
174
176
  id: "commission-fields",
175
- component: CommissionFields,
176
- props: { editable: true, sellerId: "abc-123" },
177
+ component: CustomFields,
178
+ props: { editable: true, entityId: "abc-123" },
177
179
  priority: 10,
178
180
  });
179
181
  ```
@@ -184,7 +186,7 @@ The injected component receives them as standard Vue props:
184
186
  <script setup lang="ts">
185
187
  const props = defineProps<{
186
188
  editable?: boolean;
187
- sellerId?: string;
189
+ entityId?: string;
188
190
  }>();
189
191
  </script>
190
192
  ```
@@ -199,19 +201,25 @@ Categorize extensions with `meta` and render different subsets in different loca
199
201
 
200
202
  ```typescript
201
203
  const { add } = useExtensionPoint("product:details");
202
- add({ id: "specs-tab", component: SpecsTab, meta: { zone: "tabs" }, priority: 10 });
203
- add({ id: "review-tab", component: ReviewTab, meta: { zone: "tabs" }, priority: 20 });
204
- add({ id: "quick-action", component: QuickAction, meta: { zone: "toolbar" } });
204
+ add({ id: "specs-tab", component: SpecsTab, meta: { zone: "tabs" }, priority: 10 });
205
+ add({ id: "review-tab", component: ReviewTab, meta: { zone: "tabs" }, priority: 20 });
206
+ add({ id: "quick-action", component: QuickAction, meta: { zone: "toolbar" } });
205
207
  ```
206
208
 
207
209
  ```vue
208
210
  <template>
209
211
  <VcBlade title="Product Details">
210
212
  <div class="toolbar">
211
- <ExtensionPoint name="product:details" :filter="{ zone: 'toolbar' }" />
213
+ <ExtensionPoint
214
+ name="product:details"
215
+ :filter="{ zone: 'toolbar' }"
216
+ />
212
217
  </div>
213
218
  <div class="tabs">
214
- <ExtensionPoint name="product:details" :filter="{ zone: 'tabs' }" />
219
+ <ExtensionPoint
220
+ name="product:details"
221
+ :filter="{ zone: 'tabs' }"
222
+ />
215
223
  </div>
216
224
  </VcBlade>
217
225
  </template>
@@ -259,7 +267,9 @@ add({
259
267
  priority: 20,
260
268
  });
261
269
 
262
- export default defineAppModule({ /* ... */ });
270
+ export default defineAppModule({
271
+ /* ... */
272
+ });
263
273
  ```
264
274
 
265
275
  **Step 3 -- The injected component:**
@@ -286,23 +296,22 @@ const carrier = ref("FedEx");
286
296
 
287
297
  ## Common Mistakes
288
298
 
289
- | Mistake | Symptom | Fix |
290
- |---------|---------|-----|
291
- | Typo in extension point name | Component registered but never rendered | Check dev console for `"Extension point X is not declared"` warning. Use shared constants. |
292
- | Duplicate `id` across modules | Later registration silently replaces the earlier one | Prefix IDs with module name: `"shipping:tracking-tab"` |
293
- | Forgetting `import { ExtensionPoint }` in host template | Vue renders nothing (unknown component) | Add the import in `<script setup>` |
294
- | Calling `defineExtensionPoint` outside setup context | Computed refs not reactive | Call inside `<script setup>` or a composable used during setup |
299
+ | Mistake | Symptom | Fix |
300
+ | ------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------ |
301
+ | Typo in extension point name | Component registered but never rendered | Check dev console for `"Extension point X is not declared"` warning. Use shared constants. |
302
+ | Duplicate `id` across modules | Later registration silently replaces the earlier one | Prefix IDs with module name: `"shipping:tracking-tab"` |
303
+ | Forgetting `import { ExtensionPoint }` in host template | Vue renders nothing (unknown component) | Add the import in `<script setup>` |
304
+ | Calling `defineExtensionPoint` outside setup context | Computed refs not reactive | Call inside `<script setup>` or a composable used during setup |
295
305
 
296
306
  ---
297
307
 
298
308
  ## Related
299
309
 
300
- | Resource | Path |
301
- |----------|------|
310
+ | Resource | Path |
311
+ | ----------------------------------- | ------------------------------------------------------------------ |
302
312
  | Extension Points Plugin (full docs) | `framework/core/plugins/extension-points/extension-points.docs.md` |
303
- | Store implementation | `framework/core/plugins/extension-points/store.ts` |
304
- | ExtensionPoint component | `framework/core/plugins/extension-points/ExtensionPoint.vue` |
305
- | Types | `framework/core/plugins/extension-points/types.ts` |
306
- | Public API exports | `framework/core/plugins/extension-points/public.ts` |
307
- | Real-world host usage | `apps/vendor-portal/src/modules/seller-details/pages/seller-details-edit.vue` |
308
- | Framework host usage | `framework/shell/auth/LoginPage/components/login/Login.vue` |
313
+ | Store implementation | `framework/core/plugins/extension-points/store.ts` |
314
+ | ExtensionPoint component | `framework/core/plugins/extension-points/ExtensionPoint.vue` |
315
+ | Types | `framework/core/plugins/extension-points/types.ts` |
316
+ | Public API exports | `framework/core/plugins/extension-points/public.ts` |
317
+ | Framework host usage | `framework/shell/auth/LoginPage/components/login/Login.vue` |