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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/CHANGELOG.md +78 -54
  2. package/README.md +42 -12
  3. package/package.json +4 -4
  4. package/runtime/VERSION +1 -1
  5. package/runtime/agents/api-analyzer.md +31 -16
  6. package/runtime/agents/blade-enhancer.md +15 -9
  7. package/runtime/agents/details-blade-generator.md +47 -31
  8. package/runtime/agents/list-blade-generator.md +21 -37
  9. package/runtime/agents/locales-generator.md +3 -0
  10. package/runtime/agents/migration-agent.md +18 -7
  11. package/runtime/agents/module-analyzer.md +2 -0
  12. package/runtime/agents/module-assembler.md +15 -0
  13. package/runtime/agents/promote-agent.md +15 -4
  14. package/runtime/agents/type-checker.md +11 -0
  15. package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
  16. package/runtime/knowledge/docs/core/api/platform.docs.md +30 -30
  17. package/runtime/knowledge/docs/core/blade-navigation/blade-nav-composables.docs.md +41 -41
  18. package/runtime/knowledge/docs/core/composables/bladeContext/index.docs.md +12 -10
  19. package/runtime/knowledge/docs/core/composables/useApiClient/useApiClient.docs.md +11 -14
  20. package/runtime/knowledge/docs/core/composables/useAppBarMobileButtons/useAppBarMobileButtons.docs.md +35 -35
  21. package/runtime/knowledge/docs/core/composables/useAppBarWidget/useAppBarWidget.docs.md +35 -35
  22. package/runtime/knowledge/docs/core/composables/useAppInsights/useAppInsights.docs.md +15 -15
  23. package/runtime/knowledge/docs/core/composables/useAssets/useAssets.docs.md +21 -18
  24. package/runtime/knowledge/docs/core/composables/useAssetsManager/useAssetsManager.docs.md +28 -24
  25. package/runtime/knowledge/docs/core/composables/useAsync/useAsync.docs.md +90 -61
  26. package/runtime/knowledge/docs/core/composables/useBeforeUnload/useBeforeUnload.docs.md +19 -18
  27. package/runtime/knowledge/docs/core/composables/useBlade/useBlade.docs.md +89 -68
  28. package/runtime/knowledge/docs/core/composables/useBladeForm/useBladeForm.docs.md +27 -25
  29. package/runtime/knowledge/docs/core/composables/useBladeRegistry/useBladeRegistry.docs.md +15 -15
  30. package/runtime/knowledge/docs/core/composables/useBladeWidgets/index.docs.md +43 -47
  31. package/runtime/knowledge/docs/core/composables/useBreadcrumbs/useBreadcrumbs.docs.md +11 -11
  32. package/runtime/knowledge/docs/core/composables/useConnectionStatus/useConnectionStatus.docs.md +27 -15
  33. package/runtime/knowledge/docs/core/composables/useDashboard/useDashboard.docs.md +30 -30
  34. package/runtime/knowledge/docs/core/composables/useDynamicProperties/useDynamicProperties.docs.md +34 -36
  35. package/runtime/knowledge/docs/core/composables/useErrorHandler/useErrorHandler.docs.md +44 -23
  36. package/runtime/knowledge/docs/core/composables/useFunctions/useFunctions.docs.md +14 -11
  37. package/runtime/knowledge/docs/core/composables/useKeyboardNavigation/useKeyboardNavigation.docs.md +47 -38
  38. package/runtime/knowledge/docs/core/composables/useLanguages/useLanguages.docs.md +37 -28
  39. package/runtime/knowledge/docs/core/composables/useLoading/useLoading.docs.md +23 -17
  40. package/runtime/knowledge/docs/core/composables/useMenuExpanded/index.docs.md +9 -9
  41. package/runtime/knowledge/docs/core/composables/useMenuService/useMenuService.docs.md +42 -42
  42. package/runtime/knowledge/docs/core/composables/useModificationTracker/useModificationTracker.docs.md +22 -12
  43. package/runtime/knowledge/docs/core/composables/useNotifications/useNotifications.docs.md +33 -41
  44. package/runtime/knowledge/docs/core/composables/usePermissions/usePermissions.docs.md +16 -16
  45. package/runtime/knowledge/docs/core/composables/usePlatformLocaleSync/usePlatformLocaleSync.docs.md +28 -0
  46. package/runtime/knowledge/docs/core/composables/usePopup/usePopup.docs.md +32 -24
  47. package/runtime/knowledge/docs/core/composables/useResponsive/useResponsive.docs.md +32 -11
  48. package/runtime/knowledge/docs/core/composables/useSettings/useSettings.docs.md +22 -13
  49. package/runtime/knowledge/docs/core/composables/useSettingsMenu/useSettingsMenu.docs.md +7 -7
  50. package/runtime/knowledge/docs/core/composables/useSidebarState/useSidebarState.docs.md +32 -24
  51. package/runtime/knowledge/docs/core/composables/useSlowNetworkDetection/useSlowNetworkDetection.docs.md +21 -17
  52. package/runtime/knowledge/docs/core/composables/useTheme/useTheme.docs.md +24 -24
  53. package/runtime/knowledge/docs/core/composables/useToolbar/useToolbar.docs.md +28 -31
  54. package/runtime/knowledge/docs/core/composables/useUser/useUser.docs.md +43 -24
  55. package/runtime/knowledge/docs/core/composables/useUserManagement/useUserManagement.docs.md +68 -48
  56. package/runtime/knowledge/docs/core/composables/useWebVitals/useWebVitals.docs.md +19 -19
  57. package/runtime/knowledge/docs/core/composables/useWidgets/useWidgets.docs.md +42 -47
  58. package/runtime/knowledge/docs/core/directives/autofocus/autofocus.docs.md +10 -4
  59. package/runtime/knowledge/docs/core/directives/loading/loading.docs.md +35 -20
  60. package/runtime/knowledge/docs/core/notifications/notifications.docs.md +36 -35
  61. package/runtime/knowledge/docs/core/plugins/ai-agent/ai-agent.docs.md +38 -38
  62. package/runtime/knowledge/docs/core/plugins/extension-points/extension-points.docs.md +79 -62
  63. package/runtime/knowledge/docs/core/plugins/global-error-handler/global-error-handler.docs.md +10 -10
  64. package/runtime/knowledge/docs/core/plugins/i18n/i18n.docs.md +21 -23
  65. package/runtime/knowledge/docs/core/plugins/modularity/modularity.docs.md +91 -83
  66. package/runtime/knowledge/docs/core/plugins/permissions/permissions.docs.md +10 -16
  67. package/runtime/knowledge/docs/core/plugins/signalR/signalR.docs.md +9 -9
  68. package/runtime/knowledge/docs/core/plugins/validation/validation.docs.md +65 -22
  69. package/runtime/knowledge/docs/core/services/services.docs.md +19 -22
  70. package/runtime/knowledge/docs/core/types/types.docs.md +40 -40
  71. package/runtime/knowledge/docs/core/utilities/date/date-utilities.docs.md +27 -27
  72. package/runtime/knowledge/docs/core/utilities/shared-utilities.docs.md +23 -23
  73. package/runtime/knowledge/docs/core/utilities/thumbnail/thumbnail.docs.md +22 -25
  74. package/runtime/knowledge/docs/core/utilities/utilities.docs.md +64 -64
  75. package/runtime/knowledge/docs/injection-keys.docs.md +52 -51
  76. package/runtime/knowledge/docs/modules/assets-manager/assets-manager.docs.md +9 -9
  77. package/runtime/knowledge/docs/shell/_internal/popup/common/popup-common.docs.md +23 -43
  78. package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +5 -5
  79. package/runtime/knowledge/docs/shell/auth/ForgotPasswordPage/forgot-password-page.docs.md +5 -5
  80. package/runtime/knowledge/docs/shell/auth/InvitePage/invite-page.docs.md +8 -7
  81. package/runtime/knowledge/docs/shell/auth/LoginPage/login-page.docs.md +7 -7
  82. package/runtime/knowledge/docs/shell/auth/ResetPasswordPage/reset-password-page.docs.md +8 -7
  83. package/runtime/knowledge/docs/shell/auth/sign-in/sign-in.docs.md +29 -13
  84. package/runtime/knowledge/docs/shell/components/change-password/change-password.docs.md +13 -16
  85. package/runtime/knowledge/docs/shell/components/change-password-button/change-password-button.docs.md +1 -7
  86. package/runtime/knowledge/docs/shell/components/error-interceptor/error-interceptor.docs.md +5 -5
  87. package/runtime/knowledge/docs/shell/components/language-selector/language-selector.docs.md +1 -1
  88. package/runtime/knowledge/docs/shell/components/logout-button/logout-button.docs.md +1 -1
  89. package/runtime/knowledge/docs/shell/components/notification-template/notification-template.docs.md +17 -9
  90. package/runtime/knowledge/docs/shell/components/settings-menu/settings-menu.docs.md +11 -17
  91. package/runtime/knowledge/docs/shell/components/settings-menu-item/settings-menu-item.docs.md +34 -65
  92. package/runtime/knowledge/docs/shell/components/sidebar/sidebar.docs.md +16 -26
  93. package/runtime/knowledge/docs/shell/components/theme-selector/theme-selector.docs.md +2 -2
  94. package/runtime/knowledge/docs/shell/components/user-dropdown-button/user-dropdown-button.docs.md +7 -9
  95. package/runtime/knowledge/docs/shell/dashboard/dashboard-charts/dashboard-charts.docs.md +30 -40
  96. package/runtime/knowledge/docs/shell/dashboard/dashboard-widget-card/dashboard-widget-card.docs.md +26 -19
  97. package/runtime/knowledge/docs/shell/dashboard/draggable-dashboard/draggable-dashboard.docs.md +15 -12
  98. package/runtime/knowledge/docs/ui/components/atoms/vc-badge/vc-badge.docs.md +15 -26
  99. package/runtime/knowledge/docs/ui/components/atoms/vc-banner/vc-banner.docs.md +21 -19
  100. package/runtime/knowledge/docs/ui/components/atoms/vc-button/vc-button.docs.md +83 -67
  101. package/runtime/knowledge/docs/ui/components/atoms/vc-card/vc-card.docs.md +100 -59
  102. package/runtime/knowledge/docs/ui/components/atoms/vc-col/vc-col.docs.md +28 -11
  103. package/runtime/knowledge/docs/ui/components/atoms/vc-container/vc-container.docs.md +20 -17
  104. package/runtime/knowledge/docs/ui/components/atoms/vc-hint/vc-hint.docs.md +26 -17
  105. package/runtime/knowledge/docs/ui/components/atoms/vc-icon/vc-icon.docs.md +30 -32
  106. package/runtime/knowledge/docs/ui/components/atoms/vc-image/vc-image.docs.md +25 -48
  107. package/runtime/knowledge/docs/ui/components/atoms/vc-label/vc-label.docs.md +29 -24
  108. package/runtime/knowledge/docs/ui/components/atoms/vc-link/vc-link.docs.md +23 -15
  109. package/runtime/knowledge/docs/ui/components/atoms/vc-loading/vc-loading.docs.md +22 -13
  110. package/runtime/knowledge/docs/ui/components/atoms/vc-progress/vc-progress.docs.md +33 -18
  111. package/runtime/knowledge/docs/ui/components/atoms/vc-row/vc-row.docs.md +56 -15
  112. package/runtime/knowledge/docs/ui/components/atoms/vc-scrollable-container/vc-scrollable-container.docs.md +28 -15
  113. package/runtime/knowledge/docs/ui/components/atoms/vc-skeleton/vc-skeleton.docs.md +40 -20
  114. package/runtime/knowledge/docs/ui/components/atoms/vc-status/vc-status.docs.md +25 -14
  115. package/runtime/knowledge/docs/ui/components/atoms/vc-status-icon/vc-status-icon.docs.md +40 -14
  116. package/runtime/knowledge/docs/ui/components/atoms/vc-tooltip/vc-tooltip.docs.md +54 -42
  117. package/runtime/knowledge/docs/ui/components/atoms/vc-video/vc-video.docs.md +17 -17
  118. package/runtime/knowledge/docs/ui/components/atoms/vc-widget/vc-widget.docs.md +21 -21
  119. package/runtime/knowledge/docs/ui/components/molecules/multilanguage-selector/multilanguage-selector.docs.md +23 -10
  120. package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +55 -44
  121. package/runtime/knowledge/docs/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.docs.md +23 -20
  122. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +92 -65
  123. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +22 -36
  124. package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +65 -23
  125. package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +52 -73
  126. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown/vc-dropdown.docs.md +91 -85
  127. package/runtime/knowledge/docs/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.docs.md +38 -42
  128. package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +56 -73
  129. package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +61 -27
  130. package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +42 -50
  131. package/runtime/knowledge/docs/ui/components/molecules/vc-form/vc-form.docs.md +35 -64
  132. package/runtime/knowledge/docs/ui/components/molecules/vc-image-tile/vc-image-tile.docs.md +38 -41
  133. package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +109 -131
  134. package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +47 -88
  135. package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +50 -64
  136. package/runtime/knowledge/docs/ui/components/molecules/vc-input-group/vc-input-group.docs.md +29 -24
  137. package/runtime/knowledge/docs/ui/components/molecules/vc-menu/vc-menu.docs.md +32 -28
  138. package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +57 -65
  139. package/runtime/knowledge/docs/ui/components/molecules/vc-pagination/vc-pagination.docs.md +28 -26
  140. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +55 -20
  141. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +21 -35
  142. package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +38 -33
  143. package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +72 -83
  144. package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +21 -16
  145. package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +55 -64
  146. package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +51 -70
  147. package/runtime/knowledge/docs/ui/components/molecules/vc-toast/vc-toast.docs.md +58 -57
  148. package/runtime/knowledge/docs/ui/components/organisms/vc-app/vc-app.docs.md +49 -26
  149. package/runtime/knowledge/docs/ui/components/organisms/vc-auth-layout/vc-auth-layout.docs.md +82 -28
  150. package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +90 -75
  151. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/composables/table-composables.docs.md +99 -48
  152. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +548 -367
  153. package/runtime/knowledge/docs/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.docs.md +35 -52
  154. package/runtime/knowledge/docs/ui/components/organisms/vc-gallery/vc-gallery.docs.md +33 -62
  155. package/runtime/knowledge/docs/ui/components/organisms/vc-image-upload/vc-image-upload.docs.md +17 -23
  156. package/runtime/knowledge/docs/ui/components/organisms/vc-popup/vc-popup.docs.md +109 -68
  157. package/runtime/knowledge/docs/ui/components/organisms/vc-sidebar/vc-sidebar.docs.md +82 -44
  158. package/runtime/knowledge/docs/ui/composables/ui-composables.docs.md +8 -8
  159. package/runtime/knowledge/docs/ui/composables/useDataTablePagination.docs.md +164 -0
  160. package/runtime/knowledge/docs/ui/composables/useDataTableSort.docs.md +34 -26
  161. package/runtime/knowledge/docs/ui/composables/useTableSelection.docs.md +48 -40
  162. package/runtime/knowledge/docs/ui/composables/useTableSort.docs.md +30 -17
  163. package/runtime/knowledge/docs/ui/types/ui-types.docs.md +40 -29
  164. package/runtime/knowledge/examples/offers-module.md +15 -13
  165. package/runtime/knowledge/examples/team-module.md +82 -119
  166. package/runtime/knowledge/examples/videos-module.md +44 -17
  167. package/runtime/knowledge/index.md +22 -0
  168. package/runtime/knowledge/migration-prompts/blade-form-migration.md +17 -8
  169. package/runtime/knowledge/migration-prompts/blade-props-migration.md +1 -2
  170. package/runtime/knowledge/migration-prompts/datatable-migration.md +801 -0
  171. package/runtime/knowledge/migration-prompts/icon-migration.md +97 -0
  172. package/runtime/knowledge/migration-prompts/manual-migration-audit.md +117 -0
  173. package/runtime/knowledge/migration-prompts/notifications-migration.md +8 -3
  174. package/runtime/knowledge/migration-prompts/nswag-migration.md +25 -29
  175. package/runtime/knowledge/migration-prompts/use-assets-migration.md +164 -0
  176. package/runtime/knowledge/migration-prompts/use-data-table-pagination-migration.md +176 -0
  177. package/runtime/knowledge/migration-prompts/widgets-migration.md +48 -27
  178. package/runtime/knowledge/patterns/assets-management.md +20 -20
  179. package/runtime/knowledge/patterns/blade-navigation.md +7 -14
  180. package/runtime/knowledge/patterns/blade-widget.md +19 -17
  181. package/runtime/knowledge/patterns/child-blade-flow.md +19 -7
  182. package/runtime/knowledge/patterns/composable-details.md +20 -50
  183. package/runtime/knowledge/patterns/composable-list.md +43 -31
  184. package/runtime/knowledge/patterns/dashboard-widget.md +14 -16
  185. package/runtime/knowledge/patterns/datatable-pattern.md +521 -0
  186. package/runtime/knowledge/patterns/details-blade-pattern.md +78 -116
  187. package/runtime/knowledge/patterns/extension-points-usage.md +53 -44
  188. package/runtime/knowledge/patterns/form-validation.md +28 -64
  189. package/runtime/knowledge/patterns/list-blade-pattern.md +33 -21
  190. package/runtime/knowledge/patterns/module-structure.md +7 -1
  191. package/runtime/knowledge/patterns/multilanguage-fields.md +8 -14
  192. package/runtime/knowledge/patterns/notification-template.md +21 -14
  193. package/runtime/knowledge/patterns/signalr-notifications.md +30 -32
  194. package/runtime/knowledge/patterns/toolbar-pattern.md +18 -20
  195. package/runtime/vc-app.md +241 -62
@@ -2,7 +2,7 @@
2
2
 
3
3
  Shared composable exposing the full user management API: sign-in, sign-out, password reset, token validation, and login type discovery. This composable extends the same internal logic as `useUser` but surfaces the administrative and authentication-flow methods that `useUser` intentionally hides. The separation ensures that regular blades only have access to read-only user state, while auth pages and admin screens get the full API.
4
4
 
5
- Uses `createSharedComposable` from VueUse, so all callers share the same state instance. Internally, it calls `_createInternalUserLogic()` -- the same factory used by `useUser` -- so both composables operate on the same underlying user ref and auth data.
5
+ Both `useUser()` and `useUserManagement()` read from the same singleton internal logic, so everything is shared: the `user` ref, `authData`, the `loading` ref, in-flight request deduplication (`loadUser`), and the underlying `SecurityClient` instance. The two composables are thin selectors over a single source of truth — picking a narrow read-only slice or the full management slice.
6
6
 
7
7
  ## When to Use
8
8
 
@@ -17,29 +17,45 @@ Uses `createSharedComposable` from VueUse, so all callers share the same state i
17
17
 
18
18
  ```vue
19
19
  <script setup lang="ts">
20
- import { useUserManagement } from '@vc-shell/framework';
21
- import { ref } from 'vue';
20
+ import { useUserManagement } from "@vc-shell/framework";
21
+ import { ref } from "vue";
22
22
 
23
23
  const { signIn, loading, isAuthenticated } = useUserManagement();
24
- const username = ref('');
25
- const password = ref('');
26
- const errorMessage = ref('');
24
+ const username = ref("");
25
+ const password = ref("");
26
+ const errorMessage = ref("");
27
27
 
28
28
  async function handleLogin() {
29
- errorMessage.value = '';
29
+ errorMessage.value = "";
30
30
  const result = await signIn(username.value, password.value);
31
31
  if (!result.succeeded) {
32
- errorMessage.value = result.error ?? 'Login failed';
32
+ errorMessage.value = result.error ?? "Login failed";
33
33
  }
34
34
  }
35
35
  </script>
36
36
 
37
37
  <template>
38
38
  <form @submit.prevent="handleLogin">
39
- <VcInput v-model="username" label="Username" />
40
- <VcInput v-model="password" label="Password" type="password" />
41
- <p v-if="errorMessage" class="tw-text-red-500">{{ errorMessage }}</p>
42
- <VcButton type="submit" :loading="loading">Sign In</VcButton>
39
+ <VcInput
40
+ v-model="username"
41
+ label="Username"
42
+ />
43
+ <VcInput
44
+ v-model="password"
45
+ label="Password"
46
+ type="password"
47
+ />
48
+ <p
49
+ v-if="errorMessage"
50
+ class="tw-text-red-500"
51
+ >
52
+ {{ errorMessage }}
53
+ </p>
54
+ <VcButton
55
+ type="submit"
56
+ :loading="loading"
57
+ >Sign In</VcButton
58
+ >
43
59
  </form>
44
60
  </template>
45
61
  ```
@@ -52,25 +68,25 @@ None.
52
68
 
53
69
  ### Returns
54
70
 
55
- | Property | Type | Description |
56
- |----------|------|-------------|
57
- | `user` | `ComputedRef<UserDetail \| undefined>` | Current user details. |
58
- | `loading` | `ComputedRef<boolean>` | Whether any operation is in progress. |
59
- | `isAdministrator` | `ComputedRef<boolean \| undefined>` | Admin status of the current user. |
60
- | `isAuthenticated` | `ComputedRef<boolean>` | Whether user session is active. |
61
- | `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. |
62
- | `signOut` | `() => Promise<void>` | Clears session, auth data, and localStorage. Handles both standard and external SSO sign-out. |
63
- | `loadUser` | `() => Promise<UserDetail>` | Loads/reloads user info from the server. Deduplicates concurrent calls. |
64
- | `validateToken` | `(userId: string, token: string) => Promise<boolean>` | Validates a password-reset token. Returns `true` if valid. |
65
- | `validatePassword` | `(password: string) => Promise<IdentityResult>` | Validates a password against the platform's password policy (length, complexity, etc.). |
66
- | `resetPasswordByToken` | `(userId: string, password: string, token: string) => Promise<SecurityResult>` | Resets a user's password using a reset token. Returns `{ succeeded: true }` on success. |
67
- | `requestPasswordReset` | `(loginOrEmail: string) => Promise<RequestPasswordResult>` | Sends a password-reset email to the user. Returns `{ succeeded: true }` on success. |
68
- | `changeUserPassword` | `(oldPassword: string, newPassword: string) => Promise<SecurityResult \| undefined>` | Changes the current user's password. Requires the old password for verification. |
69
- | `getLoginType` | `() => Promise<LoginType[]>` | Returns available login types (password-based, external SSO providers, etc.). Used to render the appropriate sign-in UI. |
71
+ | Property | Type | Description |
72
+ | ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
73
+ | `user` | `ComputedRef<UserDetail \| undefined>` | Current user details. |
74
+ | `loading` | `ComputedRef<boolean>` | Whether any operation is in progress. |
75
+ | `isAdministrator` | `ComputedRef<boolean \| undefined>` | Admin status of the current user. |
76
+ | `isAuthenticated` | `ComputedRef<boolean>` | Whether user session is active. |
77
+ | `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. |
78
+ | `signOut` | `() => Promise<void>` | Clears session, auth data, and localStorage. Handles both standard and external SSO sign-out. |
79
+ | `loadUser` | `() => Promise<UserDetail>` | Loads/reloads user info from the server. Deduplicates concurrent calls. |
80
+ | `validateToken` | `(userId: string, token: string) => Promise<boolean>` | Validates a password-reset token. Returns `true` if valid. |
81
+ | `validatePassword` | `(password: string) => Promise<IdentityResult>` | Validates a password against the platform's password policy (length, complexity, etc.). |
82
+ | `resetPasswordByToken` | `(userId: string, password: string, token: string) => Promise<SecurityResult>` | Resets a user's password using a reset token. Returns `{ succeeded: true }` on success. |
83
+ | `requestPasswordReset` | `(loginOrEmail: string) => Promise<RequestPasswordResult>` | Sends a password-reset email to the user. Returns `{ succeeded: true }` on success. |
84
+ | `changeUserPassword` | `(oldPassword: string, newPassword: string) => Promise<SecurityResult \| undefined>` | Changes the current user's password. Requires the old password for verification. |
85
+ | `getLoginType` | `() => Promise<LoginType[]>` | Returns available login types (password-based, external SSO providers, etc.). Used to render the appropriate sign-in UI. |
70
86
 
71
87
  ## How It Works
72
88
 
73
- The composable creates (or reuses) the internal user logic via `_createInternalUserLogic()`. The `signIn` flow has three phases:
89
+ The composable reads from the singleton internal user logic (instantiated lazily on first call to `useUser()` or `useUserManagement()`). The `signIn` flow has three phases:
74
90
 
75
91
  1. **Cookie login**: Calls `securityClient.login()` to establish a server-side session cookie.
76
92
  2. **OAuth token**: Fetches an OAuth token via `POST /connect/token` with `grant_type: password` and `scope: offline_access`. The refresh token enables automatic token renewal.
@@ -82,9 +98,9 @@ Token data is stored in localStorage under `vc_auth_data` and survives page relo
82
98
 
83
99
  ```vue
84
100
  <script setup lang="ts">
85
- import { useUserManagement } from '@vc-shell/framework';
86
- import { ref } from 'vue';
87
- import { useRoute, useRouter } from 'vue-router';
101
+ import { useUserManagement } from "@vc-shell/framework";
102
+ import { ref } from "vue";
103
+ import { useRoute, useRouter } from "vue-router";
88
104
 
89
105
  const { validateToken, validatePassword, resetPasswordByToken, loading } = useUserManagement();
90
106
  const route = useRoute();
@@ -92,39 +108,39 @@ const router = useRouter();
92
108
 
93
109
  const userId = route.query.userId as string;
94
110
  const token = route.query.token as string;
95
- const newPassword = ref('');
96
- const confirmPassword = ref('');
97
- const error = ref('');
111
+ const newPassword = ref("");
112
+ const confirmPassword = ref("");
113
+ const error = ref("");
98
114
  const tokenValid = ref(false);
99
115
 
100
116
  // Validate the token on mount
101
117
  onMounted(async () => {
102
118
  tokenValid.value = await validateToken(userId, token);
103
119
  if (!tokenValid.value) {
104
- error.value = 'This reset link has expired or is invalid.';
120
+ error.value = "This reset link has expired or is invalid.";
105
121
  }
106
122
  });
107
123
 
108
124
  async function handleReset() {
109
- error.value = '';
125
+ error.value = "";
110
126
 
111
127
  if (newPassword.value !== confirmPassword.value) {
112
- error.value = 'Passwords do not match.';
128
+ error.value = "Passwords do not match.";
113
129
  return;
114
130
  }
115
131
 
116
132
  // Validate against password policy
117
133
  const validation = await validatePassword(newPassword.value);
118
134
  if (!validation.succeeded) {
119
- error.value = validation.errors?.join(', ') ?? 'Password does not meet requirements.';
135
+ error.value = validation.errors?.join(", ") ?? "Password does not meet requirements.";
120
136
  return;
121
137
  }
122
138
 
123
139
  const result = await resetPasswordByToken(userId, newPassword.value, token);
124
140
  if (result.succeeded) {
125
- router.push({ name: 'SignIn', query: { message: 'Password reset successfully' } });
141
+ router.push({ name: "SignIn", query: { message: "Password reset successfully" } });
126
142
  } else {
127
- error.value = result.errors?.join(', ') ?? 'Reset failed.';
143
+ error.value = result.errors?.join(", ") ?? "Reset failed.";
128
144
  }
129
145
  }
130
146
  </script>
@@ -134,8 +150,8 @@ async function handleReset() {
134
150
 
135
151
  ```vue
136
152
  <script setup lang="ts">
137
- import { useUserManagement } from '@vc-shell/framework';
138
- import { ref, onMounted } from 'vue';
153
+ import { useUserManagement } from "@vc-shell/framework";
154
+ import { ref, onMounted } from "vue";
139
155
 
140
156
  const { getLoginType, signIn } = useUserManagement();
141
157
  const loginTypes = ref<LoginType[]>([]);
@@ -144,20 +160,24 @@ const showPasswordForm = ref(false);
144
160
  onMounted(async () => {
145
161
  loginTypes.value = await getLoginType();
146
162
  // Show password form only if password auth is available
147
- showPasswordForm.value = loginTypes.value.some((t) => t.loginProvider === 'password');
163
+ showPasswordForm.value = loginTypes.value.some((t) => t.loginProvider === "password");
148
164
  });
149
165
  </script>
150
166
 
151
167
  <template>
152
168
  <div>
153
- <form v-if="showPasswordForm" @submit.prevent="handlePasswordLogin">
169
+ <form
170
+ v-if="showPasswordForm"
171
+ @submit.prevent="handlePasswordLogin"
172
+ >
154
173
  <!-- standard username/password form -->
155
174
  </form>
156
175
 
157
- <div v-for="provider in loginTypes.filter((t) => t.loginProvider !== 'password')" :key="provider.loginProvider">
158
- <VcButton @click="redirectToSSO(provider)">
159
- Sign in with {{ provider.loginProvider }}
160
- </VcButton>
176
+ <div
177
+ v-for="provider in loginTypes.filter((t) => t.loginProvider !== 'password')"
178
+ :key="provider.loginProvider"
179
+ >
180
+ <VcButton @click="redirectToSSO(provider)"> Sign in with {{ provider.loginProvider }} </VcButton>
161
181
  </div>
162
182
  </div>
163
183
  </template>
@@ -12,16 +12,16 @@ Registers Core Web Vitals observers (FCP, LCP, CLS, INP, TTFB) and reports metri
12
12
  ## Quick Start
13
13
 
14
14
  ```typescript
15
- import { useWebVitals } from '@vc-shell/framework';
15
+ import { useWebVitals } from "@vc-shell/framework";
16
16
 
17
17
  // Option 1: Default behavior -- logs to console.warn in dev mode, silent in production
18
18
  useWebVitals();
19
19
 
20
20
  // Option 2: Custom callback for production analytics
21
21
  useWebVitals((metric) => {
22
- analytics.track('web-vital', {
23
- name: metric.name, // "FCP", "LCP", "CLS", "INP", or "TTFB"
24
- value: metric.value, // milliseconds (or unitless for CLS)
22
+ analytics.track("web-vital", {
23
+ name: metric.name, // "FCP", "LCP", "CLS", "INP", or "TTFB"
24
+ value: metric.value, // milliseconds (or unitless for CLS)
25
25
  rating: metric.rating, // "good", "needs-improvement", or "poor"
26
26
  });
27
27
  });
@@ -32,7 +32,7 @@ Call this once after `app.mount()` in your application entry point:
32
32
  ```typescript
33
33
  // main.ts
34
34
  const app = createApp(App);
35
- app.mount('#app');
35
+ app.mount("#app");
36
36
 
37
37
  // Register Web Vitals observers after mount
38
38
  useWebVitals();
@@ -42,17 +42,17 @@ useWebVitals();
42
42
 
43
43
  ### Parameters
44
44
 
45
- | Parameter | Type | Required | Description |
46
- |---|---|---|---|
47
- | `callback` | `(metric: IWebVitalsMetric) => void` | No | Custom handler for each metric. Defaults to `console.warn` formatted output in dev mode; no-op in production. |
45
+ | Parameter | Type | Required | Description |
46
+ | ---------- | ------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------- |
47
+ | `callback` | `(metric: IWebVitalsMetric) => void` | No | Custom handler for each metric. Defaults to `console.warn` formatted output in dev mode; no-op in production. |
48
48
 
49
49
  ### IWebVitalsMetric
50
50
 
51
- | Field | Type | Description |
52
- |---|---|---|
53
- | `name` | `string` | Metric name: `"FCP"` (First Contentful Paint), `"LCP"` (Largest Contentful Paint), `"CLS"` (Cumulative Layout Shift), `"INP"` (Interaction to Next Paint), `"TTFB"` (Time to First Byte) |
54
- | `value` | `number` | Metric value in milliseconds for all metrics except CLS, which is a unitless score |
55
- | `rating` | `"good" \| "needs-improvement" \| "poor"` | Performance rating based on Google's thresholds (e.g., LCP < 2500ms = "good") |
51
+ | Field | Type | Description |
52
+ | -------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
53
+ | `name` | `string` | Metric name: `"FCP"` (First Contentful Paint), `"LCP"` (Largest Contentful Paint), `"CLS"` (Cumulative Layout Shift), `"INP"` (Interaction to Next Paint), `"TTFB"` (Time to First Byte) |
54
+ | `value` | `number` | Metric value in milliseconds for all metrics except CLS, which is a unitless score |
55
+ | `rating` | `"good" \| "needs-improvement" \| "poor"` | Performance rating based on Google's thresholds (e.g., LCP < 2500ms = "good") |
56
56
 
57
57
  ### Returns
58
58
 
@@ -75,7 +75,7 @@ The default callback formats CLS values to 4 decimal places (since CLS is a dime
75
75
  ## Recipe: Sending Web Vitals to Application Insights
76
76
 
77
77
  ```typescript
78
- import { useWebVitals, useAppInsights } from '@vc-shell/framework';
78
+ import { useWebVitals, useAppInsights } from "@vc-shell/framework";
79
79
 
80
80
  const { appInsights } = useAppInsights();
81
81
 
@@ -96,14 +96,14 @@ This sends each Web Vital as a custom metric to Application Insights, where you
96
96
  ## Recipe: Conditional Reporting Based on Rating
97
97
 
98
98
  ```typescript
99
- import { useWebVitals } from '@vc-shell/framework';
99
+ import { useWebVitals } from "@vc-shell/framework";
100
100
 
101
101
  useWebVitals((metric) => {
102
102
  // Only report poor metrics to reduce noise
103
- if (metric.rating === 'poor') {
104
- fetch('/api/telemetry/web-vitals', {
105
- method: 'POST',
106
- headers: { 'Content-Type': 'application/json' },
103
+ if (metric.rating === "poor") {
104
+ fetch("/api/telemetry/web-vitals", {
105
+ method: "POST",
106
+ headers: { "Content-Type": "application/json" },
107
107
  body: JSON.stringify({
108
108
  metric: metric.name,
109
109
  value: metric.value,
@@ -14,15 +14,15 @@ Also exports `provideWidgetService()` for framework-level initialization and `re
14
14
  ## Quick Start
15
15
 
16
16
  ```typescript
17
- import { useWidgets } from '@vc-shell/framework';
17
+ import { useWidgets } from "@vc-shell/framework";
18
18
 
19
19
  const widgetService = useWidgets();
20
20
 
21
21
  // Query all widgets registered for a specific blade
22
- const widgets = widgetService.getWidgets('order-details');
22
+ const widgets = widgetService.getWidgets("order-details");
23
23
 
24
24
  // Check if a widget is currently active (visible and expanded)
25
- if (widgetService.isActiveWidget('order-status-widget')) {
25
+ if (widgetService.isActiveWidget("order-status-widget")) {
26
26
  // widget is currently in focus
27
27
  }
28
28
  ```
@@ -35,29 +35,29 @@ None.
35
35
 
36
36
  ### Returns (`IWidgetService`)
37
37
 
38
- | Property / Method | Type | Description |
39
- |-------------------|------|-------------|
40
- | `registerWidget` | `(widget: IWidget, bladeId: string) => void` | Registers a widget for a specific blade. The widget will appear in that blade's widget area. |
41
- | `unregisterWidget` | `(widgetId: string, bladeId: string) => void` | Removes a widget from a blade by ID. |
42
- | `getWidgets` | `(bladeId: string) => IWidget[]` | Returns all widgets registered for a specific blade. |
43
- | `clearBladeWidgets` | `(bladeId: string) => void` | Removes all widgets for a blade (used during blade teardown). |
44
- | `registeredWidgets` | `IWidgetRegistration[]` | All widget registrations across all blades. |
45
- | `isActiveWidget` | `(id: string) => boolean` | Checks if a widget is currently active (selected/expanded). |
46
- | `setActiveWidget` | `(args) => void` | Sets a widget as active with its exposed instance. |
47
- | `updateActiveWidget` | `() => void` | Triggers the active widget's update function. Deprecated -- use headless widgets instead. |
48
- | `isWidgetRegistered` | `(id: string) => boolean` | Checks if a widget ID exists in any blade's registry. |
49
- | `updateWidget` | `(args) => void` | Updates properties of a registered widget (trigger, badge, etc.). |
50
- | `resolveWidgetProps` | `(widget, bladeData) => Record<string, unknown>` | Resolves widget props from blade data. Deprecated. |
51
- | `getExternalWidgetsForBlade` | `(bladeId: string) => IExternalWidgetRegistration[]` | Gets external widgets that target a specific blade (registered by other modules). |
52
- | `getAllExternalWidgets` | `() => IExternalWidgetRegistration[]` | Gets all registered external widgets across all modules. |
38
+ | Property / Method | Type | Description |
39
+ | ---------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------- |
40
+ | `registerWidget` | `(widget: IWidget, bladeId: string) => void` | Registers a widget for a specific blade. The widget will appear in that blade's widget area. |
41
+ | `unregisterWidget` | `(widgetId: string, bladeId: string) => void` | Removes a widget from a blade by ID. |
42
+ | `getWidgets` | `(bladeId: string) => IWidget[]` | Returns all widgets registered for a specific blade. |
43
+ | `clearBladeWidgets` | `(bladeId: string) => void` | Removes all widgets for a blade (used during blade teardown). |
44
+ | `registeredWidgets` | `IWidgetRegistration[]` | All widget registrations across all blades. |
45
+ | `isActiveWidget` | `(id: string) => boolean` | Checks if a widget is currently active (selected/expanded). |
46
+ | `setActiveWidget` | `(args) => void` | Sets a widget as active with its exposed instance. |
47
+ | `updateActiveWidget` | `() => void` | Triggers the active widget's update function. Deprecated -- use headless widgets instead. |
48
+ | `isWidgetRegistered` | `(id: string) => boolean` | Checks if a widget ID exists in any blade's registry. |
49
+ | `updateWidget` | `(args) => void` | Updates properties of a registered widget (trigger, badge, etc.). |
50
+ | `resolveWidgetProps` | `(widget, bladeData) => Record<string, unknown>` | Resolves widget props from blade data. Deprecated. |
51
+ | `getExternalWidgetsForBlade` | `(bladeId: string) => IExternalWidgetRegistration[]` | Gets external widgets that target a specific blade (registered by other modules). |
52
+ | `getAllExternalWidgets` | `() => IExternalWidgetRegistration[]` | Gets all registered external widgets across all modules. |
53
53
 
54
54
  ### Additional Exports
55
55
 
56
- | Export | Description |
57
- |--------|-------------|
58
- | `provideWidgetService()` | Creates and provides the widget service via Vue injection. Idempotent -- returns existing service if already provided. Cleans up via `onScopeDispose`. |
59
- | `registerWidget(widget, bladeId)` | Global pre-registration. Widgets registered this way are picked up when `provideWidgetService()` creates the service. Use in module `install()`. |
60
- | `registerExternalWidget(registration)` | Global pre-registration for cross-module widgets. These widgets are rendered in blades owned by other modules. |
56
+ | Export | Description |
57
+ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
58
+ | `provideWidgetService()` | Creates and provides the widget service via Vue injection. Idempotent -- returns existing service if already provided. Cleans up via `onScopeDispose`. |
59
+ | `registerWidget(widget, bladeId)` | Global pre-registration. Widgets registered this way are picked up when `provideWidgetService()` creates the service. Use in module `install()`. |
60
+ | `registerExternalWidget(registration)` | Global pre-registration for cross-module widgets. These widgets are rendered in blades owned by other modules. |
61
61
 
62
62
  ## How It Works
63
63
 
@@ -75,20 +75,20 @@ The service tracks active widgets (which widget is currently expanded/focused) s
75
75
 
76
76
  ```typescript
77
77
  // my-module/index.ts
78
- import { registerWidget } from '@vc-shell/framework';
79
- import { markRaw } from 'vue';
80
- import OrderStatusWidget from './widgets/OrderStatusWidget.vue';
78
+ import { registerWidget } from "@vc-shell/framework";
79
+ import { markRaw } from "vue";
80
+ import OrderStatusWidget from "./widgets/OrderStatusWidget.vue";
81
81
 
82
82
  export default {
83
83
  install() {
84
84
  registerWidget(
85
85
  {
86
- id: 'order-status',
87
- title: 'Order Status',
86
+ id: "order-status",
87
+ title: "Order Status",
88
88
  component: markRaw(OrderStatusWidget),
89
- icon: 'fas fa-clipboard-check',
89
+ icon: "fas fa-clipboard-check",
90
90
  },
91
- 'order-details', // blade ID where this widget appears
91
+ "order-details", // blade ID where this widget appears
92
92
  );
93
93
  },
94
94
  };
@@ -100,18 +100,18 @@ A shipping module can add a widget to the order module's detail blade:
100
100
 
101
101
  ```typescript
102
102
  // shipping-module/index.ts
103
- import { registerExternalWidget } from '@vc-shell/framework';
104
- import { markRaw } from 'vue';
105
- import ShippingTracker from './widgets/ShippingTracker.vue';
103
+ import { registerExternalWidget } from "@vc-shell/framework";
104
+ import { markRaw } from "vue";
105
+ import ShippingTracker from "./widgets/ShippingTracker.vue";
106
106
 
107
107
  export default {
108
108
  install() {
109
109
  registerExternalWidget({
110
- widgetId: 'shipping-tracker',
111
- bladeId: 'order-details', // target blade from another module
110
+ widgetId: "shipping-tracker",
111
+ bladeId: "order-details", // target blade from another module
112
112
  component: markRaw(ShippingTracker),
113
- title: 'Shipping',
114
- icon: 'fas fa-truck',
113
+ title: "Shipping",
114
+ icon: "fas fa-truck",
115
115
  });
116
116
  },
117
117
  };
@@ -121,21 +121,16 @@ export default {
121
121
 
122
122
  ```vue
123
123
  <script setup lang="ts">
124
- import { useWidgets } from '@vc-shell/framework';
125
- import { computed } from 'vue';
124
+ import { useWidgets } from "@vc-shell/framework";
125
+ import { computed } from "vue";
126
126
 
127
127
  const props = defineProps<{ bladeId: string }>();
128
128
  const widgetService = useWidgets();
129
129
 
130
130
  const bladeWidgets = computed(() => widgetService.getWidgets(props.bladeId));
131
- const externalWidgets = computed(() =>
132
- widgetService.getExternalWidgetsForBlade(props.bladeId),
133
- );
134
-
135
- const allWidgets = computed(() => [
136
- ...bladeWidgets.value,
137
- ...externalWidgets.value,
138
- ]);
131
+ const externalWidgets = computed(() => widgetService.getExternalWidgetsForBlade(props.bladeId));
132
+
133
+ const allWidgets = computed(() => [...bladeWidgets.value, ...externalWidgets.value]);
139
134
  </script>
140
135
  ```
141
136
 
@@ -12,8 +12,8 @@ The directive is registered globally by the framework, so no manual import is ne
12
12
 
13
13
  ## API
14
14
 
15
- | Binding | Type | Description |
16
- |---------|------|-------------|
15
+ | Binding | Type | Description |
16
+ | ------------------------- | --------- | --------------------------------------------------- |
17
17
  | `v-autofocus="condition"` | `boolean` | Focus the element on mount if `condition` is truthy |
18
18
 
19
19
  The directive only acts on the `mounted` hook. It does not re-focus on updates.
@@ -40,7 +40,10 @@ export const autofocus = {
40
40
  ```vue
41
41
  <template>
42
42
  <!-- The search field gets focus as soon as the blade opens -->
43
- <input v-autofocus="true" placeholder="Search orders..." />
43
+ <input
44
+ v-autofocus="true"
45
+ placeholder="Search orders..."
46
+ />
44
47
  </template>
45
48
  ```
46
49
 
@@ -68,7 +71,10 @@ const isEditMode = computed(() => !!props.param);
68
71
 
69
72
  ```vue
70
73
  <template>
71
- <VcPopup v-model:show="showDialog" title="Rename Item">
74
+ <VcPopup
75
+ v-model:show="showDialog"
76
+ title="Rename Item"
77
+ >
72
78
  <VcInput
73
79
  v-autofocus="showDialog"
74
80
  v-model="newName"
@@ -14,20 +14,20 @@ Unlike a standalone loading component, `v-loading` scopes the overlay to the ele
14
14
 
15
15
  ## API
16
16
 
17
- | Binding | Type | Description |
18
- |---------|------|-------------|
19
- | `v-loading="true"` | `boolean` | Show/hide the loading overlay |
20
- | `v-loading="options"` | `LoadingOptions` | Show with configuration (see below) |
21
- | `v-loading:1000="true"` | `arg: string` | Set custom z-index (default: `9999`) |
17
+ | Binding | Type | Description |
18
+ | ----------------------- | ---------------- | ------------------------------------ |
19
+ | `v-loading="true"` | `boolean` | Show/hide the loading overlay |
20
+ | `v-loading="options"` | `LoadingOptions` | Show with configuration (see below) |
21
+ | `v-loading:1000="true"` | `arg: string` | Set custom z-index (default: `9999`) |
22
22
 
23
23
  ### LoadingOptions
24
24
 
25
- | Property | Type | Default | Description |
26
- |----------|------|---------|-------------|
27
- | `size` | `"small" \| "medium" \| "large"` | -- | Spinner size via `data-loading-size` attribute |
28
- | `color` | `string` | -- | Custom spinner color (sets `--v-loading-spinner-color`) |
29
- | `blur` | `boolean` | `true` | Enable backdrop blur; `false` adds `v-loading--no-blur` |
30
- | `fullscreen` | `boolean` | `false` | Fullscreen overlay via `v-loading--fullscreen` |
25
+ | Property | Type | Default | Description |
26
+ | ------------ | -------------------------------- | ------- | ------------------------------------------------------- |
27
+ | `size` | `"small" \| "medium" \| "large"` | -- | Spinner size via `data-loading-size` attribute |
28
+ | `color` | `string` | -- | Custom spinner color (sets `--v-loading-spinner-color`) |
29
+ | `blur` | `boolean` | `true` | Enable backdrop blur; `false` adds `v-loading--no-blur` |
30
+ | `fullscreen` | `boolean` | `false` | Fullscreen overlay via `v-loading--fullscreen` |
31
31
 
32
32
  ## How It Works
33
33
 
@@ -45,7 +45,10 @@ Because the directive modifies the element directly (not through Vue reactivity)
45
45
 
46
46
  ```vue
47
47
  <template>
48
- <div v-loading="isLoading" class="tw-min-h-[200px]">
48
+ <div
49
+ v-loading="isLoading"
50
+ class="tw-min-h-[200px]"
51
+ >
49
52
  <p>Order details will appear here</p>
50
53
  </div>
51
54
  </template>
@@ -72,7 +75,10 @@ async function loadOrder() {
72
75
  <template>
73
76
  <!-- Small spinner with brand color, no blur -->
74
77
  <div v-loading="{ size: 'small', color: 'var(--primary-500)', blur: false }">
75
- <img :src="thumbnailUrl" alt="Product thumbnail" />
78
+ <img
79
+ :src="thumbnailUrl"
80
+ alt="Product thumbnail"
81
+ />
76
82
  </div>
77
83
  </template>
78
84
  ```
@@ -104,9 +110,18 @@ async function loadOrder() {
104
110
 
105
111
  ```vue
106
112
  <template>
107
- <VcBlade title="Products" :closable="true">
108
- <div v-loading="loading" class="tw-p-4">
109
- <VcDataTable :items="products" :columns="columns" />
113
+ <VcBlade
114
+ title="Products"
115
+ :closable="true"
116
+ >
117
+ <div
118
+ v-loading="loading"
119
+ class="tw-p-4"
120
+ >
121
+ <VcDataTable
122
+ :items="products"
123
+ :columns="columns"
124
+ />
110
125
  </div>
111
126
  </VcBlade>
112
127
  </template>
@@ -146,10 +161,10 @@ Passing an options object when you want to hide the spinner does not work as exp
146
161
 
147
162
  ## CSS Classes Reference
148
163
 
149
- | Class | Applied When | Effect |
150
- |-------|-------------|--------|
151
- | `v-loading` | Value is truthy | Shows the spinner overlay |
152
- | `v-loading--no-blur` | `blur: false` | Disables backdrop blur filter |
164
+ | Class | Applied When | Effect |
165
+ | ----------------------- | ------------------ | ---------------------------------- |
166
+ | `v-loading` | Value is truthy | Shows the spinner overlay |
167
+ | `v-loading--no-blur` | `blur: false` | Disables backdrop blur filter |
153
168
  | `v-loading--fullscreen` | `fullscreen: true` | Overlay covers the entire viewport |
154
169
 
155
170
  ## Related