@vc-shell/vc-app-skill 2.1.0 → 2.2.0-pr260.a8bd3a7

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 (141) hide show
  1. package/package.json +1 -1
  2. package/runtime/VERSION +1 -1
  3. package/runtime/agents/migration-agent.md +4 -2
  4. package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
  5. package/runtime/knowledge/docs/core/api/platform.docs.md +20 -18
  6. package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +43 -34
  7. package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +5 -3
  8. package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +12 -10
  9. package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +7 -5
  10. package/runtime/knowledge/docs/core/composables/useAssets/useAssets.docs.md +8 -6
  11. package/runtime/knowledge/docs/core/composables/useAssetsManager/useAssetsManager.docs.md +3 -1
  12. package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +1 -1
  13. package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +8 -5
  14. package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +12 -12
  15. package/runtime/knowledge/docs/core/composables/useBreadcrumbs/useBreadcrumbs.docs.md +3 -3
  16. package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md +4 -3
  17. package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +1 -0
  18. package/runtime/knowledge/docs/core/composables/useFunctions/useFunctions.docs.md +3 -3
  19. package/runtime/knowledge/docs/core/composables/useKeyboardNavigation/useKeyboardNavigation.docs.md +5 -4
  20. package/runtime/knowledge/docs/core/composables/useLanguages/useLanguages.docs.md +3 -3
  21. package/runtime/knowledge/docs/core/composables/useLoading/useLoading.docs.md +2 -0
  22. package/runtime/knowledge/docs/core/composables/useModificationTracker/useModificationTracker.docs.md +1 -2
  23. package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +1 -1
  24. package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +3 -3
  25. package/runtime/knowledge/docs/core/composables/usePlatformLocaleSync/usePlatformLocaleSync.docs.md +1 -0
  26. package/runtime/knowledge/docs/core/composables/usePopup/usePopup.docs.md +1 -1
  27. package/runtime/knowledge/docs/core/composables/useResponsive/useResponsive.docs.md +2 -2
  28. package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +2 -1
  29. package/runtime/knowledge/docs/core/composables/useSettingsMenu/useSettingsMenu.docs.md +18 -18
  30. package/runtime/knowledge/docs/core/composables/useSidebarState/useSidebarState.docs.md +3 -3
  31. package/runtime/knowledge/docs/core/composables/useSlowNetworkDetection/useSlowNetworkDetection.docs.md +10 -7
  32. package/runtime/knowledge/docs/core/composables/useTheme/useTheme.docs.md +7 -7
  33. package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +18 -12
  34. package/runtime/knowledge/docs/core/composables/useUser/useUser.docs.md +2 -2
  35. package/runtime/knowledge/docs/core/composables/useUserManagement/useUserManagement.docs.md +20 -20
  36. package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +15 -24
  37. package/runtime/knowledge/docs/core/directives/loading/loading.docs.md +2 -2
  38. package/runtime/knowledge/docs/core/notifications/composables/useBladeNotifications.docs.md +1 -2
  39. package/runtime/knowledge/docs/core/notifications/composables/useBroadcastFilter.docs.md +3 -3
  40. package/runtime/knowledge/docs/core/notifications/composables/useNotificationStore.docs.md +19 -18
  41. package/runtime/knowledge/docs/core/notifications/notifications.docs.md +50 -30
  42. package/runtime/knowledge/docs/core/plugins/ai-agent/ai-agent.docs.md +30 -11
  43. package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +1 -1
  44. package/runtime/knowledge/docs/core/plugins/global-error-handler/global-error-handler.docs.md +2 -3
  45. package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +26 -26
  46. package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +2 -3
  47. package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +11 -50
  48. package/runtime/knowledge/docs/core/plugins/validation/validation.docs.md +9 -6
  49. package/runtime/knowledge/docs/core/services/services.docs.md +15 -13
  50. package/runtime/knowledge/docs/core/types/types.docs.md +37 -40
  51. package/runtime/knowledge/docs/core/utilities/date/date-utilities.docs.md +1 -2
  52. package/runtime/knowledge/docs/core/utilities/shared-utilities.docs.md +21 -30
  53. package/runtime/knowledge/docs/core/utilities/thumbnail/thumbnail.docs.md +2 -2
  54. package/runtime/knowledge/docs/core/utilities/utilities.docs.md +9 -8
  55. package/runtime/knowledge/docs/injection-keys.docs.md +6 -11
  56. package/runtime/knowledge/docs/modules/assets/assets-details.docs.md +7 -7
  57. package/runtime/knowledge/docs/modules/assets-manager/assets-manager.docs.md +1 -1
  58. package/runtime/knowledge/docs/shell/_internal/popup/common/popup-common.docs.md +20 -12
  59. package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +10 -10
  60. package/runtime/knowledge/docs/shell/auth/ForgotPasswordPage/forgot-password-page.docs.md +6 -6
  61. package/runtime/knowledge/docs/shell/auth/InvitePage/invite-page.docs.md +4 -4
  62. package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +16 -14
  63. package/runtime/knowledge/docs/shell/auth/ResetPasswordPage/reset-password-page.docs.md +1 -1
  64. package/runtime/knowledge/docs/shell/auth/sign-in/sign-in.docs.md +12 -11
  65. package/runtime/knowledge/docs/shell/components/change-password/change-password.docs.md +10 -3
  66. package/runtime/knowledge/docs/shell/components/change-password-button/change-password-button.docs.md +3 -3
  67. package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +9 -2
  68. package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +4 -2
  69. package/runtime/knowledge/docs/shell/components/logout-button/logout-button.docs.md +1 -1
  70. package/runtime/knowledge/docs/shell/components/notification-dropdown/notification-dropdown.docs.md +35 -31
  71. package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +17 -11
  72. package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +8 -7
  73. package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +23 -21
  74. package/runtime/knowledge/docs/shell/components/sidebar/sidebar.docs.md +5 -3
  75. package/runtime/knowledge/docs/shell/components/theme-selector/theme-selector.docs.md +7 -7
  76. package/runtime/knowledge/docs/shell/components/user-dropdown-button/user-dropdown-button.docs.md +11 -11
  77. package/runtime/knowledge/docs/shell/dashboard/dashboard-charts/dashboard-charts.docs.md +28 -16
  78. package/runtime/knowledge/docs/shell/dashboard/dashboard-widget-card/dashboard-widget-card.docs.md +17 -19
  79. package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +21 -0
  80. package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +2 -1
  81. package/runtime/knowledge/docs/ui/components/atoms/vc-banner/vc-banner.docs.md +2 -2
  82. package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +15 -14
  83. package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +9 -6
  84. package/runtime/knowledge/docs/ui/components/atoms/vc-environment-banner/vc-environment-banner.docs.md +42 -0
  85. package/runtime/knowledge/docs/ui/components/atoms/vc-hint/vc-hint.docs.md +1 -1
  86. package/runtime/knowledge/docs/ui/components/atoms/vc-icon/vc-icon.docs.md +10 -9
  87. package/runtime/knowledge/docs/ui/components/atoms/vc-image/vc-image.docs.md +19 -4
  88. package/runtime/knowledge/docs/ui/components/atoms/vc-label/vc-label.docs.md +2 -2
  89. package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +5 -4
  90. package/runtime/knowledge/docs/ui/components/atoms/vc-loading/vc-loading.docs.md +5 -4
  91. package/runtime/knowledge/docs/ui/components/atoms/vc-progress/vc-progress.docs.md +9 -8
  92. package/runtime/knowledge/docs/ui/components/atoms/vc-scrollable-container/vc-scrollable-container.docs.md +7 -0
  93. package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +1 -1
  94. package/runtime/knowledge/docs/ui/components/atoms/vc-status/vc-status.docs.md +2 -2
  95. package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +1 -1
  96. package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +11 -10
  97. package/runtime/knowledge/docs/ui/components/atoms/vc-video/vc-video.docs.md +28 -8
  98. package/runtime/knowledge/docs/ui/components/atoms/vc-widget/vc-widget.docs.md +22 -19
  99. package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +8 -8
  100. package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +16 -6
  101. package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +9 -8
  102. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +42 -34
  103. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +1 -1
  104. package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +14 -1
  105. package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +3 -1
  106. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown/vc-dropdown.docs.md +34 -33
  107. package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +26 -24
  108. package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +12 -14
  109. package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +30 -30
  110. package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +2 -2
  111. package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +1 -1
  112. package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +34 -31
  113. package/runtime/knowledge/docs/ui/components/molecules/vc-input-group/vc-input-group.docs.md +14 -12
  114. package/runtime/knowledge/docs/ui/components/molecules/vc-menu/vc-menu.docs.md +1 -1
  115. package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +36 -27
  116. package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +5 -1
  117. package/runtime/knowledge/docs/ui/components/molecules/{vc-dropdown-panel/vc-dropdown-panel.docs.md → vc-popover/vc-popover.docs.md} +24 -27
  118. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +10 -9
  119. package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +44 -19
  120. package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +11 -11
  121. package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +15 -14
  122. package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +15 -15
  123. package/runtime/knowledge/docs/ui/components/molecules/vc-toast/vc-toast.docs.md +15 -13
  124. package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +5 -1
  125. package/runtime/knowledge/docs/ui/components/organisms/vc-auth-layout/vc-auth-layout.docs.md +18 -0
  126. package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +48 -78
  127. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +9 -11
  128. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +71 -43
  129. package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +27 -20
  130. package/runtime/knowledge/docs/ui/components/organisms/vc-gallery/vc-gallery.docs.md +2 -2
  131. package/runtime/knowledge/docs/ui/components/organisms/vc-image-upload/vc-image-upload.docs.md +12 -12
  132. package/runtime/knowledge/docs/ui/components/organisms/vc-popup/vc-popup.docs.md +33 -24
  133. package/runtime/knowledge/docs/ui/components/organisms/vc-scheduler/vc-scheduler.docs.md +509 -0
  134. package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +43 -26
  135. package/runtime/knowledge/docs/ui/composables/ui-composables.docs.md +15 -9
  136. package/runtime/knowledge/docs/ui/composables/useDataTableSort.docs.md +8 -6
  137. package/runtime/knowledge/docs/ui/composables/useTableSearch.docs.md +3 -3
  138. package/runtime/knowledge/docs/ui/composables/useTableSelection.docs.md +4 -4
  139. package/runtime/knowledge/docs/ui/composables/useTableSort.docs.md +2 -3
  140. package/runtime/knowledge/migration-prompts/table-url-state-migration.md +221 -0
  141. package/runtime/vc-app.md +1 -0
@@ -2,6 +2,7 @@
2
2
  title: useKeyboardNavigation
3
3
  category: composables
4
4
  group: ui-state
5
+ internal: true
5
6
  ---
6
7
 
7
8
  # useKeyboardNavigation
@@ -20,8 +21,8 @@ The composable supports two attachment modes: **auto-attach** on mount via a CSS
20
21
 
21
22
  ```vue
22
23
  <script setup lang="ts">
23
- import { useKeyboardNavigation } from "@vc-shell/framework";
24
- import { ref } from "vue";
24
+ import { useKeyboardNavigation } from "@core/composables/useKeyboardNavigation";
25
+ import { ref, nextTick } from "vue";
25
26
 
26
27
  const menuRef = ref<HTMLElement | null>(null);
27
28
  const items = ref(["Dashboard", "Products", "Orders", "Settings"]);
@@ -112,7 +113,7 @@ Auto-attach happens in `onMounted`: if `containerSelector` is set and a matching
112
113
 
113
114
  ```vue
114
115
  <script setup lang="ts">
115
- import { useKeyboardNavigation } from "@vc-shell/framework";
116
+ import { useKeyboardNavigation } from "@core/composables/useKeyboardNavigation";
116
117
  import { ref, watch, nextTick } from "vue";
117
118
 
118
119
  const dropdownRef = ref<HTMLElement | null>(null);
@@ -180,7 +181,7 @@ function selectSuggestion(value: string) {
180
181
  - **Items are re-queried on every key press.** This means dynamically added or removed items are picked up automatically. You do not need to re-initialize after the list changes.
181
182
  - **`loop: false` stops at boundaries.** When looping is disabled, pressing ArrowDown on the last item or ArrowUp on the first item does nothing. This is appropriate for linear navigation patterns.
182
183
  - **Clean up if you manually init.** While auto-attached listeners are cleaned up on `onBeforeUnmount`, if you call `initKeyboardNavigation` on a dynamic element, call `cleanupKeyboardNavigation` when that element is removed.
183
- - **Tab key is intercepted.** The composable handles Tab/Shift+Tab within the container, moving focus between items rather than leaving the container. This follows the WAI-ARIA composite widget pattern.
184
+ - **Tab moves the focused index but is not trapped.** Tab/Shift+Tab advances the composable's focused item, but it does not call `preventDefault`, so the browser's native Tab behavior still applies and focus can leave the container. This follows the WAI-ARIA composite widget pattern.
184
185
 
185
186
  ## Related
186
187
 
@@ -67,9 +67,9 @@ None.
67
67
  | `currentLocale` | `ComputedRef<string>` | The currently active locale code (e.g., `"en-US"`, `"de-DE"`). |
68
68
  | `setLocale` | `(locale: string) => void` | Switches the application locale. This updates `vue-i18n`'s locale and triggers re-rendering of all translated text. |
69
69
  | `getLocaleByTag` | `(localeTag: string) => string \| undefined` | Resolves a locale tag to its native display name. Regional tags stay distinct (e.g., `"en-US"` → `"American English"`, `"en-GB"` → `"British English"`); plain codes resolve to the base native name (`"fr"` → `"Français"`). Returns `undefined` if the tag is not recognized. |
70
- | `resolveCamelCaseLocale` | `(locale: string) => string` | Converts a locale code to camelCase format (e.g., `"en-US"` to `"enUs"`). Useful for dynamic property access on objects keyed by locale. |
70
+ | `resolveCamelCaseLocale` | `(locale: string) => string` | Normalizes and validates a locale code to a supported hyphenated lowercase locale (e.g., `"enUS"` to `"en-us"`), falling back to `"en"` if the locale is not supported. Delegates to `resolveSupportedLocale`. |
71
71
  | `getFlag` | `(language: string) => Promise<string>` | Fetches a flag image URL for the given language/locale. Returns a promise because flags may be loaded lazily. |
72
- | `getCountryCode` | `(language: string) => string` | Extracts the country code from a language tag (e.g., `"en-US"` to `"US"`, `"de-DE"` to `"DE"`). |
72
+ | `getCountryCode` | `(language: string) => string` | Extracts the lowercase country code from a language tag (e.g., `"en-US"` to `"us"`, `"de-DE"` to `"de"`). Falls back to `"xx"` for unknown languages. |
73
73
 
74
74
  ### Additional Exports
75
75
 
@@ -149,7 +149,7 @@ const displayValue = computed(() => getPropertyValue(property.value, currentLoca
149
149
  - **`setLocale` triggers a full re-render of translated text.** This is expected behavior from Vue I18n. If your app has many translated strings, the switch may cause a brief layout recalculation. There is no way to avoid this.
150
150
  - **`getFlag` is async.** Flag images may be loaded from a CDN or bundled as lazy imports. Always await the result before using it in templates.
151
151
  - **Fallback singleton is not reactive to injection changes.** If `provideLanguages()` is called after `useLanguages()` was already invoked outside an injection context, the fallback instance is not replaced. This is rarely an issue in practice since `provideLanguages()` runs before module installation.
152
- - **`resolveCamelCaseLocale` is useful for object property access.** Platform API responses sometimes key multilanguage data by camelCase locale (e.g., `{ enUs: "Hello", deDe: "Hallo" }`).
152
+ - **`resolveCamelCaseLocale` normalizes locale codes.** It returns a supported hyphenated lowercase locale (e.g., `"enUS"` -> `"en-us"`), or `"en"` when the locale is not supported. Despite the name, it does not produce camelCase output.
153
153
 
154
154
  ## Related
155
155
 
@@ -37,6 +37,8 @@ const combinedLoading = useLoading(loadingA, loadingB, loadingC);
37
37
  | ---------------------- | ------------------------------------------------------------------------------------------------------ |
38
38
  | `ComputedRef<boolean>` | `true` if any of the input refs is `true`, `false` otherwise. Re-evaluates whenever any input changes. |
39
39
 
40
+ The module also exports a shape-helper interface `HasLoading` (`{ loading: Readonly<Ref<boolean>> }`), for typing objects that expose a readonly `loading` ref. It is not part of `useLoading`'s call signature.
41
+
40
42
  <!-- internal:start -->
41
43
 
42
44
  ## How It Works
@@ -58,8 +58,7 @@ resetModificationState(); // currentValue becomes the new pristine baseline
58
58
  ```vue
59
59
  <script setup lang="ts">
60
60
  import { ref, watch } from "vue";
61
- import { useModificationTracker } from "@vc-shell/framework";
62
- import { useBeforeUnload } from "@vueuse/core";
61
+ import { useModificationTracker, useBeforeUnload } from "@vc-shell/framework";
63
62
 
64
63
  // Simulate API data loaded into a ref
65
64
  const apiData = ref({ name: "Widget A", price: 19.99, tags: ["sale"] });
@@ -78,7 +78,7 @@ For the canonical blade-side example and the registration of notification types
78
78
 
79
79
  4. **Module notifications**: The `moduleNotifications` computed filters the store's real-time queue for items that are new (`isNew: true`) and match the subscribed types.
80
80
 
81
- 5. **History**: `loadFromHistory` delegates to the store, which fetches from the platform API and merges into the local history.
81
+ 5. **History**: `loadFromHistory` delegates to `store.loadHistory`, which fetches a page from the platform API and replaces the local history with the result (`take` controls page size, default 10). It does not merge with or page onto existing entries.
82
82
 
83
83
  ## Recipe: Notification Panel with Real-Time Updates
84
84
 
@@ -130,13 +130,13 @@ Use `hasAccess` in a blade component to redirect users who lack the required per
130
130
 
131
131
  ```typescript
132
132
  <script setup lang="ts">
133
- import { usePermissions, useBladeContext } from "@vc-shell/framework";
133
+ import { usePermissions, useBlade } from "@vc-shell/framework";
134
134
 
135
135
  const { hasAccess } = usePermissions();
136
- const { closeSelf } = useBladeContext();
136
+ const { closeSelf } = useBlade();
137
137
 
138
138
  if (!hasAccess("order:read")) {
139
- closeSelf();
139
+ await closeSelf(); // returns Promise<boolean>
140
140
  return;
141
141
  }
142
142
  </script>
@@ -2,6 +2,7 @@
2
2
  title: usePlatformLocaleSync
3
3
  category: composables
4
4
  group: user
5
+ internal: true
5
6
  ---
6
7
 
7
8
  # usePlatformLocaleSync
@@ -62,7 +62,7 @@ async function deleteProduct(id: string) {
62
62
 
63
63
  | Field | Type | Required | Description |
64
64
  | ----------- | --------------------------------------------- | -------- | ------------------------------------------------------------------------- |
65
- | `component` | `ComponentPublicInstanceConstructor` | Yes | The popup component to render |
65
+ | `component` | `T` (`extends Component`) | Yes | The popup component to render |
66
66
  | `props` | `RawProps<T>` | No | Props to pass to the component (typed from the component's `defineProps`) |
67
67
  | `emits` | `RawEmits<T>` | No | Event handlers (typed from the component's `defineEmits`) |
68
68
  | `slots` | `Record<string, string \| Component \| Slot>` | No | Named slots — strings render as text, components render as VNodes |
@@ -50,12 +50,12 @@ None. The composable reads breakpoint state from the framework's provide/inject
50
50
  | Property | Type | Default | Description |
51
51
  | ----------- | -------------- | ------- | --------------------------------------------------------------------- |
52
52
  | `isMobile` | `Ref<boolean>` | `false` | `true` when viewport width < 1024px |
53
- | `isDesktop` | `Ref<boolean>` | `true` | `true` when viewport width >= 1024px |
53
+ | `isDesktop` | `Ref<boolean>` | `true` | `true` when viewport width > 1024px |
54
54
  | `isPhone` | `Ref<boolean>` | `false` | `true` when viewport width < 480px |
55
55
  | `isTablet` | `Ref<boolean>` | `false` | `true` when 480px <= viewport width < 1024px |
56
56
  | `isTouch` | `boolean` | `false` | `true` on touch-capable devices (not reactive — set once at app init) |
57
57
 
58
- Breakpoint thresholds: phone < 480px, tablet 480–1023px, desktop >= 1024px. These match the framework's `setupBreakpoints()` configuration.
58
+ Breakpoint thresholds: phone < 480px, tablet 480–1023px, desktop > 1024px (bound to `bp.greater("desktop")`, strictly greater than 1024px). These match the framework's `setupBreakpoints()` configuration.
59
59
 
60
60
  Note: `isMobile` is the union of `isPhone` and `isTablet` — it covers all viewports below the desktop threshold.
61
61
 
@@ -104,10 +104,11 @@ applySettings({
104
104
 
105
105
  ```vue
106
106
  <script setup lang="ts">
107
+ import { watch } from "vue";
107
108
  import { useSettings } from "@vc-shell/framework";
108
109
  import { useUserManagement } from "@vc-shell/framework";
109
110
 
110
- const { uiSettings } = useSettings();
111
+ const { uiSettings, applySettings } = useSettings();
111
112
  const { user } = useUserManagement();
112
113
 
113
114
  // Apply user-specific settings after login
@@ -41,6 +41,18 @@ const items = settingsMenu.items.value;
41
41
  | `unregister` | `(id: string) => void` | Remove a settings menu item by ID |
42
42
  | `items` | `ComputedRef<ISettingsMenuItem[]>` | Reactive array of all registered settings menu items |
43
43
 
44
+ ### RegisterSettingsMenuItemOptions
45
+
46
+ | Field | Type | Required | Description |
47
+ | ----------- | ------------------------- | -------- | ------------------------------------------------------------------------ |
48
+ | `id` | `string` | No | Item ID. If omitted, a UUID is generated and returned from `register()`. |
49
+ | `order` | `number` | No | Sort order. Defaults to the current registry size (appended at the end). |
50
+ | `group` | `string` | No | Group key used to cluster related items. |
51
+ | `component` | `Component` | Yes | Component rendered for this item. Wrapped in `markRaw()` internally. |
52
+ | `props` | `Record<string, unknown>` | No | Props passed to the component. |
53
+
54
+ There is no `title` or `icon` field; the registered component is responsible for rendering its own label and icon.
55
+
44
56
  ### Related Exports
45
57
 
46
58
  | Export | Description |
@@ -58,11 +70,9 @@ const settingsMenu = useSettingsMenu();
58
70
 
59
71
  const itemId = settingsMenu.register({
60
72
  id: "notification-preferences",
61
- title: "Notifications",
62
- icon: "fas fa-bell",
63
73
  component: NotificationSettingsPage,
64
74
  group: "General",
65
- priority: 10,
75
+ order: 10,
66
76
  });
67
77
  ```
68
78
 
@@ -77,29 +87,23 @@ const settingsMenu = useSettingsMenu();
77
87
  // Group related settings under a common section
78
88
  settingsMenu.register({
79
89
  id: "catalog-general",
80
- title: "General",
81
- icon: "lucide-settings",
82
90
  component: markRaw(CatalogGeneralSettings),
83
91
  group: "Catalog",
84
- priority: 1,
92
+ order: 1,
85
93
  });
86
94
 
87
95
  settingsMenu.register({
88
96
  id: "catalog-seo",
89
- title: "SEO Settings",
90
- icon: "lucide-search",
91
97
  component: markRaw(CatalogSeoSettings),
92
98
  group: "Catalog",
93
- priority: 2,
99
+ order: 2,
94
100
  });
95
101
 
96
102
  settingsMenu.register({
97
103
  id: "catalog-import-export",
98
- title: "Import / Export",
99
- icon: "lucide-arrow-left-right",
100
104
  component: markRaw(CatalogImportExportSettings),
101
105
  group: "Catalog",
102
- priority: 3,
106
+ order: 3,
103
107
  });
104
108
  ```
105
109
 
@@ -112,11 +116,9 @@ import { onBeforeUnmount } from "vue";
112
116
  const settingsMenu = useSettingsMenu();
113
117
  const itemId = settingsMenu.register({
114
118
  id: "my-settings",
115
- title: "My Module Settings",
116
- icon: "lucide-wrench",
117
119
  component: markRaw(MySettingsPage),
118
120
  group: "Modules",
119
- priority: 10,
121
+ order: 10,
120
122
  });
121
123
 
122
124
  onBeforeUnmount(() => {
@@ -136,11 +138,9 @@ const { hasAccess } = usePermissions();
136
138
  if (hasAccess("catalog:manage")) {
137
139
  settingsMenu.register({
138
140
  id: "catalog-advanced",
139
- title: "Advanced Catalog Settings",
140
- icon: "lucide-settings-2",
141
141
  component: markRaw(AdvancedCatalogSettings),
142
142
  group: "Catalog",
143
- priority: 99,
143
+ order: 99,
144
144
  });
145
145
  }
146
146
  ```
@@ -87,10 +87,10 @@ provideSidebarState();
87
87
  ```vue
88
88
  <script setup lang="ts">
89
89
  import { useSidebarState } from "@vc-shell/framework";
90
- import { useBladeContext } from "@vc-shell/framework";
90
+ import { useBlade } from "@vc-shell/framework";
91
91
 
92
92
  const { closeMenu, isMenuOpen } = useSidebarState();
93
- const { openBlade } = useBladeContext();
93
+ const { openBlade } = useBlade();
94
94
 
95
95
  async function navigateToProducts() {
96
96
  // Close the mobile menu first so it does not overlay the new blade
@@ -99,7 +99,7 @@ async function navigateToProducts() {
99
99
  }
100
100
 
101
101
  await openBlade({
102
- component: ProductListBlade,
102
+ name: "ProductList",
103
103
  param: { catalogId: "default" },
104
104
  });
105
105
  }
@@ -2,6 +2,7 @@
2
2
  title: useSlowNetworkDetection
3
3
  category: composables
4
4
  group: ui-state
5
+ internal: true
5
6
  ---
6
7
 
7
8
  # useSlowNetworkDetection
@@ -23,7 +24,7 @@ The composable is initialized automatically at app startup. To reactively read t
23
24
 
24
25
  ```vue
25
26
  <script setup lang="ts">
26
- import { useSlowNetworkDetection } from "@vc-shell/framework";
27
+ import { useSlowNetworkDetection } from "@core/composables/useSlowNetworkDetection";
27
28
 
28
29
  const { isSlowNetwork } = useSlowNetworkDetection();
29
30
  </script>
@@ -54,7 +55,11 @@ const { isSlowNetwork } = useSlowNetworkDetection();
54
55
  | `trackRequest` | `(id: string) => void` | Start tracking a request. If it isn't untracked within 10 s, it counts as slow. |
55
56
  | `untrackRequest` | `(id: string) => void` | Stop tracking a request. Cancels the timer or decrements the slow count. |
56
57
 
57
- ### Constants
58
+ <!-- internal:start -->
59
+
60
+ ### Internal Constants
61
+
62
+ These are module-private `const` declarations, not exported symbols — do not `import` them. They document the thresholds baked into the composable.
58
63
 
59
64
  | Name | Value | Purpose |
60
65
  | --------------------------- | ------------------- | --------------------------------------------------- |
@@ -62,8 +67,6 @@ const { isSlowNetwork } = useSlowNetworkDetection();
62
67
  | `DISMISS_DELAY_MS` | `3000` | Delay before hiding the notification after recovery |
63
68
  | `SLOW_EFFECTIVE_TYPES` | `["slow-2g", "2g"]` | Connection types flagged as slow |
64
69
 
65
- <!-- internal:start -->
66
-
67
70
  ## How It Works
68
71
 
69
72
  ### Channel 1: effectiveType (proactive)
@@ -88,7 +91,7 @@ The fetch interceptor in `framework/core/interceptors/index.ts` calls `trackRequ
88
91
  ```vue
89
92
  <script setup lang="ts">
90
93
  import { watch } from "vue";
91
- import { useSlowNetworkDetection } from "@vc-shell/framework";
94
+ import { useSlowNetworkDetection } from "@core/composables/useSlowNetworkDetection";
92
95
 
93
96
  const { isSlowNetwork } = useSlowNetworkDetection();
94
97
 
@@ -109,7 +112,7 @@ watch(isSlowNetwork, (slow) => {
109
112
  If you bypass the standard fetch interceptor (e.g., direct `XMLHttpRequest` or third-party SDK), you can manually track the request:
110
113
 
111
114
  ```ts
112
- import { useSlowNetworkDetection } from "@vc-shell/framework";
115
+ import { useSlowNetworkDetection } from "@core/composables/useSlowNetworkDetection";
113
116
 
114
117
  const { trackRequest, untrackRequest } = useSlowNetworkDetection();
115
118
 
@@ -168,4 +171,4 @@ trackRequest("my-request-2");
168
171
 
169
172
  - [`useConnectionStatus`](../useConnectionStatus/useConnectionStatus.docs.md) — offline detection (binary online/offline)
170
173
  - [`registerInterceptors`](https://github.com/VirtoCommerce/vc-shell/blob/main/framework/core/interceptors/index.ts) — the fetch wrapper that calls `trackRequest`/`untrackRequest`
171
- - `notification` from `@shared/components/notifications` — the notification system used to display the warning
174
+ - `notification` from `@core/notifications/notification` — the notification system used to display the warning
@@ -6,7 +6,7 @@ group: ui-state
6
6
 
7
7
  # useTheme
8
8
 
9
- Manages color theme registration, switching, and persistence. Themes are applied via a `data-theme` attribute on `<html>`, and the active theme key is persisted to localStorage via `@vueuse/core`'s `useColorMode`. The composable maintains a global registry of theme definitions, supports runtime registration/unregistration from modules, and provides both explicit (`setTheme`) and sequential (`next`) theme switching. A default `"light"` theme is always registered out of the box.
9
+ Manages color theme registration, switching, and persistence. Themes are applied via a `data-theme` attribute on `<html>`, and the active theme key is persisted to localStorage via `@vueuse/core`'s `useColorMode`. The composable maintains a global registry of theme definitions, supports runtime registration/unregistration from modules, and provides both explicit (`setTheme`) and sequential (`next`) theme switching. Both `"light"` and `"dark"` themes are registered out of the box.
10
10
 
11
11
  ## When to Use
12
12
 
@@ -23,13 +23,13 @@ import { useTheme } from "@vc-shell/framework";
23
23
 
24
24
  const { themes, currentThemeKey, currentLocalizedName, next, setTheme, register } = useTheme();
25
25
 
26
- // Register a dark theme from your module
27
- register({ key: "dark", localizationKey: "CORE.THEMES.DARK" });
26
+ // light and dark are registered by default; register a custom theme from your module
27
+ register({ key: "ocean", localizationKey: "MY_MODULE.THEMES.OCEAN" });
28
28
 
29
29
  // Switch to it explicitly
30
- setTheme("dark");
30
+ setTheme("ocean");
31
31
 
32
- // Or cycle through all registered themes (light -> dark -> light -> ...)
32
+ // Or cycle through all registered themes (light -> dark -> ocean -> light -> ...)
33
33
  next();
34
34
  </script>
35
35
 
@@ -47,9 +47,9 @@ next();
47
47
 
48
48
  | Property | Type | Description |
49
49
  | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
50
- | `themes` | `ComputedRef<DisplayTheme[]>` | All registered themes with their `key` and localized `name`. Reactive -- updates when themes are registered/unregistered. |
50
+ | `themes` | `Ref<DisplayTheme[]>` | All registered themes with their `key` and localized `name`. Reactive -- updates when themes are registered/unregistered. |
51
51
  | `currentThemeKey` | `Ref<string>` | Active theme key (e.g., `"light"`, `"dark"`). Two-way reactive -- setting it switches the theme. |
52
- | `currentLocalizedName` | `ComputedRef<string>` | Localized display name of the active theme (e.g., "Light", "Dark"). Falls back to capitalized key. |
52
+ | `currentLocalizedName` | `Ref<string>` | Localized display name of the active theme (e.g., "Light", "Dark"). Falls back to capitalized key. |
53
53
  | `next` | `() => void` | Cycle to the next registered theme in order. Wraps around at the end. |
54
54
  | `setTheme` | `(themeKey: string) => void` | Switch to a specific registered theme. Logs a warning if the key is not registered. |
55
55
  | `register` | `(themes: ThemeDefinition \| ThemeDefinition[]) => void` | Add one or more themes to the global registry. Duplicates (by key) are silently ignored. |
@@ -326,20 +326,26 @@ function helperFunction() {
326
326
  | `isToolbarItemRegistered` | `(id: string) => boolean` | Check if a toolbar item with the given ID exists |
327
327
  | `registeredToolbarItems` | `IToolbarRegistration[]` | All registered toolbar items across all blades |
328
328
 
329
+ ### Additional Exports
330
+
331
+ | Export | Description |
332
+ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
333
+ | `provideToolbarService()` | Creates and provides the toolbar service via Vue injection. Idempotent -- returns existing service if already provided. Cleans up via `onScopeDispose`. |
334
+
329
335
  ### IToolbarItem
330
336
 
331
- | Property | Type | Required | Description |
332
- | -------------- | -------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- |
333
- | `id` | `string` | Yes | Unique identifier for the button |
334
- | `title` | `string \| Ref<string> \| ComputedRef<string>` | No | Button label (supports reactive values) |
335
- | `icon` | `string \| (() => string)` | No | Icon class (e.g., `"fas fa-save"`) or a function returning one |
336
- | `clickHandler` | `(app?) => void` | No | Click callback |
337
- | `disabled` | `boolean \| ComputedRef<boolean>` | No | Whether the button is disabled |
338
- | `isVisible` | `boolean \| Ref<boolean> \| ComputedRef<boolean> \| ((blade?) => boolean)` | No | Controls button visibility |
339
- | `priority` | `number` | No | Sort order (higher = displayed first, default `0`) |
340
- | `separator` | `"left" \| "right" \| "both"` | No | Adds a visual divider next to the button |
341
- | `permissions` | `string \| string[]` | No | Required permission(s) to display the button |
342
- | `bladeId` | `string` | No | Target blade ID (auto-resolved from context) |
337
+ | Property | Type | Required | Description |
338
+ | -------------- | ----------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- |
339
+ | `id` | `string` | Yes | Unique identifier for the button |
340
+ | `title` | `string \| Ref<string> \| ComputedRef<string>` | No | Button label (supports reactive values) |
341
+ | `icon` | `string \| (() => string)` | No | Icon class (e.g., `"fas fa-save"`) or a function returning one |
342
+ | `clickHandler` | `(app?) => void` | No | Click callback |
343
+ | `disabled` | `boolean \| ComputedRef<boolean \| undefined>` | No | Whether the button is disabled |
344
+ | `isVisible` | `boolean \| Ref<boolean \| undefined> \| ComputedRef<boolean \| undefined> \| ((blade?) => boolean \| undefined)` | No | Controls button visibility |
345
+ | `priority` | `number` | No | Sort order (higher = displayed first, default `0`) |
346
+ | `separator` | `"left" \| "right" \| "both"` | No | Adds a visual divider next to the button |
347
+ | `permissions` | `string \| string[]` | No | Required permission(s) to display the button |
348
+ | `bladeId` | `string` | No | Target blade ID (auto-resolved from context) |
343
349
 
344
350
  `IToolbarItem` is the shape consumed by `ToolbarService`. The blade-level array binding uses `IBladeToolbar` (see [Core types](../../types/)), a near-identical shape that the framework normalizes into `IToolbarItem` before render.
345
351
 
@@ -60,7 +60,7 @@ None.
60
60
 
61
61
  | Property | Type | Description |
62
62
  | ----------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
63
- | `user` | `ComputedRef<UserDetail \| undefined>` | Current user details (userName, email, id, etc.), or `undefined` if not authenticated. |
63
+ | `user` | `ComputedRef<UserDetail \| undefined>` | Current user details (userName, id, permissions, isAdministrator, etc.), or `undefined` if not authenticated. |
64
64
  | `loading` | `ComputedRef<boolean>` | Whether a user operation (loadUser, signOut) is in progress. |
65
65
  | `isAuthenticated` | `ComputedRef<boolean>` | Whether a user session is active. Derived from `user.userName != null`. |
66
66
  | `isAdministrator` | `ComputedRef<boolean \| undefined>` | Whether the current user has admin privileges. `undefined` if user is not loaded. |
@@ -118,7 +118,7 @@ router.beforeEach(async (to) => {
118
118
  />
119
119
  <div>
120
120
  <p class="tw-text-sm tw-font-medium">{{ user?.userName }}</p>
121
- <p class="tw-text-xs tw-text-gray-500">{{ user?.email }}</p>
121
+ <p class="tw-text-xs tw-text-gray-500">{{ user?.id }}</p>
122
122
  </div>
123
123
  <VcButton
124
124
  size="sm"
@@ -75,21 +75,21 @@ None.
75
75
 
76
76
  ### Returns
77
77
 
78
- | Property | Type | Description |
79
- | ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
80
- | `user` | `ComputedRef<UserDetail \| undefined>` | Current user details. |
81
- | `loading` | `ComputedRef<boolean>` | Whether any operation is in progress. |
82
- | `isAdministrator` | `ComputedRef<boolean \| undefined>` | Admin status of the current user. |
83
- | `isAuthenticated` | `ComputedRef<boolean>` | Whether user session is active. |
84
- | `signIn` | `(username: string, password: string) => Promise<SignInResult>` | Authenticates with username/password. Performs cookie-based login, obtains an OAuth token with offline_access scope, and loads user details. Returns `{ succeeded: true }` on success or `{ succeeded: false, error: string }` on failure. |
85
- | `signOut` | `() => Promise<void>` | Clears session, auth data, and localStorage. Handles both standard and external SSO sign-out. |
86
- | `loadUser` | `() => Promise<UserDetail>` | Loads/reloads user info from the server. Deduplicates concurrent calls. |
87
- | `validateToken` | `(userId: string, token: string) => Promise<boolean>` | Validates a password-reset token. Returns `true` if valid. |
88
- | `validatePassword` | `(password: string) => Promise<IdentityResult>` | Validates a password against the platform's password policy (length, complexity, etc.). |
89
- | `resetPasswordByToken` | `(userId: string, password: string, token: string) => Promise<SecurityResult>` | Resets a user's password using a reset token. Returns `{ succeeded: true }` on success. |
90
- | `requestPasswordReset` | `(loginOrEmail: string) => Promise<RequestPasswordResult>` | Sends a password-reset email to the user. Returns `{ succeeded: true }` on success. |
91
- | `changeUserPassword` | `(oldPassword: string, newPassword: string) => Promise<SecurityResult \| undefined>` | Changes the current user's password. Requires the old password for verification. |
92
- | `getLoginType` | `() => Promise<LoginType[]>` | Returns available login types (password-based, external SSO providers, etc.). Used to render the appropriate sign-in UI. |
78
+ | Property | Type | Description |
79
+ | ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
80
+ | `user` | `ComputedRef<UserDetail \| undefined>` | Current user details. |
81
+ | `loading` | `ComputedRef<boolean>` | Whether any operation is in progress. |
82
+ | `isAdministrator` | `ComputedRef<boolean \| undefined>` | Admin status of the current user. |
83
+ | `isAuthenticated` | `ComputedRef<boolean>` | Whether user session is active. |
84
+ | `signIn` | `(username: string, password: string) => Promise<SignInResult \| { succeeded: boolean; error?: any }>` | Authenticates with username/password. Performs cookie-based login, obtains an OAuth token with offline_access scope, and loads user details. Returns `{ succeeded: true }` on success or `{ succeeded: false, error: string }` on failure. |
85
+ | `signOut` | `() => Promise<void>` | Clears session, auth data, and localStorage. Handles both standard and external SSO sign-out. |
86
+ | `loadUser` | `() => Promise<UserDetail>` | Loads/reloads user info from the server. Deduplicates concurrent calls. |
87
+ | `validateToken` | `(userId: string, token: string) => Promise<boolean>` | Validates a password-reset token. Returns `true` if valid. |
88
+ | `validatePassword` | `(password: string) => Promise<IdentityResult>` | Validates a password against the platform's password policy (length, complexity, etc.). |
89
+ | `resetPasswordByToken` | `(userId: string, password: string, token: string) => Promise<SecurityResult>` | Resets a user's password using a reset token. Returns `{ succeeded: true }` on success. |
90
+ | `requestPasswordReset` | `(loginOrEmail: string) => Promise<RequestPasswordResult>` | Sends a password-reset email to the user. Returns `{ succeeded: true }` on success. |
91
+ | `changeUserPassword` | `(oldPassword: string, newPassword: string) => Promise<SecurityResult \| undefined>` | Changes the current user's password. Requires the old password for verification. |
92
+ | `getLoginType` | `() => Promise<LoginType[]>` | Returns available login types (password-based, external SSO providers, etc.). Used to render the appropriate sign-in UI. |
93
93
 
94
94
  ## How It Works
95
95
 
@@ -139,7 +139,7 @@ async function handleReset() {
139
139
  // Validate against password policy
140
140
  const validation = await validatePassword(newPassword.value);
141
141
  if (!validation.succeeded) {
142
- error.value = validation.errors?.join(", ") ?? "Password does not meet requirements.";
142
+ error.value = validation.errors?.map((e) => e.description).join(", ") ?? "Password does not meet requirements.";
143
143
  return;
144
144
  }
145
145
 
@@ -167,7 +167,7 @@ const showPasswordForm = ref(false);
167
167
  onMounted(async () => {
168
168
  loginTypes.value = await getLoginType();
169
169
  // Show password form only if password auth is available
170
- showPasswordForm.value = loginTypes.value.some((t) => t.loginProvider === "password");
170
+ showPasswordForm.value = loginTypes.value.some((t) => t.hasLoginForm);
171
171
  });
172
172
  </script>
173
173
 
@@ -181,10 +181,10 @@ onMounted(async () => {
181
181
  </form>
182
182
 
183
183
  <div
184
- v-for="provider in loginTypes.filter((t) => t.loginProvider !== 'password')"
185
- :key="provider.loginProvider"
184
+ v-for="provider in loginTypes.filter((t) => !t.hasLoginForm)"
185
+ :key="provider.authenticationType"
186
186
  >
187
- <VcButton @click="redirectToSSO(provider)"> Sign in with {{ provider.loginProvider }} </VcButton>
187
+ <VcButton @click="redirectToSSO(provider)"> Sign in with {{ provider.authenticationType }} </VcButton>
188
188
  </div>
189
189
  </div>
190
190
  </template>
@@ -6,7 +6,7 @@ group: services
6
6
 
7
7
  # useWidgets
8
8
 
9
- Provides access to the `IWidgetService` singleton for managing blade widget registrations, activation state, and external widgets. This is the low-level composable for direct widget service interaction. It exposes the full widget lifecycle API: registering widgets to specific blades, querying registered widgets, tracking active widget state, and managing external (cross-module) widget registrations.
9
+ Provides access to the `IWidgetService` singleton for managing blade widget registrations and external widgets. This is the low-level composable for direct widget service interaction. It exposes the widget lifecycle API: registering widgets to specific blades, querying and updating registered widgets, and managing external (cross-module) widget registrations.
10
10
 
11
11
  Also exports `provideWidgetService()` for framework-level initialization and `registerWidget()` / `registerExternalWidget()` for global pre-registration before the service is created.
12
12
 
@@ -27,10 +27,8 @@ const widgetService = useWidgets();
27
27
  // Query all widgets registered for a specific blade
28
28
  const widgets = widgetService.getWidgets("order-details");
29
29
 
30
- // Check if a widget is currently active (visible and expanded)
31
- if (widgetService.isActiveWidget("order-status-widget")) {
32
- // widget is currently in focus
33
- }
30
+ // Query external widgets contributed by other modules
31
+ const externalWidgets = widgetService.getExternalWidgetsForBlade("order-details");
34
32
  ```
35
33
 
36
34
  ## API
@@ -41,21 +39,15 @@ None.
41
39
 
42
40
  ### Returns (`IWidgetService`)
43
41
 
44
- | Property / Method | Type | Description |
45
- | ---------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------- |
46
- | `registerWidget` | `(widget: IWidget, bladeId: string) => void` | Registers a widget for a specific blade. The widget will appear in that blade's widget area. |
47
- | `unregisterWidget` | `(widgetId: string, bladeId: string) => void` | Removes a widget from a blade by ID. |
48
- | `getWidgets` | `(bladeId: string) => IWidget[]` | Returns all widgets registered for a specific blade. |
49
- | `clearBladeWidgets` | `(bladeId: string) => void` | Removes all widgets for a blade (used during blade teardown). |
50
- | `registeredWidgets` | `IWidgetRegistration[]` | All widget registrations across all blades. |
51
- | `isActiveWidget` | `(id: string) => boolean` | Checks if a widget is currently active (selected/expanded). |
52
- | `setActiveWidget` | `(args) => void` | Sets a widget as active with its exposed instance. |
53
- | `updateActiveWidget` | `() => void` | Triggers the active widget's update function. Deprecated -- use headless widgets instead. |
54
- | `isWidgetRegistered` | `(id: string) => boolean` | Checks if a widget ID exists in any blade's registry. |
55
- | `updateWidget` | `(args) => void` | Updates properties of a registered widget (trigger, badge, etc.). |
56
- | `resolveWidgetProps` | `(widget, bladeData) => Record<string, unknown>` | Resolves widget props from blade data. Deprecated. |
57
- | `getExternalWidgetsForBlade` | `(bladeId: string) => IExternalWidgetRegistration[]` | Gets external widgets that target a specific blade (registered by other modules). |
58
- | `getAllExternalWidgets` | `() => IExternalWidgetRegistration[]` | Gets all registered external widgets across all modules. |
42
+ | Property / Method | Type | Description |
43
+ | ---------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
44
+ | `registerWidget` | `(widget: IWidget, bladeId: string) => void` | Registers a widget for a specific blade. The widget will appear in that blade's widget area. |
45
+ | `unregisterWidget` | `(widgetId: string, bladeId: string) => void` | Removes a widget from a blade by ID. |
46
+ | `getWidgets` | `(bladeId: string) => IWidget[]` | Returns all widgets registered for a specific blade. |
47
+ | `updateWidget` | `({ id, bladeId, widget }: { id: string; bladeId: string; widget: Partial<IWidget> }) => void` | Updates properties of a registered widget (trigger, badge, etc.). |
48
+ | `getExternalWidgetsForBlade` | `(bladeId: string) => IExternalWidgetRegistration[]` | Gets external widgets that target a specific blade (registered by other modules). |
49
+ | `getAllExternalWidgets` | `() => IExternalWidgetRegistration[]` | Gets all registered external widgets across all modules. |
50
+ | `cloneWidget` | `<T extends IWidget \| IExternalWidgetRegistration>(widget: T) => T` | Returns a deep-ish clone of a widget or external widget registration. |
59
51
 
60
52
  ### Additional Exports
61
53
 
@@ -77,7 +69,7 @@ The widget system has three layers:
77
69
 
78
70
  3. **Runtime access** (`useWidgets()`): Components inject the service and use it to query or modify widget state.
79
71
 
80
- The service tracks active widgets (which widget is currently expanded/focused) separately from registrations, enabling the widget panel to highlight the active widget and call its update function.
72
+ The service stores widget registrations per blade and returns cloned widget definitions on query. It does not track active/expanded/focused state.
81
73
 
82
74
  <!-- internal:end -->
83
75
 
@@ -117,11 +109,10 @@ import ShippingTracker from "./widgets/ShippingTracker.vue";
117
109
  export default {
118
110
  install() {
119
111
  registerExternalWidget({
120
- widgetId: "shipping-tracker",
121
- bladeId: "order-details", // target blade from another module
112
+ id: "shipping-tracker",
113
+ targetBlades: ["order-details"], // target blades from other modules
122
114
  component: markRaw(ShippingTracker),
123
115
  title: "Shipping",
124
- icon: "fas fa-truck",
125
116
  });
126
117
  },
127
118
  };