@vc-shell/vc-app-skill 2.0.3 → 2.0.4-pr228.1e79eae

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 (154) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/package.json +1 -1
  3. package/runtime/VERSION +1 -1
  4. package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
  5. package/runtime/knowledge/docs/core/api/platform.docs.md +7 -0
  6. package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +20 -4
  7. package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +15 -3
  8. package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +13 -4
  9. package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +10 -0
  10. package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +6 -0
  11. package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +6 -0
  12. package/runtime/knowledge/docs/core/composables/useAssets/useAssets.docs.md +8 -1
  13. package/runtime/knowledge/docs/core/composables/useAssetsManager/useAssetsManager.docs.md +15 -4
  14. package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +13 -0
  15. package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +6 -0
  16. package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +13 -0
  17. package/runtime/knowledge/docs/core/composables/useBladeForm/useBladeForm.docs.md +12 -2
  18. package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +14 -4
  19. package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +23 -9
  20. package/runtime/knowledge/docs/core/composables/useBreadcrumbs/useBreadcrumbs.docs.md +6 -0
  21. package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md +10 -0
  22. package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +9 -0
  23. package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +6 -0
  24. package/runtime/knowledge/docs/core/composables/useErrorHandler/useErrorHandler.docs.md +6 -0
  25. package/runtime/knowledge/docs/core/composables/useFunctions/useFunctions.docs.md +6 -0
  26. package/runtime/knowledge/docs/core/composables/useKeyboardNavigation/useKeyboardNavigation.docs.md +10 -0
  27. package/runtime/knowledge/docs/core/composables/useLanguages/useLanguages.docs.md +6 -0
  28. package/runtime/knowledge/docs/core/composables/useLoading/useLoading.docs.md +10 -0
  29. package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +10 -0
  30. package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +9 -0
  31. package/runtime/knowledge/docs/core/composables/useModificationTracker/useModificationTracker.docs.md +6 -0
  32. package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +6 -0
  33. package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +9 -0
  34. package/runtime/knowledge/docs/core/composables/usePopup/usePopup.docs.md +9 -0
  35. package/runtime/knowledge/docs/core/composables/useResponsive/useResponsive.docs.md +10 -0
  36. package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +6 -0
  37. package/runtime/knowledge/docs/core/composables/useSettingsMenu/useSettingsMenu.docs.md +6 -0
  38. package/runtime/knowledge/docs/core/composables/useSidebarState/useSidebarState.docs.md +10 -0
  39. package/runtime/knowledge/docs/core/composables/useSlowNetworkDetection/useSlowNetworkDetection.docs.md +9 -0
  40. package/runtime/knowledge/docs/core/composables/useTheme/useTheme.docs.md +9 -0
  41. package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +9 -0
  42. package/runtime/knowledge/docs/core/composables/useUser/useUser.docs.md +6 -0
  43. package/runtime/knowledge/docs/core/composables/useUserManagement/useUserManagement.docs.md +7 -0
  44. package/runtime/knowledge/docs/core/composables/useWebVitals/useWebVitals.docs.md +6 -0
  45. package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +10 -0
  46. package/runtime/knowledge/docs/core/directives/autofocus/autofocus.docs.md +7 -0
  47. package/runtime/knowledge/docs/core/directives/loading/loading.docs.md +7 -0
  48. package/runtime/knowledge/docs/core/notifications/notifications.docs.md +21 -0
  49. package/runtime/knowledge/docs/core/plugins/ai-agent/ai-agent.docs.md +7 -0
  50. package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +10 -0
  51. package/runtime/knowledge/docs/core/plugins/global-error-handler/global-error-handler.docs.md +7 -0
  52. package/runtime/knowledge/docs/core/plugins/i18n/i18n.docs.md +10 -0
  53. package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +10 -0
  54. package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +8 -1
  55. package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +7 -0
  56. package/runtime/knowledge/docs/core/plugins/validation/validation.docs.md +10 -0
  57. package/runtime/knowledge/docs/core/services/services.docs.md +16 -1
  58. package/runtime/knowledge/docs/core/types/types.docs.md +7 -0
  59. package/runtime/knowledge/docs/core/utilities/date/date-utilities.docs.md +7 -0
  60. package/runtime/knowledge/docs/core/utilities/shared-utilities.docs.md +7 -0
  61. package/runtime/knowledge/docs/core/utilities/thumbnail/thumbnail.docs.md +7 -0
  62. package/runtime/knowledge/docs/core/utilities/utilities.docs.md +7 -0
  63. package/runtime/knowledge/docs/injection-keys.docs.md +11 -0
  64. package/runtime/knowledge/docs/modules/assets-manager/assets-manager.docs.md +89 -12
  65. package/runtime/knowledge/docs/shell/_internal/popup/common/popup-common.docs.md +7 -0
  66. package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +7 -0
  67. package/runtime/knowledge/docs/shell/auth/ForgotPasswordPage/forgot-password-page.docs.md +7 -0
  68. package/runtime/knowledge/docs/shell/auth/InvitePage/invite-page.docs.md +7 -0
  69. package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +7 -0
  70. package/runtime/knowledge/docs/shell/auth/ResetPasswordPage/reset-password-page.docs.md +7 -0
  71. package/runtime/knowledge/docs/shell/auth/sign-in/sign-in.docs.md +7 -0
  72. package/runtime/knowledge/docs/shell/components/change-password/change-password.docs.md +7 -0
  73. package/runtime/knowledge/docs/shell/components/change-password-button/change-password-button.docs.md +7 -0
  74. package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +7 -0
  75. package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +7 -0
  76. package/runtime/knowledge/docs/shell/components/logout-button/logout-button.docs.md +7 -0
  77. package/runtime/knowledge/docs/shell/components/notification-dropdown/notification-dropdown.docs.md +7 -0
  78. package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +7 -0
  79. package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +7 -0
  80. package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +7 -0
  81. package/runtime/knowledge/docs/shell/components/sidebar/sidebar.docs.md +7 -0
  82. package/runtime/knowledge/docs/shell/components/theme-selector/theme-selector.docs.md +7 -0
  83. package/runtime/knowledge/docs/shell/components/user-dropdown-button/user-dropdown-button.docs.md +7 -0
  84. package/runtime/knowledge/docs/shell/dashboard/dashboard-charts/dashboard-charts.docs.md +7 -0
  85. package/runtime/knowledge/docs/shell/dashboard/dashboard-widget-card/dashboard-widget-card.docs.md +7 -0
  86. package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +7 -0
  87. package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +24 -0
  88. package/runtime/knowledge/docs/ui/components/atoms/vc-banner/vc-banner.docs.md +20 -0
  89. package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +32 -5
  90. package/runtime/knowledge/docs/ui/components/atoms/vc-card/vc-card.docs.md +15 -2
  91. package/runtime/knowledge/docs/ui/components/atoms/vc-col/vc-col.docs.md +11 -1
  92. package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +10 -0
  93. package/runtime/knowledge/docs/ui/components/atoms/vc-hint/vc-hint.docs.md +20 -0
  94. package/runtime/knowledge/docs/ui/components/atoms/vc-icon/vc-icon.docs.md +24 -0
  95. package/runtime/knowledge/docs/ui/components/atoms/vc-image/vc-image.docs.md +26 -0
  96. package/runtime/knowledge/docs/ui/components/atoms/vc-label/vc-label.docs.md +24 -0
  97. package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +22 -0
  98. package/runtime/knowledge/docs/ui/components/atoms/vc-loading/vc-loading.docs.md +21 -0
  99. package/runtime/knowledge/docs/ui/components/atoms/vc-progress/vc-progress.docs.md +20 -0
  100. package/runtime/knowledge/docs/ui/components/atoms/vc-row/vc-row.docs.md +11 -1
  101. package/runtime/knowledge/docs/ui/components/atoms/vc-scrollable-container/vc-scrollable-container.docs.md +11 -1
  102. package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +20 -0
  103. package/runtime/knowledge/docs/ui/components/atoms/vc-status/vc-status.docs.md +20 -0
  104. package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +20 -0
  105. package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +25 -1
  106. package/runtime/knowledge/docs/ui/components/atoms/vc-video/vc-video.docs.md +25 -0
  107. package/runtime/knowledge/docs/ui/components/atoms/vc-widget/vc-widget.docs.md +22 -0
  108. package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +10 -0
  109. package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +17 -0
  110. package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +27 -0
  111. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +27 -0
  112. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +23 -0
  113. package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +24 -0
  114. package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +27 -0
  115. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown/vc-dropdown.docs.md +27 -0
  116. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +22 -0
  117. package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +17 -0
  118. package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +17 -0
  119. package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +17 -0
  120. package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +15 -0
  121. package/runtime/knowledge/docs/ui/components/molecules/vc-image-tile/vc-image-tile.docs.md +12 -0
  122. package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +30 -0
  123. package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +27 -0
  124. package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +26 -0
  125. package/runtime/knowledge/docs/ui/components/molecules/vc-input-group/vc-input-group.docs.md +21 -0
  126. package/runtime/knowledge/docs/ui/components/molecules/vc-menu/vc-menu.docs.md +24 -0
  127. package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +28 -0
  128. package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +25 -0
  129. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +25 -0
  130. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +22 -0
  131. package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +17 -0
  132. package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +32 -0
  133. package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +22 -0
  134. package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +25 -0
  135. package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +27 -0
  136. package/runtime/knowledge/docs/ui/components/molecules/vc-toast/vc-toast.docs.md +28 -0
  137. package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +19 -0
  138. package/runtime/knowledge/docs/ui/components/organisms/vc-auth-layout/vc-auth-layout.docs.md +13 -0
  139. package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +22 -1
  140. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +30 -5
  141. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +18 -0
  142. package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +12 -0
  143. package/runtime/knowledge/docs/ui/components/organisms/vc-gallery/vc-gallery.docs.md +14 -0
  144. package/runtime/knowledge/docs/ui/components/organisms/vc-image-upload/vc-image-upload.docs.md +12 -0
  145. package/runtime/knowledge/docs/ui/components/organisms/vc-popup/vc-popup.docs.md +14 -1
  146. package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +13 -0
  147. package/runtime/knowledge/docs/ui/composables/ui-composables.docs.md +7 -0
  148. package/runtime/knowledge/docs/ui/composables/useDataTablePagination.docs.md +9 -3
  149. package/runtime/knowledge/docs/ui/composables/useDataTableSort.docs.md +6 -0
  150. package/runtime/knowledge/docs/ui/composables/useTableSelection.docs.md +6 -0
  151. package/runtime/knowledge/docs/ui/composables/useTableSort.docs.md +6 -0
  152. package/runtime/knowledge/docs/ui/types/ui-types.docs.md +7 -0
  153. package/runtime/knowledge/docs/core/composables/usePlatformLocaleSync/usePlatformLocaleSync.docs.md +0 -28
  154. package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/dashboard-widget-skeleton.docs.md +0 -26
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.4](https://github.com/VirtoCommerce/vc-shell/compare/v2.0.3...v2.0.4) (2026-05-18)
4
+
5
+ **Note:** Version bump only for package @vc-shell/vc-app-skill
6
+
3
7
  ## [2.0.3](https://github.com/VirtoCommerce/vc-shell/compare/v2.0.2...v2.0.3) (2026-04-30)
4
8
 
5
9
  **Note:** Version bump only for package @vc-shell/vc-app-skill
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vc-shell/vc-app-skill",
3
- "version": "2.0.3",
3
+ "version": "2.0.4-pr228.1e79eae",
4
4
  "description": "AI coding skill for scaffolding and generating VirtoCommerce Shell applications. Works with Claude Code, OpenCode, Gemini, Codex, Cursor.",
5
5
  "bin": "./bin/install.cjs",
6
6
  "files": [
package/runtime/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.3
1
+ 2.0.4
@@ -1 +1 @@
1
- Synced from framework at commit d658f5b4c on 2026-04-30T07:59:28.391Z
1
+ Synced from framework at commit d15c26a1e on 2026-05-18T12:39:15.446Z
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: Platform Client
3
+ category: reference
4
+ group: api
5
+ slug: platform-client
6
+ ---
7
+
1
8
  # Platform API Client
2
9
 
3
10
  Auto-generated TypeScript API client for the VirtoCommerce Platform REST API. Generated by NSwag from the platform's Swagger/OpenAPI specification.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: Blade Navigation Composables
3
+ category: composables
4
+ group: blade-navigation
5
+ ---
6
+
1
7
  # Blade Navigation Composables
2
8
 
3
9
  The core composables that implement the blade navigation system -- the stacked-panel UI paradigm used throughout VirtoCommerce admin applications.
@@ -14,7 +20,9 @@ Blade navigation manages an ordered stack of blade descriptors (plain data objec
14
20
 
15
21
  - Build or extend the blade navigation infrastructure itself (plugin authors, framework internals)
16
22
  - Need direct access to the blade stack state machine (`useBladeStack`) or inter-blade messaging (`useBladeMessaging`)
17
- - When NOT to use: for everyday blade operations in modules -- prefer `useBlade()` from `core/composables/useBlade/`, which wraps these low-level composables with a cleaner, context-aware API
23
+ - When NOT to use: for everyday blade operations in modules -- prefer `useBlade()`, which wraps these low-level composables with a cleaner, context-aware API
24
+
25
+ <!-- internal:start -->
18
26
 
19
27
  ## Exports
20
28
 
@@ -24,6 +32,8 @@ export { createBladeStack, useBladeStack } from "./useBladeStack";
24
32
  export { createBladeMessaging, useBladeMessaging } from "./useBladeMessaging";
25
33
  ```
26
34
 
35
+ <!-- internal:end -->
36
+
27
37
  ## useBladeStack
28
38
 
29
39
  The blade stack state machine. Manages an ordered array of `BladeDescriptor` objects.
@@ -139,7 +149,7 @@ The plain data object stored in the stack for each blade:
139
149
 
140
150
  ## Tips
141
151
 
142
- - Prefer `useBlade()` / `useBladeContext()` (from `core/composables/useBlade/`) for new code -- they provide a cleaner API than the legacy adapter.
152
+ - Prefer `useBlade()` / `useBladeContext()` for new code -- they provide a cleaner API than the legacy adapter.
143
153
  - Close guards return `true` to PREVENT closing (opposite of the legacy convention where `false` prevented closing). The adapter handles the inversion.
144
154
  - `replaceCurrentBlade` destroys the current blade and creates a new one at the same index with the same `parentId`. Use `coverCurrentBlade` to hide instead of destroy — the covering blade's `callParent` reaches the hidden blade's exposed methods.
145
155
  - URL sync only updates the address bar for blades that have a `url` segment. Third-level detail panels without URLs leave the previous URL intact.
@@ -147,6 +157,12 @@ The plain data object stored in the stack for each blade:
147
157
 
148
158
  ## Related
149
159
 
160
+ - [`useBlade`](../composables/useBlade/) -- recommended API for everyday blade operations
161
+ - [`useBladeContext`](../composables/bladeContext/) -- share reactive blade data with descendant components
162
+
163
+ <!-- internal:start -->
164
+
150
165
  - `framework/core/composables/useBlade/` -- `useBlade()`, `useBladeContext()` (new API)
151
- - `framework/shared/components/blade-navigation/plugin-v2.ts` -- plugin that creates and provides the stack/messaging
152
- - `framework/shared/components/blade-navigation/types.ts` -- `BladeDescriptor`, `IBladeStack`, `IBladeMessaging`
166
+ - `framework/shell/_internal/blade-nav/plugin-v2.ts` -- plugin that creates and provides the stack/messaging
167
+ - `framework/core/blade-navigation/types/index.ts` -- `BladeDescriptor`, `IBladeStack`, `IBladeMessaging`
168
+ <!-- internal:end -->
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: useBladeContext
3
+ category: composables
4
+ group: blade-navigation
5
+ slug: useBladeContext
6
+ ---
7
+
1
8
  # useBladeContext (defineBladeContext / injectBladeContext)
2
9
 
3
10
  Exposes blade-level data to descendant widgets, extensions, and nested components via Vue's provide/inject mechanism. This pair of functions eliminates the need for prop drilling when child widgets or extension points need access to the parent blade's entity data, loading flags, or other shared state.
@@ -96,7 +103,7 @@ defineBladeContext(
96
103
 
97
104
  - **Automatic ref unwrapping**: `defineBladeContext` shallow-unwraps all ref/computed values in the provided object. Consumers get plain values directly (`ctx.value.item` instead of `ctx.value.item.value`). This works reactively — when the source ref changes, the context updates automatically.
98
105
  - **Reactivity**: The provided context is always wrapped in a `computed`, so consumers receive a `ComputedRef` regardless of whether the provider passed a plain object, a ref, or a getter. Changes propagate automatically.
99
- - **Injection key**: Uses `BladeContextKey` from `framework/injection-keys.ts`. This is a framework-level Symbol, so there is no risk of key collision with application code.
106
+ - **Injection key**: Uses `BladeContextKey` (a framework-level Symbol), so there is no risk of key collision with application code.
100
107
  - **Error handling**: `injectBladeContext` throws an `InjectionError` with a descriptive message if called outside a blade component tree. This fails fast during development rather than silently returning `undefined`.
101
108
  - **Scope**: The context is scoped to the Vue component subtree. Each blade in the stack has its own context, so nested blades do not leak data upward or sideways.
102
109
 
@@ -108,6 +115,11 @@ defineBladeContext(
108
115
 
109
116
  ## Related
110
117
 
118
+ - [`useBladeWidgets`](../useBladeWidgets/) -- widgets that consume blade context
119
+ - [`useBlade`](../useBlade/) -- cross-blade communication via `callParent` / `exposeToChildren`
120
+
121
+ <!-- internal:start -->
122
+
111
123
  - `BladeContextKey` in `framework/injection-keys.ts`
112
- - `useBladeWidgets` -- widgets that consume blade context
113
- - `useBladeStack` -- manages the blade navigation stack
124
+ - `useBladeStack` in `framework/core/blade-navigation/` -- manages the blade navigation stack
125
+ <!-- internal:end -->
@@ -1,7 +1,16 @@
1
+ ---
2
+ title: useApiClient
3
+ category: composables
4
+ group: data
5
+ ---
6
+
1
7
  # useApiClient
2
8
 
3
9
  Creates a typed API client instance for communicating with VirtoCommerce platform APIs. The composable accepts a generated client class constructor and returns an async factory function that produces a configured, authenticated client. Base URL resolution and authentication token injection are handled automatically.
4
10
 
11
+ !!! tip "Always call getApiClient inside async functions"
12
+ `getApiClient` is async. Never call it at the top level of `<script setup>` — always call it inside the async function you pass to `useAsync`. Storing the client in a variable outside the function gives you a stale reference when tokens rotate.
13
+
5
14
  ## When to Use
6
15
 
7
16
  - Instantiate a generated VirtoCommerce API client with automatic authentication and base-URL resolution
@@ -291,7 +300,7 @@ API clients are generated from Swagger/OpenAPI specs using the `@vc-shell/api-cl
291
300
 
292
301
  ## Related
293
302
 
294
- - [useAsync](../useAsync/) -- wraps async API calls with loading/error state management
295
- - [CLI API Client Generator](../../../../cli/) -- generates typed client classes from Swagger specs
296
- - [useToolbar](../useToolbar/) -- disable toolbar buttons during API calls using the loading ref
297
- - [useNotifications](../useNotifications/) -- display success/error messages after API operations
303
+ - [`useAsync`](../useAsync/) -- wraps async API calls with loading/error state management
304
+ - CLI API Client Generator (`@vc-shell/api-client-generator`) -- generates typed client classes from Swagger specs
305
+ - [`useToolbar`](../useToolbar/) -- disable toolbar buttons during API calls using the loading ref
306
+ - [`useNotifications`](../useNotifications/) -- display success/error messages after API operations
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useAppBarMobileButtons
3
+ category: composables
4
+ group: services
5
+ ---
6
+
1
7
  # useAppBarMobileButtons
2
8
 
3
9
  Manages custom action buttons in the mobile app bar. Uses provide/inject to share a singleton service across the component tree. This composable gives any blade or module the ability to register, update, and remove buttons that appear in the top app bar on mobile devices. Buttons are sorted by their `order` property and can include icons, custom Vue components, click handlers, badges, and reactive visibility toggles. The service is scoped to the VcApp tree and automatically cleans up when the scope is disposed.
@@ -59,6 +65,8 @@ onUnmounted(() => unregister("notifications-btn"));
59
65
  | `isVisible` | `MaybeRef<boolean>` | No | Reactive visibility toggle. When `false`, the button is excluded from `getButtons`. Defaults to `true`. |
60
66
  | `badge` | `MaybeRef<boolean>` | No | Show a small badge indicator on the button (e.g., for unread notifications). |
61
67
 
68
+ <!-- internal:start -->
69
+
62
70
  ## Setup
63
71
 
64
72
  `provideAppBarMobileButtonsService()` must be called once in the app root (VcApp). It is idempotent -- calling it again in the same injection tree returns the existing service. Descendant components then call `useAppBarMobileButtons()` to register buttons.
@@ -70,6 +78,8 @@ import { provideAppBarMobileButtonsService } from "@vc-shell/framework";
70
78
  provideAppBarMobileButtonsService();
71
79
  ```
72
80
 
81
+ <!-- internal:end -->
82
+
73
83
  ## Recipe: Filter Toggle Button That Reflects Active State
74
84
 
75
85
  ```vue
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useAppBarWidget
3
+ category: composables
4
+ group: services
5
+ ---
6
+
1
7
  # useAppBarWidget
2
8
 
3
9
  Provides access to the app bar widget service for registering custom widgets (buttons, icons, dropdowns) in the application's top navigation bar. Uses Vue's provide/inject system.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useAppInsights
3
+ category: composables
4
+ group: utilities
5
+ ---
6
+
1
7
  # useAppInsights
2
8
 
3
9
  Integrates Azure Application Insights page-view tracking with Vue Router and the current user context. This composable bridges the `vue3-application-insights` plugin with the vc-shell framework by automatically enriching every page-view event with the authenticated user's ID and name, generating fresh W3C trace IDs per navigation for distributed tracing, and optionally prefixing page names with the application name (e.g., `[Vendor Portal] Dashboard`).
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useAssets
3
+ category: composables
4
+ group: data
5
+ ---
6
+
1
7
  # useAssets
2
8
 
3
9
  Handles file upload, removal, and editing for `ICommonAsset` arrays (images, documents, etc.). This composable encapsulates the platform's asset storage API, handling multipart form upload with batched concurrency (max 4 simultaneous uploads), sort-order assignment, URL decoding, and immutable array operations for remove and edit. It returns a new array from every operation rather than mutating in place, which plays well with Vue's reactivity system and makes undo/redo patterns straightforward.
@@ -131,5 +137,6 @@ async function handleUpload(files: FileList) {
131
137
 
132
138
  ## Related
133
139
 
134
- - `ICommonAsset` type in `@core/types`
140
+ - `ICommonAsset` -- type imported from `@vc-shell/framework`
135
141
  - `VcGallery` / `VcImageTile` -- UI components that consume asset arrays
142
+ - [`useAssetsManager`](../useAssetsManager/) -- higher-level composable that wraps `useAssets` with two-way sync
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useAssetsManager
3
+ category: composables
4
+ group: data
5
+ ---
6
+
1
7
  # useAssetsManager
2
8
 
3
9
  High-level composable for managing asset arrays (images, documents, files). Wraps upload, remove, reorder, and metadata editing operations, mutating a reactive ref directly — no manual wiring needed.
@@ -147,7 +153,12 @@ interface AssetLike {
147
153
 
148
154
  ## Related
149
155
 
150
- - `framework/modules/assets-manager/` AssetsManager blade (table UI for managing assets)
151
- - `framework/modules/assets/` AssetsDetails blade (single asset editing)
152
- - `framework/ui/components/organisms/vc-gallery/` — VcGallery component
153
- - `framework/core/composables/useAssets/` — deprecated low-level composable
156
+ - `VcGallery` -- gallery component that integrates with `useAssetsManager` events
157
+ - [`useAssets`](../useAssets/) -- lower-level composable for manual upload/remove operations
158
+
159
+ <!-- internal:start -->
160
+
161
+ - `framework/modules/assets-manager/` -- AssetsManager blade (table UI for managing assets)
162
+ - `framework/modules/assets/` -- AssetsDetails blade (single asset editing)
163
+ - `framework/ui/components/organisms/vc-gallery/` -- VcGallery component source
164
+ <!-- internal:end -->
@@ -1,3 +1,12 @@
1
+ ---
2
+ title: useAsync
3
+ category: composables
4
+ group: utilities
5
+ ---
6
+
7
+ !!! note "Large reference"
8
+ This page is long. Use the section headings to navigate: [Quick Start](#quick-start), [API Reference](#api-reference), [Features](#features), [Recipes](#recipes), [Common Mistakes](#common-mistakes).
9
+
1
10
  # useAsync
2
11
 
3
12
  Wraps an asynchronous function with reactive `loading` state, reactive `error` state, and automatic error notifications. This is the standard way to handle API calls, saves, deletes, and other async operations throughout VC-Shell applications.
@@ -400,12 +409,16 @@ const { action: save, loading: saveLoading } = useAsync(async () => saveData());
400
409
 
401
410
  ---
402
411
 
412
+ <!-- internal:start -->
413
+
403
414
  ## Internals
404
415
 
405
416
  - Errors are parsed via `parseError()` into `DisplayableError` objects that have a user-friendly `message` property.
406
417
  - Toast notifications are deferred with `setTimeout(0)` and registered via `setPendingErrorNotification`. The `ErrorInterceptor` (blade-level `onErrorCaptured`) can call `cancelPendingErrorNotification` to suppress the toast when a blade error banner is shown instead.
407
418
  - The notification module is lazy-imported to avoid circular dependencies with `@core/composables`.
408
419
 
420
+ <!-- internal:end -->
421
+
409
422
  ---
410
423
 
411
424
  ## Related
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useBeforeUnload
3
+ category: composables
4
+ group: utilities
5
+ ---
6
+
1
7
  # useBeforeUnload
2
8
 
3
9
  Prevents the browser tab from closing when unsaved changes exist by hooking into the native `beforeunload` event. This composable is the last line of defense against accidental data loss -- it triggers the browser's built-in "Leave site?" confirmation dialog whenever the user tries to close or refresh the tab while the `modified` flag is `true`. It complements in-app guards (like blade `onBeforeClose`) by covering the case where the user bypasses the application entirely via the browser chrome.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useBlade
3
+ category: composables
4
+ group: blade-navigation
5
+ ---
6
+
1
7
  # useBlade
2
8
 
3
9
  Unified composable for blade navigation, identity, communication, guards, and error management in VC-Shell applications. This is the primary API for working with the blade navigation system -- the stacked panel paradigm (similar to Azure Portal) that drives every screen in a VC-Shell app.
@@ -644,6 +650,9 @@ function goToOrders() {
644
650
 
645
651
  ## Common Mistakes
646
652
 
653
+ !!! warning "Blade-specific methods throw outside blade context"
654
+ Methods like `closeSelf`, `callParent`, `onBeforeClose`, and `setError` require a blade context (i.e., must be called from inside a blade component's `<script setup>`). Calling them from a dashboard card, a toolbar handler, or a plain composable throws a descriptive runtime error. Only `openBlade` works everywhere.
655
+
647
656
  ### Calling blade-specific methods outside blade context
648
657
 
649
658
  ```typescript
@@ -740,6 +749,8 @@ if (param.value) {
740
749
 
741
750
  ---
742
751
 
752
+ <!-- internal:start -->
753
+
743
754
  ## How It Works Under the Hood
744
755
 
745
756
  1. **Plugin setup:** `BladeNavigationPlugin` (plugin-v2) installs a `BladeStack` and `BladeMessaging` singleton and provides them via Vue's dependency injection.
@@ -747,6 +758,8 @@ if (param.value) {
747
758
  3. **Outside a blade:** `useBlade()` falls back to the singleton instances. Only `openBlade` works because it does not need a blade descriptor.
748
759
  4. **URL sync:** When blades with a `url` property are opened or closed, `useBlade()` synchronizes the browser URL via `createUrlSync`, enabling deep linking and back/forward navigation.
749
760
 
761
+ <!-- internal:end -->
762
+
750
763
  ---
751
764
 
752
765
  ## Related
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useBladeForm
3
+ category: composables
4
+ group: forms
5
+ ---
6
+
1
7
  # useBladeForm
2
8
 
3
9
  Unified form state management for blades. Replaces manual combination of `useForm` + `useModificationTracker` + `useBeforeUnload` + `onBeforeClose` with a single composable.
@@ -152,8 +158,8 @@ onMounted(async () => {
152
158
 
153
159
  At composable creation, `useBladeForm` takes a snapshot of `data` (the **setup-time snapshot**). When `markReady()` is called:
154
160
 
155
- 1. `isReady` → `true` (gates `canSave` and the deep watcher)
156
- 2. `trackerIsModified` = `!semanticEqual(data, setupTimeSnapshot)` — since data was mutated during `onMounted`, this evaluates to `true`
161
+ 1. `isReady` → `true` (gates `canSave` and subsequent edit tracking)
162
+ 2. Modification state is computed by comparing the current data to the setup-time snapshot — since data was mutated during `onMounted`, `isModified` evaluates to `true`
157
163
  3. Subsequent edits are tracked normally by the deep watcher
158
164
 
159
165
  After save, call `setBaseline()` as usual to capture the saved state as the new pristine snapshot.
@@ -164,6 +170,10 @@ After save, call `setBaseline()` as usual to capture the saved state as the new
164
170
  - Validation rules stay in template (`<Field rules="...">`).
165
171
  - `setBaseline()` must be called after data is loaded — before that, `canSave` and `isModified` are `false`.
166
172
 
173
+ <!-- internal:start -->
174
+
167
175
  ## Migration
168
176
 
169
177
  See `MIGRATION_GUIDE.md` for step-by-step instructions on migrating existing modules.
178
+
179
+ <!-- internal:end -->
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useBladeRegistry
3
+ category: composables
4
+ group: blade-navigation
5
+ ---
6
+
1
7
  # useBladeRegistry
2
8
 
3
9
  Provides read-only access to the blade registry -- a central map of all registered blade components, their routes, and metadata.
@@ -129,7 +135,7 @@ function canAccessBlade(bladeName: string): boolean {
129
135
 
130
136
  ## Notes
131
137
 
132
- - The composable must be called after `createBladeRegistry()` has provided the registry via `BladeRegistryKey`. Calling it too early (e.g., outside a setup function or before app bootstrap) throws an error.
138
+ - The composable must be called after the navigation plugin has initialized. Calling it too early (e.g., outside a setup function or before app bootstrap) throws an error.
133
139
  - `getBladeComponent()` falls back to Vue's global component registry if the blade is not found in the framework registry. This supports legacy components registered via `app.component()`.
134
140
  - The `registeredBladesMap` is a `ComputedRef` wrapping a `ReadonlyMap`, so it updates reactively when new modules are loaded.
135
141
 
@@ -147,6 +153,10 @@ if (!registration) {
147
153
 
148
154
  ## Related
149
155
 
150
- - [useBlade](../useBlade/) -- opens and manages blades by name
151
- - [Dynamic Module Loading](../../plugins/modularity/) -- registers blades during module initialization
152
- - `framework/injection-keys.ts` -- `BladeRegistryKey` (defined in the composable file, not in injection-keys.ts)
156
+ - [`useBlade`](../useBlade/) -- opens and manages blades by name
157
+ - Dynamic Module Loading -- registers blades during module initialization
158
+
159
+ <!-- internal:start -->
160
+
161
+ - `createBladeRegistry()` in `framework/core/composables/useBladeRegistry/index.ts` -- factory called by the navigation plugin; `BladeRegistryKey` is defined here
162
+ <!-- internal:end -->
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: useBladeWidgets
3
+ category: composables
4
+ group: blade-navigation
5
+ slug: useBladeWidgets
6
+ ---
7
+
1
8
  # useBladeWidgets / useWidgetTrigger
2
9
 
3
10
  Two composables for the widget system — one for the **blade side**, one for the **widget side**.
@@ -239,21 +246,24 @@ async function save() {
239
246
 
240
247
  ## Prerequisites
241
248
 
249
+ !!! warning "Call site requirements"
250
+ `useBladeWidgets` must be called inside a blade component's `<script setup>` — it requires blade context to be present. `useWidgetTrigger` must be called inside a widget component rendered by `WidgetContainer`. Calling either outside their required scope produces a runtime error or silent no-op respectively.
251
+
242
252
  **`useBladeWidgets`**:
243
253
 
244
- - Must be called inside a blade component rendered by `VcBladeSlot` (requires `BladeDescriptorKey` injection).
245
- - `WidgetService` must be provided in the component tree (automatically available in vc-shell apps).
254
+ - Must be called inside a blade component's `<script setup>`.
255
+ - Widget service must be provided in the component tree (automatically available in vc-shell apps).
246
256
  - Calling outside a blade context throws an error with a descriptive message.
247
257
 
248
258
  **`useWidgetTrigger`**:
249
259
 
250
- - Must be called inside a widget component rendered by `WidgetContainer` (requires `WidgetScopeKey` injection).
260
+ - Must be called inside a widget component rendered by `WidgetContainer`.
251
261
  - If called outside a widget scope, logs a warning and does nothing (does not throw).
252
262
 
253
263
  ## Details
254
264
 
255
- - **Lifecycle management**: Widgets are registered in `onMounted` and unregistered in `onUnmounted`. This ensures the WidgetService always reflects the currently visible blades.
256
- - **Blade ID resolution**: The composable injects `BladeDescriptorKey` to determine which blade the widgets belong to. Each blade has its own isolated widget list.
265
+ - **Lifecycle management**: Widgets are registered in `onMounted` and unregistered in `onUnmounted`. This ensures the widget service always reflects the currently visible blades.
266
+ - **Blade ID resolution**: The composable injects the blade descriptor to determine which blade the widgets belong to. Each blade has its own isolated widget list.
257
267
  - **Trigger pattern**: The `onRefresh` callback is stored as a `trigger` on the registered widget. When `refresh(id)` or `refreshAll()` is called, the trigger is invoked. Widgets without `onRefresh` are silently skipped.
258
268
 
259
269
  ## Tips
@@ -294,8 +304,12 @@ const { refreshAll } = useBladeWidgets([]);
294
304
 
295
305
  ## Related
296
306
 
297
- - `defineBladeContext` / `injectBladeContext` -- expose/consume blade data in external widgets
307
+ - [`defineBladeContext` / `injectBladeContext`](../bladeContext/) -- expose/consume blade data in external widgets
298
308
  - `registerExternalWidget` -- register a component-based widget globally for target blades
299
- - `WidgetService` in `@core/services/widget-service` -- underlying service
300
- - `WidgetScope` in `vc-blade/_internal/widgets/WidgetScope.vue` -- provides `WidgetScopeKey` to widget components
301
- - `VcBladeSlot` -- the blade wrapper that provides `BladeDescriptorKey`
309
+
310
+ <!-- internal:start -->
311
+
312
+ - `WidgetService` in `framework/core/services/widget-service/` -- underlying service
313
+ - `WidgetScope` in `framework/ui/components/organisms/vc-blade/_internal/widgets/WidgetScope.vue` -- provides `WidgetScopeKey` to widget components
314
+ - `VcBladeSlot` in `framework/shell/_internal/blade-nav/` -- provides `BladeDescriptorKey` to blade components
315
+ <!-- internal:end -->
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useBreadcrumbs
3
+ category: composables
4
+ group: ui-state
5
+ ---
6
+
1
7
  # useBreadcrumbs
2
8
 
3
9
  Manages a reactive breadcrumb trail for blade navigation. Supports push, remove, and automatic trail trimming on click.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useConnectionStatus
3
+ category: composables
4
+ group: ui-state
5
+ ---
6
+
1
7
  # useConnectionStatus
2
8
 
3
9
  Monitors the browser's network connectivity and shows a persistent notification when the user goes offline. This composable wraps `@vueuse/core`'s `useNetwork()` and adds framework-specific behavior: it displays a warning notification via the vc-shell notification system, applies a `vc-offline` CSS class to `<html>` for global styling hooks, and logs state changes through the framework logger. The state is a module-level singleton, so only one set of event listeners is ever created regardless of how many components call the composable.
@@ -43,6 +49,8 @@ const { isOnline } = useConnectionStatus();
43
49
  | ---------- | ------------------------ | --------------------------------------------------------------------------------------------------------------- |
44
50
  | `isOnline` | `Readonly<Ref<boolean>>` | `true` when the browser has network connectivity, `false` when offline. Read-only to prevent external mutation. |
45
51
 
52
+ <!-- internal:start -->
53
+
46
54
  ## How It Works
47
55
 
48
56
  On the very first call to `useConnectionStatus()`, the composable initializes a watcher on `@vueuse/core`'s `useNetwork().isOnline`. This watcher runs with `{ immediate: true }`, so the state is correct from the start. Subsequent calls skip initialization and return the same shared reactive state.
@@ -55,6 +63,8 @@ When the network drops:
55
63
 
56
64
  When connectivity is restored, the notification is removed, the CSS class is cleared, and an info message is logged.
57
65
 
66
+ <!-- internal:end -->
67
+
58
68
  ## Recipe: Disabling Auto-Save While Offline
59
69
 
60
70
  ```vue
@@ -1,3 +1,12 @@
1
+ ---
2
+ title: useDashboard
3
+ category: composables
4
+ group: services
5
+ ---
6
+
7
+ !!! tip "Long page"
8
+ Use the section headings to jump directly to what you need: [Quick Start](#quick-start), [Widget Registration](#widget-registration), [Permission-Based Visibility](#permission-based-visibility), or [API Reference](#api-reference).
9
+
1
10
  # useDashboard
2
11
 
3
12
  Accesses the dashboard service for registering and managing dashboard widgets. Widgets are permission-aware, support layout positioning, and can be pre-registered during module setup before the service is initialized.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useDynamicProperties
3
+ category: composables
4
+ group: forms
5
+ ---
6
+
1
7
  # useDynamicProperties
2
8
 
3
9
  Composable for managing dynamic (runtime-defined) property values with support for multilanguage, multivalue, dictionary, color, and measurement property types.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useErrorHandler
3
+ category: composables
4
+ group: utilities
5
+ ---
6
+
1
7
  # useErrorHandler
2
8
 
3
9
  Captures and normalizes errors within a component's subtree using Vue's `onErrorCaptured` hook. This composable acts as an error boundary: it catches errors thrown by any child component, normalizes them into a `DisplayableError` with a user-friendly `message` and technical `details`, automatically reports them to Application Insights with user context, and emits events so parent components can react. It also includes re-entrancy protection to prevent infinite error loops when the error display itself triggers an error.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useFunctions
3
+ category: composables
4
+ group: utilities
5
+ ---
6
+
1
7
  # useFunctions
2
8
 
3
9
  Provides lightweight utility functions for timing control: debounce, throttle, delay, and once. These are thin, dependency-free implementations that cover the most common use cases without pulling in lodash or other large utility libraries. The composable returns plain functions, not reactive wrappers, making them suitable for event handlers, API calls, and other imperative code paths where you do not need VueUse's reactive cancellation features.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useKeyboardNavigation
3
+ category: composables
4
+ group: ui-state
5
+ ---
6
+
1
7
  # useKeyboardNavigation
2
8
 
3
9
  Implements keyboard navigation (Arrow keys, Tab, Enter, Escape) within a container of focusable elements. This composable provides full WAI-ARIA-style keyboard interaction for custom menus, dropdowns, autocomplete lists, and other composite widgets that are not natively keyboard-accessible. It manages a focused-item index, handles wrap-around (looping), and automatically attaches/detaches event listeners tied to the component lifecycle.
@@ -85,6 +91,8 @@ function openMenu() {
85
91
  | `setFocusedIndex` | `(index: number) => void` | Set focus to a specific index. No-op if index is out of bounds. |
86
92
  | `getFocusedIndex` | `() => number` | Get the currently focused index (`-1` if no item is focused). |
87
93
 
94
+ <!-- internal:start -->
95
+
88
96
  ## How It Works
89
97
 
90
98
  The composable listens for `keydown` events on the container element and handles:
@@ -98,6 +106,8 @@ On each key event, the composable re-queries the container for matching items (`
98
106
 
99
107
  Auto-attach happens in `onMounted`: if `containerSelector` is set and a matching element exists in the DOM, keyboard navigation is initialized automatically. Cleanup happens in `onBeforeUnmount`.
100
108
 
109
+ <!-- internal:end -->
110
+
101
111
  ## Recipe: Keyboard-Navigable Autocomplete Dropdown
102
112
 
103
113
  ```vue
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useLanguages
3
+ category: composables
4
+ group: user
5
+ ---
6
+
1
7
  # useLanguages
2
8
 
3
9
  Provides access to the language service for locale management: getting/setting the current locale, resolving locale tags, and fetching country flags. The service is created once via `provideLanguages()` at the framework level and shared through Vue's injection system. If called outside an injection context (e.g., during module initialization), a fallback singleton service is used so the composable never throws.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useLoading
3
+ category: composables
4
+ group: ui-state
5
+ ---
6
+
1
7
  # useLoading
2
8
 
3
9
  Aggregates multiple reactive boolean loading refs into a single computed that is `true` when any source is loading. This is a minimal utility composable -- just one line of logic -- but it solves a very common problem in blade development: when a component depends on several async data sources, you need a single flag for the loading overlay. Instead of writing `computed(() => loadingA.value || loadingB.value || loadingC.value)` in every blade, `useLoading` provides a clean, readable shorthand that scales to any number of sources.
@@ -31,6 +37,8 @@ const combinedLoading = useLoading(loadingA, loadingB, loadingC);
31
37
  | ---------------------- | ------------------------------------------------------------------------------------------------------ |
32
38
  | `ComputedRef<boolean>` | `true` if any of the input refs is `true`, `false` otherwise. Re-evaluates whenever any input changes. |
33
39
 
40
+ <!-- internal:start -->
41
+
34
42
  ## How It Works
35
43
 
36
44
  The implementation is a single `computed` that calls `Array.some()` on the input refs:
@@ -41,6 +49,8 @@ computed(() => args.some((item) => item.value));
41
49
 
42
50
  Because `computed` tracks all `.value` accesses, Vue knows to re-evaluate whenever any of the input refs changes. The `some()` short-circuits on the first `true`, so it is efficient even with many inputs.
43
51
 
52
+ <!-- internal:end -->
53
+
44
54
  ## Recipe: Blade with Multiple Data Sources
45
55
 
46
56
  ```vue
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: useMenuExpanded
3
+ category: composables
4
+ group: ui-state
5
+ slug: useMenuExpanded
6
+ ---
7
+
1
8
  # useMenuExpanded
2
9
 
3
10
  Manages the sidebar menu expanded/collapsed and hover-expanded state with localStorage persistence. This is the low-level composable that powers the sidebar pin/unpin behavior in the vc-shell admin UI. It tracks two independent states: the permanent "pinned" state (persisted across sessions) and the transient "hover-expanded" state (active only while the user hovers over a collapsed sidebar).
@@ -65,12 +72,15 @@ const isVisuallyExpanded = computed(() => isExpanded.value || isHoverExpanded.va
65
72
  </template>
66
73
  ```
67
74
 
75
+ <!-- internal:start -->
76
+
68
77
  ## Details
69
78
 
70
79
  - **Storage key scoping**: The key is scoped per application using the first URL path segment: `VC_APP_MENU_EXPANDED_{appName}`. For example, if the app is hosted at `/vendor-portal/`, the key is `VC_APP_MENU_EXPANDED_vendor-portal`. This allows multiple vc-shell apps on the same domain to maintain independent sidebar states.
71
80
  - **Hover delay**: Opening uses a 200ms debounce to prevent accidental expansion when the cursor briefly passes over the sidebar. Closing is immediate to feel responsive.
72
81
  - **Cleanup**: Pending hover timeouts are cleaned up via `onScopeDispose` to prevent memory leaks when the composable's effect scope is destroyed.
73
82
  - **Default state**: The sidebar starts pinned open (`true`) on first visit, which is the most user-friendly default for new users.
83
+ <!-- internal:end -->
74
84
 
75
85
  ## Tips
76
86