@vc-shell/vc-app-skill 2.0.3 → 2.0.4-pr228.833ff5f

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
@@ -1,7 +1,18 @@
1
+ ---
2
+ title: VcTextarea
3
+ category: components
4
+ group: form
5
+ ---
6
+
7
+ !!! note "Large reference page"
8
+ This page is long. Use the section links in the sidebar or your browser's in-page search (Ctrl/Cmd+F) to jump to the section you need.
9
+
1
10
  # VcTextarea
2
11
 
3
12
  A multi-line text input field for entering and editing large blocks of text. Provides label, placeholder, hint text, validation error display, character limits, and multilanguage support out of the box.
4
13
 
14
+ ::storybook id="form-vctextarea--default"
15
+
5
16
  ## When to Use
6
17
 
7
18
  - Multi-line free-form text: descriptions, comments, notes, addresses, bios
@@ -99,6 +110,8 @@ const form = reactive({
99
110
 
100
111
  ### States
101
112
 
113
+ ::storybook id="form-vctextarea--with-error"
114
+
102
115
  ```vue
103
116
  <!-- Required field -->
104
117
  <VcTextarea v-model="value" label="Address" required />
@@ -112,6 +125,8 @@ const form = reactive({
112
125
 
113
126
  ## Recipes
114
127
 
128
+ ::storybook id="form-vctextarea--with-max-length"
129
+
115
130
  ### Product Description in a Blade Form
116
131
 
117
132
  A typical product-editing blade with a description textarea and character limit:
@@ -293,3 +308,15 @@ const description = ref<string>("");
293
308
  When placed inside a `VcBlade` with `loading=true`, the component automatically renders a skeleton placeholder matching its visual footprint — a label block (when the `label` prop is set) and an input-shaped block. No additional props or configuration needed.
294
309
 
295
310
  This behavior is powered by `BladeLoadingKey` via Vue's provide/inject. The component injects the loading state from the nearest `VcBlade` ancestor.
311
+
312
+ <!-- internal:start -->
313
+
314
+ ## Architecture Notes
315
+
316
+ - The native `<textarea>` element is exposed via `defineExpose({ focus })` so parent components can call `focus()` programmatically.
317
+ - The `invalid` computed is `props.error || !!props.errorMessage` — either flag alone triggers error styling.
318
+ - There is no debounce on the textarea; all `input` events fire `update:modelValue` immediately.
319
+ - The `disabled` state is inherited from the nearest `VcInputGroup` ancestor via provide/inject (when used inside a group).
320
+ - Source file: `framework/ui/components/molecules/vc-textarea/vc-textarea.vue`
321
+
322
+ <!-- internal:end -->
@@ -1,3 +1,12 @@
1
+ ---
2
+ title: VcToast
3
+ category: components
4
+ group: feedback
5
+ ---
6
+
7
+ !!! tip "Quick reference"
8
+ Jump to [Props](#props-component) · [Events](#events) · [Notification Service Methods](#notification-service-methods) · [CSS Variables](#css-variables)
9
+
1
10
  # VcToast
2
11
 
3
12
  Toast notification component with type-based styling, auto-dismiss timer, swipe-to-dismiss on touch devices, and Sonner-style stacking animations. Most applications interact with toasts through the `notification` service rather than mounting the component directly.
@@ -17,6 +26,8 @@ When NOT to use:
17
26
 
18
27
  ## Quick Start
19
28
 
29
+ ::storybook id="overlay-vctoast--notification-service"
30
+
20
31
  The recommended approach is the `notification` service, not direct component usage:
21
32
 
22
33
  ```ts
@@ -98,6 +109,8 @@ Available positions: `"top-center"`, `"top-right"`, `"top-left"`, `"bottom-cente
98
109
 
99
110
  ### Notification Types
100
111
 
112
+ ::storybook id="overlay-vctoast--success"
113
+
101
114
  Each type displays a distinct icon and colored left accent border.
102
115
 
103
116
  | Type | Icon | Accent Color | Use Case |
@@ -129,6 +142,8 @@ notification(OrderNotification, { timeout: 10000, pauseOnHover: true });
129
142
 
130
143
  ### Stacking, Swipe, and Auto-dismiss
131
144
 
145
+ ::storybook id="overlay-vctoast--multiple-notifications"
146
+
132
147
  Toasts use Sonner-style stacking: the newest toast is in front, older toasts scale down behind it, and hovering expands the full stack. Only 3 toasts are visible by default in the collapsed state.
133
148
 
134
149
  On touch devices, horizontal swipe dismisses toasts (threshold: 45px or velocity > 0.11px/ms).
@@ -298,3 +313,16 @@ These props are used internally by the notification system. You rarely need to s
298
313
 
299
314
  - [VcHint](../../atoms/vc-hint/) -- inline hint/error text for form fields
300
315
  - [VcIcon](../../atoms/vc-icon/) -- used internally for type-specific icons
316
+
317
+ <!-- internal:start -->
318
+
319
+ ## Architecture Notes
320
+
321
+ - `VcToast` is managed by the notification system's container component (in `framework/shell/_internal/notifications/`). Direct mounting is unusual and bypasses the stacking/positioning logic.
322
+ - Stacking CSS uses data attributes (`data-mounted`, `data-removed`, `data-expanded`, `data-front`, `data-y-position`, `data-visible`, `data-swiping`, `data-swiped-out`) rather than class bindings for animation state — this matches the Sonner pattern and avoids Vue transition conflicts.
323
+ - `TIME_BEFORE_UNMOUNT = 200ms` — the toast sets `data-removed="true"` to trigger CSS exit animation, then emits `close` after 200ms to remove it from the reactive list.
324
+ - The `Timer` helper (defined inline) is a pauseable/resumeable setTimeout — `pause()` records remaining time, `resume()` restarts from remaining. Used for `pauseOnHover`.
325
+ - Height reporting via `ResizeObserver` + `onReportHeight` callback allows the container to compute accurate stack offsets using `getBoundingClientRect()` on an `height: auto` snapshot.
326
+ - Swipe detection uses pointer capture (`setPointerCapture`) to track moves even when the pointer leaves the element. Threshold: 45px displacement or velocity > 0.11 px/ms.
327
+
328
+ <!-- internal:end -->
@@ -1,7 +1,18 @@
1
+ ---
2
+ title: VcApp
3
+ category: components
4
+ group: layout
5
+ ---
6
+
1
7
  # VcApp
2
8
 
3
9
  The root application shell that bootstraps the VirtoCommerce admin UI. It provides the desktop sidebar / mobile top bar layout, blade navigation workspace, popup container, module loading, and service registration. Every VirtoCommerce admin application must render exactly one `VcApp` at the root of its authenticated route tree.
4
10
 
11
+ ::storybook id="layout-vcapp--desktop-expanded"
12
+
13
+ !!! note "One VcApp per application"
14
+ Every VirtoCommerce admin application must render exactly one `VcApp` at the root of its authenticated route tree. Multiple instances cause service registration conflicts.
15
+
5
16
  ## When to Use
6
17
 
7
18
  - Every VirtoCommerce admin application must have exactly one `VcApp` at the root.
@@ -59,6 +70,8 @@ const user = reactive({ name: "John", role: "Admin" });
59
70
  | `workspace` | `{ isAuthenticated }` | Override the blade navigation workspace. |
60
71
  | `app-hub` | `{ appsList, switchApp }` | Custom content for the Applications section of the App Hub. |
61
72
 
73
+ <!-- internal:start -->
74
+
62
75
  ## Architecture
63
76
 
64
77
  VcApp orchestrates several internal systems:
@@ -68,6 +81,8 @@ VcApp orchestrates several internal systems:
68
81
  3. **Module Loading** -- consumes `DynamicModulesKey` for runtime module registration; shows error notifications on failure. Modules declare routes, menu items, and services.
69
82
  4. **Services** -- bootstraps shell services (Menu, Toolbar, Settings, Dashboard, GlobalSearch, etc.) via `useShellBootstrap`. These services are available to all child components through provide/inject.
70
83
 
84
+ <!-- internal:end -->
85
+
71
86
  ## Features
72
87
 
73
88
  ### Responsive Layout Switching
@@ -76,6 +91,8 @@ On desktop viewports, VcApp renders a collapsible sidebar on the left with navig
76
91
 
77
92
  ### Sidebar Menu Search
78
93
 
94
+ ::storybook id="layout-vcapp--with-sidebar-search" height="500"
95
+
79
96
  When `showSearch` is `true`, a search input appears at the top of the sidebar (desktop) or mobile navigation panel. It filters menu items in real time (300ms debounce) by matching the search query against translated item titles:
80
97
 
81
98
  - **Standalone items** — shown if their title contains the query.
@@ -134,6 +151,8 @@ The App Hub is a popover panel (desktop) or a swipeable tab (mobile) that combin
134
151
 
135
152
  On desktop, the App Hub opens from the sidebar header menu button (`AppHubPopover`). On mobile, it appears as a second tab ("Hub") in the slide-out navigation panel — users can swipe between Menu and Hub tabs.
136
153
 
154
+ ::storybook id="layout-vcapp--mobile" height="500"
155
+
137
156
  ## Recipe: Minimal App Setup
138
157
 
139
158
  ```vue
@@ -1,7 +1,18 @@
1
+ ---
2
+ title: VcAuthLayout
3
+ category: components
4
+ group: layout
5
+ ---
6
+
1
7
  # VcAuthLayout
2
8
 
3
9
  A full-page centered authentication layout for login, registration, password reset, and other auth-related screens. VcAuthLayout renders a vertically and horizontally centered card on top of an optional background image, with a logo, title, subtitle, form content area, and a footer slot for legal links. It is the standard layout for all pre-authentication pages in VirtoCommerce admin applications.
4
10
 
11
+ ::storybook id="layout-vcauthlayout--default"
12
+
13
+ !!! warning "Use outside VcApp"
14
+ VcAuthLayout is a full-page layout meant to replace `VcApp`, not nest inside it. Your router should switch between VcAuthLayout (for auth routes) and VcApp (for authenticated routes) at the top level.
15
+
5
16
  ## When to Use
6
17
 
7
18
  - Use for any authentication page: sign-in, sign-up, password reset, email verification
@@ -132,6 +143,8 @@ The layout uses a `<main>` element as the page landmark and an `<h2>` for the ca
132
143
  </template>
133
144
  ```
134
145
 
146
+ ::storybook id="layout-vcauthlayout--with-sso-providers" height="500"
147
+
135
148
  ## Recipe: Password Reset Page
136
149
 
137
150
  ```vue
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: VcBlade
3
+ category: components
4
+ group: layout
5
+ ---
6
+
1
7
  # VcBlade
2
8
 
3
9
  The foundational container component of the VirtoCommerce admin shell. Blades are stacked panels -- inspired by the Azure Portal -- that form the primary navigation paradigm. Every screen in a vc-shell application is a blade.
@@ -34,6 +40,8 @@ Traditional admin panels use page-based routing: click a link, the entire viewpo
34
40
  | Full-page route without blade stack | Vue Router view |
35
41
  | Scrollable content section inside a blade | [VcContainer](../../molecules/vc-container/) |
36
42
 
43
+ ::storybook id="navigation-vcblade--default"
44
+
37
45
  Use VcBlade for every screen in a vc-shell application -- it is the standard container that integrates with the navigation system, toolbar, breadcrumbs, and unsaved-changes guards. **Do not use** VcBlade for transient dialogs (use `VcPopup` / `usePopup()`) or for content areas that do not need their own header and close button.
38
46
 
39
47
  ## Quick Start
@@ -54,7 +62,8 @@ defineOptions({ name: "MyFirstBlade", url: "/my-first-blade" });
54
62
  </script>
55
63
  ```
56
64
 
57
- > **Tip:** Every blade needs a `name` in `defineOptions`. This is how other blades reference it: `openBlade({ name: "MyFirstBlade" })`. The `url` is optional and controls the URL segment.
65
+ !!! tip "Every blade needs a name"
66
+ Every blade must define a `name` in `defineOptions`. This is how other blades reference it: `openBlade({ name: "MyFirstBlade" })`. The `url` is optional and controls the URL segment.
58
67
 
59
68
  ## Blade Anatomy
60
69
 
@@ -374,6 +383,8 @@ interface IBladeToolbar {
374
383
 
375
384
  ## Loading State and Skeleton
376
385
 
386
+ ::storybook id="navigation-vcblade--loading" height="500"
387
+
377
388
  `loading` shows skeleton placeholders for header, toolbar, and content:
378
389
 
379
390
  ```vue
@@ -384,6 +395,10 @@ interface IBladeToolbar {
384
395
 
385
396
  > **Tip:** Content is hidden (not unmounted) while loading, so `onMounted` hooks still fire.
386
397
 
398
+ > **Note:** During `loading=true`, the header keeps its **close/expand controls operational** — only the icon, title, and subtitle are replaced with skeleton placeholders. Users can always close or maximize a loading blade. The `actions` slot, breadcrumbs, and modified-status dot are hidden until loading finishes.
399
+
400
+ > **Note:** The toolbar zone uses an in-place skeleton: `BladeToolbar` itself renders skeleton buttons/widgets when its `loading` prop is true (no separate skeleton component is mounted). On mobile, the toolbar is omitted entirely while loading.
401
+
387
402
  Merge multiple loading sources with `useLoading`:
388
403
 
389
404
  ```ts
@@ -409,6 +424,8 @@ useBeforeUnload(hasChanges); // Browser tab close warning
409
424
 
410
425
  ## Custom Banners
411
426
 
427
+ ::storybook id="navigation-vcblade--custom-banners" height="500"
428
+
412
429
  Add informational, warning, or success banners to a blade programmatically. Banners appear between the header and toolbar, sorted by severity.
413
430
 
414
431
  ```vue
@@ -675,6 +692,8 @@ openBlade({ name: "ProductsList" });
675
692
  | `usePopup()` | Confirmation dialogs and error messages. |
676
693
  | `useBladeWidgets()` | Register contextual widgets for the blade widget area. |
677
694
 
695
+ <!-- internal:start -->
696
+
678
697
  ## Content Skeleton Mode
679
698
 
680
699
  When `loading=true`, VcBlade provides `BladeLoadingKey` to all descendant components via Vue's provide/inject. Each framework UI component automatically renders a skeleton placeholder matching its visual footprint.
@@ -704,3 +723,5 @@ import { useBladeLoading } from "@vc-shell/framework";
704
723
  const bladeLoading = useBladeLoading();
705
724
  // bladeLoading.value === true when parent VcBlade is loading
706
725
  ```
726
+
727
+ <!-- internal:end -->
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: Table Composables
3
+ category: composables
4
+ group: data
5
+ slug: table-composables
6
+ ---
7
+
1
8
  # VcTable Composables
2
9
 
3
10
  Composables that power VcDataTable's functionality. Each handles a single concern and is wired together by the table component. Module developers rarely use these directly -- they are consumed internally by `VcDataTable.vue`.
@@ -144,14 +151,32 @@ register({
144
151
 
145
152
  - `useTableColumns` never removes entries from `columnState` — hidden columns preserve their weight and order for when they reappear. Use `engineOutput` (not `columnState` directly) to read computed pixel widths for rendering.
146
153
  - Call `recompute()` (returned by `useTableColumns`) whenever the container width changes to force the engine to redistribute widths without altering weights.
147
- - `useDataTableState` stores the v2 schema (weights, order, hidden/shown IDs). It automatically migrates v1 state (pixel-based) on the first restore. Guard against save-during-restore loops with the `isRestoring` flag.
154
+ - `useDataTableState` stores the v2 schema (weights, order, hidden/shown IDs). It auto-migrates v1 state (pixel-based) on the first restore.
148
155
  - `useColumnWidthEngine` functions are pure — pass immutable copies of `specs` when testing or previewing layouts without committing to state.
156
+ - `useVirtualScroll` requires a fixed `itemSize` (row height in pixels) for accurate positioning.
157
+
158
+ <!-- internal:start -->
159
+
160
+ ### Contributor notes
161
+
162
+ - `useDataTableState`: Guard against save-during-restore loops with the `isRestoring` flag.
149
163
  - `useTableRowReorder`: `event.preventDefault()` in `dragover` MUST be called on every event or `drop` never fires.
150
164
  - `useTableColumnsResize` applies DOM-level px changes during drag for 60fps performance, then commits final weights to `columnState` on mouseup. No `ResizeObserver` scaling is involved.
151
- - `useVirtualScroll` requires a fixed `itemSize` (row height in pixels) for accurate positioning.
165
+
166
+ <!-- internal:end -->
152
167
 
153
168
  ## Related
154
169
 
155
- - `framework/ui/components/organisms/vc-table/VcDataTable.vue` -- main consumer
156
- - `framework/ui/components/organisms/vc-table/VcTableAdapter.vue` -- legacy API adapter
157
- - `framework/ui/components/organisms/vc-table/components/` -- sub-components (TableHead, TableRow, cells)
170
+ - [VcDataTable](../../vc-data-table) -- the main consumer of these composables
171
+ - [VcColumn](../../vc-data-table) -- declarative column definitions
172
+
173
+ <!-- internal:start -->
174
+
175
+ ## Source references
176
+
177
+ - `framework/ui/components/organisms/vc-data-table/VcDataTable.vue` -- main consumer
178
+ - `framework/ui/components/organisms/vc-data-table/VcTableAdapter.vue` -- legacy API adapter
179
+ - `framework/ui/components/organisms/vc-data-table/components/` -- sub-components (TableHead, TableRow, cells)
180
+ - `framework/ui/components/organisms/vc-data-table/composables/` -- full composable list
181
+
182
+ <!-- internal:end -->
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: VcDataTable
3
+ category: components
4
+ group: data-display
5
+ ---
6
+
1
7
  # VcDataTable
2
8
 
3
9
  The flagship data table component for VirtoCommerce admin shell. VcDataTable provides a fully declarative, template-driven API for building interactive tables with sorting, selection, inline editing, filtering, pagination, column management, row reordering, and more.
@@ -107,6 +113,8 @@ const products = ref([
107
113
 
108
114
  > **Note:** Each item must have a unique identifier field. The default is `id` -- override with the `data-key` prop if your field is named differently (e.g., `data-key="sku"`).
109
115
 
116
+ ::storybook id="data-display-vcdatatable--basic"
117
+
110
118
  ---
111
119
 
112
120
  ## Column Types
@@ -207,6 +215,8 @@ For any rendering not covered by built-in types, use the `#body` slot:
207
215
 
208
216
  ## Sorting
209
217
 
218
+ ::storybook id="data-display-vcdatatable--with-sorting" height="500"
219
+
210
220
  ### Single Column Sort
211
221
 
212
222
  Mark columns as sortable and bind the sort state:
@@ -293,6 +303,8 @@ When the backend sort field differs from the column id:
293
303
 
294
304
  ## Selection
295
305
 
306
+ ::storybook id="data-display-vcdatatable--with-selection" height="450"
307
+
296
308
  ### Multiple Selection (checkboxes)
297
309
 
298
310
  ```vue
@@ -1015,6 +1027,9 @@ async function loadNextPage() {
1015
1027
 
1016
1028
  ## State Persistence
1017
1029
 
1030
+ !!! tip "Use unique state keys"
1031
+ Every table in your application must have a distinct `state-key`. Two tables sharing the same key will silently overwrite each other's persisted column widths, order, and sort state.
1032
+
1018
1033
  Persist column widths, column order, hidden columns, sort, and filters across page reloads:
1019
1034
 
1020
1035
  ```vue
@@ -1862,6 +1877,9 @@ function onRowRemove(event: { data: PriceEntry; cancel: () => void }) {
1862
1877
 
1863
1878
  ## Common Mistakes
1864
1879
 
1880
+ !!! warning "Performance: avoid mutating the items array in-place"
1881
+ Always replace `items` with a new array reference instead of using `splice` or `push` directly on the reactive array. Vue cannot track in-place mutations reliably in all scenarios, and VcDataTable's row reorder logic depends on receiving a fresh array to reset the pending-reorder state.
1882
+
1865
1883
  ### 1. Missing `dataKey` with non-`id` identifiers
1866
1884
 
1867
1885
  ```vue
@@ -1,7 +1,15 @@
1
+ ---
2
+ title: VcDynamicProperty
3
+ category: components
4
+ group: form
5
+ ---
6
+
1
7
  # VcDynamicProperty
2
8
 
3
9
  Renders a VirtoCommerce platform dynamic property as the appropriate form control, automatically selecting the input component based on value type, dictionary, and multivalue flags. VcDynamicProperty eliminates the need for manual `v-if` chains when rendering properties whose type is determined at runtime — it maps each combination of `valueType`, `dictionary`, and `multivalue` to the correct input molecule and passes through all relevant props.
4
10
 
11
+ ::storybook id="data-display-vcdynamicproperty--default"
12
+
5
13
  ## When to Use
6
14
 
7
15
  - Use to render dynamic properties from the VirtoCommerce platform (catalog properties, member properties, store properties, etc.)
@@ -44,6 +52,8 @@ Renders a VirtoCommerce platform dynamic property as the appropriate form contro
44
52
  | `measurementsGetter` | `Function` | - | Async loader for measurement units |
45
53
  | `rules` | `object` | - | Validation rules: `{ min, max, regex }` |
46
54
 
55
+ ::storybook id="data-display-vcdynamicproperty--property-form" height="500"
56
+
47
57
  ## Value Type to Component Mapping
48
58
 
49
59
  | valueType | dictionary | multivalue | Component |
@@ -109,6 +119,8 @@ function handlePropertyUpdate(property: any, newValue: any) {
109
119
  </template>
110
120
  ```
111
121
 
122
+ ::storybook id="data-display-vcdynamicproperty--required-with-validation" height="300"
123
+
112
124
  ## Recipe: Dynamic Property with Validation
113
125
 
114
126
  ```vue
@@ -1,7 +1,15 @@
1
+ ---
2
+ title: VcGallery
3
+ category: components
4
+ group: data-display
5
+ ---
6
+
1
7
  # VcGallery
2
8
 
3
9
  A responsive multi-image gallery with drag-and-drop reorder, file upload, lightbox preview, and per-image actions. VcGallery renders images in a CSS grid that auto-fills based on the container width, with a built-in upload zone tile at the end of the grid. It is the standard component for managing collections of images such as product photos, media libraries, and document attachments.
4
10
 
11
+ ::storybook id="data-display-vcgallery--default"
12
+
5
13
  ## When to Use
6
14
 
7
15
  - Use **VcGallery** for multi-image fields (product images, media libraries, banner collections).
@@ -64,12 +72,16 @@ A responsive multi-image gallery with drag-and-drop reorder, file upload, lightb
64
72
  <VcGallery label="Product Images" required :images="product.images" imagefit="cover" @upload="handleUpload" @sort="handleSort" @edit="handleEdit" @remove="handleRemove" />
65
73
  ```
66
74
 
75
+ ::storybook id="data-display-vcgallery--filmstrip-default" height="400"
76
+
67
77
  ## Filmstrip Layout (Default)
68
78
 
69
79
  ```vue
70
80
  <VcGallery label="Images" :images="product.images" imagefit="cover" @upload="handleUpload" @sort="handleSort" @remove="handleRemove" />
71
81
  ```
72
82
 
83
+ ::storybook id="data-display-vcgallery--grid-layout" height="400"
84
+
73
85
  ## Classic Grid Layout
74
86
 
75
87
  ```vue
@@ -128,6 +140,8 @@ function handleRemove(image: ICommonAsset) {
128
140
  </template>
129
141
  ```
130
142
 
143
+ ::storybook id="data-display-vcgallery--disabled" height="300"
144
+
131
145
  ## Recipe: Read-Only Gallery (Disabled)
132
146
 
133
147
  ```vue
@@ -1,7 +1,15 @@
1
+ ---
2
+ title: VcImageUpload
3
+ category: components
4
+ group: media
5
+ ---
6
+
1
7
  # VcImageUpload
2
8
 
3
9
  A single-image upload organism that displays either a drag-and-drop upload zone or an image tile with preview and remove actions. VcImageUpload manages three visual states automatically: an interactive dropzone when no image is set, an image tile with action overlays when an image is provided, and a disabled empty state with a hint message. It integrates with vee-validate for file validation (size, format) and supports lightbox preview via the built-in VcImageTile component.
4
10
 
11
+ ::storybook id="data-display-vcimageupload--empty"
12
+
5
13
  ## When to Use
6
14
 
7
15
  - Use **VcImageUpload** for single-image fields (avatar, logo, thumbnail, hero image).
@@ -31,6 +39,8 @@ A single-image upload organism that displays either a drag-and-drop upload zone
31
39
  | `upload` | `FileList` | Emitted when files are selected or dropped. |
32
40
  | `remove` | `ICommonAsset` | Emitted when the remove button is clicked. |
33
41
 
42
+ ::storybook id="data-display-vcimageupload--with-image" height="300"
43
+
34
44
  ## Visual States
35
45
 
36
46
  The component has three visual states:
@@ -83,6 +93,8 @@ function handleRemove() {
83
93
  </template>
84
94
  ```
85
95
 
96
+ ::storybook id="data-display-vcimageupload--loading" height="250"
97
+
86
98
  ## Recipe: Conditional Upload with Loading State
87
99
 
88
100
  ```vue
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: VcPopup
3
+ category: components
4
+ group: feedback
5
+ ---
6
+
1
7
  # VcPopup
2
8
 
3
9
  A modal dialog component built on [HeadlessUI Dialog](https://headlessui.com/vue/dialog). Use it for confirmations, alerts, error messages, and focused form interactions that require the user's immediate attention.
@@ -12,7 +18,10 @@ A modal dialog component built on [HeadlessUI Dialog](https://headlessui.com/vue
12
18
  | Side panel for contextual workflows | VcSidebar |
13
19
  | Stacked detail views (master-detail) | VcBlade |
14
20
 
15
- > **Tip:** Prefer blades for CRUD workflows. Reserve popups for brief, interruptive interactions such as confirmations and alerts.
21
+ !!! tip "Prefer blades for CRUD workflows"
22
+ Reserve popups for brief, interruptive interactions such as confirmations and alerts. Use `VcBlade` for CRUD detail views and `VcSidebar` for contextual side panels.
23
+
24
+ ::storybook id="overlay-vcpopup--default"
16
25
 
17
26
  ---
18
27
 
@@ -49,6 +58,8 @@ const showPopup = ref(false);
49
58
 
50
59
  ### Variants
51
60
 
61
+ ::storybook id="overlay-vcpopup--variants" height="500"
62
+
52
63
  The `variant` prop adds a semantic icon and color to the popup. Available values: `"default"`, `"info"`, `"success"`, `"warning"`, `"error"`.
53
64
 
54
65
  ```vue
@@ -248,6 +259,8 @@ Two props control fullscreen behavior:
248
259
 
249
260
  ### Confirmation Dialog
250
261
 
262
+ ::storybook id="overlay-vcpopup--with-footer" height="400"
263
+
251
264
  The most common pattern. Uses the `warning` variant and a two-button footer.
252
265
 
253
266
  ```vue
@@ -1,7 +1,18 @@
1
+ ---
2
+ title: VcSidebar
3
+ category: components
4
+ group: layout
5
+ ---
6
+
1
7
  # VcSidebar
2
8
 
3
9
  A slide-over panel for contextual workflows, settings, and detail views. Supports left, right, and bottom positions with animated transitions, focus trapping, scroll locking, and swipe-to-dismiss gestures. VcSidebar is built for use cases where a full blade is too heavy but a popup is too small — settings panels, filter drawers, item detail previews, and mobile bottom sheets.
4
10
 
11
+ ::storybook id="overlay-vcsidebar--elevated-panel"
12
+
13
+ !!! tip "Sidebar vs Popup vs Blade"
14
+ Use VcSidebar for contextual workflows that need persistent visibility. Use `VcPopup` for brief confirmation dialogs. Use `VcBlade` for primary CRUD content that belongs in the navigation stack.
15
+
5
16
  ## When to Use
6
17
 
7
18
  - Settings panels, filter drawers, or contextual detail views.
@@ -104,6 +115,8 @@ Override with the `width` or `height` prop for custom dimensions.
104
115
 
105
116
  ### Bottom Sheet with Swipe-to-Dismiss
106
117
 
118
+ ::storybook id="overlay-vcsidebar--bottom-sheet" height="500"
119
+
107
120
  ```vue
108
121
  <VcSidebar v-model="open" position="bottom" size="md" draggable drag-handle>
109
122
  <div class="tw-p-4">Swipe down to close</div>
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: UI Composables
3
+ category: composables
4
+ group: ui-state
5
+ slug: ui-composables-overview
6
+ ---
7
+
1
8
  # UI Composables
2
9
 
3
10
  Shared composables for the VC-Shell UI component library. These provide reusable logic for layout, positioning, form fields, and scroll behavior.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useDataTablePagination
3
+ category: composables
4
+ group: data
5
+ ---
6
+
1
7
  # useDataTablePagination
2
8
 
3
9
  Manages page-level pagination state for `VcDataTable`. Derives `pages`, `skip`, `totalCount` from a reactive input, and fires an optional `onPageChange` callback when the page changes. Returns a `reactive()` object — all properties are plain values (no `.value` needed), and the object is directly passable as the VcDataTable `:pagination` prop.
@@ -159,6 +165,6 @@ Blade then simply binds:
159
165
 
160
166
  ## Related
161
167
 
162
- - [`useDataTableSort`](./useDataTableSort.docs.md) sort state composable for VcDataTable
163
- - `VcDataTable` `:pagination` prop accepts `DataTablePagination` object
164
- - `DataTablePagination` type defined in `vc-data-table/types.ts`
168
+ - [`useDataTableSort`](./useDataTableSort.docs.md) -- sort state composable for VcDataTable
169
+ - `VcDataTable` `:pagination` prop -- accepts `DataTablePagination` object
170
+ - `DataTablePagination` -- type exported from `@vc-shell/framework`
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useDataTableSort
3
+ category: composables
4
+ group: data
5
+ ---
6
+
1
7
  # useDataTableSort
2
8
 
3
9
  Manages page-level sort state for `VcDataTable` using numeric sort order conventions (`1` = ASC, `-1` = DESC, `0` = none). Provides `sortField` and `sortOrder` refs for `v-model` binding directly on `VcDataTable`, plus a `sortExpression` computed string for API calls.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useTableSelection
3
+ category: composables
4
+ group: data
5
+ ---
6
+
1
7
  # useTableSelection
2
8
 
3
9
  Manages table row selection state including multi-select, select-all, and programmatic selection. This composable provides a complete external selection API for VcDataTable, enabling bulk operations like delete, export, or status changes on selected rows.
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: useTableSort
3
+ category: composables
4
+ group: data
5
+ ---
6
+
1
7
  # useTableSort
2
8
 
3
9
  Manages table sort state with three-state cycling (ASC, DESC, none) and a formatted sort expression string. This composable externalizes the sort logic from VcDataTable, making it easy to drive server-side sorting, persist sort preferences, or share sort state across multiple components.
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: UI Types
3
+ category: reference
4
+ group: api
5
+ slug: types-ui
6
+ ---
7
+
1
8
  # UI Types
2
9
 
3
10
  TypeScript interfaces for UI component props shared across all form field components in the framework.
@@ -1,28 +0,0 @@
1
- # usePlatformLocaleSync
2
-
3
- One-way reactive bridge from the VirtoCommerce platform's locale storage key (`NG_TRANSLATE_LANG_KEY`, set by AngularJS + angular-translate) to the shell's language service.
4
-
5
- Call this composable only when the shell runs embedded inside the platform — `useShellBootstrap` invokes it automatically when `options.isEmbedded === true`. In standalone mode the shell owns its own locale via `VC_LANGUAGE_SETTINGS`, and this composable should not be used.
6
-
7
- ## When to Use
8
-
9
- - Never call directly from feature code. This is a framework-internal sync primitive.
10
- - It is invoked once per `VcApp` mount from `useShellBootstrap`.
11
-
12
- ## Behaviour
13
-
14
- - Reads `localStorage["NG_TRANSLATE_LANG_KEY"]` via VueUse's `useLocalStorage`, which subscribes to `storage` events for cross-tab reactivity.
15
- - On setup, if the value is non-empty, calls `LanguageService.setLocale(value)`. `setLocale` normalises the value (e.g. `en-US` → `en-us`), falls back to `en` for unsupported locales, updates `vue-i18n`, reconfigures `vee-validate`, and persists to `VC_LANGUAGE_SETTINGS`.
16
- - On subsequent changes of the platform key, re-applies the value.
17
- - Skips empty strings (platform clearing the key does not blank the shell locale).
18
- - Skips values equal to `currentLocale` to avoid redundant re-configuration.
19
-
20
- ## How It Works
21
-
22
- `useLocalStorage("NG_TRANSLATE_LANG_KEY", "")` returns a `Ref<string>` that VueUse keeps in sync with `localStorage` and the DOM `storage` event (which fires in tabs other than the writer). The composable applies the current ref value once synchronously and then registers a `watch` on it; any cross-tab mutation flows through the ref into `setLocale`.
23
-
24
- The watcher is bound to the active effect scope (typically `VcApp`'s setup). When `VcApp` unmounts, the watcher stops; `useLocalStorage` cleans up its own `storage` listener.
25
-
26
- ## Relationship to `VC_LANGUAGE_SETTINGS`
27
-
28
- The sync is strictly one-directional. `setLocale` writes to `VC_LANGUAGE_SETTINGS` as a side effect, but this composable never writes to `NG_TRANSLATE_LANG_KEY`. In embedded mode the in-shell `LanguageSelector` is unreachable (it lives inside `UserDropdownButton`, which is hidden when `isEmbedded` is `true`), so there is no competing writer from the shell side.