@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
@@ -7,6 +7,8 @@ internal: true
7
7
 
8
8
  # Sidebar Component
9
9
 
10
+ > **Deprecated.** The `Sidebar` wrapper is deprecated in favor of `VcSidebar` (`framework/ui/components/organisms/vc-sidebar`) and may be removed in a future release. Use this page as legacy/migration guidance only; build new code on `VcSidebar` directly.
11
+
10
12
  A responsive sidebar wrapper that conditionally renders content inside a `VcSidebar` panel or inline, based on viewport and expansion state.
11
13
 
12
14
  ## Overview
@@ -62,7 +64,7 @@ When `render="mobile"` and the viewport is desktop, the content slot renders inl
62
64
 
63
65
  ## Behavior
64
66
 
65
- - **Visibility**: The sidebar is visible when `isExpanded === true` AND the `render` mode matches the current viewport (injected via `IsMobileKey` / `IsDesktopKey`).
67
+ - **Visibility**: The sidebar is visible when `isExpanded === true` AND the `render` mode matches the current viewport (resolved via `useResponsive()` -- `isMobile` / `isDesktop`).
66
68
  - **Teleport**: On mobile, the inner `VcSidebar` teleports to the document body for proper overlay stacking.
67
69
  - **Close**: Closing the sidebar emits `close` -- the parent must update `isExpanded`.
68
70
 
@@ -70,9 +72,9 @@ When `render="mobile"` and the viewport is desktop, the content slot renders inl
70
72
 
71
73
  - Use `render="mobile"` for panels that should be drawers on phones but inline panels on desktop.
72
74
  - The `header` slot receives a `close` function so custom headers can include their own close button.
73
- - The component injects `IsMobileKey` and `IsDesktopKey` from the framework's injection keys.
75
+ - The component resolves the viewport via `useResponsive()` (`isMobile` / `isDesktop`).
74
76
 
75
77
  ## Related
76
78
 
77
79
  - `framework/ui/components/organisms/vc-sidebar/` -- the underlying `VcSidebar` organism
78
- - `framework/injection-keys.ts` -- `IsMobileKey`, `IsDesktopKey`
80
+ - `framework/core/composables/useResponsive/` -- `isMobile` / `isDesktop` viewport helper
@@ -48,12 +48,12 @@ This component has no props. Themes are managed via the `useTheme()` composable.
48
48
 
49
49
  ## Recipe: Registering Custom Themes
50
50
 
51
- Before the `ThemeSelector` can show themes, they must be registered with the theme service. Themes are defined as objects with a `key` that corresponds to a CSS class or custom property set:
51
+ Before the `ThemeSelector` can show themes, they must be registered with the theme service. Themes are defined as objects with a `key` that corresponds to a `data-theme` attribute value and its custom property set:
52
52
 
53
53
  ```ts
54
54
  import { useTheme } from "@vc-shell/framework";
55
55
 
56
- const { register, setTheme, currentTheme } = useTheme();
56
+ const { register, setTheme, currentThemeKey } = useTheme();
57
57
 
58
58
  // Register available themes during app initialization
59
59
  register([
@@ -66,16 +66,16 @@ register([
66
66
  setTheme("light");
67
67
  ```
68
68
 
69
- The theme `key` is applied as a CSS class on the root element, allowing CSS custom properties to cascade:
69
+ The theme `key` is written to the `data-theme` attribute on the root element (`<html data-theme="light">`, via `useColorMode({ attribute: "data-theme" })`), allowing CSS custom properties to cascade:
70
70
 
71
71
  ```scss
72
72
  // In your theme CSS files
73
- .light {
73
+ :root[data-theme="light"] {
74
74
  --primary-500: #3b82f6;
75
75
  --surface-bg: #ffffff;
76
76
  }
77
77
 
78
- .dark {
78
+ :root[data-theme="dark"] {
79
79
  --primary-500: #60a5fa;
80
80
  --surface-bg: #1e1e2e;
81
81
  }
@@ -103,14 +103,14 @@ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e)
103
103
  ## Details
104
104
 
105
105
  - **Theme persistence**: The selected theme is persisted to localStorage, so the user's preference survives page reloads and browser restarts.
106
- - **Toast notification**: When the user switches themes via the selector, a brief toast notification confirms the change (e.g., "Theme changed to Dark").
106
+ - **Toast notification**: When the user switches themes via the selector, a brief toast notification shows the new theme's localized name (e.g., "Dark").
107
107
  - **Cascading submenu**: On desktop, selecting the theme entry opens a submenu listing all registered themes. The current theme is highlighted.
108
108
  - **CSS custom properties**: Themes work by switching CSS custom properties defined in `framework/assets/styles/theme/colors.scss`. Components reference these variables (e.g., `tw-bg-[var(--primary-500)]`), so theme changes are instant.
109
109
 
110
110
  ## Tips
111
111
 
112
112
  - If only one theme is registered, the `ThemeSelector` still renders but the submenu will have only one option. Consider hiding it if theming is not a feature of your application.
113
- - Theme keys should be short, lowercase identifiers. They are used as CSS class names on the root element.
113
+ - Theme keys should be short, lowercase identifiers. They are written to the `data-theme` attribute on the root element.
114
114
  - Always pair theme registration with corresponding CSS custom property definitions. A registered theme without CSS variables will result in unstyled or broken visuals.
115
115
  - The framework's built-in components use CSS custom properties from the theme system. Custom components should follow the same pattern for consistent theming.
116
116
 
@@ -33,12 +33,12 @@ import { UserDropdownButton } from "@vc-shell/framework";
33
33
 
34
34
  ## Key Props
35
35
 
36
- | Prop | Type | Default | Description |
37
- | ----------- | --------- | ----------- | ----------------------------- |
38
- | `name` | `string` | `undefined` | User display name |
39
- | `role` | `string` | `undefined` | User role label |
40
- | `avatarUrl` | `string` | `undefined` | URL for the user avatar image |
41
- | `disabled` | `boolean` | `false` | Prevents menu from opening |
36
+ | Prop | Type | Default | Description |
37
+ | ----------- | --------- | ----------- | --------------------------------------------------------------------------------------------------------------- |
38
+ | `name` | `string` | `undefined` | User display name |
39
+ | `role` | `string` | `undefined` | User role label |
40
+ | `avatarUrl` | `string` | `undefined` | URL for the user avatar image |
41
+ | `disabled` | `boolean` | `false` | Visual-only: applies the `--auto-width` layout class. Does not suppress clicks or prevent the menu from opening |
42
42
 
43
43
  ## Recipe: Wiring to User Management Composable
44
44
 
@@ -50,11 +50,11 @@ import { computed } from "vue";
50
50
  import { UserDropdownButton } from "@vc-shell/framework";
51
51
  import { useUserManagement } from "@vc-shell/framework";
52
52
 
53
- const { currentUser } = useUserManagement();
53
+ const { user } = useUserManagement();
54
54
 
55
- const displayName = computed(() => (currentUser.value ? `${currentUser.value.firstName} ${currentUser.value.lastName}` : ""));
56
- const role = computed(() => currentUser.value?.roles?.[0]?.name ?? "");
57
- const avatarUrl = computed(() => currentUser.value?.photoUrl);
55
+ const displayName = computed(() => (user.value ? `${user.value.firstName} ${user.value.lastName}` : ""));
56
+ const role = computed(() => user.value?.roles?.[0]?.name ?? "");
57
+ const avatarUrl = computed(() => user.value?.photoUrl);
58
58
  </script>
59
59
 
60
60
  <template>
@@ -86,7 +86,7 @@ On mobile viewports (`$isMobile`), clicking the button opens a full-height slide
86
86
  ## Tips
87
87
 
88
88
  - The component is typically placed in the sidebar footer slot of the app shell. You rarely need to instantiate it manually -- the framework shell handles its placement.
89
- - If `disabled` is `true`, clicking the button does nothing and the menu does not open. Use this during critical operations where navigation should be prevented.
89
+ - The `disabled` prop is visual-only (it applies the `--auto-width` layout class). It does not block clicks or prevent the menu from opening; the handler always toggles the menu.
90
90
  - All menu items are driven by `useSettingsMenu()` registrations. To add custom items to the user menu, register them via the service rather than modifying this component.
91
91
 
92
92
  ## Related Components
@@ -61,25 +61,36 @@ const config: ChartConfig = {
61
61
 
62
62
  ## Key Props (shared across chart types)
63
63
 
64
- | Prop | Type | Default | Description |
65
- | ------------- | ------------- | ----------- | ------------------------------------ |
66
- | `data` | `T[]` | -- | Array of data points |
67
- | `config` | `ChartConfig` | -- | Series color and label configuration |
68
- | `xKey` | `keyof T` | -- | Key for x-axis values (line/bar) |
69
- | `yKeys` | `(keyof T)[]` | -- | Keys for y-axis series (line/bar) |
70
- | `showTooltip` | `boolean` | `true` | Enable hover tooltips |
71
- | `showLegend` | `boolean` | `true` | Show color legend below chart |
72
- | `rangeStart` | `number` | `undefined` | Filter data from this x value |
73
- | `rangeEnd` | `number` | `undefined` | Filter data up to this x value |
64
+ | Prop | Type | Default | Description |
65
+ | ------------- | ---------------------------------------------- | ----------- | ------------------------------------ |
66
+ | `data` | `T[]` | -- | Array of data points |
67
+ | `config` | `ChartConfig` | -- | Series color and label configuration |
68
+ | `xKey` | `keyof T` | -- | Key for x-axis values (line/bar) |
69
+ | `yKeys` | `(keyof T)[]` | -- | Keys for y-axis series (line/bar) |
70
+ | `showTooltip` | `boolean` | `true` | Enable hover tooltips |
71
+ | `showLegend` | `boolean` | `true` | Show color legend below chart |
72
+ | `rangeStart` | `ChartRangeValue` (`number \| string \| Date`) | `undefined` | Filter data from this x value |
73
+ | `rangeEnd` | `ChartRangeValue` (`number \| string \| Date`) | `undefined` | Filter data up to this x value |
74
+ | `showXAxis` | `boolean` | `true` | Show the x-axis (line/bar) |
75
+ | `showYAxis` | `boolean` | `true` | Show the y-axis (line/bar) |
76
+ | `showGrid` | `boolean` | `true` | Show y-axis grid lines (line/bar) |
77
+ | `numXTicks` | `number` | `undefined` | Number of x-axis ticks (line/bar) |
78
+ | `numYTicks` | `number` | `5` | Number of y-axis ticks (line/bar) |
79
+ | `xTickFormat` | `(value: number \| Date) => string` | `undefined` | Format x-axis tick labels (line/bar) |
80
+ | `yTickFormat` | `(value: number) => string` | `undefined` | Format y-axis tick labels (line/bar) |
81
+ | `height` | `number` | `undefined` | Fixed chart height in px |
74
82
 
75
83
  ### Donut-specific props
76
84
 
77
- | Prop | Type | Default | Description |
78
- | ----------------- | --------- | ----------- | ------------------------------ |
79
- | `valueKey` | `keyof T` | -- | Key for segment values |
80
- | `centralLabel` | `string` | `undefined` | Large text in donut center |
81
- | `centralSubLabel` | `string` | `undefined` | Small text below central label |
82
- | `arcWidth` | `number` | `60` | Donut arc thickness |
85
+ | Prop | Type | Default | Description |
86
+ | ----------------- | --------------------------- | ----------- | --------------------------------------- |
87
+ | `valueKey` | `keyof T` | -- | Key for segment values |
88
+ | `centralLabel` | `string` | `undefined` | Large text in donut center |
89
+ | `centralSubLabel` | `string` | `undefined` | Small text below central label |
90
+ | `arcWidth` | `number` | `60` | Donut arc thickness |
91
+ | `valueFormat` | `(value: number) => string` | `undefined` | Formats segment values in tooltip/label |
92
+ | `colorKey` | `keyof T` | `undefined` | Data key holding a per-segment color |
93
+ | `cornerRadius` | `number` | `4` | Rounded corner radius of arcs |
83
94
 
84
95
  ## ChartConfig Type
85
96
 
@@ -91,6 +102,7 @@ type ChartConfig = Record<
91
102
  {
92
103
  label: string; // Display name in legend and tooltip
93
104
  color: string; // CSS color value (hex, var(), rgb, etc.)
105
+ icon?: string; // Optional icon shown alongside the series label
94
106
  }
95
107
  >;
96
108
  ```
@@ -67,20 +67,17 @@ import { DashboardWidgetCard } from "@vc-shell/framework";
67
67
  ```vue
68
68
  <DashboardWidgetCard header="Orders" icon="lucide-shopping-cart">
69
69
  <template #stats>
70
- <DashboardStatItem :value="48" label="Total" />
71
- <DashboardStatItem :value="12" label="Today" variant="info" />
70
+ <DashboardStatItem :value="48" label="Total" variant="success" />
71
+ <DashboardStatItem :value="12" label="Today" />
72
72
  <DashboardStatItem :value="3" label="Pending" variant="warning" />
73
- <DashboardStatItem :value="1" label="Failed" variant="error" />
73
+ <DashboardStatItem :value="1" label="Failed" variant="danger" />
74
74
  </template>
75
75
  <template #content>
76
76
  <DashboardFeedList>
77
- <DashboardFeedRow v-for="order in recentOrders" :key="order.id">
78
- <template #icon>
79
- <VcIcon :icon="getOrderIcon(order.status)" size="s" />
80
- </template>
81
- <template #title>{{ order.number }}</template>
82
- <template #subtitle>{{ order.customerName }}</template>
83
- <template #meta>{{ formatDateRelative(order.createdDate) }}</template>
77
+ <DashboardFeedRow v-for="order in recentOrders" :key="order.id" @click="openOrder(order)">
78
+ <VcIcon :icon="getOrderIcon(order.status)" size="s" />
79
+ <span>{{ order.number }} — {{ order.customerName }}</span>
80
+ <template #trailing>{{ formatDateRelative(order.createdDate) }}</template>
84
81
  </DashboardFeedRow>
85
82
  </DashboardFeedList>
86
83
  </template>
@@ -167,22 +164,23 @@ import OrdersWidget from "./OrdersWidget.vue";
167
164
 
168
165
  const dashboard = useDashboard();
169
166
 
170
- dashboard.register({
167
+ dashboard.registerWidget({
171
168
  id: "orders-overview",
169
+ name: "Orders overview",
172
170
  component: markRaw(OrdersWidget),
171
+ size: { width: 6, height: 4 },
172
+ position: { x: 0, y: 0 },
173
173
  props: { limit: 10 },
174
- order: 1,
175
- layout: { w: 6, h: 4, x: 0, y: 0 },
176
174
  });
177
175
  ```
178
176
 
179
177
  ## Companion Components
180
178
 
181
- | Component | Description |
182
- | ------------------- | --------------------------------------------------------------- |
183
- | `DashboardStatItem` | Single KPI stat with value, label, and optional color variant |
184
- | `DashboardFeedList` | Scrollable list container for feed rows |
185
- | `DashboardFeedRow` | Individual feed item with icon, title, subtitle, and meta slots |
179
+ | Component | Description |
180
+ | ------------------- | -------------------------------------------------------------------------------------------------------------- |
181
+ | `DashboardStatItem` | Single KPI stat with value, label, and optional color variant |
182
+ | `DashboardFeedList` | Scrollable list container for feed rows |
183
+ | `DashboardFeedRow` | Individual feed item: default slot for leading content, `#trailing` slot for right-side content, emits `click` |
186
184
 
187
185
  ## Tip: Set a Minimum Height
188
186
 
@@ -200,4 +198,4 @@ When the card content is loaded asynchronously, the card may collapse to zero he
200
198
 
201
199
  - [DraggableDashboard](../draggable-dashboard/draggable-dashboard.docs.md) -- grid layout container
202
200
  - [DashboardCharts](../dashboard-charts/dashboard-charts.docs.md) -- chart components for widget content
203
- - [useDashboard](../../../core/composables/useDashboard/) -- dashboard widget registration service
201
+ - [useDashboard](../../../core/composables/useDashboard/useDashboard.docs.md) -- dashboard widget registration service
@@ -140,6 +140,27 @@ function resetLayout() {
140
140
  - The 12-column grid means common widget widths are: 3 (quarter), 4 (third), 6 (half), and 12 (full width).
141
141
  - Register widgets during module `install()` before the dashboard component mounts. Late registrations may not be picked up.
142
142
 
143
+ ## Advanced / Exports
144
+
145
+ Besides the `DraggableDashboard` component, `draggable-dashboard/index.ts` re-exports these symbols through the framework root, for building a custom Gridstack dashboard:
146
+
147
+ | Export | Kind | Description |
148
+ | ------------------------- | ---------- | ----------------------------------------------------------- |
149
+ | `useGridstack` | composable | Low-level Gridstack integration for a custom dashboard |
150
+ | `UseGridstackOptions` | type | Options for `useGridstack` |
151
+ | `UseGridstackReturn` | type | Return shape of `useGridstack` |
152
+ | `DashboardWidgetSize` | type | Widget size shape: `{ width, height }` |
153
+ | `DashboardWidgetPosition` | type | Widget position shape: `{ x, y }` |
154
+ | `DashboardDragEvent` | type | Payload emitted on widget drag/reorder |
155
+ | `DashboardGridConfig` | type | Grid configuration options |
156
+ | `toGridstackWidget` | function | Maps an `IDashboardWidget` to a Gridstack widget descriptor |
157
+ | `fromGridstackNode` | function | Maps a Gridstack node back to layout data |
158
+ | `loadLayoutFromStorage` | function | Reads persisted layout from localStorage |
159
+ | `saveLayoutToStorage` | function | Writes layout to localStorage |
160
+ | `mergeLayoutWithWidgets` | function | Merges a persisted layout onto the registered widget set |
161
+ | `clearLayoutStorage` | function | Clears the persisted layout |
162
+ | `LAYOUT_STORAGE_KEY` | constant | localStorage key used for layout persistence |
163
+
143
164
  ## Related Components
144
165
 
145
166
  - [DashboardWidgetCard](../dashboard-widget-card/dashboard-widget-card.docs.md) -- card container for widget content
@@ -39,6 +39,7 @@ A small indicator component for displaying counts, status dots, or short text la
39
39
  | `inline` | `boolean` | `false` | Renders as an inline element without absolute positioning |
40
40
  | `clickable` | `boolean` | `false` | Makes the badge respond to click events |
41
41
  | `disabled` | `boolean` | `false` | Disables interaction on clickable badges |
42
+ | `active` | `boolean` | `false` | Applies the active-state color tokens to the badge |
42
43
  | `customPosition` | `boolean` | `false` | Enables custom `top`/`right` positioning |
43
44
  | `top` | `string` | -- | Custom top offset (requires `customPosition`) |
44
45
  | `right` | `string` | -- | Custom right offset (requires `customPosition`) |
@@ -144,7 +145,7 @@ Fine-tune the badge position relative to its parent:
144
145
 
145
146
  - VcBadge lives in `framework/ui/components/atoms/vc-badge/`.
146
147
  - Overlay mode uses `position: absolute` on the badge element; the parent slot wrapper is set to `position: relative` via the `.vc-badge` CSS class.
147
- - The `inline` prop switches the root element from `<span class="vc-badge">` (overlay) to `<span class="vc-badge--inline">` with no position context.
148
+ - The `inline` prop switches the root element from the `<div class="vc-badge">` wrapper (overlay) to a `<div class="vc-badge__badge vc-badge__badge--inline">` rendered directly with no position context.
148
149
  - Color palette tokens: overlay uses `--{variant}-500` fills; inline uses `--{variant}-50` background + `--{variant}-700` text, defined in `framework/assets/styles/theme/colors.scss`.
149
150
  - Clickable mode integrates `role="button"` and keyboard handlers directly in the component — no separate button wrapper — to preserve the overlay stacking context.
150
151
 
@@ -172,8 +172,8 @@ Override the default "Show more" button with a custom trigger:
172
172
 
173
173
  ## Architecture notes
174
174
 
175
- - Legacy variants `"light-danger"`, `"info-dark"`, and `"primary"` are mapped in `vc-banner.vue` via a computed `resolvedVariant`. A `console.warn` is emitted in development mode only.
176
- - The collapse animation is driven by `max-height` CSS transition with a JS-measured `scrollHeight`. The `--vc-banner-collapsed-height` CSS variable is injected inline as a style binding.
175
+ - Legacy variants `"light-danger"`, `"info-dark"`, and `"primary"` are mapped in `vc-banner.vue` via a computed `normalizedVariant` (backed by the `normalizeVariant` function). A `console.warn` is emitted in development mode only.
176
+ - The collapse is driven by an inline `max-height` style bound via `wrapperStyle` from `useCollapsible` (max-height set to the measured `collapsedHeight` in px when collapsed), transitioned in CSS. There is no `--vc-banner-collapsed-height` custom property.
177
177
  - Source: `framework/ui/components/atoms/vc-banner/vc-banner.vue`
178
178
 
179
179
  <!-- internal:end -->
@@ -265,19 +265,19 @@ Use the `loading` prop, not `disabled`. A disabled button gives no progress feed
265
265
 
266
266
  ## Props
267
267
 
268
- | Prop | Type | Default | Description |
269
- | ----------- | ------------------------------------------------------------------------------------------------------------ | ----------- | --------------------------------------------------------------- |
270
- | `variant` | `"primary" \| "secondary" \| "danger" \| "warning" \| "success" \| "info" \| "outline" \| "ghost" \| "link"` | `"primary"` | Visual style variant |
271
- | `size` | `"sm" \| "default" \| "lg" \| "icon" \| "icon-sm"` | `"default"` | Button size |
272
- | `icon` | `string \| Component` | -- | Icon identifier or Vue component |
273
- | `iconClass` | `string` | -- | Additional CSS class for the icon element |
274
- | `iconSize` | `IconSize` | `"s"` | Size of the icon (`"xs"`, `"s"`, `"m"`, `"l"`, `"xl"`, `"xxl"`) |
275
- | `loading` | `boolean` | `false` | Shows spinner, disables interaction, sets `aria-busy` |
276
- | `disabled` | `boolean` | `false` | Disables the button |
277
- | `selected` | `boolean` | `false` | Applies selected/active visual state, sets `aria-pressed` |
278
- | `text` | `boolean` | `false` | Renders as borderless text in the variant's color |
279
- | `type` | `"button" \| "submit" \| "reset"` | `"button"` | HTML button type |
280
- | `ariaLabel` | `string` | -- | Accessible label (required for icon-only buttons) |
268
+ | Prop | Type | Default | Description |
269
+ | ----------- | ------------------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------------------- |
270
+ | `variant` | `"primary" \| "secondary" \| "danger" \| "warning" \| "success" \| "info" \| "outline" \| "ghost" \| "link"` | `"primary"` | Visual style variant |
271
+ | `size` | `"sm" \| "default" \| "lg" \| "icon" \| "icon-sm"` | `"default"` | Button size |
272
+ | `icon` | `string \| Component` | -- | Icon identifier or Vue component |
273
+ | `iconClass` | `string` | -- | Additional CSS class for the icon element |
274
+ | `iconSize` | `IconSize` | `"s"` | Size of the icon (`"xs"`, `"s"`, `"m"`, `"l"`, `"xl"`, `"xxl"`, `"xxxl"`) |
275
+ | `loading` | `boolean` | `false` | Shows spinner, disables interaction, sets `aria-busy` |
276
+ | `disabled` | `boolean` | `false` | Disables the button |
277
+ | `selected` | `boolean` | `false` | Applies selected/active visual state, sets `aria-pressed` |
278
+ | `text` | `boolean` | `false` | Renders as borderless text in the variant's color |
279
+ | `type` | `"button" \| "submit" \| "reset"` | `"button"` | HTML button type |
280
+ | `ariaLabel` | `string` | -- | Accessible label (required for icon-only buttons) |
281
281
 
282
282
  ## Events
283
283
 
@@ -304,6 +304,7 @@ All visual properties are customizable through CSS custom properties. Each varia
304
304
  | `--button-border-radius` | `6px` | Corner radius for all buttons |
305
305
  | `--button-focus-ring-color` | `var(--primary-300)` | Focus ring color |
306
306
  | `--button-focus-ring-width` | `2px` | Focus ring thickness |
307
+ | `--button-focus-ring-offset` | `2px` | Focus ring offset |
307
308
  | `--button-{size}-height` | `--button-default-height: 36px` | Height per size |
308
309
 
309
310
  ## Accessibility
@@ -327,6 +328,6 @@ All visual properties are customizable through CSS custom properties. Each varia
327
328
  ## Architecture notes
328
329
 
329
330
  - VcButton calls `e.preventDefault()` on click to support `link` variant pattern. Form submit buttons must use `type="submit"` to bypass this.
330
- - `VcButtonGroup` integration is via provide/inject (`vcButtonGroupSize` injection key in `framework/injection-keys.ts`).
331
+ - `VcButtonGroup` integration is via provide/inject using the `ButtonGroupKey` injection key defined in `framework/ui/components/atoms/vc-button/types.ts`.
331
332
  - Size aliases `xs`/`base` are kept for backward compatibility — slated for removal in v3.
332
333
  <!-- internal:end -->
@@ -57,12 +57,15 @@ The `shadow` prop adds an inset shadow as a scroll cue. Use it for content that
57
57
 
58
58
  ## CSS Variables
59
59
 
60
- | Variable | Default | Description |
61
- | --------------------------- | ------------- | ------------------------------------ |
62
- | `--container-padding` | `16px` | Inner padding of the scrollable area |
63
- | `--container-bg` | `transparent` | Background color |
64
- | `--container-border-radius` | `0` | Border radius |
65
- | `--container-gap` | `0` | Gap between child elements |
60
+ | Variable | Default | Description |
61
+ | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
62
+ | `--container-padding` | `16px` | Inner padding of the scrollable area |
63
+ | `--container-bg` | `transparent` | Background color |
64
+ | `--container-border-radius` | `0` | Border radius |
65
+ | `--container-gap` | `0` | Gap between child elements |
66
+ | `--container-shadow-color` | `var(--additional-950)` | Scroll-shadow color (RGB channels used by `--container-shadow`) |
67
+ | `--container-shadow-opacity` | `0.1` | Scroll-shadow opacity |
68
+ | `--container-shadow` | `0 3px 2px rgba(var(--container-shadow-color), var(--container-shadow-opacity)) inset` | Inset shadow applied when the `shadow` prop is set |
66
69
 
67
70
  ## Exposed Methods
68
71
 
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: VcEnvironmentBanner
3
+ category: components
4
+ group: feedback
5
+ ---
6
+
7
+ # VcEnvironmentBanner
8
+
9
+ Centered badge pinned to the top of the application that labels the current
10
+ environment (Development, QA, Demo, etc.). Mirrors the platform environment
11
+ banner (vc-env-badge). Purely presentational — it renders the colored badge and
12
+ its label, and does not know where the name comes from. Visibility and color are
13
+ decided by the caller (see `useEnvironmentName`).
14
+
15
+ ## When to Use
16
+
17
+ - Inside the app shell to make non-production environments visually obvious
18
+ - When NOT to use: do not place it manually in blades — `VcApp` already mounts it
19
+
20
+ ## Props
21
+
22
+ - `name: string` — environment label to render
23
+ - `color?: string` — badge color (vc-shell theme tokens); recognized values are `primary | secondary | info | success | warning | danger | neutral`, any other value falls back to neutral via CSS, default `neutral`
24
+
25
+ ## Quick Start
26
+
27
+ ```vue
28
+ <template>
29
+ <VcEnvironmentBanner
30
+ v-if="!isIgnored"
31
+ :name="environmentName"
32
+ :color="color"
33
+ />
34
+ </template>
35
+
36
+ <script setup>
37
+ import { VcEnvironmentBanner } from "@vc-shell/framework";
38
+ import { useEnvironmentName } from "@vc-shell/framework";
39
+
40
+ const { environmentName, isIgnored, color } = useEnvironmentName();
41
+ </script>
42
+ ```
@@ -145,7 +145,7 @@ Show helper text by default, but swap to an error message when validation fails:
145
145
  ## Architecture notes
146
146
 
147
147
  - VcHint is a single `<div>` element — no wrapper. `role="alert"` is toggled reactively via `:role` binding when `error` prop changes.
148
- - CSS variables are scoped with `.vc-hint` selector in `vc-hint.vue` `<style scoped>`.
148
+ - The `--hint-*` CSS variables are declared globally on `:root` (not scoped to `.vc-hint`); the component's `<style lang="scss">` block is not scoped.
149
149
  - Source: `framework/ui/components/atoms/vc-hint/vc-hint.vue`
150
150
 
151
151
  <!-- internal:end -->
@@ -25,14 +25,15 @@ A unified icon component that renders icons from multiple libraries. Lucide Icon
25
25
 
26
26
  ## Key Props
27
27
 
28
- | Prop | Type | Default | Description |
29
- | ------------ | ------------------------------------------------------ | ----------------- | ---------------------------------------- |
30
- | `icon` | `string \| Component` | `"lucide-square"` | Icon identifier or Vue component |
31
- | `size` | `"xs" \| "s" \| "m" \| "l" \| "xl" \| "xxl" \| "xxxl"` | `"m"` | Predefined size |
32
- | `variant` | `"warning" \| "danger" \| "success"` | — | Semantic color variant |
33
- | `customSize` | `number` | — | Custom size in pixels (overrides `size`) |
34
- | `ariaLabel` | `string` | — | Accessible label for meaningful icons |
35
- | `basePath` | `string` | `"/assets/icons"` | Base path for SVG sprite icons |
28
+ | Prop | Type | Default | Description |
29
+ | -------------- | ------------------------------------------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
30
+ | `icon` | `string \| Component` | `"lucide-square"` | Icon identifier or Vue component |
31
+ | `size` | `"xs" \| "s" \| "m" \| "l" \| "xl" \| "xxl" \| "xxxl"` | `"m"` | Predefined size |
32
+ | `variant` | `"warning" \| "danger" \| "success"` | — | Semantic color variant |
33
+ | `customSize` | `number` | — | Custom size in pixels (overrides `size`) |
34
+ | `ariaLabel` | `string` | — | Accessible label for meaningful icons |
35
+ | `basePath` | `string` | `"/assets/icons"` | Base path for SVG sprite icons |
36
+ | `useContainer` | `boolean` | `false` | Deprecated. Wraps the icon in a fixed-size container; removed in a future version (logs a dev warning). Remove it — icons render correctly without it. |
36
37
 
37
38
  ::storybook id="layout-vcicon--all-sizes" height="300"
38
39
 
@@ -127,6 +128,6 @@ import MyCustomIcon from "./MyCustomIcon.vue";
127
128
  - Icon resolution is handled by a switch on the string prefix: `lucide-` maps to the Lucide component registry; `fa-` / `fas fa-` / `bi-` / `material-` are legacy paths kept for backward compatibility and will be removed in v3.
128
129
  - The `svg:` prefix loads from an SVG sprite at `basePath` (default `/assets/icons`) using a `<use>` element. Sprite must be included in the app's static assets.
129
130
  - `customSize` takes a number and sets `width`/`height` inline; it overrides the `size` prop class entirely.
130
- - Color variants (`warning`, `danger`, `success`) apply CSS custom property overrides (`--icon-color`) rather than inline style to allow theme-level customization.
131
+ - Color variants (`warning`, `danger`, `success`) resolve to the per-variant CSS custom properties `--icon-color-{success|danger|warning}`. Prefix/registry icons pick these up via variant CSS classes; custom Vue-component icons receive the color inline as `color: var(--icon-color-${variant})`.
131
132
 
132
133
  <!-- internal:end -->
@@ -35,9 +35,15 @@ An image display component with predefined sizes, aspect ratio control, and a pl
35
35
  | `bordered` | `boolean` | `false` | Adds a subtle border |
36
36
  | `clickable` | `boolean` | `false` | Makes the image interactive with cursor and click event |
37
37
  | `emptyIcon` | `string` | `"lucide-image"` | Icon shown when `src` is empty |
38
- | `alt` | `string` | — | Accessible alt text |
38
+ | `alt` | `string` | — | Accessible alt text. Required to expose `role="img"`; without it the image is decorative |
39
39
  | `thumbnailSize` | `ThumbnailSize` | — | Load a thumbnail variant instead of full-size image. Values: `"sm"`, `"md"`, `"lg"`, `"64x64"`, `"128x128"`, `"168x168"`, `"216x216"`, `"348x348"` |
40
40
 
41
+ ## Events
42
+
43
+ | Event | Payload | Description |
44
+ | ------- | ------- | ----------------------------------------------------------- |
45
+ | `click` | — | Emitted on click/Enter/Space, only when `clickable` is true |
46
+
41
47
  ::storybook id="data-display-vcimage--size-variants" height="300"
42
48
 
43
49
  ## Size Reference
@@ -53,6 +59,15 @@ An image display component with predefined sizes, aspect ratio control, and a pl
53
59
  | `xxl` | 145px |
54
60
  | `auto` | 100% of parent |
55
61
 
62
+ ## CSS Custom Properties
63
+
64
+ | Variable | Default | Description |
65
+ | -------------------------- | --------------------- | ------------------------------- |
66
+ | `--image-border-radius` | `6px` | Corner radius when `bordered` |
67
+ | `--image-border-color` | `var(--neutrals-200)` | Border color when `bordered` |
68
+ | `--image-empty-icon-color` | `var(--neutrals-400)` | Placeholder icon color |
69
+ | `--image-focus-ring-color` | `var(--primary-300)` | Focus ring color when clickable |
70
+
56
71
  ## Common Patterns
57
72
 
58
73
  ### Product Thumbnail in a List
@@ -87,7 +102,7 @@ An image display component with predefined sizes, aspect ratio control, and a pl
87
102
 
88
103
  ## Accessibility
89
104
 
90
- - When `src` is present and no `clickable`, the container has `role="img"` with `aria-label` from `alt`
105
+ - When `src` **and** `alt` are present and not `clickable`, the container has `role="img"` with `aria-label` from `alt`. Without `alt` the image is treated as decorative (no `role`), since `role="img"` requires an accessible name.
91
106
  - Clickable images receive `role="button"`, `tabindex="0"`, and keyboard support (Enter/Space)
92
107
  - Empty placeholder icon is marked `aria-hidden="true"`
93
108
  - Focus ring appears on `:focus-visible` for clickable images
@@ -107,8 +122,8 @@ When displaying images in lists or grids, pass a `thumbnailSize` (e.g. `"128x128
107
122
 
108
123
  - VcImage lives in `framework/ui/components/atoms/vc-image/`.
109
124
  - Images are rendered as CSS `background-image` on a `<div>` rather than an `<img>` tag; this enables `background-size: cover/contain` and preserves aspect-ratio without JS.
110
- - HTTPS enforcement: the `src` watcher rewrites `http://` to `https://` when `window.location.protocol === 'https:'`.
111
- - `thumbnailSize` appends a query parameter to the URL compatible with Virto Commerce image proxy: `?size=128x128`. This is a platform-specific convention.
125
+ - HTTPS enforcement: the `ensureHttps()` helper (called from the `imageHandler` computed and the thumbnail-probe watcher) upgrades `http://` to `https://` when `window.location.protocol === 'https:'`.
126
+ - `thumbnailSize` inserts a size suffix before the file extension, compatible with the Virto Commerce thumbnail convention: `photo.jpg` becomes `photo_128x128.jpg`. This is a platform-specific convention.
112
127
  - Aspect ratios are implemented as Tailwind aspect-ratio utility classes (`tw-aspect-square`, `tw-aspect-video`, etc.).
113
128
  - Clickable mode adds `role="button"` and forwards keyboard Enter/Space to the click handler, consistent with other atom-level interactive components.
114
129
 
@@ -167,9 +167,9 @@ Use a different icon for the tooltip trigger:
167
167
  ## Architecture notes
168
168
 
169
169
  - VcLabel lives in `framework/ui/components/atoms/vc-label/`.
170
- - The element type (`<label>` vs `<div>`) is determined by a computed `tag` that checks whether `htmlFor` is a non-empty string.
170
+ - The root element type (`<label>` vs `<div>`) is chosen inline via `:is="htmlFor ? 'label' : 'div'"` on the root `<component>` (no `tag` computed exists).
171
171
  - The tooltip trigger is rendered by `VcTooltip` (internal molecule); the `tooltipIcon` prop simply passes through to an inner `VcIcon` instance.
172
- - `multilanguage` + `currentLanguage` render a small pill via an inline `<span>` with `.vc-label__lang` class — not a separate component.
172
+ - `multilanguage` + `currentLanguage` render a small pill via an inline `<div>` with `.vc-label__language` class — not a separate component.
173
173
  - VcLabel is the canonical label primitive consumed by `VcInput`, `VcSelect`, `VcTextarea`, `VcCheckbox`, and `VcRadioButton` in `framework/ui/components/molecules/`.
174
174
 
175
175
  <!-- internal:end -->
@@ -35,10 +35,11 @@ function openDetails() {
35
35
 
36
36
  ## Key Props
37
37
 
38
- | Prop | Type | Default | Description |
39
- | ---------- | --------- | ------- | ---------------------------------------------- |
40
- | `active` | `boolean` | `false` | Highlights the link as currently selected |
41
- | `disabled` | `boolean` | `false` | Prevents interaction and applies muted styling |
38
+ | Prop | Type | Default | Description |
39
+ | ---------- | ------------ | ------- | ------------------------------------------------------------------------------- |
40
+ | `active` | `boolean` | `false` | Highlights the link as currently selected |
41
+ | `disabled` | `boolean` | `false` | Prevents interaction and applies muted styling |
42
+ | `onClick` | `() => void` | -- | Declared prop, currently unused by the template (use the `click` event instead) |
42
43
 
43
44
  ## Events
44
45
 
@@ -52,7 +52,8 @@ const isLoading = ref(true);
52
52
  | `--loading-overlay-bg` | `rgba(255,255,255,0.6)` | Overlay background color |
53
53
  | `--loading-bar-width` | `140px` | Width of the progress bar |
54
54
  | `--loading-bar-height` | `4px` | Height of the progress bar |
55
- | `--loading-z-index` | `9998` | Z-index of the overlay layer |
55
+
56
+ > **Note:** The overlay z-index comes from the global `--z-critical-loading` token and is not overridable per-instance.
56
57
 
57
58
  ::storybook id="layout-vcloading--interactive"
58
59
 
@@ -117,7 +118,7 @@ Override the bar color to match a specific status or brand theme:
117
118
 
118
119
  ## Tips
119
120
 
120
- - VcLoading is hidden with `display: none` when inactive, so it adds zero layout cost when idle.
121
+ - VcLoading is hidden via the `tw-hidden` class when inactive, so it adds zero layout cost when idle.
121
122
  - The sweep animation runs on a 1.5-second infinite loop using CSS `@keyframes` — no JavaScript timers involved.
122
123
  - The overlay applies `backdrop-filter: blur(3px)` for a frosted-glass effect. If you need a fully opaque overlay, set `--loading-overlay-bg: rgba(255,255,255,1)`.
123
124
  - When using inside a scrollable container, the overlay covers only the visible viewport of that container because it is absolutely positioned.
@@ -138,8 +139,8 @@ Override the bar color to match a specific status or brand theme:
138
139
 
139
140
  ## Architecture notes
140
141
 
141
- - The overlay is a single `<div>` with `v-show` (not `v-if`) so it remains in the DOM and retains animation state. `display: none` from `v-show` removes it from the paint tree when inactive.
142
- - The sweeping bar is a child `<div>` animated via `@keyframes vc-loading-sweep` (translateX from `-100%` to `100%`).
142
+ - The overlay is a single `<div>` always rendered in the DOM; visibility is toggled via the `vc-loading-overlay--active` class (base state is `tw-hidden`), so it retains animation state when inactive.
143
+ - The sweeping bar is a child `<div>` animated via `@keyframes vc-bar-sweep`, animating the `left` property from `-40%` to `100%`.
143
144
  - `backdrop-filter: blur(3px)` is applied to the overlay div directly; older Safari requires `-webkit-backdrop-filter` as a fallback.
144
145
  - Source: `framework/ui/components/atoms/vc-loading/vc-loading.vue`
145
146