@vc-shell/framework 2.1.0-pr253.0b14b2c → 2.1.0-pr255.4dc5c0d
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.
- package/dist/ai-agent/index.js +11 -10
- package/dist/ai-agent/index.js.map +1 -1
- package/dist/charts/index.d.ts +2 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +9 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/chunks/DashboardDonutChart.vue_vue_type_script_setup_true_lang-hTcM33bM.js +446 -0
- package/dist/chunks/DashboardDonutChart.vue_vue_type_script_setup_true_lang-hTcM33bM.js.map +1 -0
- package/dist/chunks/VcAiAgentPanel.vue_vue_type_script_setup_true_lang-Cx8_DCu_.js +1124 -0
- package/dist/chunks/VcAiAgentPanel.vue_vue_type_script_setup_true_lang-Cx8_DCu_.js.map +1 -0
- package/dist/chunks/{VcAiAgentPanel.vue_vue_type_style_index_0_lang-D077_c8I.js → VcAiAgentPanel.vue_vue_type_style_index_0_lang-D2KmNhhl.js} +834 -1907
- package/dist/chunks/VcAiAgentPanel.vue_vue_type_style_index_0_lang-D2KmNhhl.js.map +1 -0
- package/dist/chunks/VcTableAdapter.vue_vue_type_script_setup_true_lang-BL653h9q.js +18282 -0
- package/dist/chunks/VcTableAdapter.vue_vue_type_script_setup_true_lang-BL653h9q.js.map +1 -0
- package/dist/chunks/VcTableAdapter.vue_vue_type_style_index_0_lang-CtkZR5a1.js +4227 -0
- package/dist/chunks/VcTableAdapter.vue_vue_type_style_index_0_lang-CtkZR5a1.js.map +1 -0
- package/dist/chunks/dashboard-feed-row.vue_vue_type_script_setup_true_lang-Cs-yidUE.js +641 -0
- package/dist/chunks/dashboard-feed-row.vue_vue_type_script_setup_true_lang-Cs-yidUE.js.map +1 -0
- package/dist/chunks/{index-DELXU1qy.js → index-CvSe3hjU.js} +11 -10
- package/dist/chunks/{index-DELXU1qy.js.map → index-CvSe3hjU.js.map} +1 -1
- package/dist/chunks/vendor-js-beautify-D-6mWVv0.js +1784 -0
- package/dist/chunks/vendor-js-beautify-D-6mWVv0.js.map +1 -0
- package/dist/chunks/{vendor-vueuse-core-CEdpDfzx.js → vendor-vueuse-core-BYWoPpF_.js} +5 -5
- package/dist/chunks/{vendor-vueuse-core-CEdpDfzx.js.map → vendor-vueuse-core-BYWoPpF_.js.map} +1 -1
- package/dist/core/blade-navigation/bladeConfigRegistry.d.ts +0 -11
- package/dist/core/blade-navigation/bladeConfigRegistry.d.ts.map +1 -1
- package/dist/core/blade-navigation/descriptorFactory.d.ts +2 -0
- package/dist/core/blade-navigation/descriptorFactory.d.ts.map +1 -0
- package/dist/core/blade-navigation/singletons.d.ts +0 -2
- package/dist/core/blade-navigation/singletons.d.ts.map +1 -1
- package/dist/core/blade-navigation/types/index.d.ts +12 -6
- package/dist/core/blade-navigation/types/index.d.ts.map +1 -1
- package/dist/core/blade-navigation/useBladeMessaging.d.ts +1 -17
- package/dist/core/blade-navigation/useBladeMessaging.d.ts.map +1 -1
- package/dist/core/blade-navigation/useBladeStack.d.ts +1 -18
- package/dist/core/blade-navigation/useBladeStack.d.ts.map +1 -1
- package/dist/core/composables/createServiceRegistry.d.ts +42 -0
- package/dist/core/composables/createServiceRegistry.d.ts.map +1 -0
- package/dist/core/composables/useBladeNavigationAdapter/index.d.ts +0 -5
- package/dist/core/composables/useBladeNavigationAdapter/index.d.ts.map +1 -1
- package/dist/core/composables/useDashboard/index.d.ts.map +1 -1
- package/dist/core/composables/useEnvironmentName/index.d.ts +0 -5
- package/dist/core/composables/useEnvironmentName/index.d.ts.map +1 -1
- package/dist/core/composables/useMenuService/index.d.ts.map +1 -1
- package/dist/core/composables/usePopup/index.d.ts.map +1 -1
- package/dist/core/composables/usePopup/preset-registry.d.ts +0 -2
- package/dist/core/composables/usePopup/preset-registry.d.ts.map +1 -1
- package/dist/core/composables/usePopup/singleton.d.ts +0 -2
- package/dist/core/composables/usePopup/singleton.d.ts.map +1 -1
- package/dist/core/composables/useSettings/index.d.ts.map +1 -1
- package/dist/core/composables/useSettingsMenu/index.d.ts.map +1 -1
- package/dist/core/composables/useSlowNetworkDetection/index.d.ts +0 -2
- package/dist/core/composables/useSlowNetworkDetection/index.d.ts.map +1 -1
- package/dist/core/composables/useTheme/index.d.ts.map +1 -1
- package/dist/core/composables/useToolbar/index.d.ts.map +1 -1
- package/dist/core/composables/useUser/index.d.ts +0 -2
- package/dist/core/composables/useUser/index.d.ts.map +1 -1
- package/dist/core/interceptors/index.d.ts.map +1 -1
- package/dist/core/notifications/notification.d.ts.map +1 -1
- package/dist/core/plugins/ai-agent/constants.d.ts.map +1 -1
- package/dist/core/plugins/ai-agent/services/message-transport.d.ts.map +1 -1
- package/dist/core/plugins/ai-agent/types.d.ts +12 -1
- package/dist/core/plugins/ai-agent/types.d.ts.map +1 -1
- package/dist/core/plugins/permissions/index.d.ts.map +1 -1
- package/dist/core/plugins/validation/rules.d.ts.map +1 -1
- package/dist/core/services/_internal/createGenericItemRegistry.d.ts +35 -0
- package/dist/core/services/_internal/createGenericItemRegistry.d.ts.map +1 -0
- package/dist/core/services/_internal/index.d.ts +1 -0
- package/dist/core/services/_internal/index.d.ts.map +1 -1
- package/dist/core/services/app-bar-menu-service.d.ts.map +1 -1
- package/dist/core/services/app-bar-mobile-buttons-service.d.ts +2 -0
- package/dist/core/services/app-bar-mobile-buttons-service.d.ts.map +1 -1
- package/dist/core/services/settings-menu-service.d.ts.map +1 -1
- package/dist/core/utilities/backendRegistry.d.ts +38 -0
- package/dist/core/utilities/backendRegistry.d.ts.map +1 -0
- package/dist/core/utilities/index.d.ts +1 -0
- package/dist/core/utilities/index.d.ts.map +1 -1
- package/dist/dashboard/index.d.ts +3 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +16 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/framework.js +2149 -3060
- package/dist/framework.js.map +1 -1
- package/dist/index.css +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/locales/de.js +91 -3
- package/dist/locales/en.js +91 -3
- package/dist/locales/en.json +91 -3
- package/dist/locales/types.d.ts +88 -0
- package/dist/shell/_internal/blade-navigation/components/vc-blade-slot/vc-blade-slot.vue.d.ts.map +1 -1
- package/dist/shell/_internal/notifications/components/notification-container/computeToastOffsets.d.ts +33 -0
- package/dist/shell/_internal/notifications/components/notification-container/computeToastOffsets.d.ts.map +1 -0
- package/dist/shell/_internal/notifications/components/notification-container/index.d.ts.map +1 -1
- package/dist/shell/_internal/notifications/components/notification-container/useToastStack.d.ts +17 -0
- package/dist/shell/_internal/notifications/components/notification-container/useToastStack.d.ts.map +1 -0
- package/dist/shell/auth/LoginPage/components/login/Login.vue.d.ts.map +1 -1
- package/dist/shell/auth/utils.d.ts +6 -2
- package/dist/shell/auth/utils.d.ts.map +1 -1
- package/dist/tailwind.config.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/atoms/vc-container/vc-container.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-video/vc-video.vue.d.ts +8 -0
- package/dist/ui/components/atoms/vc-video/vc-video.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.vue.d.ts +2 -0
- package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-color-input/vc-color-input.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-dropdown/vc-dropdown.vue.d.ts +3 -0
- package/dist/ui/components/molecules/vc-dropdown/vc-dropdown.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-editor/_internal/vc-editor-custom-button.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-editor/_internal/vc-editor-font-selector.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-editor/vc-editor.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-file-upload/vc-file-upload.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-input-currency/vc-input-currency.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.vue.d.ts +2 -0
- package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-switch/vc-switch.vue.d.ts +2 -0
- package/dist/ui/components/molecules/vc-switch/vc-switch.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-toast/vc-toast.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-app/_internal/app-bar/components/AppBarMobileActions.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-app/_internal/layouts/DesktopLayout.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-app/_internal/sidebar/SidebarHeader.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-blade/_internal/BladeStatusBanners.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/VcDataTable.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/ColumnFilter.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/DataTableBody.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/DataTableCellRenderer.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/DataTableHeader.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/DataTableRow.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/TableAddRowButton.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/TableCheckbox.vue.d.ts +5 -1
- package/dist/ui/components/organisms/vc-data-table/components/TableCheckbox.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/TableGroupRow.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/TableRow.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/components/TableRowActions.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/composables/createTableSelectionFacade.d.ts +50 -0
- package/dist/ui/components/organisms/vc-data-table/composables/createTableSelectionFacade.d.ts.map +1 -0
- package/dist/ui/components/organisms/vc-data-table/composables/index.d.ts +2 -0
- package/dist/ui/components/organisms/vc-data-table/composables/index.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/composables/useDataTableOrchestrator.d.ts +0 -248
- package/dist/ui/components/organisms/vc-data-table/composables/useDataTableOrchestrator.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/composables/useDataTableState.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/composables/useTableColumnsResize.d.ts +3 -0
- package/dist/ui/components/organisms/vc-data-table/composables/useTableColumnsResize.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-data-table/vc-data-table.stories.helpers.d.ts +32 -0
- package/dist/ui/components/organisms/vc-data-table/vc-data-table.stories.helpers.d.ts.map +1 -0
- package/dist/ui/components/organisms/vc-gallery/_internal/vc-gallery-filmstrip/vc-gallery-filmstrip.vue.d.ts.map +1 -1
- package/dist/ui/index.js +142 -141
- package/dist/ui/index.js.map +1 -1
- package/package.json +19 -7
- package/tailwind.config.ts +0 -6
- package/dist/chunks/VcAiAgentPanel.vue_vue_type_style_index_0_lang-D077_c8I.js.map +0 -1
- package/dist/chunks/VcTableAdapter.vue_vue_type_style_index_0_lang-BnbquDGw.js +0 -22319
- package/dist/chunks/VcTableAdapter.vue_vue_type_style_index_0_lang-BnbquDGw.js.map +0 -1
- package/dist/chunks/vendor-prettier-2Sf6a5jB.js +0 -5309
- package/dist/chunks/vendor-prettier-2Sf6a5jB.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VcTableAdapter.vue_vue_type_script_setup_true_lang-BL653h9q.js","sources":["../../core/utilities/date/convertMomentFormat.ts","../../core/utilities/date/resolveLocale.ts","../../core/utilities/date/formatDate.ts","../../core/utilities/formatBadgeCount.ts","../../core/utilities/thumbnail/index.ts","../../core/notifications/types.ts","../../core/notifications/toast-controller.ts","../../core/notifications/store.ts","../../core/notifications/composables/useNotificationStore.ts","../../core/blade-navigation/useBladeMessaging.ts","../../core/blade-navigation/bladeConfigRegistry.ts","../../core/blade-navigation/table-query-state/types.ts","../../core/blade-navigation/table-query-state/serialization.ts","../../core/blade-navigation/table-query-state/createBladeQueryState.ts","../../ui/components/atoms/vc-icon/icons/MenuBurgerIcon.vue","../../core/blade-navigation/utils/navigateToMainRoute.ts","../../core/composables/useBladeRegistry/index.ts","../../shell/components/error-interceptor/index.ts","../../shell/_internal/blade-navigation/components/vc-blade-slot/vc-blade-slot.vue","../../ui/components/atoms/vc-button/vc-button-group.vue","../../ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue","../../ui/composables/useAdaptiveItems.ts","../../ui/composables/useCollapsible.ts","../../ui/composables/useTableSort.ts","../../ui/composables/useTableSelection.ts","../../ui/composables/useDataTableSort.ts","../../ui/composables/useDataTablePagination.ts","../../ui/composables/useTableSearch.ts","../../ui/components/molecules/vc-dropdown/vc-dropdown.vue","../../ui/components/molecules/vc-dropdown/_internal/VcDropdownItem.vue","../../ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue","../../shell/_internal/blade-navigation/components/vc-blade-navigation/_internal/vc-mobile-back-button.vue","../../core/composables/useBreadcrumbs/index.ts","../../shell/_internal/blade-navigation/components/vc-blade-navigation/vc-blade-navigation-new.vue","../../core/composables/usePopup/keys.ts","../../core/composables/usePopup/singleton.ts","../../core/composables/usePopup/preset-registry.ts","../../ui/components/organisms/vc-popup/vc-popup.vue","../../shell/_internal/popup/utils/index.ts","../../shell/_internal/popup/components/vc-popup-container/vc-popup-container.vue","../../shell/_internal/popup/components/vc-popup-container/index.ts","../../core/composables/usePopup/index.ts","../../ui/components/organisms/vc-blade/_internal/BladeHeader.vue","../../ui/components/atoms/vc-badge/vc-badge.vue","../../ui/components/atoms/vc-card/vc-card.vue","../../ui/components/atoms/vc-card/index.ts","../../ui/components/atoms/vc-col/vc-col.vue","../../ui/components/atoms/vc-container/index.ts","../../ui/components/atoms/vc-image/vc-image.vue","../../ui/components/atoms/vc-link/vc-link.vue","../../ui/components/atoms/vc-link/index.ts","../../ui/components/atoms/vc-loading/vc-loading.vue","../../ui/components/atoms/vc-loading/index.ts","../../ui/components/atoms/vc-progress/vc-progress.vue","../../ui/components/atoms/vc-progress/index.ts","../../ui/components/atoms/vc-row/vc-row.vue","../../ui/components/atoms/vc-status/vc-status.vue","../../ui/components/atoms/vc-status-icon/vc-status-icon.vue","../../ui/components/atoms/vc-video/vc-video.vue","../../ui/components/atoms/vc-widget/vc-widget.vue","../../ui/components/atoms/vc-widget/index.ts","../../ui/components/atoms/vc-banner/vc-banner.vue","../../ui/components/atoms/vc-environment-banner/vc-environment-banner.vue","../../ui/components/organisms/vc-blade/utils.ts","../../ui/components/organisms/vc-blade/_internal/toolbar/ToolbarMobile.vue","../../ui/components/organisms/vc-blade/_internal/toolbar/ToolbarBaseButton.vue","../../ui/components/organisms/vc-blade/_internal/toolbar/ToolbarDesktop.vue","../../core/constants/locale.ts","../../ui/components/organisms/vc-blade/_internal/composables/useToolbarRegistration.ts","../../ui/components/organisms/vc-blade/_internal/BladeToolbar.vue","../../ui/components/organisms/vc-blade/_internal/composables/useBladeError.ts","../../ui/components/organisms/vc-blade/_internal/BladeStatusBanners.vue","../../core/composables/useWidgets/index.ts","../../ui/components/organisms/vc-blade/_internal/widgets/WidgetScope.vue","../../ui/components/organisms/vc-blade/_internal/widgets/useHeadlessWidgetHelpers.ts","../../ui/components/organisms/vc-blade/_internal/widgets/WidgetContainerDesktop.vue","../../ui/components/organisms/vc-sidebar/vc-sidebar.vue","../../ui/components/organisms/vc-blade/_internal/widgets/WidgetContainerMobile.vue","../../ui/components/organisms/vc-blade/_internal/widgets/WidgetContainer.vue","../../core/services/language-service.ts","../../core/composables/useLanguages/index.ts","../../core/composables/useAppBarWidget/index.ts","../../core/composables/useMenuExpanded/index.ts","../../core/composables/useSidebarState/index.ts","../../core/composables/useEnvironmentName/index.ts","../../ui/components/organisms/vc-blade/vc-blade.vue","../../ui/components/molecules/vc-form/vc-form.vue","../../ui/components/molecules/vc-form/index.ts","../../ui/components/molecules/vc-textarea/vc-textarea.vue","../../ui/components/molecules/vc-field/vc-field.vue","../../ui/components/molecules/vc-accordion/_internal/vc-accordion-item/vc-accordion-item.vue","../../ui/components/molecules/vc-accordion/vc-accordion.vue","../../ui/components/molecules/vc-accordion/index.ts","../../ui/components/molecules/vc-file-upload/vc-file-upload.vue","../../ui/components/molecules/vc-editor/_internal/vc-editor-button.vue","../../ui/components/molecules/vc-editor/_internal/toolbar-types.ts","../../ui/components/molecules/vc-editor/_internal/vc-editor-custom-button.vue","../../ui/components/molecules/vc-editor/_internal/vc-editor-font-selector.vue","../../ui/components/molecules/vc-editor/_internal/vc-editor-toolbar.vue","../../ui/components/molecules/vc-editor/vc-editor.vue","../../ui/components/molecules/vc-toast/vc-toast.vue","../../ui/components/molecules/vc-pagination/vc-pagination.vue","../../ui/components/molecules/vc-pagination/index.ts","../../ui/components/molecules/vc-rating/vc-rating.vue","../../ui/components/molecules/vc-slider/vc-slider.vue","../../ui/components/molecules/vc-slider/index.ts","../../ui/components/molecules/vc-multivalue/_internal/MultivalueTrigger.vue","../../ui/components/molecules/vc-multivalue/_internal/MultivalueDropdown.vue","../../ui/components/molecules/vc-multivalue/composables/useMultivalueMode.ts","../../ui/components/molecules/vc-multivalue/composables/useMultivalueValues.ts","../../ui/components/molecules/vc-multivalue/composables/useMultivalueInput.ts","../../ui/components/molecules/vc-multivalue/composables/useMultivalueColor.ts","../../ui/components/molecules/vc-multivalue/composables/useMultivalueDropdown.ts","../../ui/components/molecules/vc-multivalue/composables/useMultivalueOptions.ts","../../ui/components/molecules/vc-multivalue/vc-multivalue.vue","../../ui/components/molecules/vc-radio-button/vc-radio-button.vue","../../ui/components/molecules/vc-input-group/vc-input-group.vue","../../ui/components/molecules/vc-radio-group/vc-radio-group.vue","../../ui/components/molecules/vc-checkbox/vc-checkbox.vue","../../ui/components/molecules/vc-checkbox-group/vc-checkbox-group.vue","../../ui/components/molecules/vc-switch/vc-switch.vue","../../ui/components/molecules/vc-dropdown-panel/panel-anchor-registry.ts","../../ui/components/molecules/vc-dropdown-panel/vc-dropdown-panel.vue","../../ui/components/molecules/vc-menu/constants.ts","../../ui/components/molecules/vc-menu/vc-menu.vue","../../ui/components/molecules/vc-menu/vc-menu-item.vue","../../ui/components/molecules/vc-menu/vc-menu-group.vue","../../ui/components/molecules/vc-menu/index.ts","../../ui/components/organisms/vc-gallery/composables/useImageLoad.ts","../../ui/components/molecules/vc-image-tile/vc-image-tile.vue","../../ui/components/molecules/multilanguage-selector/multilanguage-selector.vue","../../ui/components/organisms/vc-app/_internal/sidebar/SidebarHeader.vue","../../ui/components/organisms/vc-app/_internal/menu/composables/useMenuActiveState.ts","../../ui/components/organisms/vc-app/_internal/menu/VcAppMenu.vue","../../shell/components/user-dropdown-button/_internal/user-info.vue","../../shell/components/settings-menu/settings-menu.vue","../../shell/components/user-dropdown-button/_internal/user-sidebar.vue","../../shell/components/user-dropdown-button/user-dropdown-button.vue","../../shell/components/user-dropdown-button/index.ts","../../ui/components/organisms/vc-app/_internal/sidebar/SidebarContent.vue","../../ui/components/organisms/vc-app/_internal/sidebar/SidebarCollapseButton.vue","../../ui/components/organisms/vc-app/_internal/app-bar/composables/useToggleableContent.ts","../../ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarWidgets.ts","../../ui/components/organisms/vc-app/_internal/app-bar/composables/useAppHub.ts","../../ui/components/organisms/vc-app/_internal/app-bar/components/AppBarWidgetContent.vue","../../ui/components/organisms/vc-app/_internal/app-bar/components/AppHubContent.vue","../../ui/components/organisms/vc-app/_internal/app-bar/components/AppHubPopover.vue","../../shell/components/notification-template/notification-template.vue","../../shell/components/notification-template/index.ts","../../shell/components/notification-dropdown/_internal/notification/notification.vue","../../shell/components/notification-dropdown/notification-dropdown.vue","../../shell/components/notification-dropdown/index.ts","../../ui/components/organisms/vc-app/_internal/layouts/DesktopLayout.vue","../../core/services/app-bar-mobile-buttons-service.ts","../../core/composables/useAppBarMobileButtons/index.ts","../../ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarMobileActions.ts","../../ui/components/organisms/vc-app/_internal/app-bar/components/AppBarMobileActions.vue","../../ui/components/organisms/vc-app/_internal/app-bar/components/MenuSidebar.vue","../../ui/components/organisms/vc-app/_internal/layouts/MobileLayout.vue","../../core/composables/usePlatformLocaleSync/index.ts","../../shell/components/settings-menu-item/settings-menu-item.vue","../../shell/components/language-selector/language-selector.vue","../../shell/components/language-selector/index.ts","../../shell/components/theme-selector/theme-selector.vue","../../shell/components/change-password/change-password.vue","../../shell/components/change-password/index.ts","../../shell/components/change-password-button/change-password-button.vue","../../shell/components/logout-button/logout-button.vue","../../ui/components/organisms/vc-app/composables/useShellBootstrap.ts","../../ui/components/organisms/vc-app/composables/useShellNavigation.ts","../../shell/components/app-hub/composables/useAppHub/index.ts","../../ui/components/organisms/vc-app/composables/useShellLifecycle.ts","../../ui/components/organisms/vc-app/vc-app.vue","../../ui/components/organisms/vc-app/_internal/menu/composables/useBadge.ts","../../ui/components/organisms/vc-app/_internal/app-bar/components/AppBarOverlay.vue","../../ui/components/organisms/vc-app/_internal/app-bar/components/AppBarWidgetItem.vue","../../ui/components/organisms/vc-app/_internal/app-bar/components/AppBarWidgetsMenu.vue","../../ui/components/organisms/vc-auth-layout/vc-auth-layout.vue","../../ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue","../../ui/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue","../../ui/components/organisms/vc-gallery/_internal/vc-gallery-filmstrip/vc-gallery-filmstrip.vue","../../ui/components/organisms/vc-gallery/_internal/vc-gallery-preview/vc-gallery-preview.vue","../../ui/components/organisms/vc-gallery/composables/useGalleryPreview.ts","../../ui/components/organisms/vc-image-upload/vc-image-upload.vue","../../ui/components/organisms/vc-gallery/composables/useGalleryReorder.ts","../../ui/components/organisms/vc-gallery/composables/useGalleryUpload.ts","../../ui/components/organisms/vc-gallery/composables/useGalleryFilmstrip.ts","../../ui/components/organisms/vc-gallery/vc-gallery.vue","../../ui/components/organisms/vc-data-table/components/Table.vue","../../ui/components/organisms/vc-data-table/components/TableHeader.vue","../../ui/components/organisms/vc-data-table/components/TableBody.vue","../../ui/components/organisms/vc-data-table/components/TableRow.vue","../../ui/components/organisms/vc-data-table/components/TableHead.vue","../../ui/components/organisms/vc-data-table/components/TableCell.vue","../../ui/components/organisms/vc-data-table/components/TableFooter.vue","../../ui/components/organisms/vc-data-table/components/TableEmpty.vue","../../ui/components/organisms/vc-data-table/components/TableColumnSwitcher.vue","../../ui/components/organisms/vc-data-table/components/TableRowActions.vue","../../ui/components/organisms/vc-data-table/components/TableCheckbox.vue","../../ui/components/organisms/vc-data-table/components/TableSelectAllBar.vue","../../ui/components/organisms/vc-data-table/components/TableSearchHeader.vue","../../ui/components/organisms/vc-data-table/components/TableGroupRow.vue","../../ui/components/organisms/vc-data-table/components/ColumnFilter.vue","../../ui/components/organisms/vc-data-table/components/GlobalFiltersButton.vue","../../ui/components/organisms/vc-data-table/composables/useColumnFilter.ts","../../ui/components/organisms/vc-data-table/components/GlobalFiltersPanel.vue","../../ui/components/organisms/vc-data-table/components/TableAddRowButton.vue","../../ui/components/organisms/vc-data-table/components/cells/CellEditableWrapper.vue","../../ui/components/organisms/vc-data-table/components/cells/CellDefault.vue","../../ui/components/organisms/vc-data-table/components/cells/CellMoney.vue","../../ui/components/organisms/vc-data-table/components/cells/CellNumber.vue","../../ui/components/organisms/vc-data-table/components/cells/CellDate.vue","../../ui/components/organisms/vc-data-table/components/cells/CellDateAgo.vue","../../ui/components/organisms/vc-data-table/components/cells/CellImage.vue","../../ui/components/organisms/vc-data-table/components/cells/CellStatus.vue","../../ui/components/organisms/vc-data-table/components/cells/CellStatusIcon.vue","../../ui/components/organisms/vc-data-table/components/cells/CellLink.vue","../../ui/components/organisms/vc-data-table/components/cells/CellHtml.vue","../../ui/components/organisms/vc-data-table/components/cells/DynamicCellRenderer.vue","../../ui/components/organisms/vc-data-table/components/DataTableCellRenderer.vue","../../ui/components/organisms/vc-data-table/components/DataTableRow.vue","../../ui/components/organisms/vc-data-table/components/_internal/TableSkeletonRows.vue","../../ui/components/organisms/vc-data-table/components/DataTableBody.vue","../../ui/components/organisms/vc-data-table/components/HeaderTitle.vue","../../ui/components/organisms/vc-data-table/components/DataTableHeader.vue","../../ui/components/organisms/vc-data-table/components/mobile/MobileCellRenderer.vue","../../ui/components/organisms/vc-data-table/components/mobile/MobileActionSheet.vue","../../ui/components/organisms/vc-data-table/composables/useTableSwipe.ts","../../ui/components/organisms/vc-data-table/components/mobile/DataTableMobileCard.vue","../../ui/components/organisms/vc-data-table/composables/useMobileCardLayout.ts","../../ui/components/organisms/vc-data-table/components/mobile/PullToRefresh.vue","../../ui/components/organisms/vc-data-table/components/mobile/DataTableMobileView.vue","../../ui/components/organisms/vc-data-table/composables/useTableContext.ts","../../ui/components/organisms/vc-data-table/composables/useColumnWidthEngine.ts","../../ui/components/organisms/vc-data-table/composables/useTableColumnsResize.ts","../../ui/components/organisms/vc-data-table/composables/useTableColumnsReorder.ts","../../ui/components/organisms/vc-data-table/composables/useTableRowReorder.ts","../../ui/components/organisms/vc-data-table/composables/useTableInlineEdit.ts","../../ui/components/organisms/vc-data-table/composables/useVirtualScroll.ts","../../ui/components/organisms/vc-data-table/composables/useTableRowGrouping.ts","../../ui/components/organisms/vc-data-table/composables/useTableFilter.ts","../../ui/components/organisms/vc-data-table/composables/useTableSort.ts","../../ui/components/organisms/vc-data-table/composables/useTableEditing.ts","../../ui/components/organisms/vc-data-table/composables/useTableExpansion.ts","../../ui/components/organisms/vc-data-table/composables/useTableSelectionV2.ts","../../ui/components/organisms/vc-data-table/composables/createTableSelectionFacade.ts","../../ui/components/organisms/vc-data-table/utils/columnHelpers.ts","../../ui/components/organisms/vc-data-table/composables/useTableColumns.ts","../../ui/components/organisms/vc-data-table/composables/useDataTableState.ts","../../ui/components/organisms/vc-data-table/composables/useDataTableOrchestrator.ts","../../ui/components/organisms/vc-data-table/utils/ColumnCollector.ts","../../core/directives/autofocus/index.ts","../../ui/components/organisms/vc-data-table/VcDataTable.vue","../../ui/components/organisms/vc-data-table/VcTableAdapter.vue"],"sourcesContent":["const LOCALE_SHORTCUTS: [string, string][] = [\n [\"LLLL\", \"PPPp\"],\n [\"LLL\", \"PPp\"],\n [\"LTS\", \"pp\"],\n [\"LT\", \"p\"],\n [\"LL\", \"PP\"],\n [\"L\", \"P\"],\n];\n\nconst TOKEN_MAP: [RegExp, string][] = [\n [/YYYY/g, \"yyyy\"],\n [/YY/g, \"yy\"],\n [/dddd/g, \"EEEE\"],\n [/ddd/g, \"EEE\"],\n [/DD/g, \"dd\"],\n [/Do/g, \"do\"],\n [/D(?![\\w])/g, \"d\"],\n [/A/g, \"a\"],\n];\n\nexport function convertMomentFormat(momentFormat: string): string {\n let result = momentFormat;\n for (const [moment, dateFns] of LOCALE_SHORTCUTS) {\n result = result.split(moment).join(dateFns);\n }\n for (const [pattern, replacement] of TOKEN_MAP) {\n result = result.replace(pattern, replacement);\n }\n return result;\n}\n","import { type Locale } from \"date-fns\";\nimport { enUS } from \"date-fns/locale\";\n\nconst localeCache = new Map<string, Locale>();\nlocaleCache.set(\"en-US\", enUS);\nlocaleCache.set(\"en\", enUS);\n\nexport async function resolveLocale(localeCode: string): Promise<Locale> {\n if (localeCache.has(localeCode)) {\n return localeCache.get(localeCode)!;\n }\n try {\n const mod = await import(/* @vite-ignore */ `date-fns/locale/${localeCode}`);\n const dateFnsKey = localeCode.replace(\"-\", \"\");\n const locale = mod.default ?? mod[dateFnsKey] ?? enUS;\n localeCache.set(localeCode, locale);\n return locale;\n } catch {\n const base = localeCode.split(\"-\")[0];\n if (base !== localeCode) {\n try {\n const mod = await import(/* @vite-ignore */ `date-fns/locale/${base}`);\n const locale = mod.default ?? mod[base] ?? enUS;\n localeCache.set(localeCode, locale);\n return locale;\n } catch {\n /* fall through */\n }\n }\n localeCache.set(localeCode, enUS);\n return enUS;\n }\n}\n\nexport function resolveLocaleSync(localeCode: string): Locale {\n if (localeCache.has(localeCode)) {\n return localeCache.get(localeCode)!;\n }\n void resolveLocale(localeCode);\n return enUS;\n}\n","import { formatDistanceToNow, format } from \"date-fns\";\nimport { convertMomentFormat } from \"./convertMomentFormat\";\nimport { resolveLocaleSync } from \"./resolveLocale\";\n\ntype DateInput = string | number | Date | null | undefined;\n\nfunction toDate(value: DateInput): Date | null {\n if (value == null || value === \"\") return null;\n if (value instanceof Date) return isNaN(value.getTime()) ? null : value;\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d;\n}\n\nexport function formatDateRelative(value: DateInput, localeCode?: string): string {\n const date = toDate(value);\n if (!date) return \"\";\n const locale = localeCode ? resolveLocaleSync(localeCode) : undefined;\n return formatDistanceToNow(date, { addSuffix: true, locale });\n}\n\nexport function formatDateWithPattern(value: DateInput, momentFormatStr: string, localeCode?: string): string {\n const date = toDate(value);\n if (!date) return \"\";\n const dateFnsFormat = convertMomentFormat(momentFormatStr);\n const locale = localeCode ? resolveLocaleSync(localeCode) : undefined;\n return format(date, dateFnsFormat, { locale });\n}\n","/**\r\n * Formats a badge count value, truncating numbers > 99 to \"99+\".\r\n * Used by VcWidget and WidgetDropdownItem for consistent badge display.\r\n */\r\nexport function formatBadgeCount(value: string | number | undefined): string | undefined {\r\n if (value === undefined || value === null) return undefined;\r\n\r\n const num = typeof value === \"string\" ? parseInt(value) : value;\r\n\r\n if (!isNaN(num) && num > 99) {\r\n return \"99+\";\r\n }\r\n\r\n return String(value);\r\n}\r\n","/**\n * Thumbnail URL utility.\n *\n * VirtoCommerce backend generates image thumbnails with suffixes appended\n * before the file extension:\n * - Named presets: `_sm`, `_md`, `_lg`\n * - Pixel sizes: `_64x64`, `_128x128`, `_168x168`, `_216x216`, `_348x348`\n *\n * This utility transforms a full-size image URL into a thumbnail URL\n * by inserting the appropriate suffix.\n *\n * @example\n * getThumbnailUrl(\"https://cdn.example.com/photo.jpg\", \"sm\")\n * // → \"https://cdn.example.com/photo_sm.jpg\"\n *\n * getThumbnailUrl(\"https://cdn.example.com/photo.jpg\", \"128x128\")\n * // → \"https://cdn.example.com/photo_128x128.jpg\"\n *\n * getThumbnailUrl(\"https://cdn.example.com/photo.jpg\")\n * // → \"https://cdn.example.com/photo.jpg\" (no change)\n */\n\nexport type ThumbnailPreset = \"sm\" | \"md\" | \"lg\";\nexport type ThumbnailPixelSize = \"64x64\" | \"128x128\" | \"168x168\" | \"216x216\" | \"348x348\";\nexport type ThumbnailSize = ThumbnailPreset | ThumbnailPixelSize;\n\n/**\n * Transforms an image URL to its thumbnail variant by appending a size suffix\n * before the file extension.\n *\n * @param url - Original image URL\n * @param size - Thumbnail size (preset name or pixel dimensions). If undefined, returns original URL.\n * @returns Thumbnail URL with suffix, or original URL if size is not specified or URL has no extension.\n */\nexport function getThumbnailUrl(url: string | undefined, size?: ThumbnailSize): string | undefined {\n if (!url || !size) return url;\n\n // Already has this suffix — don't double-apply\n if (url.includes(`_${size}`)) return url;\n\n // Find the filename portion (after last slash)\n const lastSlash = url.lastIndexOf(\"/\");\n const queryIndex = url.indexOf(\"?\", lastSlash);\n const filename = queryIndex > -1 ? url.slice(lastSlash + 1, queryIndex) : url.slice(lastSlash + 1);\n const dotIndex = filename.lastIndexOf(\".\");\n\n if (dotIndex <= 0) {\n // No extension in filename — return as-is\n return url;\n }\n\n // Position of the dot in the full URL\n const extensionDot = lastSlash + 1 + dotIndex;\n const base = url.slice(0, extensionDot);\n const rest = url.slice(extensionDot);\n\n return `${base}_${size}${rest}`;\n}\n\n/**\n * Maps a display size in pixels to the best-fit thumbnail preset.\n * Picks the smallest thumbnail that is >= the display size.\n *\n * @param displaySize - The display size in CSS pixels (width or height, whichever is larger)\n * @returns The best thumbnail size to use\n */\nexport function getBestThumbnailSize(displaySize: number): ThumbnailSize {\n if (displaySize <= 64) return \"64x64\";\n if (displaySize <= 128) return \"128x128\";\n if (displaySize <= 168) return \"168x168\";\n if (displaySize <= 216) return \"216x216\";\n if (displaySize <= 348) return \"348x348\";\n // For larger sizes, use \"lg\" preset or return undefined for full-size\n return \"lg\";\n}\n","import { Component, ComputedRef, InjectionKey } from \"vue\";\r\nimport { PushNotification } from \"@core/api/platform\";\r\n\r\nexport type Severity = \"info\" | \"warning\" | \"error\" | \"critical\";\r\n\r\nexport interface ToastConfig {\r\n mode: \"auto\" | \"progress\" | \"silent\";\r\n /** Toast severity. Controls timeout and toast type. Default: \"info\" */\r\n severity?: Severity | ((msg: PushNotification) => Severity);\r\n timeout?: number;\r\n /** For progress mode: determines when the operation is complete. Default: (msg) => !!(msg as any).finished */\r\n isComplete?: (msg: PushNotification) => boolean;\r\n /** For progress mode: determines toast type on completion. Default: () => \"success\" */\r\n completedType?: (msg: PushNotification) => \"success\" | \"error\";\r\n}\r\n\r\nexport interface NotificationTypeConfig {\r\n template?: Component;\r\n toast: ToastConfig | false;\r\n groupBy?: string;\r\n}\r\n\r\nexport interface ModuleNotificationsConfig {\r\n [notifyType: string]: NotificationTypeConfig;\r\n}\r\n\r\nexport interface NotificationAction {\r\n label: string;\r\n icon?: string;\r\n handler: () => void;\r\n visible?: ComputedRef<boolean> | boolean;\r\n}\r\n\r\nexport interface NotificationSubscription {\r\n id: number;\r\n types: string[];\r\n filter?: (msg: PushNotification) => boolean;\r\n handler?: (msg: PushNotification) => void;\r\n}\r\n\r\nexport interface BladeNotificationOptions<T extends PushNotification = PushNotification> {\r\n types: string[];\r\n filter?: (msg: T) => boolean;\r\n onMessage?: (msg: T) => void;\r\n}\r\n\r\nexport interface BladeNotificationReturn<T extends PushNotification = PushNotification> {\r\n messages: ComputedRef<T[]>;\r\n unreadCount: ComputedRef<number>;\r\n markAsRead: (msg: T) => void;\r\n}\r\n\r\n/** Severity → default toast timeout mapping */\r\nexport const SEVERITY_TIMEOUTS: Record<Severity, number | false> = {\r\n info: 5000,\r\n warning: 8000,\r\n error: false, // persistent\r\n critical: false, // persistent\r\n};\r\n\r\nexport const NotificationContextKey: InjectionKey<ComputedRef<PushNotification>> = Symbol(\"NotificationContext\");\r\n\r\nexport const EXCLUDED_NOTIFICATION_TYPES = [\"IndexProgressPushNotification\"];\r\n","import { PushNotification } from \"@core/api/platform\";\r\nimport { notification } from \"@core/notifications/notification\";\r\nimport { NotificationTypeConfig, Severity, SEVERITY_TIMEOUTS, ToastConfig } from \"./types\";\r\n\r\n/** PushNotification with dynamic properties (subclasses add extra fields at runtime via constructor) */\r\ntype PushNotificationRecord = PushNotification & Record<string, unknown>;\r\n\r\ninterface ActiveToast {\r\n toastId: string | number;\r\n}\r\n\r\nfunction resolveSeverity(toast: ToastConfig, msg: PushNotification): Severity {\r\n if (!toast.severity) return \"info\";\r\n return typeof toast.severity === \"function\" ? toast.severity(msg) : toast.severity;\r\n}\r\n\r\nfunction resolveToastKey(msg: PushNotification, config: NotificationTypeConfig): string {\r\n const type = msg.notifyType ?? \"unknown\";\r\n if (config.groupBy) {\r\n const groupValue = (msg as PushNotificationRecord)[config.groupBy] ?? \"default\";\r\n return `${type}::${groupValue}`;\r\n }\r\n return `${type}::${msg.id}`;\r\n}\r\n\r\nconst defaultIsComplete = (msg: PushNotification) => !!(msg as PushNotificationRecord).finished;\r\n\r\nexport interface IToastController {\r\n handle(message: PushNotification, config: NotificationTypeConfig): void;\r\n}\r\n\r\nexport function createToastController(): IToastController {\r\n const activeToasts = new Map<string, ActiveToast>();\r\n\r\n function handle(message: PushNotification, config: NotificationTypeConfig) {\r\n if (!config.toast) return;\r\n if (config.toast.mode === \"silent\") return;\r\n\r\n const severity = resolveSeverity(config.toast, message);\r\n\r\n if (config.toast.mode === \"auto\") {\r\n handleAuto(message, severity, config);\r\n } else if (config.toast.mode === \"progress\") {\r\n handleProgress(message, severity, config);\r\n }\r\n }\r\n\r\n function handleAuto(message: PushNotification, severity: Severity, config: NotificationTypeConfig) {\r\n const timeout =\r\n config.toast && typeof config.toast !== \"boolean\" && config.toast.timeout != null\r\n ? config.toast.timeout\r\n : SEVERITY_TIMEOUTS[severity];\r\n\r\n notification(message.title ?? \"\", {\r\n timeout,\r\n type: severity === \"critical\" ? \"error\" : severity === \"info\" ? \"default\" : severity,\r\n });\r\n }\r\n\r\n function handleProgress(message: PushNotification, severity: Severity, config: NotificationTypeConfig) {\r\n const toastConfig = config.toast as Exclude<typeof config.toast, false>;\r\n const key = resolveToastKey(message, config);\r\n const isComplete = toastConfig.isComplete ?? defaultIsComplete;\r\n\r\n if (isComplete(message)) {\r\n // Completion\r\n const active = activeToasts.get(key);\r\n if (active) {\r\n const completedType = toastConfig.completedType?.(message) ?? \"success\";\r\n notification.update(active.toastId, {\r\n type: completedType,\r\n timeout: 5000,\r\n content: message.title ?? \"\",\r\n });\r\n activeToasts.delete(key);\r\n }\r\n return;\r\n }\r\n\r\n const active = activeToasts.get(key);\r\n if (active) {\r\n // Update existing\r\n notification.update(active.toastId, {\r\n content: message.title ?? \"\",\r\n });\r\n } else {\r\n // Create new persistent toast\r\n const toastId = notification(message.title ?? \"\", {\r\n timeout: false,\r\n type: severity === \"critical\" ? \"error\" : severity === \"info\" ? \"default\" : severity,\r\n });\r\n if (toastId != null) {\r\n activeToasts.set(key, { toastId });\r\n }\r\n }\r\n }\r\n\r\n return { handle };\r\n}\r\n","import { type Ref, type ComputedRef, ref, computed } from \"vue\";\nimport { PushNotification, PushNotificationClient, PushNotificationSearchCriteria } from \"@core/api/platform\";\nimport { createLogger } from \"@core/utilities\";\nimport { NotificationTypeConfig, NotificationSubscription, EXCLUDED_NOTIFICATION_TYPES } from \"./types\";\nimport { createToastController } from \"./toast-controller\";\n\nconst logger = createLogger(\"notification-store\");\n\nexport interface NotificationStoreOptions {\n /** Injected toast handler. Defaults to createToastController().handle */\n toastHandle?: (msg: PushNotification, config: NotificationTypeConfig) => void;\n}\n\nexport interface NotificationStore {\n // State\n readonly registry: Map<string, NotificationTypeConfig>;\n readonly history: Ref<PushNotification[]>;\n readonly realtime: Ref<PushNotification[]>;\n\n // Computed\n readonly unreadCount: ComputedRef<number>;\n readonly hasUnread: ComputedRef<boolean>;\n\n // Actions\n registerType(type: string, config: NotificationTypeConfig): void;\n ingest(message: PushNotification, opts?: { broadcast?: boolean }): void;\n markAsRead(message: PushNotification): void;\n markAllAsRead(): Promise<void>;\n loadHistory(take?: number): Promise<void>;\n subscribe(opts: {\n types: string[];\n filter?: (msg: PushNotification) => boolean;\n handler?: (msg: PushNotification) => void;\n }): () => void;\n getByType(type: string): PushNotification[];\n setBroadcastFilter(fn: (msg: PushNotification) => boolean): void;\n clearBroadcastFilter(): void;\n}\n\nexport function createNotificationStore(options?: NotificationStoreOptions): NotificationStore {\n const registry = new Map<string, NotificationTypeConfig>();\n const history = ref<PushNotification[]>([]);\n const realtime = ref<PushNotification[]>([]);\n const subscribers = new Map<number, NotificationSubscription>();\n let subscriberCounter = 0;\n const broadcastFilter = ref<((msg: PushNotification) => boolean) | null>(null);\n let broadcastFilterWarned = false;\n\n const toastHandle = options?.toastHandle ?? createToastController().handle;\n const notificationsClient = new PushNotificationClient();\n\n // --- Computed ---\n\n const unreadCount = computed(() => history.value.filter((n) => n.isNew).length);\n\n const hasUnread = computed(() => unreadCount.value > 0);\n\n // --- Actions ---\n\n function registerType(type: string, config: NotificationTypeConfig) {\n registry.set(type, config);\n }\n\n function ingest(message: PushNotification, opts?: { broadcast?: boolean }) {\n if (opts?.broadcast) {\n if (broadcastFilter.value) {\n if (!broadcastFilter.value(message)) return;\n } else if (import.meta.env.DEV && !broadcastFilterWarned) {\n broadcastFilterWarned = true;\n logger.warn(\n \"Broadcast notifications received without a filter. \" +\n \"Call useBroadcastFilter() in your App.vue to filter by creator/seller. \" +\n \"See: MIGRATION_GUIDE.md#broadcast-filter\",\n );\n }\n }\n\n if (message.notifyType && EXCLUDED_NOTIFICATION_TYPES.includes(message.notifyType)) {\n return;\n }\n\n // Upsert into history\n let effectiveIsNew = message.isNew;\n const existingIdx = history.value.findIndex((x) => x.id === message.id);\n if (existingIdx !== -1) {\n const existing = history.value[existingIdx];\n effectiveIsNew = existing.isNew; // preserve read state\n Object.assign(existing, message);\n existing.isNew = effectiveIsNew;\n } else {\n history.value.push({ ...message } as PushNotification);\n }\n\n // Upsert into realtime\n const existingRtIdx = realtime.value.findIndex((x) => x.id === message.id);\n if (existingRtIdx !== -1) {\n const existingRt = realtime.value[existingRtIdx];\n Object.assign(existingRt, message);\n existingRt.isNew = effectiveIsNew;\n } else {\n realtime.value.push({ ...message } as PushNotification);\n }\n\n // Toast (Level 1: always-on) — use stored isNew, not incoming\n const config = message.notifyType ? registry.get(message.notifyType) : undefined;\n if (config && effectiveIsNew) {\n toastHandle(message, config);\n }\n\n // Notify subscribers (Level 2: blade-level) — use stored isNew\n if (effectiveIsNew && message.notifyType) {\n for (const sub of subscribers.values()) {\n if (!sub.types.includes(message.notifyType)) continue;\n if (sub.filter && !sub.filter(message)) continue;\n sub.handler?.(message);\n }\n }\n }\n\n function markAsRead(message: PushNotification) {\n const inHistory = history.value.find((x) => x.id === message.id);\n if (inHistory) inHistory.isNew = false;\n\n const inRealtime = realtime.value.find((x) => x.id === message.id);\n if (inRealtime) inRealtime.isNew = false;\n }\n\n async function markAllAsRead() {\n // Local update — always applied regardless of server response\n history.value.forEach((x) => {\n x.isNew = false;\n });\n realtime.value.forEach((x) => {\n x.isNew = false;\n });\n\n try {\n await notificationsClient.markAllAsRead();\n } catch (e) {\n // Server failure is non-critical — local state stays \"read\"\n // Next loadHistory() will reconcile with server state\n logger.error(\"markAllAsRead failed:\", e);\n }\n }\n\n async function loadHistory(take = 10) {\n try {\n const criteria: PushNotificationSearchCriteria = { take };\n const result = await notificationsClient.searchPushNotification(criteria);\n history.value = result.notifyEvents ?? [];\n } catch (e) {\n logger.error(\"loadHistory failed:\", e);\n throw e;\n }\n }\n\n function subscribe(opts: {\n types: string[];\n filter?: (msg: PushNotification) => boolean;\n handler?: (msg: PushNotification) => void;\n }): () => void {\n const id = ++subscriberCounter;\n subscribers.set(id, { id, ...opts });\n return () => {\n subscribers.delete(id);\n };\n }\n\n function getByType(type: string): PushNotification[] {\n return history.value.filter((n) => n.notifyType === type);\n }\n\n function setBroadcastFilter(fn: (msg: PushNotification) => boolean) {\n broadcastFilter.value = fn;\n }\n\n function clearBroadcastFilter() {\n broadcastFilter.value = null;\n }\n\n return {\n // State\n registry,\n history,\n realtime,\n\n // Computed\n unreadCount,\n hasUnread,\n\n // Actions\n registerType,\n ingest,\n markAsRead,\n markAllAsRead,\n loadHistory,\n subscribe,\n getByType,\n setBroadcastFilter,\n clearBroadcastFilter,\n };\n}\n","import { inject, getCurrentInstance } from \"vue\";\nimport { NotificationStoreKey } from \"@framework/injection-keys\";\nimport { createNotificationStore, NotificationStore } from \"../store\";\n\n/** Module-level singleton — shared by all callers when inject() is unavailable. */\nlet _singleton: NotificationStore | null = null;\n\n/**\n * Returns the shared NotificationStore singleton.\n *\n * Resolution order:\n * 1. Vue inject() — works inside component setup() or app.runWithContext()\n * 2. Module-level singleton — ensures all plugin install() calls and\n * remote microfrontend modules share the same store instance\n */\nexport function useNotificationStore(): NotificationStore {\n if (getCurrentInstance()) {\n const injected = inject(NotificationStoreKey, null);\n if (injected) {\n _singleton = injected;\n return injected;\n }\n }\n\n if (!_singleton) {\n _singleton = createNotificationStore();\n }\n return _singleton;\n}\n","import { inject } from \"vue\";\r\nimport type { IBladeMessaging, IBladeStack } from \"@core/blade-navigation/types\";\r\nimport { BladeMessagingKey } from \"@core/blade-navigation/types\";\r\n\r\n/**\r\n * Creates the inter-blade messaging system.\r\n *\r\n * Uses a Map<bladeId, Record<string, Function>> to store exposed methods.\r\n * Child blades call parent methods via direct ID lookup (no tree walking).\r\n *\r\n * @param bladeStack - BladeStack for looking up blade descriptors by ID\r\n * @internal\r\n */\r\nexport function createBladeMessaging(bladeStack: IBladeStack): IBladeMessaging {\r\n // bladeId → Record of method name → function\r\n const _exposedMethods = new Map<string, Record<string, (...args: any[]) => any>>();\r\n\r\n function exposeToChildren(bladeId: string, methods: Record<string, (...args: any[]) => any>): void {\r\n _exposedMethods.set(bladeId, methods);\r\n }\r\n\r\n async function callParent<T = unknown>(callerBladeId: string, method: string, args?: unknown): Promise<T> {\r\n // Find the caller blade to get its parentId\r\n const callerBlade = bladeStack.blades.value.find((b) => b.id === callerBladeId);\r\n if (!callerBlade) {\r\n throw new Error(`[BladeMessaging] Caller blade '${callerBladeId}' not found in stack`);\r\n }\r\n\r\n if (!callerBlade.parentId) {\r\n console.warn(`[BladeMessaging] Blade '${callerBladeId}' has no parent — callParent() ignored.`);\r\n return undefined as T;\r\n }\r\n\r\n // Look up the parent's exposed methods\r\n const parentMethods = _exposedMethods.get(callerBlade.parentId);\r\n if (!parentMethods) {\r\n return undefined as T;\r\n }\r\n\r\n const fn = parentMethods[method];\r\n if (typeof fn !== \"function\") {\r\n return undefined as T;\r\n }\r\n\r\n // Call the method and return the result\r\n return (await fn(args)) as T;\r\n }\r\n\r\n function cleanup(bladeId: string): void {\r\n _exposedMethods.delete(bladeId);\r\n }\r\n\r\n return {\r\n exposeToChildren,\r\n callParent,\r\n cleanup,\r\n };\r\n}\r\n\r\n/**\r\n * Composable for accessing BladeMessaging from within a component.\r\n * Must be used after BladeMessaging is provided via BladeMessagingKey.\r\n * @internal\r\n */\r\nexport function useBladeMessaging(): IBladeMessaging {\r\n const messaging = inject(BladeMessagingKey);\r\n if (!messaging) {\r\n throw new Error(\"[useBladeMessaging] BladeMessaging not found. Ensure BladeNavigationPlugin is installed.\");\r\n }\r\n return messaging;\r\n}\r\n","import type { BladeConfig } from \"./types\";\n\nconst registry = new Map<string, BladeConfig>();\n\n/**\n * Register blade config in global registry.\n * Called by Vite-compiled defineBlade() at module import time.\n * @internal — not part of the public API. Used by viteBladePlugin output.\n */\nexport function __registerBladeConfig(name: string, config: BladeConfig): void {\n if (registry.has(name)) {\n console.warn(`[defineBlade] Duplicate blade name: \"${name}\". Overwriting.`);\n }\n registry.set(name, config);\n}\n\n/**\n * Get blade config by registered name.\n */\nexport function getBladeConfig(name: string): BladeConfig | undefined {\n return registry.get(name);\n}\n\n/**\n * Get all registered blade configs (readonly).\n */\nexport function getAllBladeConfigs(): ReadonlyMap<string, BladeConfig> {\n return registry;\n}\n\n/**\n * Clear registry — for testing only.\n * @internal\n */\nexport function __clearBladeConfigRegistry(): void {\n registry.clear();\n}\n","import type { InjectionKey } from \"vue\";\n\n/** Partial table view state persisted to the URL query. */\nexport interface TableQueryPatch {\n /** Sort expression, e.g. \"name:ASC\" | \"name:DESC\". `undefined`/\"\" clears it. */\n sort?: string;\n /** Free-text search value. `undefined`/\"\" clears it. */\n search?: string;\n /** 1-based current page. `undefined` clears it. */\n page?: number;\n}\n\n/**\n * Per-blade service that persists table view state (sort/search/page) into the\n * URL query. Provided by the blade rendering layer for URL-addressable blades;\n * absent for standalone tables (then VcDataTable simply does not persist).\n */\nexport interface ITableQueryStateService {\n /** Read the restored view state for a table from the current URL. */\n read(tableKey?: string): TableQueryPatch;\n /** Persist a patch of the view state (debounced → URL replace). */\n write(tableKey: string | undefined, patch: TableQueryPatch): void;\n}\n\n/** Injection key — value is `undefined` when no blade provides the service. */\nexport const TableQueryStateKey: InjectionKey<ITableQueryStateService | undefined> = Symbol(\"TableQueryState\");\n","import type { TableQueryPatch } from \"./types\";\n\n/** Router query value can be string | string[] | null. */\ntype RawQuery = Record<string, string | (string | null)[] | null | undefined>;\n\n/**\n * Build the namespaced query record for a patch. Keys present in `patch` are\n * always emitted; cleared values become \"\" so the descriptor strips them.\n */\nexport function encodeQueryState(ns: string, patch: TableQueryPatch): Record<string, string> {\n const out: Record<string, string> = {};\n if (\"sort\" in patch) out[`${ns}_sort`] = patch.sort ?? \"\";\n if (\"search\" in patch) out[`${ns}_search`] = patch.search ?? \"\";\n if (\"page\" in patch) out[`${ns}_page`] = patch.page != null ? String(patch.page) : \"\";\n return out;\n}\n\nconst SORT_RE = /^.+:(ASC|DESC)$/;\n\n/** Read and validate the view state for a namespace from a router query record. */\nexport function decodeQueryState(ns: string, query: RawQuery): TableQueryPatch {\n const res: TableQueryPatch = {};\n\n const sort = query[`${ns}_sort`];\n if (typeof sort === \"string\" && SORT_RE.test(sort)) res.sort = sort;\n\n const search = query[`${ns}_search`];\n if (typeof search === \"string\" && search !== \"\") res.search = search;\n\n const pageRaw = query[`${ns}_page`];\n if (typeof pageRaw === \"string\") {\n const n = Number(pageRaw);\n if (Number.isInteger(n) && n >= 1) res.page = n;\n }\n\n return res;\n}\n","import type { ComputedRef } from \"vue\";\nimport type { Router } from \"vue-router\";\nimport type { BladeDescriptor, IBladeStack } from \"@core/blade-navigation/types\";\nimport { createUrlSync } from \"@core/blade-navigation/utils/urlSync\";\nimport type { ITableQueryStateService, TableQueryPatch } from \"./types\";\nimport { encodeQueryState, decodeQueryState } from \"./serialization\";\n\nconst DEBOUNCE_MS = 150;\n\nexport interface CreateBladeQueryStateDeps {\n /** The blade this service belongs to (provides id + url for namespacing). */\n descriptor: ComputedRef<BladeDescriptor>;\n /** Router — source of truth for the current URL query. */\n router: Router;\n /** Blade stack — target for descriptor query updates. */\n bladeStack: IBladeStack;\n}\n\n/** Remove leading/trailing slashes: \"/offers/\" → \"offers\". */\nfunction normalizeSegment(url: string | undefined): string | undefined {\n if (!url) return undefined;\n return url.replace(/^\\/+|\\/+$/g, \"\") || undefined;\n}\n\n/**\n * Create a per-blade table-query-state service. Persists table view state into\n * the owning blade's descriptor query (namespaced), then replaces the URL.\n *\n * No-op when there is no namespace (no `tableKey` and no `blade.url`).\n */\nexport function createBladeQueryState(deps: CreateBladeQueryStateDeps): ITableQueryStateService {\n const { descriptor, router, bladeStack } = deps;\n const { syncUrlReplace } = createUrlSync(router, bladeStack);\n\n // Pending patches keyed by namespace (a blade may host multiple tables).\n // Coalesced across the debounce window so a multi-field change (e.g. a sort\n // that also resets the page) does not lose all but the last field.\n const pending = new Map<string, TableQueryPatch>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n function resolveNs(tableKey?: string): string | undefined {\n return tableKey || normalizeSegment(descriptor.value.url);\n }\n\n function read(tableKey?: string): TableQueryPatch {\n const ns = resolveNs(tableKey);\n if (!ns) return {};\n\n const decoded = decodeQueryState(ns, router.currentRoute.value.query);\n\n // Hydrate the descriptor so it matches the URL. On reload, restoreFromUrl\n // reopens blades WITHOUT their query, leaving descriptor.query empty while\n // the address bar still holds the params. If we don't seed it now, the next\n // syncUrlReplace (from any table write or blade open/close) would rebuild\n // the URL from the empty descriptor and wipe the restored state. No URL\n // replace is needed here — the address bar already holds these values.\n if (Object.keys(decoded).length > 0) {\n bladeStack.updateBladeQuery(descriptor.value.id, encodeQueryState(ns, decoded));\n }\n\n return decoded;\n }\n\n function write(tableKey: string | undefined, patch: TableQueryPatch): void {\n const ns = resolveNs(tableKey);\n if (!ns) return;\n\n pending.set(ns, { ...(pending.get(ns) ?? {}), ...patch });\n\n if (timer != null) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = undefined;\n const bladeId = descriptor.value.id;\n for (const [namespace, p] of pending) {\n bladeStack.updateBladeQuery(bladeId, encodeQueryState(namespace, p));\n }\n pending.clear();\n syncUrlReplace();\n }, DEBOUNCE_MS);\n }\n\n return { read, write };\n}\n","<template>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n :width=\"width\"\n :height=\"height\"\n >\n <path\n d=\"M6 11H11M1 6H11M1 1H11\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script setup lang=\"ts\">\ndefineProps<{\n width?: number | string;\n height?: number | string;\n}>();\n</script>\n","import type { Router } from \"vue-router\";\r\n\r\n/**\r\n * Navigate to the application's main (root) route.\r\n *\r\n * Resolves the route marked with `meta.root`, preferring its alias if one exists.\r\n * Uses `router.replace()` to avoid adding a history entry.\r\n */\r\nexport function navigateToMainRoute(router: Router, params?: Record<string, string>): void {\r\n const routes = router.getRoutes();\r\n const mainRoute = routes.find((r) => r.meta?.root);\r\n const mainRouteAlias = routes.find((r) => r.aliasOf?.path === mainRoute?.path) ?? mainRoute;\r\n\r\n if (mainRouteAlias?.name) {\r\n router.replace({ name: mainRouteAlias.name, params });\r\n }\r\n}\r\n","import { App, inject, shallowRef, computed, ComputedRef } from \"vue\";\nimport type { BladeInstanceConstructor } from \"@core/blade-navigation/types\";\nimport { createLogger } from \"@core/utilities\";\nimport { getBladeConfig } from \"@core/blade-navigation/bladeConfigRegistry\";\nimport { addMenuItem } from \"@core/composables/useMenuService\";\nimport type { MenuItem } from \"@core/types\";\n\nconst logger = createLogger(\"blade-registry\");\n\n/**\n * Interface for blade registration data\n */\nexport interface IBladeRegistrationData {\n component: BladeInstanceConstructor;\n route?: string;\n isWorkspace?: boolean;\n routable?: boolean;\n permissions?: string | string[];\n}\n\n/**\n * Injection key for provide/inject pattern\n */\nexport const BladeRegistryKey = Symbol(\"BladeRegistry\");\n\n/**\n * Public interface for blade registry\n */\nexport interface UseBladeRegistryReturn {\n /** Readonly map of all registered blades */\n readonly registeredBladesMap: ComputedRef<ReadonlyMap<string, IBladeRegistrationData>>;\n /** Get blade registration data by name */\n getBlade: (name: string) => IBladeRegistrationData | undefined;\n /** Get blade component by name */\n getBladeComponent: (name: string) => BladeInstanceConstructor | undefined;\n /** Reverse lookup: find blade name + data by URL route segment (O(1)) */\n getBladeByRoute: (route: string) => { name: string; data: IBladeRegistrationData } | undefined;\n}\n\n/** @deprecated Use UseBladeRegistryReturn instead */\nexport type IBladeRegistry = UseBladeRegistryReturn;\n\n/**\n * Extended interface for blade registry instance with internal registration function\n */\nexport interface IBladeRegistryInstance extends UseBladeRegistryReturn {\n _registerBladeFn: (name: string, registrationData: IBladeRegistrationData, allowOverwrite?: boolean) => void;\n}\n\n/**\n * Validates if a component is a valid blade component\n */\nfunction isValidBladeComponent(component: unknown): component is BladeInstanceConstructor {\n if (!component || (typeof component !== \"function\" && typeof component !== \"object\")) {\n return false;\n }\n\n // Additional validation for blade-specific properties could be added here\n // For now, we accept any function or object that could be a Vue component\n return true;\n}\n\n/**\n * Creates a blade registry instance\n * This function should be called once during application initialization\n *\n * @param app - Vue application instance\n * @returns Blade registry instance with registration capabilities\n */\nexport function createBladeRegistry(app: App): IBladeRegistryInstance {\n const registeredBladesInternal = shallowRef<Map<string, IBladeRegistrationData>>(new Map());\n\n // Reverse index: normalized route → blade name (rebuilt on every registration)\n const _routeIndex = new Map<string, string>();\n\n function _normalizeRoute(route: string): string {\n return route.startsWith(\"/\") ? route : `/${route}`;\n }\n\n /**\n * Registers a blade component in the registry\n *\n * @param name - Unique name for the blade\n * @param registrationData - Blade registration data including component and metadata\n */\n /**\n * Registers a blade component in the registry.\n *\n * @param name - Unique name for the blade\n * @param registrationData - Blade registration data including component and metadata\n * @param allowOverwrite - If true, allows overwriting an existing blade (default: false).\n * Use for dynamic module hot-reload scenarios only.\n * @throws Error if blade name is already registered and allowOverwrite is false\n */\n function registerBlade(name: string, registrationData: IBladeRegistrationData, allowOverwrite = false): void {\n if (!name || typeof name !== \"string\") {\n throw new Error(\"BladeRegistry: Blade name must be a non-empty string\");\n }\n\n if (!registrationData?.component) {\n throw new Error(`BladeRegistry: Registration data must include a component for blade '${name}'`);\n }\n\n if (!isValidBladeComponent(registrationData.component)) {\n throw new Error(`BladeRegistry: Invalid component provided for blade '${name}'`);\n }\n\n // ── Merge: blade config registry (defineBlade) > registrationData (legacy) ──\n const config = getBladeConfig(name);\n const component = registrationData.component;\n\n const route = config?.url ?? registrationData.route;\n const isWorkspace = config?.isWorkspace ?? registrationData.isWorkspace ?? false;\n const routable = config?.routable ?? registrationData.routable !== false;\n const permissions = config?.permissions ?? registrationData.permissions;\n const menuItem = config?.menuItem ?? component.menuItem;\n\n // ── Duplicate check ──\n const newMap = new Map(registeredBladesInternal.value);\n\n if (newMap.has(name)) {\n if (!allowOverwrite) {\n throw new Error(\n `BladeRegistry: Blade '${name}' is already registered. ` +\n `Use allowOverwrite=true if intentional (e.g. dynamic module hot-reload).`,\n );\n }\n logger.warn(`Blade '${name}' is already registered. Overwriting (allowOverwrite=true).`);\n }\n\n // Register component globally\n const existingGlobalComponent = app.component(name);\n if (!existingGlobalComponent || existingGlobalComponent !== component) {\n if (existingGlobalComponent && existingGlobalComponent !== component) {\n logger.warn(\n `Global component '${name}' already exists and is different. Overwriting with new blade component.`,\n );\n }\n app.component(name, component);\n }\n\n // Store merged registration data\n const mergedData: IBladeRegistrationData = {\n component,\n route,\n isWorkspace,\n routable,\n permissions,\n };\n\n newMap.set(name, mergedData);\n registeredBladesInternal.value = newMap;\n\n // Maintain reverse route index\n if (route) {\n _routeIndex.set(_normalizeRoute(route), name);\n }\n\n // ── Menu registration (moved from defineAppModule) ──\n if (route && menuItem) {\n addMenuItem({\n ...menuItem,\n url: route,\n routeId: name,\n permissions: permissions || menuItem.permissions,\n } as MenuItem);\n }\n }\n\n /**\n * Gets blade registration data by name\n *\n * @param name - Blade name\n * @returns Registration data or undefined if not found\n */\n function getBlade(name: string): IBladeRegistrationData | undefined {\n if (!name || typeof name !== \"string\") {\n return undefined;\n }\n return registeredBladesInternal.value.get(name);\n }\n\n /**\n * Gets blade component by name\n * Checks registry first, then falls back to global components\n *\n * @param name - Blade name\n * @returns Blade component or undefined if not found\n */\n function getBladeComponent(name: string): BladeInstanceConstructor | undefined {\n if (!name || typeof name !== \"string\") {\n return undefined;\n }\n\n // First check registry\n const registration = registeredBladesInternal.value.get(name);\n if (registration) {\n return registration.component;\n }\n\n // Fallback to global components\n try {\n const globalComponent = app._context.components[name] as BladeInstanceConstructor | undefined;\n if (globalComponent && isValidBladeComponent(globalComponent)) {\n return globalComponent;\n }\n } catch (error) {\n logger.warn(`Error accessing global component '${name}':`, error);\n }\n\n return undefined;\n }\n\n /**\n * Reverse lookup: find a blade by its URL route segment.\n * Uses O(1) index maintained during registration.\n *\n * @param route - URL segment (e.g. \"orders\" or \"/orders\")\n * @returns Blade name and registration data, or undefined if not found\n */\n function getBladeByRoute(route: string): { name: string; data: IBladeRegistrationData } | undefined {\n if (!route) return undefined;\n const normalized = _normalizeRoute(route);\n const name = _routeIndex.get(normalized);\n if (!name) return undefined;\n const data = registeredBladesInternal.value.get(name);\n if (!data) return undefined;\n return { name, data };\n }\n\n // Cache the readonly map — computed is inherently read-only\n const readonlyBladesMap = computed<ReadonlyMap<string, IBladeRegistrationData>>(() => registeredBladesInternal.value);\n\n const registryApi: UseBladeRegistryReturn = {\n registeredBladesMap: readonlyBladesMap,\n getBlade,\n getBladeComponent,\n getBladeByRoute,\n };\n\n return {\n ...registryApi,\n _registerBladeFn: registerBlade,\n };\n}\n\n/**\n * Composable function for accessing blade registry\n * Must be used after createBladeRegistry is called and provided with BladeRegistryKey\n *\n * @returns Blade registry interface\n * @throws Error if registry is not available\n */\nexport function useBladeRegistry(): UseBladeRegistryReturn {\n const registry = inject<UseBladeRegistryReturn>(BladeRegistryKey);\n if (!registry) {\n throw new Error(\n \"useBladeRegistry must be used after createBladeRegistry is called and provided with BladeRegistryKey.\",\n );\n }\n return registry;\n}\n","import { VNode } from \"vue\";\nimport _Interceptor from \"@shell/components/error-interceptor/interceptor\";\nimport { DisplayableError } from \"@core/utilities/error\";\n\nexport const ErrorInterceptor = _Interceptor as typeof _Interceptor & {\n new (): {\n $slots: {\n default: (args: { error: DisplayableError | null; reset: () => void }) => VNode[];\n };\n };\n};\n","<template>\n <ErrorInterceptor :capture=\"true\">\n <!-- eslint-disable-next-line vue/no-unused-vars -- error available for future use -->\n <template #default=\"{ error, reset: resetInterceptor }\">\n <component\n :is=\"bladeComponent\"\n v-if=\"bladeComponent\"\n v-show=\"visible\"\n ref=\"bladeInstanceRef\"\n :param=\"descriptor.param\"\n :options=\"descriptor.options\"\n :closable=\"closable\"\n :expanded=\"expanded\"\n @close:blade=\"onCloseBlade\"\n @parent:call=\"onParentCall\"\n @expand:blade=\"onExpand\"\n @collapse:blade=\"onCollapse\"\n @vue:unmounted=\"resetInterceptor\"\n />\n </template>\n </ErrorInterceptor>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, onBeforeUnmount, provide, ref, watch } from \"vue\";\nimport { useRouter } from \"vue-router\";\nimport { useBladeRegistry } from \"@core/composables/useBladeRegistry\";\nimport { useBladeStack } from \"@core/blade-navigation/useBladeStack\";\nimport { createBladeQueryState, TableQueryStateKey } from \"@core/blade-navigation/table-query-state\";\nimport { BladeBackButtonKey } from \"@framework/injection-keys\";\nimport { ErrorInterceptor } from \"@shell/components/error-interceptor\";\nimport { useBladeMessaging } from \"@core/blade-navigation/useBladeMessaging\";\nimport type { BladeDescriptor, IParentCallArgs, IBladeBanner, CoreBladeExposed } from \"@core/blade-navigation/types\";\nimport {\n BladeDescriptorKey,\n BladeMaximizedKey,\n BladeBannersKey,\n BladeRenderingStateKey,\n} from \"@core/blade-navigation/types\";\nimport type { Breadcrumbs } from \"@ui/types\";\nimport type { Component } from \"vue\";\n\nconst props = defineProps<{\n descriptor: BladeDescriptor;\n closable: boolean;\n expanded: boolean;\n visible: boolean;\n breadcrumbs?: Breadcrumbs[];\n backButton?: Component;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\", bladeId: string): void;\n (e: \"parentCall\", args: IParentCallArgs, bladeId: string): void;\n}>();\n\nconst bladeRegistry = useBladeRegistry();\nconst maximized = ref(false);\nconst banners = ref<IBladeBanner[]>([]);\nconst bladeInstanceRef = ref<CoreBladeExposed>();\n\n// Resolve blade component from registry\nconst bladeComponent = computed(() => {\n return bladeRegistry.getBladeComponent(props.descriptor.name);\n});\n\n// ── Provide immutable BladeDescriptor (plain stack data, never enriched) ──────\nprovide(\n BladeDescriptorKey,\n computed(() => props.descriptor),\n);\n\n// ── Provide per-blade rendering state (view concerns, not stack data) ─────────\n// maximized/breadcrumbs used to be spread onto the descriptor; they now live\n// here so the descriptor stays a pure data object.\nprovide(\n BladeRenderingStateKey,\n computed(() => ({\n maximized: maximized.value,\n breadcrumbs: props.breadcrumbs,\n })),\n);\n\n// Provide writable maximized ref so VcBlade can toggle expand/collapse directly\nprovide(BladeMaximizedKey, maximized);\nprovide(BladeBannersKey, banners);\n\n// Provide back button component\nprovide(\n BladeBackButtonKey,\n computed(() => props.backButton),\n);\n\n// ── Provide per-blade table-query-state service (URL persistence) ─────────────\n// Only meaningful for URL-addressable blades; createBladeQueryState no-ops when\n// the blade has no url. If there is no router context, provide undefined so\n// VcDataTable falls back to no persistence.\nconst router = useRouter();\nprovide(\n TableQueryStateKey,\n router\n ? createBladeQueryState({\n descriptor: computed(() => props.descriptor),\n router,\n bladeStack: useBladeStack(),\n })\n : undefined,\n);\n\n// ── Auto-register exposed methods with BladeMessaging ───────────────────────\n// Bridges defineExpose() (old API) → exposeToChildren() (new BladeMessaging)\nconst messaging = useBladeMessaging();\n\nwatch(\n bladeInstanceRef,\n (instance) => {\n if (!instance) return;\n const methods: Record<string, (...args: any[]) => any> = {};\n for (const key of Object.keys(instance)) {\n if (typeof instance[key] === \"function\") {\n methods[key] = instance[key];\n }\n }\n if (Object.keys(methods).length > 0) {\n messaging.exposeToChildren(props.descriptor.id, methods);\n }\n },\n { flush: \"post\" },\n);\n\n// Clean up exposed methods when blade is removed from the stack.\n// Hidden blades (v-show via replaceCurrentBlade) stay mounted — their methods persist.\n// Only truly removed blades (v-for key removed) trigger onBeforeUnmount.\nonBeforeUnmount(() => {\n messaging.cleanup(props.descriptor.id);\n});\n\n// ── Event handlers ──────────────────────────────────────────────────────────\n\nfunction onCloseBlade(): void {\n emit(\"close\", props.descriptor.id);\n}\n\nfunction onParentCall(args: IParentCallArgs): void {\n emit(\"parentCall\", args, props.descriptor.id);\n}\n\nfunction onExpand(): void {\n maximized.value = true;\n}\n\nfunction onCollapse(): void {\n maximized.value = false;\n}\n</script>\n","<template>\r\n <div\r\n :class=\"groupClass\"\r\n role=\"group\"\r\n >\r\n <slot />\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { computed, provide, toRef } from \"vue\";\r\nimport { ButtonGroupKey, type ButtonSize } from \"@ui/components/atoms/vc-button/types\";\r\n\r\nexport interface Props {\r\n orientation?: \"horizontal\" | \"vertical\";\r\n size?: ButtonSize;\r\n attached?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n orientation: \"horizontal\",\r\n attached: false,\r\n});\r\n\r\nprovide(ButtonGroupKey, {\r\n size: toRef(props, \"size\") as { value: ButtonSize | undefined },\r\n attached: toRef(props, \"attached\"),\r\n});\r\n\r\nconst groupClass = computed(() => [\r\n \"vc-button-group\",\r\n {\r\n \"vc-button-group--horizontal\": props.orientation === \"horizontal\",\r\n \"vc-button-group--vertical\": props.orientation === \"vertical\",\r\n \"vc-button-group--attached\": props.attached,\r\n },\r\n]);\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n.vc-button-group {\r\n @apply tw-inline-flex tw-gap-2;\r\n\r\n &--vertical {\r\n @apply tw-flex-col;\r\n }\r\n\r\n // Attached mode — buttons touch, shared borders, connected radii\r\n // Selectors use `> *` to handle both direct .vc-button children\r\n // and wrapped buttons (e.g. inside VcTooltip or other wrappers).\r\n &--attached {\r\n @apply tw-gap-0;\r\n\r\n // Horizontal attached\r\n &.vc-button-group--horizontal {\r\n // All buttons inside lose rounding\r\n .vc-button {\r\n @apply tw-rounded-none;\r\n }\r\n\r\n // First slot: left rounding\r\n > *:first-child .vc-button,\r\n > .vc-button:first-child {\r\n @apply tw-rounded-l-[var(--button-border-radius)];\r\n }\r\n\r\n // Last slot: right rounding\r\n > *:last-child .vc-button,\r\n > .vc-button:last-child {\r\n @apply tw-rounded-r-[var(--button-border-radius)];\r\n }\r\n\r\n // Avoid double borders — negative margin on the flex child (wrapper or direct button)\r\n > *:not(:first-child) {\r\n @apply tw--ml-px;\r\n }\r\n }\r\n\r\n // Vertical attached\r\n &.vc-button-group--vertical {\r\n .vc-button {\r\n @apply tw-rounded-none;\r\n }\r\n\r\n > *:first-child .vc-button,\r\n > .vc-button:first-child {\r\n @apply tw-rounded-t-[var(--button-border-radius)];\r\n }\r\n\r\n > *:last-child .vc-button,\r\n > .vc-button:last-child {\r\n @apply tw-rounded-b-[var(--button-border-radius)];\r\n }\r\n\r\n > *:not(:first-child) {\r\n @apply tw--mt-px;\r\n }\r\n }\r\n }\r\n}\r\n</style>\r\n","<template>\n <span\n v-if=\"current\"\n class=\"vc-breadcrumbs-item vc-breadcrumbs-item--current\"\n :class=\"{ 'vc-breadcrumbs-item--light': variant === 'light' }\"\n aria-current=\"page\"\n >\n <VcIcon\n v-if=\"icon\"\n class=\"vc-breadcrumbs-item__icon\"\n :icon=\"icon\"\n size=\"s\"\n />\n <span\n class=\"vc-breadcrumbs-item__title\"\n :title=\"resolvedTitle\"\n >{{ resolvedTitle }}</span\n >\n </span>\n <button\n v-else\n type=\"button\"\n class=\"vc-breadcrumbs-item\"\n :class=\"{ 'vc-breadcrumbs-item--light': variant === 'light' }\"\n @click=\"onClick\"\n >\n <VcIcon\n v-if=\"icon\"\n class=\"vc-breadcrumbs-item__icon\"\n :icon=\"icon\"\n size=\"s\"\n />\n <span\n class=\"vc-breadcrumbs-item__title\"\n :title=\"resolvedTitle\"\n >{{ resolvedTitle }}</span\n >\n </button>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, toValue } from \"vue\";\nimport type { Breadcrumbs } from \"../../../../../types/index\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\nexport interface Props extends Breadcrumbs {\n current: boolean;\n variant?: \"default\" | \"light\";\n}\n\nexport interface Emits {\n (event: \"click\"): void;\n}\n\nconst props = defineProps<Props>();\nconst emit = defineEmits<Emits>();\n\nconst resolvedTitle = computed(() => toValue(props.title) ?? \"\");\n\nfunction onClick(): void {\n if (!props.current) {\n if (props.clickHandler && typeof props.clickHandler === \"function\") {\n props.clickHandler(props.id);\n } else {\n emit(\"click\");\n }\n }\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --breadcrumbs-item-text-color: var(--secondary-300);\n --breadcrumbs-item-text-color-hover: var(--neutrals-500);\n --breadcrumbs-item-color: var(--neutrals-400);\n --breadcrumbs-item-color-current: var(--primary-500);\n --breadcrumbs-item-icon-color: var(--secondary-300);\n}\n\n.vc-breadcrumbs-item {\n @apply tw-box-border tw-text-sm tw-cursor-pointer tw-inline-flex tw-items-center;\n @apply tw-h-[var(--breadcrumbs-item-height)] tw-whitespace-nowrap;\n @apply tw-text-[color:var(--breadcrumbs-item-color)] tw-leading-normal;\n @apply tw-transition-colors tw-duration-300;\n\n &--current {\n @apply tw-text-[color:var(--breadcrumbs-item-color-current)] tw-cursor-default tw-mr-0;\n }\n\n &--light {\n @apply tw-px-1;\n }\n\n &__icon {\n @apply tw-mr-2 tw-text-[color:var(--breadcrumbs-item-icon-color)];\n }\n\n &__title {\n @apply tw-max-w-[150px] tw-truncate tw-text-sm;\n }\n\n &--error {\n @apply tw-text-[color:var(--breadcrumbs-item-color-error)];\n }\n\n &:hover {\n @apply tw-text-[color:var(--breadcrumbs-item-text-color-hover)];\n }\n}\n\nbutton.vc-breadcrumbs-item {\n @apply tw-appearance-none tw-border-0 tw-bg-transparent tw-p-0 tw-cursor-pointer;\n font: inherit;\n color: inherit;\n}\n</style>\n","import { ref, computed, onMounted, onBeforeUnmount, nextTick, type Ref, watch, type ComputedRef } from \"vue\";\nimport { useElementSize, useDebounceFn } from \"@vueuse/core\";\n\nexport interface IUseAdaptiveItems<T> {\n visibleItems: Ref<T[]>;\n hiddenItems: Ref<T[]>;\n showMoreButton: ComputedRef<boolean>;\n recalculate: () => void;\n updateObserver: () => void;\n}\n\n/**\n * Measure the natural (unshrunk) width of an element.\n * Temporarily forces flex-shrink:0 so the browser reports the element's\n * preferred width rather than a compressed one.\n */\nfunction measureNaturalWidth(element: HTMLElement): number {\n const originalFlexShrink = element.style.flexShrink;\n element.style.flexShrink = \"0\";\n\n const styles = getComputedStyle(element);\n const width = element.offsetWidth + parseFloat(styles.marginLeft || \"0\") + parseFloat(styles.marginRight || \"0\");\n\n element.style.flexShrink = originalFlexShrink;\n return width;\n}\n\n/**\n * Read the CSS gap value from a flex/grid container.\n */\nfunction readContainerGap(container: HTMLElement): number {\n const styles = getComputedStyle(container);\n // `gap` is the shorthand; `columnGap` is more specific for row layouts\n const gap = styles.columnGap || styles.gap || \"0px\";\n return parseFloat(gap) || 0;\n}\n\nexport function useAdaptiveItems<T>(options: {\n containerRef: Ref<HTMLElement | null>;\n items: Ref<T[]>;\n getItemKey: (item: T) => string;\n /** Fallback width for the \"more\" button before it can be measured from DOM.\n * If the consumer marks its trigger element with `data-more-button`,\n * the composable will auto-measure the real width and use it instead. */\n moreButtonWidth: number;\n calculationStrategy?: \"forward\" | \"reverse\";\n initialItemWidth?: number;\n}): IUseAdaptiveItems<T> {\n const {\n containerRef,\n items,\n getItemKey,\n moreButtonWidth: moreButtonFallbackWidth,\n calculationStrategy = \"forward\",\n initialItemWidth = 50,\n } = options;\n\n // Container width tracking\n const { width: containerWidth } = useElementSize(containerRef);\n\n // Cache of natural element widths (key → px)\n const itemSizes = ref<Map<string, number>>(new Map());\n\n // Measured \"more\" button width (null = not yet measured, use fallback)\n const measuredMoreWidth = ref<number | null>(null);\n\n // Current CSS gap of the container\n const containerGap = ref(0);\n\n // Result arrays\n const visibleItems = ref([]) as Ref<T[]>;\n const hiddenItems = ref([]) as Ref<T[]>;\n const showMoreButton = computed(() => hiddenItems.value.length > 0);\n\n // Single persistent ResizeObserver\n let elementsObserver: ResizeObserver | null = null;\n // Track observed elements so we can unobserve stale ones\n const observedElements = new Set<Element>();\n\n /** Effective \"more\" button width: measured from DOM or fallback constant. */\n const getMoreButtonWidth = (): number => {\n return measuredMoreWidth.value ?? moreButtonFallbackWidth;\n };\n\n /**\n * Try to measure the \"more\" button from the DOM.\n * The consumer marks the trigger element with `data-more-button`.\n */\n const measureMoreButton = () => {\n if (!containerRef.value) return;\n const el = containerRef.value.querySelector(\"[data-more-button]\") as HTMLElement | null;\n if (el) {\n const width = measureNaturalWidth(el);\n if (width > 0) {\n measuredMoreWidth.value = width;\n }\n }\n };\n\n /**\n * Get element width by key.\n * Falls back to initialItemWidth if not yet measured.\n */\n const getItemWidth = (item: T): number => {\n const key = getItemKey(item);\n return itemSizes.value.get(key) || initialItemWidth;\n };\n\n /**\n * Distribute items into visible/hidden arrays for a given available width,\n * accounting for CSS gap between items.\n */\n const distributeItems = (itemsToCheck: T[], availableWidth: number) => {\n let currentWidth = 0;\n const visible: T[] = [];\n const hidden: T[] = [];\n const gap = containerGap.value;\n\n for (const item of itemsToCheck) {\n const itemWidth = getItemWidth(item);\n const gapBefore = visible.length > 0 ? gap : 0;\n\n if (currentWidth + gapBefore + itemWidth <= availableWidth) {\n visible.push(item);\n currentWidth += gapBefore + itemWidth;\n } else {\n hidden.push(item);\n }\n }\n\n return { visible, hidden };\n };\n\n /**\n * Calculate which elements will be visible and which will be hidden.\n *\n * Uses a two-pass approach:\n * 1st pass: calculate assuming no \"more\" button\n * 2nd pass (if overflow): recalculate with \"more\" button width reserved\n */\n const calculateVisibleItems = () => {\n if (!containerRef.value || !items.value.length) return;\n\n // When container has no width yet, show all items so the container gains\n // intrinsic size. ResizeObserver will trigger a recalculation once it does.\n if (containerWidth.value <= 0) {\n visibleItems.value = [...items.value];\n hiddenItems.value = [];\n return;\n }\n\n // Always read fresh gap (may change with responsive breakpoints)\n containerGap.value = readContainerGap(containerRef.value);\n const gap = containerGap.value;\n const itemsToCheck = calculationStrategy === \"reverse\" ? [...items.value].reverse() : items.value;\n\n // 1st pass: full container width (no \"more\" button)\n let result = distributeItems(itemsToCheck, containerWidth.value);\n\n // 2nd pass: if items overflowed, recalculate with \"more\" button space reserved\n // Also account for the gap before/after the \"more\" button\n if (result.hidden.length > 0) {\n const effectiveMoreWidth = getMoreButtonWidth();\n const gapBeforeMore = result.visible.length > 0 ? gap : 0;\n result = distributeItems(itemsToCheck, containerWidth.value - effectiveMoreWidth - gapBeforeMore);\n }\n\n // Restore original order for reverse strategy\n if (calculationStrategy === \"reverse\") {\n visibleItems.value = result.visible.reverse();\n hiddenItems.value = result.hidden.reverse();\n } else {\n visibleItems.value = result.visible;\n hiddenItems.value = result.hidden;\n }\n };\n\n /**\n * Measure natural widths of all rendered items and update the cache.\n * Also measures the \"more\" button if it's in the DOM.\n */\n const measureElementSizes = () => {\n if (!containerRef.value) return;\n\n // Update container gap\n containerGap.value = readContainerGap(containerRef.value);\n\n // Measure the \"more\" button if present\n measureMoreButton();\n\n const elements = containerRef.value.querySelectorAll(\"[data-item-key]\");\n\n elements.forEach((element) => {\n const key = element.getAttribute(\"data-item-key\");\n if (key) {\n const width = measureNaturalWidth(element as HTMLElement);\n if (width > 0) {\n itemSizes.value.set(key, width);\n }\n }\n });\n\n calculateVisibleItems();\n };\n\n /**\n * Remove stale entries from the size cache when items are removed.\n */\n const cleanupSizeCache = () => {\n const currentKeys = new Set(items.value.map(getItemKey));\n for (const key of itemSizes.value.keys()) {\n if (!currentKeys.has(key)) {\n itemSizes.value.delete(key);\n }\n }\n };\n\n /**\n * Setup ResizeObserver: observe current elements, unobserve removed ones.\n * Uses a single persistent observer instance.\n */\n const setupElementsObserver = () => {\n // Create observer lazily on first call\n if (!elementsObserver) {\n elementsObserver = new ResizeObserver((entries) => {\n // Avoid DOM mutations inside ResizeObserver callback to prevent re-entry loops.\n // Visible items should already be at natural width after calculateVisibleItems,\n // so reading offsetWidth directly is safe here.\n let hasChanges = false;\n\n for (const entry of entries) {\n const element = entry.target as HTMLElement;\n if (!element.isConnected) continue;\n\n const key = element.getAttribute(\"data-item-key\");\n if (!key) continue;\n\n // Use borderBoxSize from the entry when available (avoids forced reflow),\n // otherwise fall back to offsetWidth + margins.\n const styles = getComputedStyle(element);\n const borderBoxWidth = entry.borderBoxSize?.[0]?.inlineSize;\n const baseWidth = borderBoxWidth != null ? borderBoxWidth : element.offsetWidth;\n const width = baseWidth + parseFloat(styles.marginLeft || \"0\") + parseFloat(styles.marginRight || \"0\");\n\n if (width > 0 && itemSizes.value.get(key) !== width) {\n itemSizes.value.set(key, width);\n hasChanges = true;\n }\n }\n\n if (hasChanges) {\n calculateVisibleItems();\n }\n });\n }\n\n nextTick(() => {\n if (!containerRef.value) return;\n\n const elements = containerRef.value.querySelectorAll(\"[data-item-key]\");\n const newElements = new Set<Element>();\n\n // Observe new elements\n elements.forEach((element) => {\n newElements.add(element);\n if (!observedElements.has(element)) {\n elementsObserver?.observe(element);\n observedElements.add(element);\n }\n });\n\n // Unobserve removed elements\n for (const element of observedElements) {\n if (!newElements.has(element)) {\n elementsObserver?.unobserve(element);\n observedElements.delete(element);\n }\n }\n\n // Measure all current elements\n measureElementSizes();\n });\n };\n\n // Debounced recalculation for container width changes (avoid per-pixel recalcs during animation)\n const debouncedCalculate = useDebounceFn(() => {\n // Re-read gap in case container layout changed\n if (containerRef.value) {\n containerGap.value = readContainerGap(containerRef.value);\n }\n calculateVisibleItems();\n }, 50);\n\n // Recalculate when container width changes\n watch(containerWidth, () => {\n debouncedCalculate();\n });\n\n // When \"more\" button appears/disappears, measure it on the next tick\n watch(showMoreButton, (visible) => {\n if (visible) {\n nextTick(() => {\n const prevWidth = measuredMoreWidth.value;\n measureMoreButton();\n // If measured width differs from what we used, recalculate\n if (measuredMoreWidth.value !== null && measuredMoreWidth.value !== prevWidth) {\n calculateVisibleItems();\n }\n });\n }\n });\n\n // Shallow watch: react to item count / identity changes, not deep property changes\n watch(\n () => items.value.map(getItemKey).join(\"\\0\"),\n () => {\n cleanupSizeCache();\n nextTick(() => {\n setupElementsObserver();\n });\n },\n );\n\n // Initialize when mounted\n onMounted(() => {\n nextTick(() => {\n measureElementSizes();\n setupElementsObserver();\n });\n });\n\n // Cleanup resources when unmounted\n onBeforeUnmount(() => {\n if (elementsObserver) {\n elementsObserver.disconnect();\n elementsObserver = null;\n }\n observedElements.clear();\n });\n\n return {\n visibleItems,\n hiddenItems,\n showMoreButton,\n recalculate: () => {\n nextTick(() => {\n measureElementSizes();\n });\n },\n // Export function for updating observer\n updateObserver: setupElementsObserver,\n };\n}\n","import { ref, computed, type Ref, type CSSProperties } from \"vue\";\r\nimport { useResizeObserver } from \"@vueuse/core\";\r\n\r\nexport interface UseCollapsibleOptions {\r\n /** Height in px when collapsed. Default: 0 (fully hidden) */\r\n collapsedHeight?: number;\r\n /** Max height in px when expanded. Undefined = no limit */\r\n maxExpandedHeight?: number;\r\n /** Initial expanded state. Default: false */\r\n expanded?: boolean;\r\n}\r\n\r\nexport interface UseCollapsibleReturn {\r\n /** Template ref — attach to the inner content element */\r\n contentRef: Ref<HTMLElement | undefined>;\r\n /** Whether the panel is currently expanded */\r\n isExpanded: Ref<boolean>;\r\n /** True when content overflows the collapsed height (i.e. expand is meaningful) */\r\n hasOverflow: Readonly<Ref<boolean>>;\r\n /** True when expanded content exceeds maxExpandedHeight (needs scroll) */\r\n hasScroll: Readonly<Ref<boolean>>;\r\n /** Bind to the wrapper element's :style */\r\n wrapperStyle: Readonly<Ref<CSSProperties>>;\r\n /** Measured content height in px */\r\n contentHeight: Readonly<Ref<number>>;\r\n /** Toggle expanded state */\r\n toggle: () => void;\r\n}\r\n\r\nexport function useCollapsible(options: UseCollapsibleOptions = {}): UseCollapsibleReturn {\r\n const collapsedHeight = options.collapsedHeight ?? 0;\r\n const maxExpandedHeight = options.maxExpandedHeight;\r\n\r\n const contentRef = ref<HTMLElement>();\r\n const contentHeight = ref(0);\r\n const isExpanded = ref(options.expanded ?? false);\r\n\r\n const hasOverflow = computed(() => contentHeight.value > collapsedHeight);\r\n\r\n const hasScroll = computed(() => maxExpandedHeight !== undefined && contentHeight.value > maxExpandedHeight);\r\n\r\n const wrapperStyle = computed<CSSProperties>(() => {\r\n if (isExpanded.value) {\r\n if (maxExpandedHeight !== undefined && contentHeight.value > maxExpandedHeight) {\r\n return { maxHeight: `${maxExpandedHeight}px` };\r\n }\r\n return { maxHeight: `${contentHeight.value}px` };\r\n }\r\n return { maxHeight: collapsedHeight > 0 ? `${collapsedHeight}px` : \"0px\" };\r\n });\r\n\r\n function toggle() {\r\n isExpanded.value = !isExpanded.value;\r\n }\r\n\r\n useResizeObserver(contentRef, () => {\r\n if (contentRef.value) {\r\n contentHeight.value = contentRef.value.scrollHeight;\r\n }\r\n });\r\n\r\n return {\r\n contentRef,\r\n isExpanded,\r\n hasOverflow,\r\n hasScroll,\r\n wrapperStyle,\r\n contentHeight,\r\n toggle,\r\n };\r\n}\r\n","// framework/composables/useTableSort.ts\nimport { ref, computed, Ref, WritableComputedRef } from \"vue\";\nimport { createLogger } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-table-sort\");\n\nexport type ITableSortDirection = \"ASC\" | \"DESC\";\n\nexport interface TableSortState {\n property: string | null;\n direction: ITableSortDirection | null;\n}\n\nexport interface UseTableSortOptions {\n initialProperty?: string;\n initialDirection?: ITableSortDirection;\n}\n\nexport type SortParam = string;\n\nexport interface UseTableSortReturn {\n // State exposed as writable computed or refs for direct v-model or manipulation if needed\n // Though direct manipulation is less common, usually via handleSortChange\n currentSort: WritableComputedRef<TableSortState>;\n sortExpression: Ref<string | undefined>; // e.g., \"name:ASC\"\n handleSortChange: (sortParam: SortParam) => void;\n resetSort: () => void;\n}\n\nexport function useTableSort(options?: UseTableSortOptions): UseTableSortReturn {\n const currentSortProperty = ref<string | null>(options?.initialProperty || null);\n const currentSortDirection = ref<ITableSortDirection | null>(options?.initialDirection || null);\n\n const currentSort: WritableComputedRef<TableSortState> = computed({\n get: () => ({\n property: currentSortProperty.value,\n direction: currentSortDirection.value,\n }),\n set: (newState: TableSortState) => {\n currentSortProperty.value = newState.property;\n currentSortDirection.value = newState.direction;\n },\n });\n\n const sortExpression = computed<string | undefined>(() => {\n if (currentSortProperty.value && currentSortDirection.value) {\n return `${currentSortProperty.value}:${currentSortDirection.value}`;\n }\n return undefined;\n });\n\n const handleSortChange = (sortParam: SortParam) => {\n let newSortProperty: string | undefined = undefined;\n let newSortDirection: ITableSortDirection | undefined = undefined;\n\n const parts = sortParam.split(\":\");\n if (parts.length === 2) {\n newSortProperty = parts[0];\n const dir = parts[1].toUpperCase();\n if (dir === \"ASC\" || dir === \"DESC\") {\n newSortDirection = dir as ITableSortDirection;\n }\n } else {\n newSortProperty = sortParam; // Assume it's just the property name\n }\n\n if (newSortProperty) {\n if (currentSortProperty.value === newSortProperty) {\n // Clicked on the same column, toggle direction (3-state: ASC → DESC → none)\n if (newSortDirection) {\n // If table provided a new direction (e.g. explicit sort)\n currentSortDirection.value = newSortDirection;\n } else {\n // Toggle existing: ASC → DESC → clear\n if (currentSortDirection.value === \"ASC\") {\n currentSortDirection.value = \"DESC\";\n } else if (currentSortDirection.value === \"DESC\") {\n // Third click - clear sort\n currentSortProperty.value = null;\n currentSortDirection.value = null;\n } else {\n currentSortDirection.value = \"ASC\";\n }\n }\n } else {\n // Clicked on a new column\n currentSortProperty.value = newSortProperty;\n currentSortDirection.value = newSortDirection || \"ASC\"; // Default to ASC if no direction provided\n }\n } else {\n logger.warn(\"Could not determine valid sort property from sortParam:\", sortParam);\n }\n };\n\n const resetSort = () => {\n currentSortProperty.value = options?.initialProperty || null;\n currentSortDirection.value = options?.initialDirection || null;\n };\n\n return {\n currentSort,\n sortExpression,\n handleSortChange,\n resetSort,\n };\n}\n","import { ref, computed, Ref, ComputedRef } from \"vue\";\nimport { createLogger } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-table-selection\");\n\nexport interface UseTableSelectionOptions<T> {\n /**\n * The field to use for extracting IDs from items.\n * Can be a key of T or a function that extracts the ID.\n * @default 'id'\n */\n idField?: keyof T | ((item: T) => string | undefined);\n}\n\nexport interface UseTableSelectionReturn<T> {\n /**\n * Array of currently selected item objects.\n */\n selectedItems: Ref<T[]>;\n\n /**\n * Computed array of IDs extracted from selected items.\n */\n selectedIds: ComputedRef<string[]>;\n\n /**\n * Whether \"select all\" across pagination is active.\n */\n allSelected: Ref<boolean>;\n\n /**\n * Number of currently selected items.\n */\n selectionCount: ComputedRef<number>;\n\n /**\n * Whether any items are currently selected.\n */\n hasSelection: ComputedRef<boolean>;\n\n /**\n * Handler for VcTable's @selection-changed event.\n */\n handleSelectionChange: (items: T[]) => void;\n\n /**\n * Handler for VcTable's @select:all event.\n */\n handleSelectAll: (selected: boolean) => void;\n\n /**\n * Clears all selection state.\n */\n resetSelection: () => void;\n\n /**\n * Checks if a specific item is selected.\n */\n isSelected: (item: T) => boolean;\n\n /**\n * Programmatically select items.\n */\n selectItems: (items: T[]) => void;\n\n /**\n * Deselect items by their IDs.\n */\n deselectByIds: (ids: string[]) => void;\n}\n\nexport function useTableSelection<T extends object>(options?: UseTableSelectionOptions<T>): UseTableSelectionReturn<T> {\n const idField = options?.idField ?? (\"id\" as keyof T);\n\n const getItemId = (item: T): string | undefined => {\n if (typeof idField === \"function\") {\n return idField(item);\n }\n const value = item[idField as keyof T];\n return typeof value === \"string\" ? value : undefined;\n };\n\n const selectedItems = ref<T[]>([]) as Ref<T[]>;\n const allSelected = ref(false);\n\n const selectedIds = computed<string[]>(() => {\n return selectedItems.value.flatMap((item) => {\n const id = getItemId(item);\n return id ? [id] : [];\n });\n });\n\n const selectionCount = computed(() => selectedItems.value.length);\n const hasSelection = computed(() => selectedItems.value.length > 0);\n const selectedIdSet = computed(() => new Set(selectedIds.value));\n\n const handleSelectionChange = (items: T[]): void => {\n selectedItems.value = items;\n if (items.length === 0) {\n allSelected.value = false;\n }\n logger.debug(\"Selection changed\", { count: items.length });\n };\n\n const handleSelectAll = (selected: boolean): void => {\n allSelected.value = selected;\n if (!selected) {\n selectedItems.value = [];\n }\n logger.debug(\"Select all changed\", { selected });\n };\n\n const resetSelection = (): void => {\n selectedItems.value = [];\n allSelected.value = false;\n logger.debug(\"Selection reset\");\n };\n\n const isSelected = (item: T): boolean => {\n const id = getItemId(item);\n return id ? selectedIdSet.value.has(id) : false;\n };\n\n const selectItems = (items: T[]): void => {\n selectedItems.value = items;\n };\n\n const deselectByIds = (ids: string[]): void => {\n const idsToRemove = new Set(ids);\n selectedItems.value = selectedItems.value.filter((item) => {\n const id = getItemId(item);\n return id ? !idsToRemove.has(id) : true;\n });\n };\n\n return {\n selectedItems,\n selectedIds,\n allSelected,\n selectionCount,\n hasSelection,\n handleSelectionChange,\n handleSelectAll,\n resetSelection,\n isSelected,\n selectItems,\n deselectByIds,\n };\n}\n","import { ref, computed, watch, inject, type Ref, type ComputedRef } from \"vue\";\nimport { TableQueryStateKey } from \"@core/blade-navigation/table-query-state\";\n\nexport type DataTableSortDirection = \"ASC\" | \"DESC\";\nexport type DataTableSortOrder = 0 | 1 | -1;\n\nexport interface UseDataTableSortOptions {\n /** Column field to sort by initially */\n initialField?: string;\n /** Initial sort direction. Default: 'ASC' */\n initialDirection?: DataTableSortDirection;\n /** When set, syncs sort to the blade URL query under this key. */\n stateKey?: string;\n}\n\nexport interface UseDataTableSortReturn {\n /** Ref for v-model:sort-field on VcDataTable */\n sortField: Ref<string | undefined>;\n /**\n * Numeric ref for v-model:sort-order on VcDataTable.\n * 1 = ASC, -1 = DESC, 0 = none.\n */\n sortOrder: Ref<DataTableSortOrder>;\n /** String expression for API calls: \"field:ASC\" | \"field:DESC\" | undefined */\n sortExpression: ComputedRef<string | undefined>;\n /** Reset to initial values */\n resetSort: () => void;\n}\n\nfunction directionToOrder(dir?: DataTableSortDirection): DataTableSortOrder {\n if (dir === \"ASC\") return 1;\n if (dir === \"DESC\") return -1;\n return 0;\n}\n\nfunction orderToDirection(order: DataTableSortOrder): DataTableSortDirection | undefined {\n if (order === 1) return \"ASC\";\n if (order === -1) return \"DESC\";\n return undefined;\n}\n\nexport function useDataTableSort(options?: UseDataTableSortOptions): UseDataTableSortReturn {\n const initialField = options?.initialField;\n const initialOrder = directionToOrder(options?.initialDirection);\n\n const sortField = ref<string | undefined>(initialField);\n const sortOrder = ref<DataTableSortOrder>(initialOrder);\n\n const sortExpression = computed<string | undefined>(() => {\n const dir = orderToDirection(sortOrder.value);\n if (!sortField.value || !dir) return undefined;\n return `${sortField.value}:${dir}`;\n });\n\n if (options?.stateKey) {\n const service = inject(TableQueryStateKey, undefined);\n if (service) {\n const restored = service.read(options.stateKey);\n if (restored.sort) {\n const [field, dir] = restored.sort.split(\":\");\n if (field) {\n sortField.value = field;\n sortOrder.value = dir === \"DESC\" ? -1 : 1;\n }\n }\n // Registered after seeding, so the restored value is the baseline (no bounce-back write).\n watch(sortExpression, (value) => service.write(options.stateKey!, { sort: value }));\n }\n }\n\n const resetSort = () => {\n sortField.value = initialField;\n sortOrder.value = initialOrder;\n };\n\n return {\n sortField,\n sortOrder,\n sortExpression,\n resetSort,\n };\n}\n","import { ref, computed, reactive, watch, inject, type MaybeRefOrGetter, toValue } from \"vue\";\nimport { TableQueryStateKey } from \"@core/blade-navigation/table-query-state\";\n\nexport interface UseDataTablePaginationOptions {\n /** Items per page. Default: 20 */\n pageSize?: MaybeRefOrGetter<number>;\n /** Total item count from API response (reactive) */\n totalCount: MaybeRefOrGetter<number>;\n /** Event callback fired after currentPage updates via goToPage(). */\n onPageChange?: (state: { page: number; skip: number }) => void;\n /** When set, syncs the current page to the blade URL query under this key. */\n stateKey?: string;\n}\n\nexport interface UseDataTablePaginationReturn {\n /** Current 1-based page number (writable) */\n currentPage: number;\n /** Total number of pages */\n readonly pages: number;\n /** Current skip offset: (currentPage - 1) * pageSize */\n readonly skip: number;\n /** Resolved page size */\n readonly pageSize: number;\n /** Resolved total item count — pass to VcDataTable :total-count */\n readonly totalCount: number;\n /** Navigate to a specific page. Fires onPageChange if provided. */\n goToPage: (page: number) => void;\n /**\n * Set the current page without firing onPageChange. Use to seed the page from a\n * URL restore, so the seed itself does not trigger a load.\n */\n setPage: (page: number) => void;\n /** Reset to page 1. Does NOT fire onPageChange. */\n reset: () => void;\n}\n\nexport function useDataTablePagination(options: UseDataTablePaginationOptions): UseDataTablePaginationReturn {\n const pageSize = computed(() => toValue(options.pageSize) ?? 20);\n const currentPage = ref(1);\n const pages = computed(() => Math.ceil(toValue(options.totalCount) / pageSize.value) || 0);\n const skip = computed(() => (currentPage.value - 1) * pageSize.value);\n const totalCount = computed(() => toValue(options.totalCount));\n\n function goToPage(page: number) {\n currentPage.value = page;\n options.onPageChange?.({ page, skip: skip.value });\n }\n\n function setPage(page: number) {\n currentPage.value = page;\n }\n\n function reset() {\n currentPage.value = 1;\n }\n\n if (options.stateKey) {\n const service = inject(TableQueryStateKey, undefined);\n if (service) {\n const restored = service.read(options.stateKey);\n if (restored.page != null) setPage(restored.page); // seed without onPageChange\n // Page 1 is the default: clear the param rather than writing _page=1.\n watch(\n () => currentPage.value,\n (page) => service.write(options.stateKey!, { page: page === 1 ? undefined : page }),\n );\n }\n }\n\n return reactive({ currentPage, pages, skip, pageSize, totalCount, goToPage, setPage, reset });\n}\n","import { ref, watch, inject, type Ref } from \"vue\";\nimport { TableQueryStateKey } from \"@core/blade-navigation/table-query-state\";\n\nexport interface UseTableSearchOptions {\n /** When set, syncs the search keyword to the blade URL query under this key. */\n stateKey?: string;\n /** Initial keyword when nothing is restored from the URL. */\n initial?: string;\n}\n\nexport interface UseTableSearchReturn {\n /** Search keyword. Bind to `v-model:search-value` on VcDataTable. */\n searchValue: Ref<string | undefined>;\n}\n\n/**\n * Owns the list search keyword. With `stateKey`, restores it from the URL on\n * creation and writes it back on change (the query service debounces). Without\n * `stateKey`, it is a plain ref.\n */\nexport function useTableSearch(options?: UseTableSearchOptions): UseTableSearchReturn {\n const searchValue = ref<string | undefined>(options?.initial);\n\n const stateKey = options?.stateKey;\n if (stateKey) {\n const service = inject(TableQueryStateKey, undefined);\n if (service) {\n const restored = service.read(stateKey);\n if (restored.search !== undefined) searchValue.value = restored.search;\n watch(searchValue, (value) => service.write(stateKey, { search: value }));\n }\n }\n\n return { searchValue };\n}\n","<template>\n <div class=\"vc-dropdown\">\n <!--\n Passive container: the trigger control lives inside the slot (a real\n button that calls `toggle`). Making this wrapper a role=\"button\"/tabindex\n element on top of that produced nested interactive controls\n (WCAG 4.1.2 / nested-interactive) and a duplicate tab stop.\n ARIA state (aria-expanded/haspopup/controls) is exposed to the slot via\n `is-active` / `panel-id` so consumers can bind it on their own control.\n -->\n <div\n v-if=\"$slots.trigger\"\n ref=\"referenceEl\"\n class=\"vc-dropdown__trigger\"\n >\n <slot\n name=\"trigger\"\n :is-active=\"isOpen\"\n :toggle=\"toggle\"\n :open=\"open\"\n :close=\"close\"\n :panel-id=\"panelId\"\n />\n </div>\n\n <Teleport\n :to=\"teleportTarget\"\n defer\n :disabled=\"!shouldTeleport\"\n >\n <Transition\n name=\"vc-dropdown-transition\"\n appear\n >\n <div\n v-if=\"isOpen\"\n :id=\"panelId\"\n ref=\"floatingEl\"\n v-on-click-outside=\"outsideClickBinding\"\n class=\"vc-dropdown__dropdown\"\n :style=\"{\n maxHeight: normalizedMaxHeight,\n ...panelStyle,\n }\"\n :class=\"panelClasses\"\n :role=\"role\"\n :aria-label=\"ariaLabel\"\n :aria-activedescendant=\"activeDescendantId\"\n tabindex=\"0\"\n @keydown=\"onPanelKeydown\"\n >\n <div\n class=\"vc-dropdown__content\"\n :class=\"{ 'vc-dropdown__content--padded': padded }\"\n >\n <slot\n name=\"items-container\"\n :items=\"items\"\n :close=\"close\"\n >\n <div\n v-if=\"items.length\"\n class=\"vc-dropdown__items-container\"\n >\n <div\n v-for=\"(item, index) in items\"\n :id=\"itemId(index)\"\n :key=\"getItemKey(item, index)\"\n class=\"vc-dropdown__item\"\n :class=\"{\n 'vc-dropdown__item--padded': padded,\n 'vc-dropdown__item--mobile': isMobile,\n 'vc-dropdown__item--active': isItemActive?.(item),\n 'vc-dropdown__item--focused': focusedIndex === index,\n }\"\n :role=\"itemRole\"\n :aria-selected=\"role === 'listbox' ? !!isItemActive?.(item) : undefined\"\n @click=\"selectItem(item, index)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :click=\"() => selectItem(item, index)\"\n >\n {{ itemText?.(item) }}\n </slot>\n </div>\n </div>\n <div\n v-else\n class=\"vc-dropdown__empty\"\n >\n <slot name=\"empty\">\n {{ emptyText }}\n </slot>\n </div>\n </slot>\n </div>\n </div>\n </Transition>\n </Teleport>\n </div>\n</template>\n\n<script lang=\"ts\" setup generic=\"T\">\nimport { computed, getCurrentInstance, nextTick, onBeforeUnmount, ref, watch, type Ref } from \"vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport { useFloatingPosition, type FloatingOffset, useTeleportTarget } from \"@ui/composables\";\nimport type { Placement } from \"@floating-ui/vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\n\nexport type DropdownRole = \"menu\" | \"listbox\";\nexport type DropdownCloseReason = \"outside\" | \"escape\" | \"action\";\n\nexport interface VcDropdownProps<T> {\n modelValue?: boolean;\n items?: T[];\n emptyText?: string;\n itemText?: (item: T) => string;\n isItemActive?: (item: T) => boolean;\n itemKey?: (item: T, index: number) => string | number;\n floating?: boolean;\n teleport?: boolean;\n teleportTo?: string | HTMLElement;\n placement?: Placement;\n variant?: \"default\" | \"secondary\";\n offset?: FloatingOffset;\n maxHeight?: number | string;\n role?: DropdownRole;\n closeOnClickOutside?: boolean;\n closeOnEscape?: boolean;\n closeOnSelect?: boolean;\n autoFocusPanel?: boolean;\n zIndex?: number;\n /** When true (default), applies compact menu padding and rounded item backgrounds.\n * Set to false for rich content like notifications where items should span full width. */\n padded?: boolean;\n /** Accessible name for the dropdown panel (menu/listbox). Required for a named listbox. */\n ariaLabel?: string;\n}\n\nconst props = withDefaults(defineProps<VcDropdownProps<T>>(), {\n modelValue: false,\n items: () => [],\n emptyText: \"\",\n floating: false,\n placement: \"bottom\",\n variant: \"default\",\n maxHeight: 300,\n offset: () => ({\n mainAxis: 0,\n crossAxis: 0,\n }),\n role: \"menu\",\n closeOnClickOutside: true,\n closeOnEscape: true,\n closeOnSelect: false,\n autoFocusPanel: true,\n zIndex: 9300,\n padded: true,\n});\n\nconst emit = defineEmits<{\n (event: \"update:modelValue\", value: boolean): void;\n (event: \"item-click\", item: T): void;\n (event: \"open\"): void;\n (event: \"close\", reason: DropdownCloseReason): void;\n}>();\n\ndefineSlots<{\n item?: (args: { item: T; click: () => void }) => unknown;\n empty?: () => unknown;\n trigger?: (args: {\n isActive: boolean;\n toggle: () => void;\n open: () => void;\n close: () => void;\n panelId: string;\n }) => unknown;\n \"items-container\"?: (args: { items: T[]; close: () => void }) => unknown;\n}>();\n\nconst instance = getCurrentInstance();\nconst uid = instance?.uid ?? Math.round(Math.random() * 10_000);\nconst panelId = `vc-dropdown-${uid}`;\n\nconst { isMobile } = useResponsive();\n\nconst referenceEl = ref<HTMLElement | null>(null);\nconst floatingEl = ref<HTMLElement | null>(null);\nconst focusedIndex = ref(-1);\n\nconst { teleportTarget } = useTeleportTarget({\n to: computed(() => props.teleportTo),\n});\n\nconst shouldTeleport = computed(() => props.teleport ?? props.floating);\n\nconst isOpen = computed({\n get: () => props.modelValue,\n set: (value: boolean) => emit(\"update:modelValue\", value),\n});\n\nconst { x, y, resolvedPlacement, resolvedStrategy } = useFloatingPosition(referenceEl, floatingEl, {\n placement: computed(() => props.placement),\n strategy: computed(() => (props.floating ? \"fixed\" : \"absolute\")),\n offset: computed(() => props.offset),\n autoUpdate: computed(() => props.floating),\n});\n\nconst panelClasses = computed(() => [\n {\n \"vc-dropdown__dropdown--mobile\": isMobile.value,\n \"vc-dropdown__dropdown--floating\": props.floating,\n },\n `vc-dropdown__dropdown--${props.variant}`,\n `vc-dropdown__dropdown--${resolvedPlacement.value}`,\n]);\n\nconst panelStyle = computed(() => {\n if (!props.floating) {\n return {};\n }\n\n return {\n position: resolvedStrategy.value as \"fixed\" | \"absolute\",\n top: `${y.value ?? 0}px`,\n left: `${x.value ?? 0}px`,\n zIndex: props.zIndex,\n width: \"max-content\",\n };\n});\n\nconst normalizedMaxHeight = computed(() => {\n if (!props.maxHeight) {\n return \"\";\n }\n\n return typeof props.maxHeight === \"number\" ? `${props.maxHeight}px` : props.maxHeight;\n});\n\nconst itemRole = computed(() => (props.role === \"listbox\" ? \"option\" : \"menuitem\"));\n\nconst activeDescendantId = computed(() => {\n if (focusedIndex.value < 0 || focusedIndex.value >= props.items.length) {\n return undefined;\n }\n\n return itemId(focusedIndex.value);\n});\n\nconst outsideClickBinding: [() => void, { ignore: Array<Ref<HTMLElement | null>> }] = [\n () => {\n if (props.closeOnClickOutside) {\n closeByReason(\"outside\");\n }\n },\n { ignore: [referenceEl] },\n];\n\nfunction syncFocusedIndex() {\n if (!props.items.length) {\n focusedIndex.value = -1;\n return;\n }\n\n const activeIndex = props.isItemActive ? props.items.findIndex((item) => props.isItemActive?.(item)) : -1;\n focusedIndex.value = activeIndex >= 0 ? activeIndex : 0;\n}\n\nfunction itemId(index: number) {\n return `${panelId}-item-${index}`;\n}\n\nfunction getItemKey(item: T, index: number) {\n return props.itemKey ? props.itemKey(item, index) : index;\n}\n\nfunction open() {\n if (isOpen.value) {\n return;\n }\n\n isOpen.value = true;\n emit(\"open\");\n}\n\nfunction close() {\n closeByReason(\"action\");\n}\n\nfunction closeByReason(reason: DropdownCloseReason) {\n if (!isOpen.value) {\n return;\n }\n\n isOpen.value = false;\n emit(\"close\", reason);\n}\n\nfunction toggle() {\n if (isOpen.value) {\n closeByReason(\"action\");\n } else {\n open();\n }\n}\n\nfunction selectItem(item: T, index: number) {\n focusedIndex.value = index;\n emit(\"item-click\", item);\n\n if (props.closeOnSelect) {\n closeByReason(\"action\");\n }\n}\n\nfunction moveFocus(nextIndex: number) {\n const total = props.items.length;\n\n if (!total) {\n focusedIndex.value = -1;\n return;\n }\n\n const normalizedIndex = ((nextIndex % total) + total) % total;\n focusedIndex.value = normalizedIndex;\n}\n\nfunction onPanelKeydown(event: KeyboardEvent) {\n if (!isOpen.value) {\n return;\n }\n\n switch (event.key) {\n case \"ArrowDown\": {\n event.preventDefault();\n moveFocus(focusedIndex.value + 1);\n break;\n }\n case \"ArrowUp\": {\n event.preventDefault();\n moveFocus(focusedIndex.value - 1);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n moveFocus(0);\n break;\n }\n case \"End\": {\n event.preventDefault();\n moveFocus(props.items.length - 1);\n break;\n }\n case \"Enter\":\n case \" \": {\n if (focusedIndex.value < 0 || focusedIndex.value >= props.items.length) {\n return;\n }\n\n event.preventDefault();\n selectItem(props.items[focusedIndex.value], focusedIndex.value);\n break;\n }\n case \"Escape\": {\n if (!props.closeOnEscape) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n closeByReason(\"escape\");\n break;\n }\n default:\n break;\n }\n}\n\nfunction onDocumentEscapeKeydown(event: KeyboardEvent) {\n if (!props.closeOnEscape || !isOpen.value || event.key !== \"Escape\") {\n return;\n }\n\n closeByReason(\"escape\");\n}\n\nwatch(\n () => isOpen.value,\n async (opened) => {\n // Always remove first to prevent accumulation\n document.removeEventListener(\"keydown\", onDocumentEscapeKeydown);\n\n if (opened) {\n syncFocusedIndex();\n\n if (props.closeOnEscape) {\n document.addEventListener(\"keydown\", onDocumentEscapeKeydown);\n }\n\n if (props.autoFocusPanel) {\n await nextTick();\n floatingEl.value?.focus();\n }\n }\n },\n { immediate: true },\n);\n\nwatch(\n () => props.items,\n () => {\n if (isOpen.value) {\n syncFocusedIndex();\n }\n },\n { deep: true },\n);\n\nonBeforeUnmount(() => {\n document.removeEventListener(\"keydown\", onDocumentEscapeKeydown);\n});\n</script>\n\n<style lang=\"scss\">\n/* ── Transition ────────────────────────────────── */\n.vc-dropdown-transition-enter-active {\n transition:\n opacity 0.18s cubic-bezier(0.16, 1, 0.3, 1),\n transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.vc-dropdown-transition-leave-active {\n transition:\n opacity 0.12s ease-in,\n transform 0.12s ease-in;\n}\n\n.vc-dropdown-transition-enter-from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n}\n\n.vc-dropdown-transition-leave-to {\n opacity: 0;\n transform: translateY(-2px) scale(0.99);\n}\n\n/* ── Placement-aware origins ──────────────────── */\n.vc-dropdown__dropdown--top,\n.vc-dropdown__dropdown--top-start,\n.vc-dropdown__dropdown--top-end {\n &.vc-dropdown-transition-enter-from {\n transform: translateY(4px) scale(0.98);\n }\n\n &.vc-dropdown-transition-leave-to {\n transform: translateY(2px) scale(0.99);\n }\n}\n\n/* ── Component ─────────────────────────────────── */\n.vc-dropdown {\n --vc-dropdown-bg: var(--additional-50);\n --vc-dropdown-text: var(--neutrals-950);\n --vc-dropdown-border: var(--neutrals-200);\n --vc-dropdown-accent: var(--neutrals-100);\n --vc-dropdown-accent-foreground: var(--neutrals-900);\n --vc-dropdown-divider: var(--neutrals-200);\n --vc-dropdown-trigger-focus-ring-width: 2px;\n --vc-dropdown-trigger-focus-ring-offset: 1px;\n --vc-dropdown-trigger-focus-ring-color: var(--primary-300);\n\n @apply tw-relative tw-flex tw-w-full tw-h-full;\n\n &__trigger {\n @apply tw-flex tw-items-center tw-justify-center;\n\n &:focus-visible {\n @apply tw-outline-none\n tw-ring-[length:var(--vc-dropdown-trigger-focus-ring-width)]\n tw-ring-offset-[length:var(--vc-dropdown-trigger-focus-ring-offset)]\n tw-ring-[color:var(--vc-dropdown-trigger-focus-ring-color)];\n }\n }\n\n // ── Panel (= DropdownMenuContent) ──────\n &__dropdown {\n @apply tw-w-full tw-overflow-auto tw-flex tw-flex-col tw-relative;\n background-color: var(--vc-dropdown-bg);\n\n &:focus {\n outline: none;\n }\n\n &--mobile {\n @apply tw-w-full;\n display: flex !important;\n }\n\n // Floating panels\n &--floating {\n border: 1px solid var(--vc-dropdown-border);\n border-radius: 6px; // rounded-md\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n }\n }\n\n // ── Content wrapper ───────────────────────────\n &__content {\n @apply tw-w-full tw-h-full;\n\n // Compact menu mode\n &--padded {\n padding: 4px; // p-1\n }\n }\n\n &__items-container {\n @apply tw-overflow-y-auto;\n }\n\n // ── Item (= DropdownMenuItem) ──────────\n &__item {\n @apply tw-relative tw-flex tw-items-center tw-select-none tw-text-sm tw-w-full tw-cursor-default;\n color: var(--vc-dropdown-text);\n transition: background-color 0.1s ease;\n\n &:hover {\n background-color: var(--vc-dropdown-accent);\n color: var(--vc-dropdown-accent-foreground);\n }\n\n &--active,\n &--focused {\n background-color: var(--vc-dropdown-accent);\n color: var(--vc-dropdown-accent-foreground);\n }\n\n // Compact menu mode: rounded hover backgrounds + consistent padding\n &--padded {\n border-radius: 4px; // rounded-sm\n padding: 4px;\n }\n\n &--mobile:not(:last-of-type) {\n @apply tw-border-solid tw-border-b tw-border-b-[color:var(--vc-dropdown-divider)];\n border-radius: 0;\n }\n }\n\n &__empty {\n @apply tw-flex tw-justify-center tw-items-center tw-p-4 tw-text-sm;\n color: var(--neutrals-400);\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-dropdown-item\"\n :class=\"{\n 'vc-dropdown-item--active': active,\n 'vc-dropdown-item--disabled': disabled,\n }\"\n >\n <VcIcon\n v-if=\"active\"\n icon=\"lucide-check\"\n size=\"xs\"\n class=\"vc-dropdown-item__icon\"\n />\n <VcIcon\n v-else-if=\"icon\"\n :icon=\"icon\"\n size=\"xs\"\n class=\"vc-dropdown-item__icon\"\n />\n <span\n v-else\n class=\"vc-dropdown-item__icon-placeholder\"\n />\n <span class=\"vc-dropdown-item__title\">{{ title }}</span>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\nexport interface Props {\n /** Item label text */\n title: string;\n /** Optional leading Lucide icon name (e.g. \"lucide-globe\") */\n icon?: string;\n /** Show lucide-check indicator for active/selected state */\n active?: boolean;\n /** Visually disabled state */\n disabled?: boolean;\n}\n\nwithDefaults(defineProps<Props>(), {\n active: false,\n disabled: false,\n});\n</script>\n\n<style lang=\"scss\">\n.vc-dropdown-item {\n @apply tw-flex tw-items-center tw-gap-2 tw-w-full tw-px-2 tw-py-[6px] tw-rounded-md\n tw-text-xs tw-cursor-pointer tw-transition-colors tw-duration-150;\n\n &:hover {\n background: var(--neutrals-100);\n }\n\n &--active {\n @apply tw-font-medium;\n }\n\n &--disabled {\n @apply tw-opacity-50 tw-pointer-events-none;\n }\n\n &__icon {\n @apply tw-w-3.5 tw-shrink-0;\n }\n\n &__icon-placeholder {\n @apply tw-w-3.5 tw-shrink-0;\n }\n\n &__title {\n @apply tw-truncate;\n }\n}\n</style>\n","<template>\n <nav\n v-if=\"items && items.length\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_BREADCRUMBS.LABEL')\"\n class=\"vc-breadcrumbs\"\n >\n <ol\n ref=\"contentRef\"\n class=\"vc-breadcrumbs__content\"\n :class=\"{\n 'vc-breadcrumbs__content--separated': separated,\n }\"\n >\n <li\n v-if=\"showMoreButton\"\n class=\"vc-breadcrumbs__item-wrapper\"\n >\n <VcDropdown\n :items=\"hiddenItems\"\n :model-value=\"showBreadcrumbs\"\n floating\n variant=\"secondary\"\n placement=\"bottom-start\"\n :offset=\"{\n mainAxis: 10,\n }\"\n @item-click=\"onItemClick\"\n @update:model-value=\"showBreadcrumbs = $event\"\n >\n <template #trigger=\"{ isActive }\">\n <slot\n name=\"trigger\"\n :click=\"toggleBreadcrumbs\"\n :is-active=\"isActive\"\n >\n <VcButton\n text\n icon=\"lucide-ellipsis-vertical\"\n icon-size=\"xl\"\n data-more-button\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_BREADCRUMBS.SHOW_MORE')\"\n class=\"vc-breadcrumbs__expand-button\"\n :class=\"{\n 'vc-breadcrumbs__expand-button--active': isActive,\n }\"\n @click=\"toggleBreadcrumbs\"\n />\n </slot>\n </template>\n <template #item=\"{ item, click }\">\n <VcDropdownItem\n :title=\"typeof item.title === 'string' ? item.title : (item.title?.value ?? '')\"\n :icon=\"item.icon\"\n @click=\"click\"\n />\n </template>\n </VcDropdown>\n </li>\n\n <template\n v-for=\"(item, i) in visibleItems\"\n :key=\"item?.id ?? `breadcrumb-item-${i}`\"\n >\n <li\n v-if=\"item && item.title\"\n class=\"vc-breadcrumbs__item-wrapper\"\n :data-item-key=\"item.id\"\n >\n <span\n v-if=\"separated && i !== 0\"\n class=\"vc-breadcrumbs__item-separator\"\n aria-hidden=\"true\"\n >\n /\n </span>\n <VcBreadcrumbsItem\n class=\"vc-breadcrumbs__item\"\n v-bind=\"item\"\n :current=\"i === visibleItems.length - 1\"\n :aria-current=\"i === visibleItems.length - 1 ? 'page' : undefined\"\n :variant=\"variant\"\n />\n </li>\n </template>\n </ol>\n </nav>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed, toRef, VNode, nextTick } from \"vue\";\nimport type { Breadcrumbs } from \"../../../types/index\";\nimport VcBreadcrumbsItem from \"@ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue\";\nimport { VcDropdown } from \"@ui/components/molecules/vc-dropdown\";\nimport VcDropdownItem from \"@ui/components/molecules/vc-dropdown/_internal/VcDropdownItem.vue\";\nimport { useAdaptiveItems } from \"@ui/composables/useAdaptiveItems\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\n\nexport interface Props {\n items?: Breadcrumbs[];\n variant?: \"default\" | \"light\";\n separated?: boolean;\n /** When true, all items are placed in the dropdown behind the trigger. */\n collapsed?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n items: () => [],\n variant: \"default\",\n separated: false,\n collapsed: false,\n});\n\ndefineSlots<{\n trigger: (props: { click: () => void; isActive: boolean }) => VNode;\n}>();\n\n/** Width of the \"more\" button — the icon-only VcButton is ~36px */\nconst MORE_BUTTON_WIDTH = 36;\n/** Conservative estimate per breadcrumb item (icon + truncated text) */\nconst INITIAL_ITEM_WIDTH = 60;\n\nconst contentRef = ref<HTMLElement | null>(null);\nconst showBreadcrumbs = ref(false);\n\nconst adaptive = useAdaptiveItems({\n containerRef: contentRef,\n items: toRef(props, \"items\"),\n getItemKey: (item) => item.id!,\n moreButtonWidth: MORE_BUTTON_WIDTH,\n calculationStrategy: \"reverse\",\n initialItemWidth: INITIAL_ITEM_WIDTH,\n});\n\nconst visibleItems = computed(() => (props.collapsed ? [] : adaptive.visibleItems.value));\nconst hiddenItems = computed(() => (props.collapsed ? props.items : adaptive.hiddenItems.value));\nconst showMoreButton = computed(() => hiddenItems.value.length > 0);\nconst recalculate = adaptive.recalculate;\n\nfunction toggleBreadcrumbs() {\n showBreadcrumbs.value = !showBreadcrumbs.value;\n}\n\nfunction onItemClick(item: Breadcrumbs) {\n item.clickHandler?.(item.id);\n}\n\nnextTick(recalculate);\n</script>\n\n<style lang=\"scss\">\n:root {\n --separator-color: var(--neutrals-400);\n --breadcrumbs-item-border-color: var(--secondary-300);\n --breadcrumbs-item-border-color-hover: var(--secondary-400);\n --breadcrumbs-expand-button-color: var(--neutrals-500);\n --breadcrumbs-expand-button-color-hover: var(--neutrals-600);\n}\n\n.vc-breadcrumbs {\n @apply tw-flex tw-flex-grow tw-items-center tw-min-w-0 tw-overflow-hidden;\n\n &__content {\n @apply tw-flex tw-flex-grow tw-items-center tw-gap-2.5 tw-min-w-0 tw-list-none tw-m-0 tw-p-0;\n\n &--separated {\n @apply tw-gap-0;\n }\n }\n\n &__item-wrapper {\n @apply tw-flex tw-flex-row tw-items-center tw-justify-center tw-shrink-0;\n }\n\n &__item-separator {\n @apply tw-text-[color:var(--separator-color)] tw-mx-2.5;\n }\n\n &__expand-button {\n @apply tw-mr-1 tw-border-solid tw-rounded-[3px] tw-text-[color:var(--breadcrumbs-expand-button-color)] tw-cursor-pointer hover:tw-text-[color:var(--breadcrumbs-expand-button-color-hover)];\n }\n}\n</style>\n","<template>\n <VcBreadcrumbs\n v-on-click-outside=\"hideBreadcrumbs\"\n :items=\"breadcrumbs\"\n collapsed\n >\n <template #trigger=\"{ click }\">\n <OnLongPress\n as=\"button\"\n @trigger=\"click\"\n >\n <VcButton\n ref=\"buttonRef\"\n icon=\"lucide-arrow-left\"\n icon-class=\"tw-text-neutrals-500\"\n icon-size=\"l\"\n text\n @click=\"onClick\"\n @contextmenu.prevent\n />\n </OnLongPress>\n </template>\n </VcBreadcrumbs>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from \"vue\";\nimport { onLongPress } from \"@vueuse/core\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport VcBreadcrumbs from \"@ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue\";\nimport type { Breadcrumbs } from \"@ui/types\";\nimport { OnLongPress, vOnClickOutside } from \"@vueuse/components\";\n\nconst props = defineProps<{\n breadcrumbs: Breadcrumbs[];\n onBack: () => void;\n}>();\n\nconst buttonRef = ref<HTMLElement>();\nconst showBreadcrumbs = ref(false);\n\nconst onClick = () => {\n props.onBack();\n};\n\nonLongPress(\n buttonRef,\n () => {\n showBreadcrumbs.value = true;\n },\n { delay: 500 },\n);\n\nconst hideBreadcrumbs = () => {\n showBreadcrumbs.value = false;\n};\n</script>\n\n<style lang=\"scss\">\n.vc-mobile-back-button {\n position: relative;\n\n &__breadcrumbs {\n position: fixed;\n z-index: var(--z-overlay-back-button);\n background: var(--additional-50);\n border-radius: var(--blade-navigation-border-radius);\n box-shadow: var(--blade-navigation-shadow);\n padding: 0.5rem;\n\n &-button {\n &--active {\n background-color: var(--neutrals-100);\n }\n }\n }\n}\n</style>\n","import type { Breadcrumbs } from \"@core/types/breadcrumbs\";\nimport { ComputedRef, computed, shallowRef } from \"vue\";\nimport { createLogger } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-breadcrumbs\");\n\nexport interface UseBreadcrumbsReturn {\n breadcrumbs: ComputedRef<Breadcrumbs[]>;\n push: (breadcrumb: Breadcrumbs) => void;\n remove: (ids: string[]) => void;\n}\n\n/** @deprecated Use UseBreadcrumbsReturn instead */\nexport type IUseBreadcrumbs = UseBreadcrumbsReturn;\n\nexport function useBreadcrumbs(): UseBreadcrumbsReturn {\n const items = shallowRef<Breadcrumbs[]>([]);\n\n /**\n * Trim the trail: keep everything up to and including the item with `id`.\n * Called when a breadcrumb's clickHandler returns true (or void).\n */\n function trimAfter(id: string): void {\n const index = items.value.findIndex((item) => item.id === id);\n if (index !== -1) {\n items.value = items.value.slice(0, index + 1);\n }\n }\n\n function push(breadcrumb: Breadcrumbs): void {\n // Wrap the clickHandler to auto-trim the trail on successful click\n const wrapped: Breadcrumbs = {\n ...breadcrumb,\n clickHandler: breadcrumb.clickHandler\n ? async (id: string) => {\n try {\n const result = await breadcrumb.clickHandler!(id);\n // Trim trail unless handler explicitly returned false\n if (result !== false) {\n trimAfter(id);\n }\n } catch (e) {\n logger.error(\"Breadcrumb click handler failed:\", e);\n }\n }\n : undefined,\n };\n\n // Dedup by id: if a breadcrumb with this id already exists, update in place\n const existingIndex = items.value.findIndex((item) => item.id === wrapped.id);\n if (existingIndex !== -1) {\n const updated = [...items.value];\n updated[existingIndex] = wrapped;\n items.value = updated;\n } else {\n items.value = [...items.value, wrapped];\n }\n }\n\n function remove(ids: string[]): void {\n items.value = items.value.filter((item) => !ids.includes(item.id));\n }\n\n return {\n breadcrumbs: computed(() => items.value),\n push,\n remove,\n };\n}\n","<template>\n <div\n class=\"vc-blade-navigation tw-flex tw-flex-col tw-grow tw-basis-0 tw-min-w-0 tw-overflow-hidden\"\n role=\"region\"\n :aria-label=\"t('COMPONENTS.ORGANISMS.BLADE_NAVIGATION.ARIA_LABEL')\"\n >\n <!-- Non-blade routes (Dashboard, etc.) -->\n <RouterView v-if=\"!hasBlades\" />\n\n <!-- Blade stack -->\n <div\n v-else\n class=\"tw-overflow-hidden tw-flex tw-grow tw-basis-0 tw-relative tw-min-w-0\"\n >\n <VcBladeSlot\n v-for=\"(descriptor, index) in blades\"\n :key=\"descriptor.id\"\n :descriptor=\"descriptor\"\n :closable=\"index > 0\"\n :expanded=\"descriptor.id === activeBlade?.id\"\n :visible=\"isBladeVisible(descriptor, index)\"\n :breadcrumbs=\"breadcrumbs.slice(0, index)\"\n :back-button=\"bladeCount > 1 ? mobileBackButtonFor(index) : undefined\"\n @close=\"onClose\"\n @parent-call=\"onParentCall\"\n />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, h, inject, nextTick, onMounted, toRef } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { RouterView, useRouter } from \"vue-router\";\nimport { watchDebounced } from \"@vueuse/core\";\nimport { VcBladeSlot } from \"@shell/_internal/blade-navigation/components/vc-blade-slot\";\nimport VcMobileBackButton from \"@shell/_internal/blade-navigation/components/vc-blade-navigation/_internal/vc-mobile-back-button.vue\";\nimport { useBladeStack } from \"@core/blade-navigation/useBladeStack\";\nimport { useBladeMessaging } from \"@core/blade-navigation/useBladeMessaging\";\nimport { createUrlSync } from \"@core/blade-navigation/utils/urlSync\";\nimport { useBreadcrumbs } from \"@core/composables/useBreadcrumbs\";\nimport { AiAgentServiceKey } from \"@framework/injection-keys\";\nimport type { BladeDescriptor, IParentCallArgs } from \"@core/blade-navigation/types\";\n\nconst { t } = useI18n();\n\nconst bladeStack = useBladeStack();\nconst messaging = useBladeMessaging();\nconst router = useRouter();\nconst { breadcrumbs, push, remove } = useBreadcrumbs();\n\n// ── URL sync helper (centralized in urlSync.ts) ─────────────────────────────\n\nconst { syncUrlReplace } = createUrlSync(router, bladeStack);\n\n// ── Post-restore URL reconcile ──────────────────────────────────────────────\n// On a fresh load, restoreFromUrl reopens only the workspace + the deepest\n// routable blade. Non-routable blades and intermediate (off-path) blades are\n// NOT reopened, yet their table query params still sit in the address bar.\n// Once the restored blades have mounted, their tables hydrate their own query\n// into the blade descriptors (table-query-state service). Rebuilding the URL\n// from the present descriptors then drops any query owned by an absent blade.\n// Child `mounted` hooks run before this parent's `onMounted`, so the present\n// blades' descriptors are already hydrated here; `nextTick` covers stragglers.\nonMounted(() => {\n if (bladeStack.blades.value.length === 0) return;\n void nextTick(() => {\n syncUrlReplace();\n });\n});\n\n// ── Blade state ─────────────────────────────────────────────────────────────\n\nconst blades = computed(() => bladeStack.blades.value);\nconst activeBlade = computed(() => bladeStack.activeBlade.value);\nconst hasBlades = computed(() => blades.value.length > 0);\n\nconst bladeCount = computed(() => {\n return blades.value.filter((b) => b.visible).length;\n});\n\n// ── Visibility logic ────────────────────────────────────────────────────────\n\nconst { isMobile } = useResponsive();\n\nconst aiAgentService = inject(AiAgentServiceKey, undefined);\nconst isAiPanelExpanded = computed(() => aiAgentService?.isExpanded.value ?? false);\n\nconst visibleBladesCount = computed(() => {\n if (isMobile.value) return 1;\n if (isAiPanelExpanded.value) return 1;\n return 2;\n});\n\nfunction isBladeVisible(descriptor: BladeDescriptor, index: number): boolean {\n if (!descriptor.visible) return false;\n return index >= bladeCount.value - visibleBladesCount.value;\n}\n\n// ── Breadcrumbs sync ────────────────────────────────────────────────────────\n\nwatchDebounced(\n blades,\n (newVal) => {\n // Clear existing breadcrumbs\n breadcrumbs.value.forEach((bc) => bc && remove([bc.id]));\n\n // Rebuild from current blade stack (skip hidden blades from coverCurrentBlade)\n newVal\n .filter((b) => b.visible)\n .forEach((descriptor, index) => {\n push({\n id: index.toString(),\n title: toRef({ title: descriptor.name }, \"title\"),\n clickHandler: async (id) => {\n const visibleIndex = parseInt(id);\n // Map visible index back to actual blade in stack\n const visibleBlades = blades.value.filter((b) => b.visible);\n const targetBlade = visibleBlades[visibleIndex + 1];\n if (targetBlade) {\n const prevented = await bladeStack.closeBlade(targetBlade.id);\n if (!prevented) {\n syncUrlReplace();\n }\n return !prevented;\n }\n return true;\n },\n });\n });\n },\n {\n deep: true,\n immediate: true,\n flush: \"post\",\n debounce: 10,\n },\n);\n\n// ── Event handlers ──────────────────────────────────────────────────────────\n\nasync function onClose(bladeId: string): Promise<void> {\n const prevented = await bladeStack.closeBlade(bladeId);\n if (!prevented) {\n syncUrlReplace();\n }\n}\n\nasync function onParentCall(args: IParentCallArgs, bladeId: string): Promise<void> {\n try {\n const result = await messaging.callParent(bladeId, args.method as string, args.args);\n args.callback?.(result);\n } catch (error) {\n console.warn(\"[VcBladeNavigation] Parent call failed:\", error);\n }\n}\n\n// ── Mobile back button ──────────────────────────────────────────────────────\n\nfunction mobileBackButtonFor(index: number): ReturnType<typeof h> | undefined {\n if (index <= 0) return undefined;\n return h(VcMobileBackButton, {\n breadcrumbs: breadcrumbs.value.slice(0, index),\n onBack: async () => {\n const blade = blades.value[index];\n if (blade) {\n const prevented = await bladeStack.closeBlade(blade.id);\n if (!prevented) syncUrlReplace();\n }\n },\n });\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --blade-navigation-bg-color: var(--additional-50);\n --blade-navigation-shadow-color: var(--additional-950);\n --blade-navigation-shadow: 2px 2px 8px rgb(from var(--blade-navigation-shadow-color) r g b / 7%);\n --blade-navigation-border-radius: var(--blade-border-radius);\n}\n</style>\n","import type { InjectionKey } from \"vue\";\nimport type { PopupPlugin } from \"@core/composables/usePopup/types\";\n\nexport const PopupPluginKey: InjectionKey<PopupPlugin> = Symbol(\"PopupPlugin\");\n","import type { PopupPlugin } from \"@core/composables/usePopup/types\";\nimport { createBackendRegistry } from \"@core/utilities\";\n\n// `popupPluginInstance` is a live ESM binding read directly by usePopup and\n// re-exported by the shell popup plugin, so it must stay a module-scoped\n// variable. The registry is the source of truth; onChange mirrors it onto the\n// exported binding so existing importers are unchanged.\nexport let popupPluginInstance: PopupPlugin | undefined;\n\nconst registry = createBackendRegistry<PopupPlugin>((impl) => {\n popupPluginInstance = impl ?? undefined;\n});\n\nexport function setPopupPluginInstance(instance: PopupPlugin): void {\n registry.register(instance);\n}\n\n/** @internal Test teardown only */\nexport function _resetPopupSingleton(): void {\n registry.reset();\n}\n","import type { Component } from \"vue\";\nimport { createKeyedBackendRegistry } from \"@core/utilities\";\n\nexport type PopupPreset = \"warning\" | \"error\" | \"info\";\n\nconst registry = createKeyedBackendRegistry<PopupPreset, Component>();\n\nexport function registerPopupPreset(preset: PopupPreset, component: Component): void {\n registry.register(preset, component);\n}\n\nexport function getPopupPreset(preset: PopupPreset): Component | undefined {\n return registry.get(preset);\n}\n\n/** @internal Test teardown only */\nexport function _resetPopupPresets(): void {\n registry.reset();\n}\n","<template>\n <TransitionRoot\n appear\n :show=\"isVisible\"\n as=\"template\"\n >\n <Dialog\n as=\"div\"\n class=\"vc-popup\"\n :aria-labelledby=\"popupTitleId\"\n @close=\"handleDialogDismiss\"\n @keydown.esc=\"handleEscapeKeydown\"\n >\n <TransitionChild\n as=\"template\"\n enter=\"vc-popup__transition-enter\"\n enter-from=\"vc-popup__transition-enter-from\"\n enter-to=\"vc-popup__transition-enter-to\"\n leave=\"vc-popup__transition-leave\"\n leave-from=\"vc-popup__transition-leave-from\"\n leave-to=\"vc-popup__transition-leave-to\"\n >\n <div class=\"vc-popup__overlay\" />\n </TransitionChild>\n\n <div\n class=\"vc-popup__container\"\n :class=\"{\n 'vc-popup__container--desktop': !isMobileView,\n 'vc-popup__container--mobile': isMobileView,\n 'vc-popup__container--fullscreen': isFullscreen,\n }\"\n >\n <div class=\"vc-popup__center\">\n <TransitionChild\n as=\"template\"\n enter=\"vc-popup__dialog-enter\"\n enter-from=\"vc-popup__dialog-enter-from\"\n enter-to=\"vc-popup__dialog-enter-to\"\n leave=\"vc-popup__dialog-leave\"\n leave-from=\"vc-popup__dialog-leave-from\"\n leave-to=\"vc-popup__dialog-leave-to\"\n >\n <DialogPanel\n class=\"vc-popup__panel\"\n :class=\"[\n {\n 'vc-popup__panel--desktop': !isMobileView,\n 'vc-popup__panel--mobile': isMobileView,\n 'vc-popup__panel--fullscreen': isFullscreen,\n },\n modalWidth,\n ]\"\n >\n <DialogTitle\n :id=\"popupTitleId\"\n as=\"h3\"\n class=\"vc-popup__title\"\n >\n <slot name=\"header\">{{ title }}</slot>\n\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"vc-popup__close-btn\"\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_POPUP.CLOSE')\"\n @click=\"closeFromAction\"\n >\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7.27173 5.99939L11.1499 2.12967C11.3198 1.95981 11.4152 1.72943 11.4152 1.48922C11.4152 1.24901 11.3198 1.01863 11.1499 0.848777C10.9801 0.67892 10.7497 0.583496 10.5096 0.583496C10.2694 0.583496 10.0391 0.67892 9.86922 0.848777L6.00004 4.72752L2.13086 0.848777C1.96103 0.67892 1.73069 0.583496 1.49051 0.583496C1.25033 0.583496 1.01999 0.67892 0.850156 0.848777C0.680324 1.01863 0.584913 1.24901 0.584913 1.48922C0.584913 1.72943 0.680324 1.95981 0.850156 2.12967L4.72835 5.99939L0.850156 9.86912C0.765622 9.95298 0.698526 10.0527 0.652737 10.1627C0.606948 10.2726 0.583374 10.3905 0.583374 10.5096C0.583374 10.6286 0.606948 10.7465 0.652737 10.8565C0.698526 10.9664 0.765622 11.0662 0.850156 11.15C0.934 11.2346 1.03375 11.3017 1.14366 11.3475C1.25356 11.3933 1.37145 11.4168 1.49051 11.4168C1.60957 11.4168 1.72746 11.3933 1.83736 11.3475C1.94727 11.3017 2.04702 11.2346 2.13086 11.15L6.00004 7.27126L9.86922 11.15C9.95306 11.2346 10.0528 11.3017 10.1627 11.3475C10.2726 11.3933 10.3905 11.4168 10.5096 11.4168C10.6286 11.4168 10.7465 11.3933 10.8564 11.3475C10.9663 11.3017 11.0661 11.2346 11.1499 11.15C11.2345 11.0662 11.3016 10.9664 11.3473 10.8565C11.3931 10.7465 11.4167 10.6286 11.4167 10.5096C11.4167 10.3905 11.3931 10.2726 11.3473 10.1627C11.3016 10.0527 11.2345 9.95298 11.1499 9.86912L7.27173 5.99939Z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>\n </DialogTitle>\n\n <div class=\"vc-popup__content\">\n <VcIcon\n v-if=\"variant !== 'default'\"\n :class=\"['vc-popup__icon', iconStyle]\"\n :icon=\"icon\"\n />\n\n <div\n class=\"vc-popup__content-inner\"\n :class=\"{\n 'vc-popup__content-inner--grow': isMobileView,\n }\"\n >\n <div\n class=\"vc-popup__content-wrapper\"\n :class=\"{ 'vc-popup__content-wrapper--full': isFullscreen }\"\n >\n <slot name=\"content\"></slot>\n </div>\n </div>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"vc-popup__footer\"\n >\n <slot\n name=\"footer\"\n :close=\"closeFromAction\"\n >\n <VcButton\n class=\"vc-popup__close-button\"\n @click=\"closeFromAction\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_POPUP.CLOSE\") }}\n </VcButton>\n </slot>\n </div>\n </DialogPanel>\n </TransitionChild>\n </div>\n </div>\n </Dialog>\n </TransitionRoot>\n</template>\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { computed, ref, getCurrentInstance } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { TransitionRoot, TransitionChild, Dialog, DialogPanel, DialogTitle } from \"@headlessui/vue\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\nexport type PopupVariant = \"default\" | \"error\" | \"warning\" | \"success\" | \"info\";\nexport type PopupCloseReason = \"overlay\" | \"escape\" | \"action\";\n\nexport interface Props {\n modelValue?: boolean;\n title?: string;\n closable?: boolean;\n variant?: PopupVariant;\n isMobileFullscreen?: boolean;\n isFullscreen?: boolean;\n modalWidth?: string;\n closeOnOverlay?: boolean;\n closeOnEscape?: boolean;\n}\n\ninterface Emits {\n (event: \"close\", reason?: PopupCloseReason): void;\n (event: \"update:modelValue\", value: boolean): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: undefined,\n closable: true,\n variant: \"default\",\n modalWidth: \"tw-max-w-md\",\n closeOnOverlay: undefined,\n closeOnEscape: undefined,\n});\n\nconst emit = defineEmits<Emits>();\n\ndefineSlots<{\n header: (props: any) => any;\n content: (props: any) => any;\n footer: (props: { close: () => void }) => any;\n}>();\n\nconst instanceUid = getCurrentInstance()?.uid ?? 0;\nconst popupTitleId = `vc-popup-title-${instanceUid}`;\n\nconst { isMobile } = useResponsive();\nconst pendingDismissReason = ref<PopupCloseReason | null>(null);\n\nconst variantMeta: Record<Exclude<PopupVariant, \"default\">, { icon: string; className: string }> = {\n warning: { icon: \"lucide-triangle-alert\", className: \"vc-popup__icon--warning\" },\n error: { icon: \"lucide-circle-alert\", className: \"vc-popup__icon--error\" },\n success: { icon: \"lucide-circle-check\", className: \"vc-popup__icon--success\" },\n info: { icon: \"lucide-info\", className: \"vc-popup__icon--info\" },\n};\n\nconst isVisible = computed(() => props.modelValue ?? true);\nconst canCloseOnOverlay = computed(() => props.closeOnOverlay ?? props.closable);\nconst canCloseOnEscape = computed(() => props.closeOnEscape ?? props.closable);\n\nconst icon = computed(() => {\n if (props.variant === \"default\") {\n return \"\";\n }\n\n return variantMeta[props.variant].icon;\n});\n\nconst iconStyle = computed(() => {\n if (props.variant === \"default\") {\n return \"\";\n }\n\n return variantMeta[props.variant].className;\n});\n\nconst isMobileView = computed(() => isMobile.value && props.isMobileFullscreen);\n\nfunction emitClose(reason: PopupCloseReason): void {\n emit(\"update:modelValue\", false);\n emit(\"close\", reason);\n}\n\nfunction closeFromAction(): void {\n if (!props.closable) {\n return;\n }\n\n emitClose(\"action\");\n}\n\nfunction handleEscapeKeydown(): void {\n pendingDismissReason.value = \"escape\";\n}\n\nfunction handleDialogDismiss(): void {\n const reason = pendingDismissReason.value ?? \"overlay\";\n pendingDismissReason.value = null;\n\n if (reason === \"overlay\" && !canCloseOnOverlay.value) {\n return;\n }\n\n if (reason === \"escape\" && !canCloseOnEscape.value) {\n return;\n }\n\n emitClose(reason);\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --vc-popup-border-radius: var(--popup-border-radius, 6px);\n --vc-popup-shadow: var(--popup-shadow, var(--shadow-md));\n --vc-popup-overlay-blur: var(--popup-overlay-blur, var(--overlay-blur));\n\n // Deprecated aliases (prefer --vc-popup-* variables for new themes)\n --popup-close-btn-bg: var(--neutrals-100);\n --popup-close-btn-bg-hover: color-mix(in srgb, var(--popup-close-btn-bg), #000 5%);\n --popup-header-color: var(--primary-700);\n --popup-content-text-color: var(--primary-700);\n --popup-warning-icon-color: var(--warning-500);\n --popup-error-icon-color: var(--danger-500);\n --popup-success-icon-color: var(--success-500);\n --popup-info-icon-color: var(--info-500);\n --popup-footer-separator: var(--neutrals-200);\n --popup-overlay: var(--popup-overlay-override, var(--overlay-bg));\n --popup-bg: var(--additional-50);\n}\n\n.vc-popup {\n &__overlay {\n @apply tw-fixed tw-inset-0;\n z-index: var(--z-critical-popup);\n background: var(--popup-overlay);\n backdrop-filter: blur(var(--vc-popup-overlay-blur));\n -webkit-backdrop-filter: blur(var(--vc-popup-overlay-blur));\n }\n\n &__container {\n @apply tw-fixed tw-inset-0 tw-overflow-y-auto;\n z-index: var(--z-critical-popup);\n\n &--desktop {\n @apply tw-p-4;\n }\n\n &--mobile {\n @apply tw-p-0;\n }\n\n &--fullscreen {\n @apply tw-p-0 tw-overflow-hidden;\n }\n }\n\n &__center {\n @apply tw-flex tw-min-h-full tw-items-center tw-justify-center tw-text-center;\n }\n\n &__panel {\n @apply tw-w-full tw-transform tw-overflow-hidden tw-text-left tw-align-middle tw-transition-all;\n border-radius: var(--vc-popup-border-radius);\n background: var(--popup-bg);\n box-shadow: var(--vc-popup-shadow);\n\n &--desktop {\n @apply tw-flex tw-flex-col [max-height:calc(100vh-40px)];\n }\n\n &--mobile {\n @apply tw-max-w-full tw-h-[100dvh] tw-rounded-none tw-flex tw-flex-col;\n }\n\n &--fullscreen {\n @apply tw-h-[100dvh] tw-max-h-[100dvh] tw-w-screen tw-max-w-none tw-rounded-none #{!important};\n }\n }\n\n &__title {\n @apply tw-text-lg tw-font-semibold tw-leading-5 tw-text-[var(--popup-header-color)] tw-flex tw-items-center tw-gap-4 tw-px-6 tw-py-5;\n }\n\n &__close-btn {\n @apply tw-h-[26px] tw-w-[26px] tw-bg-[var(--popup-close-btn-bg)] tw-rounded-[4px] tw-inline-flex tw-items-center tw-justify-center tw-ml-auto tw-shrink-0 hover:tw-bg-[var(--popup-close-btn-bg-hover)] tw-outline-none tw-ring-offset-2 tw-ring-offset-transparent focus-visible:tw-ring-2 focus-visible:tw-ring-[var(--primary-300)];\n }\n\n &__content {\n @apply tw-flex tw-w-full tw-min-h-0 tw-grow tw-gap-5 tw-px-6 tw-pb-5 tw-pt-3;\n }\n\n &__panel--fullscreen &__content {\n @apply tw-p-0 tw-overflow-hidden tw-h-full;\n }\n\n &__content-inner {\n @apply tw-text-sm tw-font-normal tw-leading-5 tw-text-[var(--popup-content-text-color)] tw-flex tw-items-center tw-flex-auto tw-overflow-y-auto [word-break:break-word];\n\n &--grow {\n @apply tw-grow;\n }\n }\n\n &__panel--fullscreen &__content-inner {\n @apply tw-overflow-hidden tw-h-full tw-items-stretch;\n }\n\n &__content-wrapper {\n @apply tw-flex tw-flex-auto tw-self-center tw-min-h-0 tw-max-h-[-webkit-fill-available] tw-max-h-[-moz-available];\n\n &--full {\n @apply tw-h-full;\n }\n }\n\n &__panel--fullscreen &__content-wrapper {\n @apply tw-self-stretch tw-h-full tw-overflow-hidden tw-flex-col;\n min-width: 0;\n }\n\n &__footer {\n @apply tw-flex tw-items-center tw-px-6 tw-py-5 tw-border-t tw-border-t-[var(--popup-footer-separator)] tw-border-solid;\n }\n\n &__close-button {\n @apply tw-ml-auto;\n }\n\n &__icon {\n @apply tw-self-center tw-text-[40px];\n\n &--warning {\n @apply tw-text-[var(--popup-warning-icon-color)];\n }\n\n &--error {\n @apply tw-text-[var(--popup-error-icon-color)];\n }\n\n &--success {\n @apply tw-text-[var(--popup-success-icon-color)];\n }\n\n &--info {\n @apply tw-text-[var(--popup-info-icon-color)];\n }\n }\n\n &__transition-enter {\n @apply tw-duration-300 tw-ease-out;\n }\n\n &__transition-enter-from {\n @apply tw-opacity-0;\n }\n\n &__transition-enter-to {\n @apply tw-opacity-100;\n }\n\n &__transition-leave {\n @apply tw-duration-200 tw-ease-in;\n }\n\n &__transition-leave-from {\n @apply tw-opacity-100;\n }\n\n &__transition-leave-to {\n @apply tw-opacity-0;\n }\n\n &__dialog-enter {\n @apply tw-duration-300 tw-ease-out;\n }\n\n &__dialog-enter-from {\n @apply tw-opacity-0 tw-scale-95;\n }\n\n &__dialog-enter-to {\n @apply tw-opacity-100 tw-scale-100;\n }\n\n &__dialog-leave {\n @apply tw-duration-200 tw-ease-in;\n }\n\n &__dialog-leave-from {\n @apply tw-opacity-100 tw-scale-100;\n }\n\n &__dialog-leave-to {\n @apply tw-opacity-0 tw-scale-95;\n }\n}\n</style>\n","import { getCurrentInstance, inject } from \"vue\";\nimport { PopupPluginKey } from \"@shell/_internal/popup/keys\";\n\nexport function getPopupPlugin() {\n const instance = getCurrentInstance();\n if (instance) {\n return inject(PopupPluginKey, undefined);\n }\n}\n","<template>\n <component\n :is=\"popup.component\"\n v-for=\"(popup, index) in popupPlugin?.popups\"\n :key=\"popup.id ?? index\"\n v-bind=\"{ ...popup.props, ...popup.emits }\"\n @close=\"() => popup.close?.()\"\n >\n <template\n v-for=\"(slot, key) in popup.slots\"\n #[key]\n :key=\"key\"\n >\n <div\n v-if=\"typeof slot === 'string'\"\n class=\"tw-h-full tw-w-full\"\n v-html=\"sanitizeHtml(slot)\"\n ></div>\n <component\n :is=\"slot\"\n v-else\n ></component>\n </template>\n </component>\n</template>\n\n<script setup lang=\"ts\">\nimport DOMPurify from \"dompurify\";\nimport { getPopupPlugin } from \"@shell/_internal/popup/utils\";\n\nconst popupPlugin = getPopupPlugin();\n\n/**\n * Sanitize HTML content to prevent XSS attacks\n */\nfunction sanitizeHtml(html: string): string {\n return DOMPurify.sanitize(html, {\n ALLOWED_TAGS: [\n \"p\",\n \"br\",\n \"strong\",\n \"em\",\n \"u\",\n \"s\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"a\",\n \"img\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n \"hr\",\n \"div\",\n \"span\",\n ],\n ALLOWED_ATTR: [\"href\", \"src\", \"alt\", \"title\", \"class\", \"id\", \"colspan\", \"rowspan\", \"align\", \"valign\"],\n FORBID_TAGS: [\"script\", \"object\", \"embed\", \"form\", \"input\"],\n FORBID_ATTR: [\"onerror\", \"onload\", \"onclick\", \"onmouseover\", \"onfocus\", \"onblur\", \"style\"],\n });\n}\n</script>\n","import _PopupContainer from \"@shell/_internal/popup/components/vc-popup-container/vc-popup-container.vue\";\n\nexport const VcPopupContainer = _PopupContainer as typeof _PopupContainer;\n","import {\n markRaw,\n getCurrentInstance,\n inject,\n reactive,\n shallowRef,\n nextTick,\n Ref,\n watch,\n MaybeRef,\n unref,\n Component,\n} from \"vue\";\nimport { PopupPluginKey } from \"@core/composables/usePopup/keys\";\nimport type { PopupPlugin, UsePopupInternal, UsePopupProps } from \"@core/composables/usePopup/types\";\nimport { popupPluginInstance } from \"@core/composables/usePopup/singleton\";\nimport { getPopupPreset } from \"@core/composables/usePopup/preset-registry\";\nimport { useI18n } from \"vue-i18n\";\nimport { createLogger } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-popup\");\n\ninterface IUsePopup {\n open(): void;\n close(): void;\n showConfirmation(message: string | Ref<string>): Promise<boolean>;\n showError(message: string | Ref<string>): void;\n showInfo(message: string | Ref<string>): void;\n}\n\nfunction usePopupInternal() {\n const instance = getCurrentInstance();\n const popupInstance: PopupPlugin | undefined = (instance && inject(PopupPluginKey, undefined)) || popupPluginInstance;\n\n return popupInstance;\n}\n\nexport function usePopup<T extends Component = Component>(options?: MaybeRef<UsePopupProps<T>>): IUsePopup {\n const { t } = useI18n({ useScope: \"global\" });\n const popupInstance = usePopupInternal();\n let rawPopup: (UsePopupProps & UsePopupInternal) | undefined;\n\n if (options) {\n rawPopup = createInstance(unref(options));\n }\n\n watch(\n () => (options ? unref(options) : undefined),\n (newVal) => {\n if (newVal) {\n rawPopup = createInstance(newVal);\n }\n },\n { deep: true },\n );\n\n function destroy(confirmation?: Partial<UsePopupProps & UsePopupInternal>): void {\n if (!confirmation) {\n return;\n }\n\n const popupInstanceInternal = usePopupInternal();\n // Match by the unique instance id, not structural equality: each popup carries\n // its own Symbol, so reference-by-id is the correct — and only safe — comparison\n // when several popups are stacked.\n const index = popupInstanceInternal?.popups?.findIndex((x) => x.id === confirmation.id);\n\n if (typeof index === \"number\" && index !== -1) {\n popupInstanceInternal?.popups?.splice(index, 1);\n }\n }\n\n function resolveInstance(customInstance?: UsePopupProps): UsePopupProps | undefined {\n return rawPopup ?? customInstance;\n }\n\n function pushInstance(popup?: UsePopupProps) {\n if (!popup) {\n return;\n }\n\n destroy(popup);\n popupInstance?.popups?.push(popup);\n }\n\n async function open(customInstance?: UsePopupProps) {\n await nextTick();\n pushInstance(resolveInstance(customInstance));\n }\n\n function close(customInstance?: UsePopupProps) {\n const instanceToClose = resolveInstance(customInstance);\n if (!instanceToClose) {\n return;\n }\n\n const index = popupInstance?.popups.indexOf(instanceToClose);\n if (typeof index === \"number\" && index !== -1) {\n popupInstance?.popups?.splice(index, 1);\n }\n }\n\n function showSimplePopup(\n component: Component,\n title: string,\n message: string | Ref<string>,\n ): UsePopupProps & UsePopupInternal {\n const popup = createInstance({\n component,\n props: {\n title,\n },\n emits: {\n onClose() {\n close(popup);\n },\n },\n slots: {\n default: message,\n },\n });\n\n pushInstance(popup);\n return popup;\n }\n\n function showConfirmation(message: string | Ref<string>): Promise<boolean> {\n const warningComponent = getPopupPreset(\"warning\");\n if (!warningComponent) {\n logger.error(\"Popup preset 'warning' not registered. Ensure shell popup plugin is installed.\");\n return Promise.resolve(false);\n }\n\n return new Promise((resolve) => {\n const confirmation = createInstance({\n component: warningComponent,\n props: {\n title: t(\"COMPONENTS.ORGANISMS.VC_POPUP.TITLE.CONFIRMATION\"),\n },\n emits: {\n onClose() {\n resolve(false);\n close(confirmation);\n },\n onConfirm() {\n resolve(true);\n close(confirmation);\n },\n },\n slots: {\n default: message,\n },\n });\n\n pushInstance(confirmation);\n });\n }\n\n function showError(message: string | Ref<string>) {\n const errorComponent = getPopupPreset(\"error\");\n if (!errorComponent) {\n logger.error(\"Popup preset 'error' not registered. Ensure shell popup plugin is installed.\");\n return;\n }\n showSimplePopup(errorComponent, t(\"COMPONENTS.ORGANISMS.VC_POPUP.TITLE.ERROR\"), message);\n }\n\n function showInfo(message: string | Ref<string>) {\n const infoComponent = getPopupPreset(\"info\");\n if (!infoComponent) {\n logger.error(\"Popup preset 'info' not registered. Ensure shell popup plugin is installed.\");\n return;\n }\n showSimplePopup(infoComponent, t(\"COMPONENTS.ORGANISMS.VC_POPUP.TITLE.INFO\"), message);\n }\n\n function createInstance<T extends Component = Component>(options: UsePopupProps<T>) {\n const popup = reactive({\n ...createComponent(options),\n id: Symbol(\"vc-popup-instance\"),\n close: () => undefined,\n open: () => undefined,\n }) as unknown as UsePopupProps & UsePopupInternal;\n\n popup.close = () => close(popup);\n popup.open = () => open(popup);\n\n return popup;\n }\n\n return {\n open,\n close,\n showConfirmation,\n showError,\n showInfo,\n };\n}\n\nfunction createComponent<T extends Component = Component>(options: UsePopupProps<T>) {\n const slots =\n typeof options.slots === \"undefined\"\n ? {}\n : Object.fromEntries(\n Object.entries(options.slots).map(([slotName, slotContent]) => {\n if (typeof slotContent === \"string\") {\n return [slotName, slotContent];\n }\n return [slotName, markRaw(slotContent)];\n }),\n );\n\n return {\n ...options,\n slots,\n component: markRaw(shallowRef(options.component)),\n };\n}\n","<template>\r\n <div\r\n class=\"vc-blade-header\"\r\n :class=\"{\r\n 'vc-blade-header--mobile': isMobile,\r\n }\"\r\n >\r\n <slot name=\"prepend\"></slot>\r\n\r\n <div class=\"vc-blade-header__status-container\">\r\n <div\r\n v-if=\"!loading && typeof modified !== 'undefined'\"\r\n ref=\"tooltipIconRef\"\r\n :class=\"{\r\n 'vc-blade-header__status-not-edited': !modified,\r\n 'vc-blade-header__status-edited': modified,\r\n }\"\r\n class=\"vc-blade-header__status\"\r\n @mouseenter=\"tooltipVisible = true\"\r\n @mouseleave=\"tooltipVisible = false\"\r\n >\r\n <teleport :to=\"teleportTarget\">\r\n <span\r\n v-if=\"tooltipVisible\"\r\n ref=\"tooltipRef\"\r\n :style=\"floatingStyle\"\r\n class=\"vc-blade-header__tooltip\"\r\n >\r\n {{\r\n modified\r\n ? $t(\"COMPONENTS.ORGANISMS.VC_BLADE_HEADER.UNSAVED_CHANGES\")\r\n : $t(\"COMPONENTS.ORGANISMS.VC_BLADE_HEADER.NO_CHANGES\")\r\n }}\r\n </span>\r\n </teleport>\r\n </div>\r\n\r\n <div\r\n v-if=\"loading\"\r\n class=\"vc-blade-header__icon\"\r\n >\r\n <VcSkeleton\r\n variant=\"circle\"\r\n :width=\"24\"\r\n :height=\"24\"\r\n />\r\n </div>\r\n <div\r\n v-else-if=\"icon\"\r\n class=\"vc-blade-header__icon\"\r\n >\r\n <VcIcon\r\n :icon=\"icon\"\r\n size=\"xxl\"\r\n />\r\n </div>\r\n\r\n <div class=\"vc-blade-header__wrapper\">\r\n <div\r\n v-if=\"loading\"\r\n class=\"vc-blade-header__content vc-blade-header__content--loading\"\r\n >\r\n <VcSkeleton\r\n variant=\"block\"\r\n :width=\"180\"\r\n :height=\"19\"\r\n />\r\n <div class=\"tw-mt-1.5\">\r\n <VcSkeleton\r\n variant=\"block\"\r\n :width=\"120\"\r\n :height=\"12\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n v-else\r\n class=\"vc-blade-header__content\"\r\n >\r\n <div\r\n :id=\"titleId\"\r\n class=\"vc-blade-header__title\"\r\n :class=\"{\r\n 'vc-blade-header__title-no-subtitle': !subtitle,\r\n }\"\r\n >\r\n {{ title }}\r\n </div>\r\n <div\r\n v-if=\"subtitle\"\r\n class=\"vc-blade-header__subtitle\"\r\n >\r\n {{ subtitle }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n v-if=\"!loading && $slots['actions']\"\r\n class=\"vc-blade-header__actions\"\r\n >\r\n <slot name=\"actions\"></slot>\r\n </div>\r\n </div>\r\n\r\n <div\r\n v-if=\"!isMobile && closable\"\r\n class=\"vc-blade-header__controls\"\r\n >\r\n <div\r\n v-if=\"renderingState?.maximized\"\r\n class=\"vc-blade-header__button\"\r\n @click=\"onCollapse\"\r\n >\r\n <VcIcon icon=\"lucide-minus\" />\r\n </div>\r\n <div\r\n v-else\r\n class=\"vc-blade-header__button\"\r\n @click=\"onExpand\"\r\n >\r\n <VcIcon icon=\"lucide-panel-top\" />\r\n </div>\r\n <div\r\n class=\"vc-blade-header__button\"\r\n @click=\"onClose\"\r\n >\r\n <VcIcon icon=\"lucide-x\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\r\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\r\nimport { ref, inject } from \"vue\";\r\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\r\nimport { shift } from \"@floating-ui/vue\";\r\nimport { BladeRenderingStateKey } from \"@core/blade-navigation/types\";\r\nimport { useFloatingPosition, useTeleportTarget } from \"@ui/composables\";\r\n\r\nexport interface Props {\r\n closable?: boolean;\r\n title?: string;\r\n subtitle?: string;\r\n icon?: string;\r\n modified?: boolean;\r\n /** Id to apply to the title element, for aria-labelledby linking from VcBlade */\r\n titleId?: string;\r\n /** When true, shows skeleton placeholders for icon/title/subtitle while keeping controls usable */\r\n loading?: boolean;\r\n}\r\nconst props = defineProps<Props>();\r\n\r\nconst emit = defineEmits<{\r\n close: [];\r\n expand: [];\r\n collapse: [];\r\n}>();\r\n\r\nconst { isMobile } = useResponsive();\r\nconst renderingState = inject(BladeRenderingStateKey, undefined);\r\nconst tooltipVisible = ref(false);\r\nconst tooltipIconRef = ref<HTMLElement | null>(null);\r\nconst tooltipRef = ref<HTMLElement | null>(null);\r\nconst { teleportTarget } = useTeleportTarget();\r\nconst { floatingStyle } = useFloatingPosition(tooltipIconRef, tooltipRef, {\r\n placement: \"bottom-start\",\r\n middleware: () => [shift()],\r\n});\r\n\r\nfunction onExpand(): void {\r\n if (props.closable) {\r\n emit(\"expand\");\r\n }\r\n}\r\n\r\nfunction onCollapse(): void {\r\n if (props.closable) {\r\n emit(\"collapse\");\r\n }\r\n}\r\n\r\nfunction onClose(): void {\r\n if (props.closable) {\r\n emit(\"close\");\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --blade-header-height: 70px;\r\n --blade-header-mobile-height: 60px;\r\n --blade-header-background-color: var(--additional-50);\r\n --blade-header-button-color: var(--neutrals-400);\r\n --blade-header-button-color-hover: var(--neutrals-500);\r\n --blade-header-breadcrumbs-button-color: var(--neutrals-500);\r\n --blade-header-breadcrumbs-button-color-hover: var(--neutrals-700);\r\n --blade-header-icon-color: var(--secondary-500);\r\n --blade-header-title-font-size: 19px;\r\n --blade-header-title-color: var(--neutrals-950);\r\n --blade-header-subtitle-color: var(--secondary-500);\r\n --blade-not-edited: var(--success-400);\r\n --blade-edited: var(--warning-500);\r\n --blade-header-border-color: var(--neutrals-200);\r\n --blade-tooltip-background: var(--additional-50);\r\n --blade-tooltip-border: var(--neutrals-200);\r\n --blade-tooltip-text: var(--neutrals-600);\r\n}\r\n\r\n.vc-blade-header {\r\n @apply tw-shrink-0 tw-h-[var(--blade-header-height)] tw-bg-[color:var(--blade-header-background-color)] tw-flex tw-items-center tw-py-0 tw-px-6 tw-border-solid tw-border-b tw-border-b-[color:var(--blade-header-border-color)];\r\n\r\n &--mobile {\r\n @apply tw-min-h-[var(--blade-header-mobile-height)] tw-h-auto tw-py-2;\r\n\r\n .vc-blade-header__title {\r\n @apply tw-text-lg/[22px];\r\n }\r\n\r\n .vc-blade-header__wrapper {\r\n @apply tw-flex-col tw-items-start tw-gap-1;\r\n }\r\n\r\n .vc-blade-header__content {\r\n @apply tw-w-full tw-min-w-0;\r\n }\r\n\r\n .vc-blade-header__actions {\r\n @apply tw-flex tw-items-center tw-gap-1 tw-overflow-x-auto tw-max-w-full;\r\n }\r\n }\r\n\r\n &--hidden {\r\n @apply tw-hidden;\r\n }\r\n\r\n &__wrapper {\r\n @apply tw-flex tw-items-center tw-justify-between tw-grow tw-basis-0 tw-overflow-hidden;\r\n }\r\n\r\n &__actions {\r\n @apply tw-overflow-hidden tw-flex-shrink-0;\r\n }\r\n\r\n &__status {\r\n @apply tw-block tw-w-2 tw-h-2 tw-rounded-full tw-z-[var(--z-local-above)] tw-mr-[10px];\r\n }\r\n\r\n &__status-container {\r\n @apply tw-flex tw-flex-1 tw-flex-row tw-items-center tw-truncate;\r\n }\r\n\r\n &__status-not-edited {\r\n @apply tw-bg-[color:var(--blade-not-edited)] #{!important};\r\n }\r\n\r\n &__status-edited {\r\n @apply tw-bg-[color:var(--blade-edited)] #{!important};\r\n }\r\n\r\n &__tooltip {\r\n @apply tw-absolute tw-z-[var(--z-local-sticky)] tw-bg-[color:var(--blade-tooltip-background)] tw-border tw-border-solid tw-border-[color:var(--blade-tooltip-border)] tw-shadow-[1px_1px_8px_rgba(126,142,157,0.25)] tw-rounded-[3px] tw-text-[color:var(--blade-tooltip-text)] tw-font-normal tw-py-1 tw-px-2 tw-ml-4;\r\n }\r\n\r\n &__icon {\r\n @apply tw-text-[color:var(--blade-header-icon-color)] tw-mr-3;\r\n }\r\n\r\n &__content {\r\n @apply tw-overflow-hidden;\r\n }\r\n\r\n &__title {\r\n @apply tw-text-[color:var(--blade-header-title-color)] tw-text-xl/[23px] tw-truncate;\r\n }\r\n\r\n &__title-no-subtitle {\r\n @apply tw-text-[length:var(--blade-header-title-font-size)] tw-font-semibold #{!important};\r\n }\r\n\r\n &__subtitle {\r\n @apply tw-text-[color:var(--blade-header-subtitle-color)] tw-text-xs tw-mt-1;\r\n }\r\n\r\n &__controls {\r\n @apply tw-flex tw-items-center;\r\n }\r\n\r\n &__button {\r\n @apply tw-text-[color:var(--blade-header-button-color)] tw-ml-2.5 tw-cursor-pointer hover:tw-text-[color:var(--blade-header-button-color-hover)];\r\n }\r\n}\r\n</style>\r\n","<template>\n <!-- Inline mode: render badge element directly without wrapper -->\n <div\n v-if=\"inline && (typeof content !== 'undefined' || isDot)\"\n ref=\"badge\"\n class=\"vc-badge__badge vc-badge__badge--inline\"\n :class=\"[\n `vc-badge__badge--${variant}`,\n {\n 'vc-badge__badge--active': active,\n 'vc-badge__badge--clickable': clickable,\n 'vc-badge__badge--disabled': disabled,\n 'vc-badge__badge--content-long': String(content).length > 1,\n 'vc-badge__badge--content-very-long': String(content).length > 2,\n 'vc-badge__badge--dot': isDot,\n 'vc-badge__badge--inline-small': size === 's',\n 'vc-badge__badge--inline-medium': size === 'm',\n },\n ]\"\n :role=\"clickable ? 'button' : ariaLabel || isDot ? 'img' : undefined\"\n :tabindex=\"clickable && !disabled ? 0 : undefined\"\n :aria-disabled=\"clickable && disabled ? true : undefined\"\n :aria-label=\"ariaLabel || (isDot ? 'Notification' : undefined)\"\n @click=\"onClick\"\n @keydown.enter.prevent=\"onClick\"\n @keydown.space.prevent=\"onClick\"\n >\n <span\n v-if=\"!isDot\"\n class=\"vc-badge__text\"\n >{{ content }}</span\n >\n </div>\n\n <!-- Standard mode: wrapper with slot and positioned badge -->\n <div\n v-else\n ref=\"badgeContainer\"\n class=\"vc-badge\"\n :class=\"{\n 'vc-badge--small': size === 's',\n 'vc-badge--medium': size === 'm',\n }\"\n >\n <div class=\"vc-badge__content\">\n <slot name=\"default\"></slot>\n\n <div\n v-if=\"typeof content !== 'undefined' || isDot\"\n ref=\"badge\"\n class=\"vc-badge__badge\"\n :class=\"[\n `vc-badge__badge--${variant}`,\n {\n 'vc-badge__badge--active': active,\n 'vc-badge__badge--clickable': clickable,\n 'vc-badge__badge--disabled': disabled,\n 'vc-badge__badge--content-long': String(content).length > 1,\n 'vc-badge__badge--content-very-long': String(content).length > 2,\n 'vc-badge__badge--dot': isDot,\n 'vc-badge__badge--custom-position': customPosition,\n },\n ]\"\n :style=\"customPositionStyle\"\n :role=\"clickable ? 'button' : ariaLabel || isDot ? 'img' : undefined\"\n :tabindex=\"clickable && !disabled ? 0 : undefined\"\n :aria-disabled=\"clickable && disabled ? true : undefined\"\n :aria-label=\"ariaLabel || (isDot ? 'Notification' : undefined)\"\n @click=\"onClick\"\n @keydown.enter.prevent=\"onClick\"\n @keydown.space.prevent=\"onClick\"\n >\n <span\n v-if=\"!isDot\"\n class=\"vc-badge__text\"\n >{{ content }}</span\n >\n </div>\n </div>\n </div>\n</template>\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\n\nexport interface Props {\n active?: boolean;\n disabled?: boolean;\n clickable?: boolean;\n content?: string | number;\n size?: \"s\" | \"m\";\n isDot?: boolean;\n variant?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"info\" | \"secondary\";\n customPosition?: boolean;\n top?: string;\n right?: string;\n /** When true, renders badge as inline element without absolute positioning (no slot content) */\n inline?: boolean;\n /** Accessible label for the badge (useful for screen readers) */\n ariaLabel?: string;\n}\n\nexport interface Emits {\n (event: \"click\"): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: \"m\",\n isDot: false,\n variant: \"primary\",\n customPosition: false,\n top: undefined,\n right: undefined,\n inline: false,\n});\n\nconst emit = defineEmits<Emits>();\n\ndefineSlots<{\n /**\n * Slot for component content\n * */\n default: (props: any) => any;\n}>();\n\nfunction onClick(): void {\n if (props.clickable && !props.disabled) {\n emit(\"click\");\n }\n}\n\nconst customPositionStyle = computed(() => {\n if (!props.customPosition) return {};\n\n return {\n top: props.top,\n right: props.right,\n };\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n // Default variant\n --badge-background-color: var(--accent-500);\n --badge-text-color: var(--additional-50);\n --badge-border-color: var(--additional-50);\n\n // Hover states\n --badge-background-color-hover: var(--neutrals-200);\n --badge-text-color-hover: var(--neutrals-800);\n --badge-border-color-hover: var(--primary-300);\n\n // Active states\n --badge-background-color-active: var(--neutrals-200);\n --badge-text-color-active: var(--neutrals-800);\n --badge-border-color-active: var(--primary-300);\n\n // Disabled states\n --badge-background-color-disabled: var(--neutrals-300);\n --badge-text-color-disabled: var(--neutrals-500);\n --badge-border-color-disabled: var(--primary-200);\n\n // Variants — positioned (notification badges: solid)\n --badge-background-color-primary: var(--primary-500);\n --badge-background-color-secondary: var(--secondary-500);\n --badge-background-color-success: var(--success-500);\n --badge-background-color-warning: var(--warning-500);\n --badge-background-color-danger: var(--danger-500);\n --badge-background-color-info: var(--info-500);\n\n // Variants — inline (tag/pill: soft)\n --badge-inline-bg-primary: var(--primary-50);\n --badge-inline-text-primary: var(--primary-700);\n --badge-inline-border-primary: var(--primary-200);\n\n --badge-inline-bg-secondary: var(--secondary-50);\n --badge-inline-text-secondary: var(--secondary-700);\n --badge-inline-border-secondary: var(--secondary-200);\n\n --badge-inline-bg-success: var(--success-50);\n --badge-inline-text-success: var(--success-700);\n --badge-inline-border-success: var(--success-200);\n\n --badge-inline-bg-warning: var(--warning-50);\n --badge-inline-text-warning: var(--warning-700);\n --badge-inline-border-warning: var(--warning-200);\n\n --badge-inline-bg-danger: var(--danger-50);\n --badge-inline-text-danger: var(--danger-700);\n --badge-inline-border-danger: var(--danger-200);\n\n --badge-inline-bg-info: var(--info-50);\n --badge-inline-text-info: var(--info-700);\n --badge-inline-border-info: var(--info-200);\n\n // Sizes\n --badge-size-small: 17px;\n --badge-size-medium: 20px;\n\n // Positioning\n --badge-distance-top-small: -8px;\n --badge-distance-right-small: -10px;\n --badge-distance-top-medium: -8px;\n --badge-distance-right-medium: -10px;\n\n // Misc\n --badge-border-radius: 9999px;\n --badge-dot-size-small: 8px;\n --badge-dot-size-medium: 10px;\n\n // Focus\n --badge-focus-ring-color: var(--primary-300);\n}\n\n$sizes: small, medium;\n\n@each $size in $sizes {\n .vc-badge {\n &--#{$size} {\n .vc-badge__badge {\n height: var(--badge-size-#{$size});\n min-width: var(--badge-size-#{$size});\n top: var(--badge-distance-top-#{$size});\n right: var(--badge-distance-right-#{$size});\n\n &.vc-badge__badge--dot {\n height: var(--badge-dot-size-#{$size});\n min-width: var(--badge-dot-size-#{$size});\n width: var(--badge-dot-size-#{$size});\n }\n }\n }\n }\n}\n\n.vc-badge__content {\n @apply tw-flex tw-relative;\n}\n\n.vc-badge__badge {\n @apply tw-absolute tw-rounded-full tw-font-semibold tw-bg-[color:var(--badge-background-color)] tw-text-[color:var(--badge-text-color)] tw-border tw-border-solid tw-border-[color:var(--badge-border-color)] tw-transition-all tw-duration-150 tw-shrink-0;\n box-sizing: border-box;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 0 4px;\n line-height: 1;\n\n &:focus-visible {\n @apply tw-outline-none tw-ring-2 tw-ring-offset-1 tw-ring-[color:var(--badge-focus-ring-color)];\n }\n}\n\n.vc-badge__text {\n @apply tw-text-xxs tw-leading-none;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n height: 100%;\n}\n\n.vc-badge__badge--content-long {\n @apply tw-px-1;\n}\n\n.vc-badge__badge--content-very-long {\n @apply tw-px-1;\n max-width: 40px;\n .vc-badge__text {\n @apply tw-overflow-hidden tw-text-ellipsis;\n white-space: nowrap;\n }\n}\n\n.vc-badge__badge--dot {\n @apply tw-p-0;\n}\n\n// Variants\n.vc-badge__badge--primary {\n @apply tw-bg-[color:var(--badge-background-color-primary)];\n}\n\n.vc-badge__badge--success {\n @apply tw-bg-[color:var(--badge-background-color-success)];\n}\n\n.vc-badge__badge--warning {\n @apply tw-bg-[color:var(--badge-background-color-warning)];\n}\n\n.vc-badge__badge--danger {\n @apply tw-bg-[color:var(--badge-background-color-danger)];\n}\n\n.vc-badge__badge--info {\n @apply tw-bg-[color:var(--badge-background-color-info)];\n}\n\n.vc-badge__badge--secondary {\n @apply tw-bg-[color:var(--badge-background-color-secondary)];\n}\n\n.vc-badge__badge--active {\n @apply tw-bg-[color:var(--badge-background-color-active)] tw-text-[color:var(--badge-text-color-active)] tw-border-[color:var(--badge-border-color-active)];\n}\n\n.vc-badge__badge--clickable {\n @apply tw-cursor-pointer hover:tw-bg-[color:var(--badge-background-color-hover)] hover:tw-text-[color:var(--badge-text-color-hover)] hover:tw-border-[color:var(--badge-border-color-hover)];\n}\n\n.vc-badge__badge--disabled {\n @apply tw-cursor-not-allowed tw-opacity-50 tw-bg-[color:var(--badge-background-color-disabled)] tw-text-[color:var(--badge-text-color-disabled)] tw-border-[color:var(--badge-border-color-disabled)] hover:tw-bg-[color:var(--badge-background-color-disabled)] hover:tw-text-[color:var(--badge-text-color-disabled)] hover:tw-border-[color:var(--badge-border-color-disabled)];\n}\n\n// Inline mode - relative positioning, no wrapper\n.vc-badge__badge--inline {\n @apply tw-relative tw-top-0 tw-right-0;\n}\n\n.vc-badge__badge--inline-small {\n height: var(--badge-size-small);\n min-width: var(--badge-size-small);\n\n &.vc-badge__badge--dot {\n height: var(--badge-dot-size-small);\n min-width: var(--badge-dot-size-small);\n width: var(--badge-dot-size-small);\n }\n}\n\n.vc-badge__badge--inline-medium {\n height: var(--badge-size-medium);\n min-width: var(--badge-size-medium);\n\n &.vc-badge__badge--dot {\n height: var(--badge-dot-size-medium);\n min-width: var(--badge-dot-size-medium);\n width: var(--badge-dot-size-medium);\n }\n}\n\n// Inline variant overrides — soft bg-{color}-50 / text-{color}-700 pattern\n$badge-variants: primary, secondary, success, warning, danger, info;\n\n@each $v in $badge-variants {\n .vc-badge__badge--inline.vc-badge__badge--#{$v} {\n @apply tw-bg-[color:var(--badge-inline-bg-#{$v})] tw-text-[color:var(--badge-inline-text-#{$v})] tw-border-[color:var(--badge-inline-border-#{$v})];\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-card\"\n :class=\"[{ 'vc-card--collapsable': isCollapsable }, `vc-card--${variant}`]\"\n >\n <!-- Skeleton header -->\n <div\n v-if=\"(header || $slots['header']) && bladeLoading\"\n class=\"vc-card__header\"\n >\n <div class=\"vc-card__header-content\">\n <VcSkeleton\n v-if=\"icon\"\n variant=\"circle\"\n :width=\"22\"\n :height=\"22\"\n class=\"tw-mr-3\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"80 + (header?.length || 0) * 4\"\n :height=\"14\"\n />\n </div>\n </div>\n <!-- Normal header -->\n <div\n v-else-if=\"header || $slots['header']\"\n class=\"vc-card__header\"\n :role=\"isCollapsable ? 'button' : undefined\"\n :tabindex=\"isCollapsable ? 0 : undefined\"\n :aria-expanded=\"isCollapsable ? !isCollapsedInternal : undefined\"\n :aria-controls=\"isCollapsable ? cardBodyId : undefined\"\n @click=\"onHeaderClick\"\n @keydown.enter.prevent=\"onHeaderClick\"\n @keydown.space.prevent=\"onHeaderClick\"\n >\n <slot name=\"header\">\n <div class=\"vc-card__header-content\">\n <VcIcon\n v-if=\"icon\"\n class=\"vc-card__icon\"\n :icon=\"icon\"\n size=\"xl\"\n ></VcIcon>\n <div class=\"vc-card__title\">{{ header }}</div>\n </div>\n </slot>\n <div\n v-if=\"$slots['actions']\"\n class=\"vc-card__actions\"\n >\n <slot name=\"actions\"></slot>\n </div>\n <VcIcon\n v-if=\"isCollapsable\"\n class=\"vc-card__collapse\"\n :class=\"{ 'vc-card__collapse--rotated': !isCollapsedInternal }\"\n icon=\"lucide-chevron-down\"\n size=\"s\"\n ></VcIcon>\n </div>\n <div\n :id=\"cardBodyId\"\n class=\"vc-card__body-wrapper\"\n :class=\"{\n 'vc-card__body-wrapper--collapsed': isCollapsedInternal,\n 'vc-card__body-wrapper--fill': fill,\n }\"\n >\n <div\n :class=\"[{ 'tw-flex': fill }, 'vc-card__body']\"\n v-bind=\"$attrs\"\n >\n <slot></slot>\n </div>\n </div>\n </div>\n</template>\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport { ref, watch, useId } from \"vue\";\n\nconst bladeLoading = useBladeLoading();\n\nexport interface Props {\n header?: string;\n icon?: string;\n isCollapsable?: boolean;\n isCollapsed?: boolean;\n /**\n * Card content will fill the available space\n */\n fill?: boolean;\n variant?: \"default\" | \"success\" | \"danger\";\n}\n\nexport interface Emits {\n (event: \"header:click\"): void;\n (event: \"state:collapsed\", isCollapsedState: boolean): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: \"default\",\n});\n\nconst emit = defineEmits<Emits>();\n\ndefineOptions({\n name: \"VcCard\",\n inheritAttrs: false,\n});\n\ndefineSlots<{\n default: (props?: any) => any;\n actions: (props?: any) => any;\n header: (props?: any) => any;\n}>();\n\nconst cardBodyId = `vc-card-body-${useId()}`;\nconst isCollapsedInternal = ref();\n\nfunction onHeaderClick() {\n if (props.isCollapsable) {\n isCollapsedInternal.value = !isCollapsedInternal.value;\n emit(\"state:collapsed\", isCollapsedInternal.value);\n }\n emit(\"header:click\");\n}\n\nwatch(\n () => props.isCollapsed,\n (value) => {\n isCollapsedInternal.value = value;\n },\n {\n immediate: true,\n },\n);\n</script>\n\n<style lang=\"scss\">\n:root {\n --card-background: var(--additional-50);\n --card-border-radius: 6px;\n --card-header-background: var(--secondary-50);\n --card-header-color: var(--secondary-950);\n\n --card-header-background-success: var(--success-100);\n --card-header-background-danger: var(--danger-100);\n\n --card-header-color-success: var(--success-600);\n --card-header-color-danger: var(--danger-600);\n\n --card-header-padding-hor: 24px;\n --card-header-padding-vert: 17px;\n\n --card-border-color: var(--neutrals-200);\n --card-hover-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n\n --card-focus-ring-color: var(--primary-300);\n}\n\n$variants: success, danger;\n\n.vc-card {\n @apply tw-bg-[color:var(--card-background)] tw-border\n tw-border-[color:var(--card-border-color)] tw-border-solid tw-box-border\n tw-rounded-[var(--card-border-radius)] tw-overflow-hidden\n tw-flex-grow tw-flex tw-flex-col tw-transition-shadow tw-duration-200;\n\n &:hover {\n box-shadow: var(--card-hover-shadow);\n }\n\n &__header {\n @apply tw-border-b tw-border-[color:var(--card-border-color)] tw-border-solid tw-bg-[color:var(--card-header-background)] tw-px-[var(--card-header-padding-hor)] tw-py-[var(--card-header-padding-vert)] tw-flex tw-items-center tw-justify-between tw-w-full tw-box-border\n tw-transition-colors tw-duration-150;\n\n &:focus-visible {\n @apply tw-outline-none tw-ring-2 tw-ring-inset tw-ring-[color:var(--card-focus-ring-color)];\n }\n }\n\n &__header-content {\n @apply tw-flex tw-items-center;\n }\n\n &--collapsable &__header {\n @apply tw-cursor-pointer tw-select-none;\n\n &:hover {\n @apply tw-bg-[color:var(--card-header-background)] tw-brightness-[0.97];\n }\n }\n\n &__title {\n @apply tw-normal-case tw-flex-grow\n tw-text-[color:var(--card-header-color)]\n tw-text-sm tw-font-bold;\n }\n\n &__icon {\n @apply tw-text-[color:var(--card-header-color)] tw-mr-3;\n }\n\n &__collapse {\n @apply tw-text-[color:var(--card-header-color)] tw-ml-3\n tw-transition-transform tw-duration-200;\n\n &--rotated {\n @apply tw-rotate-180;\n }\n }\n\n // Collapsible body wrapper with smooth height animation\n &__body-wrapper {\n display: grid;\n grid-template-rows: 1fr;\n transition: grid-template-rows 200ms ease-out;\n\n &--collapsed {\n grid-template-rows: 0fr;\n }\n\n // Fill mode: absorb remaining height of the card's flex column so that\n // body content (e.g. VcDataTable) is bounded and can manage its own scroll.\n // `minmax(0, 1fr)` is required — plain `1fr` resolves to `minmax(auto, 1fr)`,\n // whose `auto` minimum lets the grid row expand past the card under\n // tall content, pushing footer elements (pagination) outside the card.\n &--fill {\n @apply tw-grow tw-min-h-0;\n grid-template-rows: minmax(0, 1fr);\n }\n\n // Keep the collapse animation consistent when fill is active —\n // interpolating between `minmax(0, 1fr)` and `minmax(0, 0fr)` preserves\n // the matching track syntax required for a smooth transition.\n &--fill#{&}--collapsed {\n grid-template-rows: minmax(0, 0fr);\n }\n }\n\n &__body {\n @apply tw-flex-grow tw-box-border tw-flex-col tw-overflow-hidden;\n }\n\n @each $variant in $variants {\n &--#{$variant} {\n .vc-card__header {\n @apply tw-bg-[color:var(--card-header-background-#{$variant})];\n }\n .vc-card__title {\n @apply tw-text-[color:var(--card-header-color-#{$variant})];\n }\n }\n }\n}\n</style>\n","import _Card from \"@ui/components/atoms/vc-card/vc-card.vue\";\r\n\r\nexport const VcCard = _Card as typeof _Card;\r\n","<template>\r\n <div\r\n class=\"vc-col\"\r\n :style=\"{ flexGrow: size }\"\r\n >\r\n <slot></slot>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nexport interface Props {\r\n size?: number;\r\n}\r\n\r\nwithDefaults(defineProps<Props>(), {\r\n size: 1,\r\n});\r\n\r\ndefineSlots<{\r\n default: (props: any) => any;\r\n}>();\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --col-gap: 0;\r\n}\r\n\r\n.vc-col {\r\n @apply tw-flex tw-flex-col tw-min-w-0 tw-basis-0;\r\n gap: var(--col-gap);\r\n}\r\n</style>\r\n","import { VNode } from \"vue\";\r\nimport _Container from \"@ui/components/atoms/vc-container/vc-container.vue\";\r\n\r\nexport const VcContainer = _Container as typeof _Container & {\r\n new (): {\r\n $slots: {\r\n default: () => VNode[];\r\n };\r\n };\r\n};\r\n","<template>\n <div\n class=\"vc-image\"\n :class=\"[`vc-image_${size}`]\"\n >\n <div\n :class=\"[\n 'vc-image__container',\n `vc-image_${aspect}`,\n {\n 'vc-image__container--rounded': rounded,\n 'vc-image__container--bordered': bordered,\n 'vc-image__container--clickable': clickable,\n },\n ]\"\n :style=\"imageHandler\"\n :role=\"clickable ? 'button' : src && alt ? 'img' : undefined\"\n :tabindex=\"clickable ? 0 : undefined\"\n :aria-label=\"alt || (clickable ? 'Image' : undefined)\"\n @click=\"onClick\"\n @keydown.enter.prevent=\"onClick\"\n @keydown.space.prevent=\"onClick\"\n >\n <div\n v-if=\"!src\"\n class=\"vc-image__placeholder\"\n aria-hidden=\"true\"\n >\n <VcIcon\n :icon=\"emptyIcon\"\n size=\"xl\"\n ></VcIcon>\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { computed, ref, watch } from \"vue\";\nimport { createLogger } from \"@core/utilities\";\nimport { getThumbnailUrl, type ThumbnailSize } from \"@core/utilities/thumbnail\";\n\nconst logger = createLogger(\"vc-image\");\n\nexport interface Props {\n aspect?: \"1x1\" | \"16x9\" | \"4x3\" | \"3x2\";\n rounded?: boolean;\n bordered?: boolean;\n clickable?: boolean;\n src?: string;\n size?: \"auto\" | \"xxs\" | \"xs\" | \"s\" | \"m\" | \"l\" | \"xl\" | \"xxl\";\n background?: \"cover\" | \"contain\" | \"auto\";\n emptyIcon?: string;\n /** Accessible alt text for the image */\n alt?: string;\n /** Load a thumbnail variant instead of the full-size image */\n thumbnailSize?: ThumbnailSize;\n}\n\nexport interface Emits {\n (event: \"click\"): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n aspect: \"1x1\",\n size: \"auto\",\n background: \"cover\",\n emptyIcon: \"lucide-image\",\n});\n\nconst emit = defineEmits<Emits>();\n\nfunction ensureHttps(url: string): string {\n if (!url) return url;\n\n try {\n const urlObject = new URL(url);\n if (urlObject.protocol === \"http:\" && window.location.protocol === \"https:\") {\n urlObject.protocol = \"https:\";\n return urlObject.href;\n }\n } catch (_e) {\n logger.warn(\"Invalid URL:\", url);\n }\n return url;\n}\n\nconst thumbnailSrc = computed(() => getThumbnailUrl(props.src, props.thumbnailSize) ?? props.src);\nconst useFallback = ref(false);\nconst resolvedSrc = computed(() => (useFallback.value ? props.src : thumbnailSrc.value));\n\n// Reset fallback when src or thumbnailSize changes\nwatch(\n () => [props.src, props.thumbnailSize],\n () => {\n useFallback.value = false;\n },\n);\n\n// Probe thumbnail URL — fall back to original on error\nwatch(\n resolvedSrc,\n (url) => {\n if (!url || !props.thumbnailSize || useFallback.value) return;\n if (url === props.src) return; // already original, nothing to probe\n const img = new Image();\n img.src = ensureHttps(url);\n img.onerror = () => {\n useFallback.value = true;\n };\n },\n { immediate: true },\n);\n\nconst imageHandler = computed(() => {\n if (resolvedSrc.value) {\n const secureUrl = ensureHttps(resolvedSrc.value);\n return `background: url(${CSS.escape(secureUrl)}) center / ${props.background} no-repeat`;\n }\n return undefined;\n});\n\nfunction onClick(): void {\n if (props.clickable) {\n emit(\"click\");\n }\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --image-size-xxs: 24px;\n --image-size-xs: 32px;\n --image-size-s: 48px;\n --image-size-m: 64px;\n --image-size-l: 96px;\n --image-size-xl: 128px;\n --image-size-xxl: 145px;\n\n --image-border-radius: 6px;\n --image-border-color: var(--neutrals-200);\n --image-empty-icon-color: var(--neutrals-400);\n --image-focus-ring-color: var(--primary-300);\n}\n\n$aspects: (\n 1x1: 100%,\n 16x9: 56.25%,\n 4x3: 75%,\n 3x2: 66.66%,\n);\n\n$sizes: xxs, xs, s, m, l, xl, xxl;\n\n.vc-image {\n @apply tw-inline-block tw-relative;\n\n @each $name, $aspect in $aspects {\n &_#{$name} {\n @apply tw-pb-[#{$aspect}];\n }\n }\n\n @each $size in $sizes {\n &_#{$size} {\n @apply tw-w-[var(--image-size-#{$size})] tw-max-w-full tw-min-w-0;\n }\n }\n\n &_auto {\n @apply tw-w-full;\n }\n\n &__container {\n @apply tw-relative tw-transition-shadow tw-duration-150;\n\n &:focus-visible {\n @apply tw-outline-none tw-ring-2 tw-ring-offset-2 tw-ring-[color:var(--image-focus-ring-color)];\n }\n }\n\n &__container--rounded {\n @apply tw-rounded-full tw-overflow-hidden;\n }\n\n &__container--bordered {\n @apply tw-rounded-[var(--image-border-radius)] tw-border tw-border-solid tw-border-[color:var(--image-border-color)] tw-overflow-hidden;\n }\n\n &__container--clickable {\n @apply tw-cursor-pointer;\n\n &:hover {\n @apply tw-opacity-90;\n }\n }\n\n &__placeholder {\n @apply tw-absolute tw-w-full tw-h-full tw-flex tw-items-center tw-justify-center tw-text-[color:var(--image-empty-icon-color)] tw-bg-neutrals-100 tw-rounded-[inherit];\n }\n}\n</style>\n","<template>\n <button\n type=\"button\"\n class=\"vc-link\"\n :class=\"{\n 'vc-link--active': active,\n 'vc-link--disabled': disabled,\n }\"\n :disabled=\"disabled\"\n :aria-disabled=\"disabled\"\n @click=\"onClickFn\"\n >\n <span class=\"vc-link__text\"><slot></slot></span>\n </button>\n</template>\n\n<script lang=\"ts\" setup>\nexport interface Props {\n active?: boolean;\n disabled?: boolean;\n onClick?: () => void;\n}\n\nexport interface Emits {\n (event: \"click\"): void;\n}\n\nconst props = defineProps<Props>();\nconst emit = defineEmits<Emits>();\n\nfunction onClickFn(): void {\n if (!props.disabled) {\n emit(\"click\");\n }\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --link-text-color: var(--primary-500);\n --link-text-color-hover: var(--primary-400);\n --link-text-color-active: var(--primary-700);\n --link-text-color-disabled: var(--neutrals-300);\n --link-focus-ring-color: color-mix(in srgb, var(--primary-500) 30%, transparent);\n}\n\n.vc-link {\n @apply tw-text-[color:var(--link-text-color)] tw-no-underline tw-cursor-pointer tw-transition tw-duration-200 tw-max-w-full hover:tw-text-[color:var(--link-text-color-hover)] hover:tw-underline\n focus-visible:tw-outline-none focus-visible:tw-ring-[3px] focus-visible:tw-ring-[color:var(--link-focus-ring-color)] focus-visible:tw-rounded-sm;\n /* Reset button styles for link appearance */\n @apply tw-bg-transparent tw-border-none tw-p-0 tw-text-left;\n\n &--active {\n @apply tw-text-[color:var(--link-text-color-active)] tw-no-underline hover:tw-text-[color:var(--link-text-color-active)] hover:tw-no-underline;\n }\n\n &--disabled {\n @apply tw-cursor-not-allowed tw-text-[color:var(--link-text-color-disabled)] tw-no-underline tw-opacity-50 hover:tw-text-[color:var(--link-text-color-disabled)] hover:tw-no-underline;\n }\n\n &__text {\n @apply tw-block tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap;\n }\n}\n</style>\n","import { VNode } from \"vue\";\r\nimport _Link from \"@ui/components/atoms/vc-link/vc-link.vue\";\r\n\r\nexport const VcLink = _Link as typeof _Link & {\r\n new (): {\r\n $slots: {\r\n default: () => VNode[];\r\n };\r\n };\r\n};\r\n","<template>\r\n <div\r\n class=\"vc-loading-overlay\"\r\n :class=\"{\r\n 'vc-loading-overlay--active': active,\r\n }\"\r\n role=\"status\"\r\n :aria-busy=\"active\"\r\n aria-live=\"polite\"\r\n >\r\n <div class=\"vc-loading-overlay__bar\">\r\n <div class=\"vc-loading-overlay__bar-fill\"></div>\r\n </div>\r\n <span class=\"tw-sr-only\">{{ active ? \"Loading...\" : \"\" }}</span>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nexport interface Props {\r\n active?: boolean;\r\n}\r\n\r\ndefineProps<Props>();\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --loading-bar-color: var(--primary-500);\r\n --loading-bar-track: var(--primary-100);\r\n --loading-overlay-bg: rgba(255, 255, 255, 0.6);\r\n --loading-bar-width: 140px;\r\n --loading-bar-height: 4px;\r\n}\r\n\r\n.vc-loading-overlay {\r\n @apply tw-absolute tw-items-center tw-justify-center tw-w-full tw-h-full tw-box-border tw-hidden;\r\n z-index: var(--z-critical-loading);\r\n\r\n &--active {\r\n @apply tw-flex #{!important};\r\n @apply tw-backdrop-blur-[3px];\r\n background-color: var(--loading-overlay-bg);\r\n }\r\n\r\n &__bar {\r\n width: var(--loading-bar-width);\r\n height: var(--loading-bar-height);\r\n border-radius: 9999px;\r\n background: var(--loading-bar-track);\r\n overflow: hidden;\r\n position: relative;\r\n }\r\n\r\n &__bar-fill {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n height: 100%;\r\n width: 40%;\r\n border-radius: 9999px;\r\n background: linear-gradient(90deg, var(--loading-bar-track), var(--loading-bar-color));\r\n animation: vc-bar-sweep 1.5s ease-in-out infinite;\r\n }\r\n}\r\n\r\n@keyframes vc-bar-sweep {\r\n 0% {\r\n left: -40%;\r\n }\r\n 100% {\r\n left: 100%;\r\n }\r\n}\r\n</style>\r\n","import _Loading from \"@ui/components/atoms/vc-loading/vc-loading.vue\";\r\n\r\nexport const VcLoading = _Loading as typeof _Loading;\r\n","<template>\n <div\n class=\"vc-progress\"\n :class=\"{\n 'vc-progress--striped': variant === 'striped',\n }\"\n role=\"progressbar\"\n :aria-valuenow=\"clampedValue\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-label=\"ariaLabel\"\n >\n <div\n class=\"vc-progress__value\"\n :style=\"{ transform: `translateX(-${100 - clampedValue}%)` }\"\n ></div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\n\nexport interface Props {\n value?: number;\n variant?: \"default\" | \"striped\";\n /** Accessible label describing what the progress represents */\n ariaLabel?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n value: 0,\n variant: \"default\",\n ariaLabel: \"Progress\",\n});\n\nconst clampedValue = computed(() => Math.max(0, Math.min(100, props.value)));\n</script>\n\n<style lang=\"scss\">\n:root {\n --progressbar-height: 8px;\n --progressbar-border-radius: 9999px;\n --progressbar-background-color: var(--neutrals-200);\n --progressbar-foreground-color: var(--primary-500);\n --progressbar-striped-bg:\n linear-gradient(45deg, transparent 50%, var(--primary-400) 50%, var(--primary-400) 75%, transparent 75%) left/30px\n 30px repeat-x,\n var(--primary-500);\n --progressbar-striped-color: var(--primary-400);\n}\n\n@keyframes progress-stripe {\n from {\n background-position: 0 0;\n }\n to {\n background-position: 30px 0;\n }\n}\n\n.vc-progress {\n @apply tw-relative tw-rounded-[var(--progressbar-border-radius)] tw-h-[var(--progressbar-height)] tw-box-border tw-bg-[color:var(--progressbar-background-color)] tw-overflow-hidden;\n\n &__value {\n @apply tw-bg-[color:var(--progressbar-foreground-color)] tw-h-full tw-w-full tw-rounded-[inherit];\n transition: transform 300ms ease-out;\n }\n\n &--striped .vc-progress__value {\n background: var(--progressbar-striped-bg);\n animation: progress-stripe 1s linear infinite;\n }\n}\n</style>\n","import { VNode } from \"vue\";\r\nimport _Progress from \"@ui/components/atoms/vc-progress/vc-progress.vue\";\r\n\r\nexport const VcProgress = _Progress as typeof _Progress & {\r\n new (): {\r\n $slots: {\r\n default: () => VNode[];\r\n };\r\n };\r\n};\r\n","<template>\r\n <div class=\"vc-row\">\r\n <slot></slot>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\ndefineSlots<{\r\n default: (props: any) => any;\r\n}>();\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --row-gap: 0;\r\n}\r\n\r\n.vc-row {\r\n @apply tw-flex tw-flex-nowrap tw-items-stretch;\r\n gap: var(--row-gap);\r\n\r\n .vc-app--mobile & {\r\n @apply tw-grid;\r\n }\r\n}\r\n</style>\r\n","<template>\n <div\n class=\"vc-status\"\n :class=\"[\n `vc-status--${variant}`,\n {\n 'vc-status--extended': extend,\n 'vc-status--dot': dot,\n },\n ]\"\n role=\"status\"\n :aria-label=\"dot ? variant : undefined\"\n >\n <div class=\"vc-status__content\">\n <slot></slot>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nexport interface Props {\n variant?: \"info\" | \"warning\" | \"danger\" | \"success\" | \"light-danger\" | \"info-dark\" | \"primary\";\n extend?: boolean;\n dot?: boolean;\n}\n\nwithDefaults(defineProps<Props>(), {\n variant: \"info\",\n dot: false,\n});\n\ndefineSlots<{\n default: (props?: any) => any;\n}>();\n</script>\n\n<style lang=\"scss\">\n:root {\n --status-padding: 4px 14px;\n --status-padding-extended: 8px;\n --status-dot-size: 10px;\n --status-text-color: var(--neutrals-700);\n\n --status-border-radius: 9999px;\n --status-border-radius-extended: 6px;\n --status-border-width: 1px;\n\n --status-border-color: var(--neutrals-200);\n --status-bg-color: var(--additional-50);\n\n --status-info-color: var(--info-700);\n --status-info-main-color: var(--info-500);\n --status-info-bg-color: var(--info-50);\n\n --status-warning-color: var(--warning-700);\n --status-warning-main-color: var(--warning-500);\n --status-warning-bg-color: var(--warning-50);\n\n --status-danger-color: var(--danger-700);\n --status-danger-main-color: var(--danger-500);\n --status-danger-bg-color: var(--danger-50);\n\n --status-success-color: var(--success-700);\n --status-success-main-color: var(--success-500);\n --status-success-bg-color: var(--success-50);\n\n --status-light-danger-color: var(--danger-700);\n --status-light-danger-main-color: var(--danger-300);\n --status-light-danger-bg-color: var(--danger-50);\n\n --status-info-dark-color: var(--additional-50);\n --status-info-dark-main-color: var(--info-600);\n --status-info-dark-bg-color: var(--info-600);\n\n --status-primary-color: var(--primary-700);\n --status-primary-main-color: var(--primary-500);\n --status-primary-bg-color: var(--primary-50);\n}\n\n$variants: info, warning, danger, success, light-danger, info-dark, primary;\n\n.vc-status {\n @apply tw-inline-block tw-font-normal tw-whitespace-nowrap tw-text-xs tw-truncate tw-text-center tw-border tw-border-solid tw-box-border;\n @apply tw-py-1 tw-px-3 tw-rounded-[var(--status-border-radius)];\n @apply tw-flex tw-items-center tw-justify-center tw-flex-row tw-relative;\n @apply tw-border-[length:var(--status-border-width)] tw-bg-[color:var(--status-bg-color)] tw-border-[color:var(--status-border-color)];\n\n &.vc-status--dot {\n @apply tw-p-0 tw-w-[var(--status-dot-size)] tw-h-[var(--status-dot-size)] tw-max-w-[var(--status-dot-size)] tw-rounded-full tw-border-0 #{!important};\n }\n\n @each $variant in $variants {\n &.vc-status--#{$variant} {\n @apply tw-bg-[color:var(--status-bg-color)] tw-max-w-fit;\n @apply tw-border-[color:var(--status-border-color)] #{!important};\n\n &::before {\n @apply tw-content-[''] tw-bg-[color:var(--status-#{$variant}-main-color)] tw-w-2 tw-h-2 tw-rounded-full tw-mr-2 tw-shrink-0;\n }\n\n &.vc-status--dot {\n @apply tw-bg-[color:var(--status-#{$variant}-main-color)];\n &::before {\n @apply tw-content-none;\n }\n }\n\n &.vc-status--extended {\n @apply tw-whitespace-normal tw-rounded-[var(--status-border-radius-extended)] tw-justify-start;\n @apply tw-max-w-full tw-p-[var(--status-padding-extended)] tw-bg-[color:var(--status-#{$variant}-bg-color)] tw-border-none;\n\n &::before {\n @apply tw-content-none;\n }\n\n .vc-status__content {\n @apply tw-whitespace-normal tw-text-[color:var(--status-#{$variant}-color)] #{!important};\n }\n }\n }\n }\n\n &__content {\n @apply tw-truncate tw-text-[color:var(--status-text-color)] tw-font-medium;\n .vc-status--dot & {\n @apply tw-hidden;\n }\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-status-icon\"\n role=\"img\"\n :aria-label=\"status ? 'Active' : 'Inactive'\"\n >\n <VcIcon\n v-if=\"status\"\n icon=\"lucide-circle-check\"\n class=\"vc-status-icon__icon vc-status-icon__icon--success\"\n aria-hidden=\"true\"\n ></VcIcon>\n <VcIcon\n v-else\n icon=\"lucide-circle-x\"\n class=\"vc-status-icon__icon vc-status-icon__icon--inactive\"\n aria-hidden=\"true\"\n ></VcIcon>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nexport interface Props {\n status?: boolean;\n}\n\ndefineProps<Props>();\n</script>\n\n<style lang=\"scss\">\n:root {\n --status-icon-success-color: var(--success-500);\n --status-icon-inactive-color: var(--neutrals-300);\n}\n\n.vc-status-icon {\n @apply tw-inline-flex tw-items-center tw-justify-center;\n\n &__icon--success {\n @apply tw-text-[color:var(--status-icon-success-color)];\n }\n\n &__icon--inactive {\n @apply tw-text-[color:var(--status-icon-inactive-color)];\n }\n}\n</style>\n","<template>\n <div class=\"vc-video\">\n <VcLabel\n v-if=\"label\"\n class=\"vc-video__label\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >\n {{ tooltip }}\n </template>\n </VcLabel>\n\n <div class=\"vc-video__container\">\n <div v-if=\"source\">\n <iframe\n :src=\"source\"\n :title=\"label || 'Video'\"\n width=\"100%\"\n height=\"300px\"\n frameborder=\"0\"\n :sandbox=\"sandbox\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowfullscreen\n loading=\"lazy\"\n >\n </iframe>\n </div>\n <div\n v-else\n class=\"vc-video__placeholder\"\n role=\"img\"\n :aria-label=\"$t('COMPONENTS.ATOMS.VC_VIDEO.NO_SOURCE')\"\n >\n <VcIcon\n icon=\"lucide-film\"\n size=\"xl\"\n aria-hidden=\"true\"\n ></VcIcon>\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\n\nexport interface Props {\n label?: string;\n tooltip?: string;\n source?: string;\n /**\n * Additional iframe sandbox tokens to append to the secure default\n * (`allow-scripts allow-presentation`). Space-separated.\n *\n * Enabling `allow-same-origin` together with `allow-scripts` disables sandbox\n * protection entirely and is strongly discouraged for untrusted sources.\n */\n additionalSandbox?: string;\n}\n\nexport interface Emits {\n (event: \"click\"): void;\n}\n\nconst props = defineProps<Props>();\ndefineEmits<Emits>();\n\nconst sandbox = computed(() => {\n const base = [\"allow-scripts\", \"allow-presentation\"];\n const extra = (props.additionalSandbox ?? \"\").split(/\\s+/).filter(Boolean);\n return [...new Set([...base, ...extra])].join(\" \");\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --video-icon-color: var(--neutrals-400);\n --video-placeholder-bg: var(--neutrals-100);\n --video-border-radius: 6px;\n --video-border-color: var(--neutrals-200);\n}\n\n.vc-video {\n @apply tw-inline-block tw-relative;\n\n &__label {\n @apply tw-mb-2;\n }\n\n &__container {\n @apply tw-w-full tw-relative tw-rounded-[var(--video-border-radius)] tw-overflow-hidden tw-border tw-border-solid tw-border-[color:var(--video-border-color)];\n }\n\n &__placeholder {\n @apply tw-w-full tw-h-[200px] tw-flex tw-items-center tw-justify-center tw-text-[color:var(--video-icon-color)] tw-bg-[color:var(--video-placeholder-bg)];\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-widget\"\n :data-widget-id=\"widgetId\"\n :data-widget-name=\"title\"\n :class=\"[\n { 'vc-widget--expanded': isExpanded },\n { 'vc-widget--collapsed': !isExpanded },\n { 'vc-widget--disabled': disabled },\n { 'vc-widget--horizontal': horizontal },\n ]\"\n role=\"button\"\n :tabindex=\"disabled ? -1 : 0\"\n :aria-disabled=\"disabled || undefined\"\n :aria-label=\"title || undefined\"\n @click=\"onClick\"\n @keydown.enter.prevent=\"onClick\"\n @keydown.space.prevent=\"onClick\"\n >\n <VcBadge\n :content=\"truncateCount\"\n custom-position\n top=\"-6px\"\n size=\"s\"\n >\n <div class=\"vc-widget__icon-container\">\n <VcIcon\n v-if=\"icon\"\n class=\"vc-widget__icon\"\n :icon=\"icon\"\n size=\"m\"\n aria-hidden=\"true\"\n ></VcIcon>\n </div>\n </VcBadge>\n <div\n v-if=\"title\"\n class=\"vc-widget__content\"\n >\n <div class=\"vc-widget__title\">\n {{ title }}\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcBadge } from \"@ui/components/atoms/vc-badge\";\nimport { formatBadgeCount } from \"@core/utilities/formatBadgeCount\";\n\nexport interface Props {\n icon?: string;\n title?: string;\n value?: string | number;\n disabled?: boolean;\n isExpanded?: boolean;\n horizontal?: boolean;\n widgetId?: string;\n}\n\nconst props = defineProps<Props>();\nconst emit = defineEmits<{\n (event: \"click\"): void;\n}>();\n\nfunction onClick() {\n if (props.disabled) return;\n emit(\"click\");\n}\n\nconst truncateCount = computed(() => formatBadgeCount(props.value));\n</script>\n\n<style lang=\"scss\">\n:root {\n --widget-bg-color: transparent;\n --widget-bg-hover-color: var(--neutrals-50);\n --widget-icon-color: var(--neutrals-700);\n --widget-icon-hover-color: var(--primary-600);\n --widget-icon-disabled-color: var(--neutrals-400);\n --widget-title-color: var(--neutrals-600);\n --widget-title-hover-color: var(--primary-600);\n --widget-title-disabled-color: var(--neutrals-400);\n --widget-border-radius: 8px;\n --widget-focus-ring-color: var(--primary-300);\n}\n\n.vc-widget {\n @apply tw-relative tw-shrink-0 tw-px-2 tw-py-1.5 tw-w-max;\n @apply tw-flex tw-overflow-visible tw-box-border tw-flex-col tw-items-center tw-justify-center tw-cursor-pointer;\n @apply tw-bg-[color:var(--widget-bg-color)];\n @apply tw-transition-all tw-duration-150;\n @apply tw-rounded-[var(--widget-border-radius)];\n\n &:focus-visible {\n @apply tw-outline-none tw-ring-2 tw-ring-offset-1 tw-ring-[color:var(--widget-focus-ring-color)];\n }\n\n &--horizontal {\n @apply tw-flex-row tw-gap-2;\n\n .vc-widget__content {\n @apply tw-ml-1;\n }\n\n .vc-widget__title {\n @apply tw-mt-0 tw-text-left tw-whitespace-nowrap;\n }\n }\n\n &:hover:not(.vc-widget--disabled) {\n @apply tw-bg-[color:var(--widget-bg-hover-color)];\n\n .vc-widget__title {\n @apply tw-text-[color:var(--widget-title-hover-color)];\n }\n\n .vc-widget__icon {\n @apply tw-text-[color:var(--widget-icon-hover-color)];\n }\n }\n\n &__icon-container {\n @apply tw-flex tw-flex-col tw-items-center tw-justify-center;\n }\n\n &__icon {\n @apply tw-text-[color:var(--widget-icon-color)] tw-transition-colors tw-duration-150;\n }\n\n &__content {\n @apply tw-w-full;\n }\n\n &__title {\n @apply tw-font-medium tw-text-xs tw-text-[color:var(--widget-title-color)] tw-mt-1 tw-mx-0 tw-text-center tw-line-clamp-2\n tw-transition-colors tw-duration-150;\n }\n\n &--disabled {\n @apply tw-cursor-default tw-opacity-50;\n\n .vc-widget__icon {\n @apply tw-text-[color:var(--widget-icon-disabled-color)];\n }\n\n .vc-widget__title {\n @apply tw-text-[color:var(--widget-title-disabled-color)];\n }\n }\n}\n</style>\n","import _Widget from \"@ui/components/atoms/vc-widget/vc-widget.vue\";\r\n\r\nexport const VcWidget = _Widget as typeof _Widget;\r\n","<template>\n <div\n v-if=\"!bladeLoading\"\n class=\"vc-banner\"\n :class=\"[\n `vc-banner--${normalizedVariant}`,\n {\n 'vc-banner--title-only': isTitleOnly,\n 'vc-banner--collapsed': isCollapsed,\n },\n ]\"\n :role=\"normalizedVariant === 'danger' || normalizedVariant === 'warning' ? 'alert' : 'region'\"\n :aria-label=\"normalizedVariant === 'danger' ? 'Error' : normalizedVariant === 'warning' ? 'Warning' : 'Information'\"\n >\n <VcIcon\n v-if=\"icon\"\n :icon=\"icon\"\n :size=\"iconSize\"\n :variant=\"iconVariant\"\n class=\"vc-banner__icon\"\n aria-hidden=\"true\"\n />\n <div class=\"vc-banner__body\">\n <div\n v-if=\"hasTitle\"\n class=\"vc-banner__title\"\n >\n <slot name=\"title\"></slot>\n </div>\n <div\n v-if=\"hasContent\"\n class=\"vc-banner__content-wrapper\"\n :style=\"wrapperStyle\"\n >\n <div\n ref=\"contentRef\"\n class=\"vc-banner__content\"\n >\n <slot name=\"default\"></slot>\n </div>\n </div>\n <div\n v-if=\"showTrigger\"\n class=\"vc-banner__trigger\"\n >\n <slot\n name=\"trigger\"\n :is-expanded=\"isExpanded\"\n :toggle=\"toggle\"\n >\n <button\n type=\"button\"\n class=\"vc-banner__trigger-button\"\n :aria-expanded=\"isExpanded\"\n @click=\"toggle\"\n >\n {{ isExpanded ? $t(\"COMPONENTS.ATOMS.VC_BANNER.SHOW_LESS\") : $t(\"COMPONENTS.ATOMS.VC_BANNER.SHOW_MORE\") }}\n </button>\n </slot>\n </div>\n </div>\n </div>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { computed, useSlots } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useCollapsible } from \"@ui/composables/useCollapsible\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\n\nexport type CurrentBannerVariant = \"info\" | \"warning\" | \"danger\" | \"success\";\n/**\n * @deprecated Use current variants: \"info\" | \"warning\" | \"danger\" | \"success\".\n */\nexport type LegacyBannerVariant = \"light-danger\" | \"info-dark\" | \"primary\";\nexport type BannerVariant = CurrentBannerVariant | LegacyBannerVariant;\n\nexport interface Props {\n /**\n * @deprecated Legacy variants (\"light-danger\", \"info-dark\", \"primary\") are supported for backward compatibility\n * and mapped to modern variants (\"danger\", \"info\", \"info\").\n */\n variant?: BannerVariant;\n icon?: string;\n iconSize?: InstanceType<typeof VcIcon>[\"$props\"][\"size\"];\n iconVariant?: InstanceType<typeof VcIcon>[\"$props\"][\"variant\"];\n collapsedHeight?: number;\n}\n\ndefineSlots<{\n title: (props: any) => any;\n default: (props: any) => any;\n trigger: (props: { isExpanded: boolean; toggle: () => void }) => any;\n}>();\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: \"info\",\n iconSize: \"l\",\n collapsedHeight: 100,\n});\n\nconst bladeLoading = useBladeLoading();\nconst slots = useSlots();\nconst { contentRef, isExpanded, hasOverflow, wrapperStyle, toggle } = useCollapsible({\n collapsedHeight: props.collapsedHeight,\n});\n\nfunction normalizeVariant(variant: BannerVariant): CurrentBannerVariant {\n switch (variant) {\n case \"light-danger\":\n return \"danger\";\n case \"info-dark\":\n case \"primary\":\n return \"info\";\n default:\n return variant;\n }\n}\n\nconst normalizedVariant = computed<CurrentBannerVariant>(() => normalizeVariant(props.variant));\nconst hasTitle = computed(() => Boolean(slots.title));\nconst hasContent = computed(() => Boolean(slots.default));\nconst isTitleOnly = computed(() => hasTitle.value && !hasContent.value);\nconst showTrigger = computed(() => hasContent.value && hasOverflow.value);\nconst isCollapsed = computed(() => showTrigger.value && !isExpanded.value);\n\nif (import.meta.env?.DEV) {\n if (props.variant === \"light-danger\" || props.variant === \"info-dark\" || props.variant === \"primary\") {\n console.warn(\n `[VcBanner] variant \"${props.variant}\" is deprecated. Use \"${normalizeVariant(props.variant)}\" instead.`,\n );\n }\n}\n</script>\n\n<style lang=\"scss\">\n@use \"sass:map\";\n\n$banner-variants: (\n info: (\n bg: var(--neutrals-50),\n border: var(--info-100),\n accent: var(--info-500),\n ),\n warning: (\n bg: var(--neutrals-50),\n border: var(--warning-100),\n accent: var(--warning-500),\n ),\n danger: (\n bg: var(--neutrals-50),\n border: var(--danger-100),\n accent: var(--danger-500),\n ),\n success: (\n bg: var(--neutrals-50),\n border: var(--success-100),\n accent: var(--success-500),\n ),\n);\n\n.vc-banner {\n @apply tw-relative tw-flex tw-items-start tw-gap-3 tw-overflow-hidden tw-rounded-md tw-border tw-border-solid tw-py-3 tw-pr-3 tw-pl-4;\n --vc-banner-accent: var(--info-500);\n\n &::before {\n content: \"\";\n @apply tw-absolute tw-left-0 tw-top-0 tw-bottom-0;\n width: 3px;\n background-color: var(--vc-banner-accent);\n }\n\n @each $name, $colors in $banner-variants {\n &.vc-banner--#{$name} {\n --vc-banner-accent: #{map.get($colors, accent)};\n background-color: #{map.get($colors, bg)};\n border-color: #{map.get($colors, border)};\n }\n }\n\n &.vc-banner--title-only {\n @apply tw-items-center;\n\n .vc-banner__icon {\n @apply tw-mt-0;\n }\n }\n\n &__icon {\n @apply tw-mt-0.5 tw-shrink-0;\n color: var(--vc-banner-accent);\n }\n\n &__body {\n @apply tw-flex tw-flex-col tw-min-w-0 tw-flex-1;\n }\n\n &__title {\n @apply tw-text-sm tw-font-medium tw-leading-5;\n color: var(--neutrals-900);\n }\n\n &__content-wrapper {\n @apply tw-relative tw-overflow-hidden;\n transition: max-height 0.28s cubic-bezier(0.22, 1, 0.36, 1);\n will-change: max-height;\n\n &::after {\n content: \"\";\n @apply tw-pointer-events-none tw-absolute tw-bottom-0 tw-left-0 tw-right-0 tw-h-8;\n background: linear-gradient(to bottom, rgb(250 250 250 / 0), var(--neutrals-50));\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n }\n\n &__content {\n @apply tw-text-sm tw-leading-5;\n color: var(--neutrals-700);\n }\n\n &__title + &__content-wrapper {\n @apply tw-mt-0.5;\n }\n\n &.vc-banner--collapsed {\n .vc-banner__content-wrapper::after {\n opacity: 1;\n }\n }\n\n &__trigger {\n @apply tw-mt-1;\n }\n\n &__trigger-button {\n @apply tw-inline-flex tw-cursor-pointer tw-items-center tw-border-0 tw-bg-transparent tw-p-0 tw-text-sm tw-font-medium tw-leading-5;\n color: var(--vc-banner-accent);\n transition: color 0.15s ease;\n\n &:hover {\n @apply tw-underline;\n }\n\n &:focus-visible {\n outline: 2px solid var(--vc-banner-accent);\n outline-offset: 2px;\n border-radius: 2px;\n }\n }\n}\n</style>\n","<template>\n <aside\n class=\"vc-environment-banner\"\n :class=\"`vc-environment-banner--${color}`\"\n :aria-label=\"`Environment indicator: ${name}`\"\n >\n <span class=\"vc-environment-banner__label\">{{ name }}</span>\n </aside>\n</template>\n\n<script lang=\"ts\" setup>\nexport interface Props {\n name: string;\n /**\n * Badge color. Accepts a free string (matches `ComputedRef<string>` from\n * useEnvironmentName). Known values: primary | secondary | info | success |\n * warning | danger | neutral. Anything else falls back to neutral via CSS.\n */\n color?: string;\n}\n\nwithDefaults(defineProps<Props>(), {\n color: \"neutral\",\n});\n</script>\n\n<style lang=\"scss\">\n// Centered badge pinned to the top, matching the platform environment banner\n// (vc-env-badge). Colors use vc-shell theme tokens.\n.vc-environment-banner {\n @apply tw-fixed tw-top-0 tw-z-[2000] tw-inline-flex tw-items-center tw-justify-center;\n left: 50%;\n transform: translateX(-50%);\n height: 28px;\n padding: 0 14px;\n border-radius: 0 0 0.5rem 0.5rem;\n font-size: 13px;\n line-height: 1;\n font-weight: 700;\n color: var(--additional-50);\n pointer-events: none;\n box-shadow: 0 2px 6px rgb(0 0 0 / 15%);\n background: var(--environment-banner-color, var(--neutrals-500));\n\n &__label {\n white-space: nowrap;\n }\n\n &--primary {\n --environment-banner-color: var(--primary-500);\n }\n &--secondary {\n --environment-banner-color: var(--secondary-500);\n }\n &--info {\n --environment-banner-color: var(--info-500);\n }\n &--success {\n --environment-banner-color: var(--success-500);\n }\n &--warning {\n --environment-banner-color: var(--warning-500);\n }\n &--danger {\n --environment-banner-color: var(--danger-500);\n }\n &--neutral {\n --environment-banner-color: var(--neutrals-500);\n }\n}\n</style>\n","import { isRef, toValue } from \"vue\";\r\nimport type { BladeDescriptor } from \"@core/blade-navigation/types\";\r\n\r\n/**\r\n * Resolves a visibility value that can be:\r\n * - `undefined` → defaults to `true` (visible)\r\n * - `boolean` → used directly\r\n * - `Ref<boolean>` or `ComputedRef<boolean>` → unwrapped\r\n * - `(blade?: BladeDescriptor) => boolean` → called with blade context\r\n */\r\nexport function resolveVisibility(\r\n isVisible: boolean | ((...args: any[]) => boolean | undefined) | { value: boolean | undefined } | undefined,\r\n bladeInstance?: BladeDescriptor,\r\n): boolean {\r\n if (isVisible === undefined) {\r\n return true;\r\n }\r\n\r\n if (typeof isVisible === \"function\") {\r\n return Boolean(isVisible(bladeInstance));\r\n }\r\n\r\n if (isRef(isVisible)) {\r\n return Boolean(toValue(isVisible));\r\n }\r\n\r\n return Boolean(isVisible);\r\n}\r\n\r\n/**\r\n * Resolves a reactive boolean that can be:\r\n * - `undefined` → defaults to `false`\r\n * - `boolean` → used directly\r\n * - `Ref<boolean>` or `ComputedRef<boolean>` → unwrapped\r\n */\r\nexport function resolveReactiveBoolean(value: boolean | { value: boolean | undefined } | undefined): boolean {\r\n if (value === undefined) {\r\n return false;\r\n }\r\n\r\n if (isRef(value)) {\r\n return Boolean(toValue(value));\r\n }\r\n\r\n return Boolean(value);\r\n}\r\n","<template>\r\n <div\r\n class=\"vc-blade-toolbar-mobile\"\r\n role=\"toolbar\"\r\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_BLADE.TOOLBAR')\"\r\n >\r\n <!-- Backdrop with frosted glass -->\r\n <Transition name=\"toolbar-mobile-backdrop\">\r\n <div\r\n v-if=\"isExpanded\"\r\n class=\"vc-blade-toolbar-mobile__backdrop\"\r\n aria-hidden=\"true\"\r\n @click=\"closeMenu\"\r\n />\r\n </Transition>\r\n\r\n <!-- Staggered action items -->\r\n <div\r\n class=\"vc-blade-toolbar-mobile__menu\"\r\n :class=\"{ 'vc-blade-toolbar-mobile__menu--open': isExpanded }\"\r\n role=\"menu\"\r\n :aria-hidden=\"!isExpanded\"\r\n >\r\n <button\r\n v-for=\"(item, index) in items\"\r\n :key=\"item.id ?? index\"\r\n class=\"vc-blade-toolbar-mobile__action\"\r\n :style=\"getStaggerStyle(index)\"\r\n :disabled=\"isItemDisabled(item)\"\r\n :aria-label=\"resolveTitle(item)\"\r\n :tabindex=\"isExpanded ? 0 : -1\"\r\n role=\"menuitem\"\r\n @click=\"handleItemClick(item)\"\r\n >\r\n <span class=\"vc-blade-toolbar-mobile__action-label\">\r\n {{ resolveTitle(item) }}\r\n </span>\r\n <span\r\n class=\"vc-blade-toolbar-mobile__action-icon\"\r\n aria-hidden=\"true\"\r\n >\r\n <VcIcon\r\n :icon=\"resolveIcon(item)\"\r\n size=\"s\"\r\n />\r\n </span>\r\n </button>\r\n </div>\r\n\r\n <!-- FAB area -->\r\n <Transition\r\n name=\"toolbar-mobile-fab\"\r\n mode=\"out-in\"\r\n >\r\n <!-- Expanded: close FAB -->\r\n <button\r\n v-if=\"isExpanded\"\r\n key=\"close\"\r\n class=\"vc-blade-toolbar-mobile__close-fab\"\r\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_BLADE.CLOSE_MENU')\"\r\n aria-expanded=\"true\"\r\n @click=\"closeMenu\"\r\n >\r\n <VcIcon\r\n icon=\"lucide-x\"\r\n size=\"s\"\r\n />\r\n </button>\r\n\r\n <!-- Collapsed: pill -->\r\n <div\r\n v-else\r\n key=\"pill\"\r\n class=\"vc-blade-toolbar-mobile__pill\"\r\n >\r\n <button\r\n v-if=\"items[0]\"\r\n class=\"vc-blade-toolbar-mobile__pill-action\"\r\n :aria-label=\"resolveTitle(items[0])\"\r\n @click=\"handlePrimaryClick\"\r\n >\r\n <VcIcon\r\n :icon=\"resolveIcon(items[0])\"\r\n size=\"s\"\r\n aria-hidden=\"true\"\r\n />\r\n <span class=\"vc-blade-toolbar-mobile__pill-label\">\r\n {{ resolveTitle(items[0]) }}\r\n </span>\r\n </button>\r\n <button\r\n v-if=\"items.length > 1\"\r\n class=\"vc-blade-toolbar-mobile__pill-more\"\r\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_BLADE.MORE')\"\r\n aria-haspopup=\"menu\"\r\n aria-expanded=\"false\"\r\n @click=\"openMenu\"\r\n >\r\n <VcIcon\r\n icon=\"lucide-chevron-up\"\r\n size=\"xs\"\r\n />\r\n </button>\r\n </div>\r\n </Transition>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { ref, isRef, toValue } from \"vue\";\r\nimport { VcIcon } from \"@ui/components/atoms\";\r\nimport type { IBladeToolbar } from \"@core/types\";\r\nimport { resolveReactiveBoolean } from \"@ui/components/organisms/vc-blade/utils\";\r\n\r\nconst props = defineProps<{\r\n items: IBladeToolbar[];\r\n}>();\r\n\r\nconst isExpanded = ref(false);\r\n\r\nfunction resolveTitle(item: IBladeToolbar): string {\r\n if (!item.title) return \"\";\r\n if (isRef(item.title)) return toValue(item.title) ?? \"\";\r\n return String(item.title);\r\n}\r\n\r\nfunction resolveIcon(item: IBladeToolbar): string {\r\n if (!item.icon) return \"\";\r\n if (typeof item.icon === \"function\") return item.icon();\r\n return item.icon;\r\n}\r\n\r\nfunction isItemDisabled(item: IBladeToolbar): boolean {\r\n return resolveReactiveBoolean(item.disabled);\r\n}\r\n\r\nfunction getStaggerStyle(index: number): Record<string, string> {\r\n const delay = isExpanded.value ? `${index * 40}ms` : `${(props.items.length - 1 - index) * 25}ms`;\r\n return { transitionDelay: delay };\r\n}\r\n\r\nfunction openMenu() {\r\n isExpanded.value = true;\r\n}\r\n\r\nfunction closeMenu() {\r\n isExpanded.value = false;\r\n}\r\n\r\nfunction handlePrimaryClick() {\r\n if (props.items[0]) {\r\n props.items[0].clickHandler?.();\r\n }\r\n}\r\n\r\nfunction handleItemClick(item: IBladeToolbar) {\r\n item.clickHandler?.();\r\n closeMenu();\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --blade-toolbar-mobile-pill-bg-color: var(--primary-500);\r\n --blade-toolbar-mobile-toggle-border-color: var(--primary-200);\r\n --blade-toolbar-mobile-toggle-icon-color: var(--additional-50);\r\n --blade-toolbar-mobile-action-bg: var(--surface-color);\r\n --blade-toolbar-mobile-action-text: var(--neutrals-800);\r\n // Circle button colors\r\n --blade-toolbar-circle-button-text-color: var(--additional-50);\r\n --blade-toolbar-circle-button-bg-color: var(--neutrals-500);\r\n --blade-toolbar-circle-button-main-bg-color: var(--primary-500);\r\n}\r\n\r\n// iOS-like spring timing function\r\n$spring: cubic-bezier(0.32, 0.72, 0, 1);\r\n$fab-bottom: 76px;\r\n$fab-right: 20px;\r\n// WCAG minimum touch target\r\n$touch-min: 44px;\r\n\r\n.vc-blade-toolbar-mobile {\r\n // ── Backdrop ──────────────────────────────────────────────────────────\r\n &__backdrop {\r\n @apply tw-fixed tw-inset-0 tw-z-[var(--z-layout-toolbar)];\r\n background: var(--overlay-bg);\r\n backdrop-filter: blur(var(--overlay-blur));\r\n -webkit-backdrop-filter: blur(var(--overlay-blur));\r\n }\r\n\r\n // ── Menu container ────────────────────────────────────────────────────\r\n &__menu {\r\n position: fixed;\r\n bottom: calc(#{$fab-bottom} + #{$touch-min} + 8px);\r\n right: $fab-right;\r\n z-index: var(--z-layout-toolbar);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n align-items: flex-end;\r\n pointer-events: none;\r\n\r\n &--open {\r\n pointer-events: auto;\r\n\r\n .vc-blade-toolbar-mobile__action {\r\n opacity: 1;\r\n transform: translateY(0);\r\n\r\n &:disabled {\r\n opacity: 0.4;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ── Individual action item ────────────────────────────────────────────\r\n &__action {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 4px 4px 4px 16px;\r\n min-height: $touch-min;\r\n border: 1px solid var(--surface-border);\r\n border-radius: 28px;\r\n background: color-mix(in srgb, var(--blade-toolbar-mobile-action-bg) 92%, transparent);\r\n backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-blur));\r\n -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-blur));\r\n box-shadow: var(--shadow-sm);\r\n cursor: pointer;\r\n\r\n opacity: 0;\r\n transform: translateY(16px);\r\n transition:\r\n opacity 0.28s $spring,\r\n transform 0.28s $spring;\r\n\r\n &:hover:not(:disabled) {\r\n background: var(--blade-toolbar-mobile-action-bg);\r\n box-shadow: var(--shadow-md);\r\n transition-duration: 0.15s;\r\n }\r\n\r\n &:active:not(:disabled) {\r\n transform: scale(0.96) !important;\r\n transition-duration: 0.08s;\r\n }\r\n\r\n &:disabled {\r\n cursor: default;\r\n }\r\n\r\n &:focus-visible {\r\n outline: 2px solid var(--blade-toolbar-mobile-pill-bg-color);\r\n outline-offset: 2px;\r\n }\r\n }\r\n\r\n &__action-label {\r\n @apply tw-text-sm tw-font-medium tw-whitespace-nowrap tw-leading-none;\r\n color: var(--blade-toolbar-mobile-action-text);\r\n }\r\n\r\n &__action-icon {\r\n @apply tw-flex tw-items-center tw-justify-center tw-w-9 tw-h-9 tw-rounded-full tw-shrink-0;\r\n background: var(--blade-toolbar-circle-button-main-bg-color);\r\n color: var(--blade-toolbar-circle-button-text-color);\r\n }\r\n\r\n // ── Close FAB (expanded state) ────────────────────────────────────────\r\n &__close-fab {\r\n position: fixed;\r\n bottom: $fab-bottom;\r\n @supports (bottom: env(safe-area-inset-bottom)) {\r\n bottom: calc(#{$fab-bottom} + env(safe-area-inset-bottom));\r\n }\r\n right: $fab-right;\r\n z-index: var(--z-layout-toolbar);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: $touch-min;\r\n height: $touch-min;\r\n border: none;\r\n border-radius: 50%;\r\n background: var(--blade-toolbar-mobile-pill-bg-color);\r\n color: var(--blade-toolbar-mobile-toggle-icon-color);\r\n cursor: pointer;\r\n -webkit-tap-highlight-color: transparent;\r\n box-shadow: var(--shadow-sm);\r\n\r\n &:active {\r\n transform: scale(0.92);\r\n transition: transform 0.08s ease;\r\n }\r\n\r\n &:focus-visible {\r\n outline: 2px solid var(--blade-toolbar-mobile-toggle-icon-color);\r\n outline-offset: 2px;\r\n }\r\n }\r\n\r\n // ── Pill (collapsed state) ────────────────────────────────────────────\r\n &__pill {\r\n position: fixed;\r\n bottom: $fab-bottom;\r\n @supports (bottom: env(safe-area-inset-bottom)) {\r\n bottom: calc(#{$fab-bottom} + env(safe-area-inset-bottom));\r\n }\r\n right: $fab-right;\r\n z-index: var(--z-layout-toolbar);\r\n display: flex;\r\n align-items: stretch;\r\n height: $touch-min;\r\n border-radius: calc(#{$touch-min} / 2);\r\n background: var(--blade-toolbar-mobile-pill-bg-color);\r\n overflow: hidden;\r\n box-shadow: var(--shadow-sm);\r\n }\r\n\r\n &__pill-action {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 0 14px;\r\n min-height: $touch-min;\r\n border: none;\r\n background: transparent;\r\n color: var(--blade-toolbar-mobile-toggle-icon-color);\r\n cursor: pointer;\r\n -webkit-tap-highlight-color: transparent;\r\n\r\n &:active {\r\n background: rgba(255, 255, 255, 0.12);\r\n }\r\n\r\n &:focus-visible {\r\n outline: 2px solid var(--blade-toolbar-mobile-toggle-icon-color);\r\n outline-offset: -2px;\r\n }\r\n }\r\n\r\n &__pill-label {\r\n @apply tw-text-sm tw-font-semibold tw-whitespace-nowrap tw-leading-none;\r\n }\r\n\r\n &__pill-more {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n min-width: $touch-min;\r\n padding: 0 12px;\r\n border: none;\r\n border-left: 1px solid rgba(255, 255, 255, 0.24);\r\n background: transparent;\r\n color: var(--blade-toolbar-mobile-toggle-icon-color);\r\n cursor: pointer;\r\n -webkit-tap-highlight-color: transparent;\r\n\r\n &:active {\r\n background: rgba(255, 255, 255, 0.12);\r\n }\r\n\r\n &:focus-visible {\r\n outline: 2px solid var(--blade-toolbar-mobile-toggle-icon-color);\r\n outline-offset: -2px;\r\n }\r\n }\r\n}\r\n\r\n// ── Backdrop transition ─────────────────────────────────────────────────\r\n.toolbar-mobile-backdrop-enter-active {\r\n transition:\r\n opacity 0.25s ease,\r\n backdrop-filter 0.3s ease;\r\n}\r\n\r\n.toolbar-mobile-backdrop-leave-active {\r\n transition:\r\n opacity 0.2s ease 0.08s,\r\n backdrop-filter 0.2s ease 0.08s;\r\n}\r\n\r\n.toolbar-mobile-backdrop-enter-from,\r\n.toolbar-mobile-backdrop-leave-to {\r\n opacity: 0;\r\n backdrop-filter: blur(0);\r\n -webkit-backdrop-filter: blur(0);\r\n}\r\n\r\n// ── FAB morph transition ────────────────────────────────────────────────\r\n.toolbar-mobile-fab-enter-active {\r\n transition:\r\n opacity 0.15s ease,\r\n transform 0.25s $spring;\r\n}\r\n\r\n.toolbar-mobile-fab-leave-active {\r\n transition:\r\n opacity 0.1s ease,\r\n transform 0.15s ease;\r\n}\r\n\r\n.toolbar-mobile-fab-enter-from {\r\n opacity: 0;\r\n transform: scale(0.85);\r\n}\r\n\r\n.toolbar-mobile-fab-leave-to {\r\n opacity: 0;\r\n transform: scale(0.85);\r\n}\r\n</style>\r\n","<template>\r\n <button\r\n class=\"vc-blade-toolbar-base-button\"\r\n :class=\"{\r\n 'vc-blade-toolbar-base-button--disabled': isDisabled || isWaiting,\r\n 'vc-blade-toolbar-base-button--with-separator-left': separator === 'left',\r\n 'vc-blade-toolbar-base-button--with-separator-right': separator === 'right',\r\n 'vc-blade-toolbar-base-button--with-separator-both': separator === 'both',\r\n }\"\r\n :data-test-id=\"id ?? 'vc-blade-toolbar-button'\"\r\n v-bind=\"$attrs\"\r\n @click=\"handleClick\"\r\n >\r\n <div\r\n class=\"vc-blade-toolbar-base-button__content\"\r\n :style=\"{ flexDirection: contentDirection }\"\r\n >\r\n <VcIcon\r\n class=\"vc-blade-toolbar-base-button__icon\"\r\n :class=\"iconClassName\"\r\n :icon=\"resolvedIcon\"\r\n :size=\"size\"\r\n />\r\n <span\r\n class=\"vc-blade-toolbar-base-button__title\"\r\n :class=\"titleClassName\"\r\n >\r\n {{ resolvedTitle }}\r\n </span>\r\n </div>\r\n </button>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { computed, isRef, ref, toValue } from \"vue\";\r\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\r\nimport { resolveReactiveBoolean } from \"@ui/components/organisms/vc-blade/utils\";\r\nimport type { Props } from \"@ui/components/organisms/vc-blade/_internal/toolbar/toolbar-button-props\";\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n disabled: false,\r\n size: \"m\",\r\n separator: undefined,\r\n contentDirection: \"column\",\r\n});\r\n\r\ndefineOptions({\r\n inheritAttrs: false,\r\n});\r\n\r\nconst isWaiting = ref(false);\r\nconst isDisabled = computed(() => resolveReactiveBoolean(props.disabled));\r\n\r\nconst resolvedTitle = computed(() => {\r\n if (isRef(props.title)) {\r\n return toValue(props.title);\r\n }\r\n\r\n return props.title;\r\n});\r\n\r\nconst resolvedIcon = computed(() => {\r\n if (typeof props.icon === \"function\") {\r\n return props.icon();\r\n }\r\n\r\n return props.icon;\r\n});\r\n\r\nasync function handleClick(): Promise<void> {\r\n if (isDisabled.value || isWaiting.value || !props.onClick) return;\r\n\r\n isWaiting.value = true;\r\n try {\r\n await props.onClick();\r\n } finally {\r\n isWaiting.value = false;\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --blade-toolbar-base-button-separator-color: var(--neutrals-200);\r\n --blade-toolbar-base-button-title-color: var(--neutrals-600);\r\n --blade-toolbar-base-button-hover-color: var(--primary-600);\r\n --blade-toolbar-base-button-disabled-color: var(--neutrals-400);\r\n --blade-toolbar-base-button-icon-color: var(--neutrals-700);\r\n}\r\n\r\n.vc-blade-toolbar-base-button {\r\n @apply tw-px-3 tw-bg-transparent tw-border-0 tw-cursor-pointer tw-shrink-0;\r\n\r\n &__content {\r\n @apply tw-inline-flex tw-items-center tw-gap-1;\r\n }\r\n\r\n &__icon {\r\n @apply tw-text-[var(--blade-toolbar-base-button-icon-color)];\r\n @apply tw-flex #{!important};\r\n }\r\n\r\n &__title {\r\n @apply tw-text-xs tw-text-[var(--blade-toolbar-base-button-title-color)] tw-text-nowrap;\r\n }\r\n\r\n &--with-separator-left {\r\n @apply tw-border-l tw-border-solid tw-border-[var(--blade-toolbar-base-button-separator-color)];\r\n }\r\n\r\n &--with-separator-right {\r\n @apply tw-border-r tw-border-solid tw-border-[var(--blade-toolbar-base-button-separator-color)];\r\n }\r\n\r\n &--with-separator-both {\r\n @apply tw-border-l tw-border-r tw-border-solid tw-border-[var(--blade-toolbar-base-button-separator-color)];\r\n }\r\n\r\n &:hover:not(&--disabled) {\r\n .vc-blade-toolbar-base-button__icon,\r\n .vc-blade-toolbar-base-button__title {\r\n @apply tw-text-[var(--blade-toolbar-base-button-hover-color)];\r\n }\r\n }\r\n\r\n &--disabled {\r\n @apply tw-cursor-default;\r\n\r\n .vc-blade-toolbar-base-button__icon,\r\n .vc-blade-toolbar-base-button__title {\r\n @apply tw-text-[var(--blade-toolbar-base-button-disabled-color)];\r\n }\r\n }\r\n}\r\n</style>\r\n","<template>\n <div class=\"vc-blade-toolbar-desktop\">\n <div\n ref=\"toolbarContentRef\"\n class=\"vc-blade-toolbar-desktop__content\"\n >\n <template\n v-for=\"item in visibleItems\"\n :key=\"item.id\"\n >\n <ToolbarBaseButton\n v-bind=\"item\"\n :data-item-key=\"item.id\"\n :show-title=\"isExpanded\"\n :on-click=\"item.clickHandler\"\n />\n </template>\n\n <VcDropdown\n v-if=\"showMoreButton\"\n :model-value=\"isMenuOpen\"\n :items=\"hiddenItems\"\n floating\n placement=\"bottom-end\"\n variant=\"secondary\"\n @item-click=\"handleItemClick\"\n @update:model-value=\"isMenuOpen = $event\"\n >\n <template #trigger=\"{ isActive }\">\n <div\n data-more-button\n class=\"vc-blade-toolbar-desktop__more\"\n :class=\"{ 'vc-blade-toolbar-desktop__more--active': isActive }\"\n @click=\"isMenuOpen = !isMenuOpen\"\n >\n <VcIcon icon=\"lucide-ellipsis\" />\n <span\n v-if=\"isExpanded\"\n class=\"vc-blade-toolbar-desktop__more-text\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_BLADE.MORE\") }}\n </span>\n </div>\n </template>\n\n <template #item=\"{ item }\">\n <VcDropdownItem\n :title=\"toValue(item.title) ?? ''\"\n :icon=\"typeof item.icon === 'function' ? item.icon() : item.icon\"\n />\n </template>\n </VcDropdown>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, toRef, toValue, watch, nextTick } from \"vue\";\nimport { VcDropdown } from \"@ui/components/molecules/vc-dropdown\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport VcDropdownItem from \"@ui/components/molecules/vc-dropdown/_internal/VcDropdownItem.vue\";\nimport { useAdaptiveItems } from \"@ui/composables/useAdaptiveItems\";\nimport type { IBladeToolbar } from \"@core/types\";\nimport ToolbarBaseButton from \"@ui/components/organisms/vc-blade/_internal/toolbar/ToolbarBaseButton.vue\";\n\nconst props = defineProps<{\n items: IBladeToolbar[];\n isExpanded: boolean;\n}>();\n\nconst isMenuOpen = ref(false);\nconst toolbarContentRef = ref<HTMLElement | null>(null);\n\nconst { visibleItems, hiddenItems, showMoreButton, recalculate, updateObserver } = useAdaptiveItems<IBladeToolbar>({\n containerRef: toolbarContentRef,\n items: toRef(props, \"items\"),\n getItemKey: (item) => item.id ?? `toolbar_item_${props.items.indexOf(item)}`,\n moreButtonWidth: 70,\n initialItemWidth: 60,\n});\n\nfunction handleItemClick(item: IBladeToolbar) {\n item.clickHandler?.();\n isMenuOpen.value = false;\n}\n\nwatch(\n () => props.isExpanded,\n () => {\n nextTick(() => {\n recalculate();\n updateObserver();\n });\n },\n);\n</script>\n\n<style lang=\"scss\">\n:root {\n --blade-toolbar-desktop-more-color: var(--neutrals-700);\n --blade-toolbar-desktop-more-hover-color: var(--primary-600);\n}\n\n.vc-blade-toolbar-desktop {\n @apply tw-w-full tw-relative;\n\n &__content {\n @apply tw-flex tw-items-center tw-px-4 tw-h-full;\n }\n\n &__more {\n @apply tw-flex tw-items-center tw-gap-1 tw-px-2 tw-cursor-pointer tw-text-[var(--blade-toolbar-desktop-more-color)] tw-flex-col;\n\n &-text {\n @apply tw-text-xs;\n }\n\n &:hover,\n &--active {\n @apply tw-text-[var(--blade-toolbar-desktop-more-hover-color)];\n }\n }\n}\n</style>\n","/**\n * Mapping ISO 639-1 language codes (and culture codes) to ISO 3166-1 alpha-2 country codes\n * @see https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes\n * @see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2\n */\nexport const languageToCountryMap: Record<string, string> = {\n af: \"za\",\n ar: \"sa\",\n az: \"az\",\n be: \"by\",\n bg: \"bg\",\n bn: \"bd\",\n bs: \"ba\",\n ca: \"es\",\n cs: \"cz\",\n cy: \"gb\",\n da: \"dk\",\n de: \"de\",\n el: \"gr\",\n en: \"us\",\n \"en-gb\": \"gb\",\n es: \"es\",\n et: \"ee\",\n fa: \"ir\",\n fi: \"fi\",\n fil: \"ph\",\n fr: \"fr\",\n gu: \"in\",\n he: \"il\",\n hi: \"in\",\n hr: \"hr\",\n hu: \"hu\",\n hy: \"am\",\n id: \"id\",\n is: \"is\",\n it: \"it\",\n ja: \"jp\",\n ka: \"ge\",\n kk: \"kz\",\n km: \"kh\",\n kn: \"in\",\n ko: \"kr\",\n ky: \"kg\",\n lt: \"lt\",\n lv: \"lv\",\n mk: \"mk\",\n ml: \"in\",\n mn: \"mn\",\n mr: \"in\",\n ms: \"my\",\n mt: \"mt\",\n ne: \"np\",\n nl: \"nl\",\n no: \"no\",\n pa: \"in\",\n pl: \"pl\",\n pt: \"pt\",\n ro: \"ro\",\n ru: \"ru\",\n si: \"lk\",\n sk: \"sk\",\n sl: \"si\",\n sq: \"al\",\n sr: \"rs\",\n sv: \"se\",\n sw: \"tz\",\n ta: \"in\",\n te: \"in\",\n th: \"th\",\n tr: \"tr\",\n uk: \"ua\",\n ur: \"pk\",\n uz: \"uz\",\n vi: \"vn\",\n yo: \"ng\",\n zh: \"cn\",\n zu: \"za\",\n};\n","import { type Ref, computed, onBeforeUnmount, ref, watch } from \"vue\";\r\nimport { useBlade } from \"@core/composables/useBlade\";\r\nimport { usePermissions } from \"@core/composables/usePermissions\";\r\nimport { useToolbar } from \"@core/composables/useToolbar\";\r\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\r\nimport type { IBladeToolbar } from \"@core/types\";\r\nimport { FALLBACK_BLADE_ID } from \"@core/constants\";\r\nimport type { IToolbarItem } from \"@core/services/toolbar-service\";\r\nimport { resolveVisibility, resolveReactiveBoolean } from \"@ui/components/organisms/vc-blade/utils\";\r\n\r\nconst PROP_ITEM_ID_PREFIX = \"prop_toolbar_item_\";\r\n\r\n/**\r\n * Manages the lifecycle of toolbar items:\r\n * - Converts `IBladeToolbar[]` props to `IToolbarItem[]` for the ToolbarService\r\n * - Registers/unregisters items as props or blade ID change\r\n * - Filters by permissions, visibility, and disabled-on-mobile\r\n * - Sorts by priority\r\n * - Cleans up on unmount\r\n */\r\nexport function useToolbarRegistration(items: Ref<IBladeToolbar[]>) {\r\n const { hasAccess } = usePermissions();\r\n const { registerToolbarItem, unregisterToolbarItem, getToolbarItems, updateToolbarItem } = useToolbar({\r\n autoCleanup: false,\r\n });\r\n\r\n const { id: currentBladeId } = useBlade();\r\n const bladeId = computed(() => (currentBladeId.value ?? FALLBACK_BLADE_ID).toLowerCase());\r\n\r\n const { isMobile } = useResponsive();\r\n\r\n const registeredItemIds = new Set<string>();\r\n const registrationBladeId = ref(bladeId.value);\r\n\r\n function convertToToolbarItem(item: IBladeToolbar, index: number): IToolbarItem {\r\n const activeBladeId = registrationBladeId.value;\r\n const id = item.id || `${PROP_ITEM_ID_PREFIX}${activeBladeId}_${index}`;\r\n\r\n return {\r\n ...item,\r\n id,\r\n bladeId: activeBladeId,\r\n priority: index * -1,\r\n } as IToolbarItem;\r\n }\r\n\r\n function updateItems(): void {\r\n const activeBladeId = registrationBladeId.value;\r\n const nextRegisteredIds = new Set<string>();\r\n\r\n items.value.forEach((item, index) => {\r\n const toolbarItem = convertToToolbarItem(item, index);\r\n const id = toolbarItem.id;\r\n nextRegisteredIds.add(id);\r\n\r\n if (registeredItemIds.has(id)) {\r\n updateToolbarItem(id, toolbarItem, activeBladeId);\r\n } else {\r\n registerToolbarItem(toolbarItem, activeBladeId);\r\n }\r\n });\r\n\r\n for (const id of registeredItemIds) {\r\n if (!nextRegisteredIds.has(id)) {\r\n unregisterToolbarItem(id, activeBladeId);\r\n }\r\n }\r\n\r\n registeredItemIds.clear();\r\n nextRegisteredIds.forEach((id) => registeredItemIds.add(id));\r\n }\r\n\r\n function clearToolbarItems(targetBladeId = registrationBladeId.value): void {\r\n for (const id of registeredItemIds) {\r\n unregisterToolbarItem(id, targetBladeId);\r\n }\r\n registeredItemIds.clear();\r\n }\r\n\r\n const visibleItems = computed(() => {\r\n // getToolbarItems reads from reactive registry (blade-scoped + global \"*\"),\r\n // so Vue automatically tracks changes to toolbar items for this blade.\r\n return getToolbarItems(registrationBladeId.value)\r\n .filter(\r\n (item) =>\r\n hasAccess(item.permissions) &&\r\n resolveVisibility(item.isVisible) &&\r\n (isMobile.value ? !resolveReactiveBoolean(item.disabled) : true),\r\n )\r\n .sort((a, b) => {\r\n const priorityA = a.priority ?? 0;\r\n const priorityB = b.priority ?? 0;\r\n return priorityB - priorityA;\r\n });\r\n });\r\n\r\n watch(items, () => updateItems(), { deep: true, immediate: true });\r\n\r\n watch(bladeId, (newBladeId, oldBladeId) => {\r\n if (newBladeId === oldBladeId) return;\r\n clearToolbarItems(oldBladeId);\r\n registrationBladeId.value = newBladeId;\r\n updateItems();\r\n });\r\n\r\n onBeforeUnmount(() => {\r\n clearToolbarItems();\r\n });\r\n\r\n return { visibleItems };\r\n}\r\n","<template>\n <div\n v-if=\"!(loading && isMobile)\"\n class=\"vc-blade-toolbar\"\n :class=\"{\n 'vc-blade-toolbar--mobile': isMobile,\n 'vc-blade-toolbar--loading': loading,\n }\"\n >\n <div class=\"vc-blade-toolbar__content\">\n <template v-if=\"loading\">\n <div class=\"vc-blade-toolbar-skeleton__buttons\">\n <div\n v-for=\"i in 3\"\n :key=\"i\"\n class=\"vc-blade-toolbar-skeleton__button\"\n >\n <VcSkeleton\n variant=\"circle\"\n :width=\"18\"\n :height=\"18\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"28 + i * 6\"\n :height=\"10\"\n />\n </div>\n </div>\n\n <div class=\"vc-blade-toolbar-skeleton__widgets\">\n <div\n v-for=\"i in 2\"\n :key=\"'w' + i\"\n class=\"vc-blade-toolbar-skeleton__widget\"\n >\n <VcSkeleton\n variant=\"circle\"\n :width=\"18\"\n :height=\"18\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"30 + i * 4\"\n :height=\"10\"\n class=\"tw-mt-1\"\n />\n </div>\n </div>\n </template>\n <template v-else>\n <div class=\"vc-blade-toolbar__buttons\">\n <ToolbarMobile\n v-if=\"isMobile\"\n :items=\"visibleItems\"\n />\n <ToolbarDesktop\n v-else\n :items=\"visibleItems\"\n :is-expanded=\"isExpanded\"\n />\n </div>\n\n <slot\n v-if=\"$slots['widgets-container']\"\n name=\"widgets-container\"\n />\n </template>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { toRef } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport type { IBladeToolbar } from \"@core/types\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport ToolbarMobile from \"@ui/components/organisms/vc-blade/_internal/toolbar/ToolbarMobile.vue\";\nimport ToolbarDesktop from \"@ui/components/organisms/vc-blade/_internal/toolbar/ToolbarDesktop.vue\";\nimport { useToolbarRegistration } from \"@ui/components/organisms/vc-blade/_internal/composables/useToolbarRegistration\";\n\nexport interface Props {\n items?: IBladeToolbar[];\n /** When true, renders skeleton placeholders instead of toolbar buttons/widgets */\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n items: () => [],\n});\n\nconst { isMobile } = useResponsive();\nconst isExpanded = true;\nconst { visibleItems } = useToolbarRegistration(toRef(props, \"items\"));\n</script>\n\n<style lang=\"scss\">\n:root {\n --blade-toolbar-height: 54px;\n --blade-toolbar-background-color: var(--neutrals-50);\n --blade-toolbar-border-color: var(--neutrals-200);\n --blade-toolbar-icon-color: var(--neutrals-700);\n --blade-toolbar-icon-hover-color: var(--primary-600);\n}\n\n.vc-blade-toolbar {\n @apply tw-bg-[color:var(--blade-toolbar-background-color)] tw-border-b-[color:var(--blade-toolbar-border-color)] tw-border-solid tw-border-b tw-flex tw-box-border tw-w-full tw-content-center tw-items-stretch tw-shrink-0;\n\n &__content {\n @apply tw-flex tw-flex-row tw-w-full tw-relative tw-overflow-hidden tw-min-h-[var(--blade-toolbar-height)];\n }\n\n &__buttons {\n @apply tw-relative tw-overflow-hidden tw-flex tw-flex-1 tw-min-w-0;\n }\n\n &--mobile {\n @apply tw-fixed tw-bottom-0 tw-right-0 tw-z-[var(--z-layout-sidebar)] tw-p-4 tw-bg-transparent tw-border-0 tw-w-auto;\n }\n}\n\n.vc-blade-toolbar-skeleton {\n &__buttons {\n @apply tw-flex tw-items-center tw-px-4 tw-flex-1 tw-min-w-0;\n }\n\n &__button {\n @apply tw-shrink-0 tw-px-3 tw-inline-flex tw-flex-col tw-items-center tw-gap-1;\n }\n\n &__widgets {\n @apply tw-flex tw-flex-row tw-gap-1 tw-shrink-0;\n background-color: var(--blade-toolbar-widgets-bg-color);\n }\n\n &__widget {\n @apply tw-shrink-0 tw-px-2 tw-py-1.5 tw-flex tw-flex-col tw-items-center tw-justify-center;\n }\n}\n</style>\n","import { computed, type ComputedRef } from \"vue\";\r\nimport type { BladeDescriptor } from \"@core/blade-navigation/types\";\r\n\r\n/**\r\n * Encapsulates blade error state: reactive computeds for the banner\r\n * and a helper to copy full error details to clipboard.\r\n */\r\nexport function useBladeError(blade: ComputedRef<BladeDescriptor> | undefined) {\r\n const error = computed(() => blade?.value?.error ?? null);\r\n\r\n const hasError = computed(() => Boolean(error.value));\r\n\r\n const shortErrorMessage = computed(() => {\r\n const err = error.value;\r\n if (!err) return \"\";\r\n return err instanceof Error ? err.message : String(err);\r\n });\r\n\r\n const errorDetails = computed(() => {\r\n const err = error.value;\r\n if (!err) return \"\";\r\n if (err instanceof Error) {\r\n return (err as Error & { details?: string }).details || err.stack || String(err);\r\n }\r\n return String(err);\r\n });\r\n\r\n async function copyError(): Promise<boolean> {\r\n try {\r\n const text = [shortErrorMessage.value, errorDetails.value].filter(Boolean).join(\"\\n\\n\");\r\n await navigator.clipboard.writeText(text);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n return {\r\n hasError,\r\n shortErrorMessage,\r\n errorDetails,\r\n copyError,\r\n };\r\n}\r\n","<template>\n <TransitionGroup name=\"banner-reveal\">\n <div\n v-for=\"banner in sortedBanners\"\n :key=\"banner.id\"\n class=\"vc-blade-status-banners__banner\"\n :class=\"`vc-blade-status-banners__banner--${banner.variant}`\"\n :role=\"banner.variant === 'danger' || banner.variant === 'warning' ? 'alert' : 'status'\"\n >\n <div class=\"vc-blade-status-banners__accent\" />\n\n <!-- Error banner: collapsible with details -->\n <template v-if=\"banner.id === ERROR_BANNER_ID\">\n <div\n class=\"vc-blade-status-banners__header vc-blade-status-banners__header--clickable\"\n @click=\"toggleError\"\n >\n <VcIcon\n size=\"s\"\n :icon=\"banner.icon || variantIcon(banner.variant)\"\n class=\"vc-blade-status-banners__icon\"\n />\n <span class=\"vc-blade-status-banners__text\">{{ banner.message }}</span>\n <VcIcon\n size=\"xs\"\n :icon=\"isErrorExpanded ? 'lucide-chevron-up' : 'lucide-chevron-down'\"\n class=\"vc-blade-status-banners__chevron\"\n />\n <button\n v-if=\"banner.dismissible\"\n class=\"vc-blade-status-banners__dismiss\"\n :title=\"t('COMPONENTS.ORGANISMS.VC_BLADE.ERROR_POPUP.CLOSE')\"\n @click.stop=\"dismissBanner(banner)\"\n >\n <VcIcon\n size=\"xs\"\n icon=\"lucide-x\"\n />\n </button>\n </div>\n <div\n :ref=\"\n (el) => {\n errorContentRef = el as HTMLElement | undefined;\n }\n \"\n class=\"vc-blade-status-banners__error-details-wrapper\"\n :style=\"errorWrapperStyle\"\n >\n <div class=\"vc-blade-status-banners__error-details\">\n <pre\n class=\"vc-blade-status-banners__error-details-text\"\n tabindex=\"0\"\n >{{ errorDetailsText }}</pre\n >\n <button\n class=\"vc-blade-status-banners__error-copy\"\n :title=\"t('COMPONENTS.ORGANISMS.VC_BLADE.ERROR_POPUP.COPY_ERROR')\"\n @click.stop=\"handleCopy\"\n >\n <VcIcon\n size=\"xs\"\n :icon=\"copied ? 'lucide-check' : 'lucide-copy'\"\n />\n </button>\n </div>\n </div>\n </template>\n\n <!-- Standard banner: message / render / action -->\n <template v-else>\n <div class=\"vc-blade-status-banners__header\">\n <VcIcon\n size=\"s\"\n :icon=\"banner.icon || variantIcon(banner.variant)\"\n class=\"vc-blade-status-banners__icon\"\n />\n <span\n v-if=\"banner.message && !banner.render\"\n class=\"vc-blade-status-banners__text\"\n >\n {{ banner.message }}\n </span>\n <BannerRenderSlot\n v-if=\"banner.render\"\n :render-fn=\"banner.render\"\n class=\"vc-blade-status-banners__text\"\n />\n <button\n v-if=\"banner.action\"\n class=\"vc-blade-status-banners__action\"\n @click=\"banner.action.handler\"\n >\n {{ banner.action.label }}\n </button>\n <button\n v-if=\"banner.dismissible\"\n class=\"vc-blade-status-banners__dismiss\"\n :title=\"t('COMPONENTS.ORGANISMS.VC_BLADE.ERROR_POPUP.CLOSE')\"\n @click=\"dismissBanner(banner)\"\n >\n <VcIcon\n size=\"xs\"\n icon=\"lucide-x\"\n />\n </button>\n </div>\n </template>\n </div>\n </TransitionGroup>\n</template>\n\n<script lang=\"ts\" setup>\nimport { inject, ref, computed, watch, defineComponent, type VNode } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useCollapsible } from \"@ui/composables/useCollapsible\";\nimport { BladeDescriptorKey, BladeBannersKey, BladeStackKey } from \"@core/blade-navigation/types\";\nimport type { IBladeBanner } from \"@core/blade-navigation/types\";\nimport { useBladeError } from \"./composables/useBladeError\";\n\n// ── Functional component for render() banners ─────────────────────────────\n// Defined once — avoids recreating component objects on every render cycle.\nconst BannerRenderSlot = defineComponent({\n props: {\n renderFn: { type: Function, required: true },\n },\n setup(props) {\n return () => (props.renderFn as () => VNode)();\n },\n});\n\ninterface Props {\n modified?: boolean;\n}\n\nconst props = defineProps<Props>();\n\nconst descriptor = inject(BladeDescriptorKey, undefined);\nconst bannersRef = inject(BladeBannersKey, undefined);\nconst bladeStack = inject(BladeStackKey, undefined);\nconst { t } = useI18n({ useScope: \"global\" });\nconst { hasError, shortErrorMessage, errorDetails, copyError } = useBladeError(descriptor);\n\n// ── Error collapsible state ───────────────────────────────────────────────\nconst {\n contentRef: errorContentRef,\n isExpanded: isErrorExpanded,\n wrapperStyle: errorWrapperStyle,\n toggle: toggleError,\n} = useCollapsible();\n\nconst copied = ref(false);\nconst errorDetailsText = errorDetails;\n\nasync function handleCopy() {\n const ok = await copyError();\n if (ok) {\n copied.value = true;\n setTimeout(() => {\n copied.value = false;\n }, 2000);\n }\n}\n\n// ── System banner IDs ─────────────────────────────────────────────────────\nconst ERROR_BANNER_ID = \"__system-error__\";\nconst MODIFIED_BANNER_ID = \"__system-modified__\";\n\n// ── Sync system error banner ──────────────────────────────────────────────\nwatch(\n [hasError, shortErrorMessage],\n ([has]) => {\n if (!bannersRef) return;\n const idx = bannersRef.value.findIndex((b) => b.id === ERROR_BANNER_ID);\n if (has && idx === -1) {\n bannersRef.value.push({\n id: ERROR_BANNER_ID,\n variant: \"danger\",\n message: shortErrorMessage.value,\n dismissible: true,\n _system: true,\n });\n } else if (has && idx !== -1) {\n // Update message in case error changed\n bannersRef.value[idx] = {\n ...bannersRef.value[idx],\n message: shortErrorMessage.value,\n };\n } else if (!has && idx !== -1) {\n bannersRef.value.splice(idx, 1);\n }\n },\n { immediate: true },\n);\n\n// ── Sync system modified banner ───────────────────────────────────────────\nwatch(\n () => props.modified,\n (mod) => {\n if (!bannersRef) return;\n const idx = bannersRef.value.findIndex((b) => b.id === MODIFIED_BANNER_ID);\n if (mod && idx === -1) {\n bannersRef.value.push({\n id: MODIFIED_BANNER_ID,\n variant: \"warning\",\n icon: \"lucide-pencil\",\n message: t(\"COMPONENTS.ORGANISMS.VC_BLADE.UNSAVED_CHANGES\"),\n dismissible: false,\n _system: true,\n });\n } else if (!mod && idx !== -1) {\n bannersRef.value.splice(idx, 1);\n }\n },\n { immediate: true },\n);\n\n// ── Priority sort ─────────────────────────────────────────────────────────\nconst VARIANT_PRIORITY: Record<string, number> = {\n danger: 0,\n warning: 1,\n info: 2,\n success: 3,\n};\n\nconst sortedBanners = computed(() => {\n if (!bannersRef) return [];\n return [...bannersRef.value].sort((a, b) => (VARIANT_PRIORITY[a.variant] ?? 9) - (VARIANT_PRIORITY[b.variant] ?? 9));\n});\n\n// ── Helpers ───────────────────────────────────────────────────────────────\nfunction variantIcon(variant: IBladeBanner[\"variant\"]): string {\n const icons: Record<string, string> = {\n danger: \"lucide-circle-alert\",\n warning: \"lucide-triangle-alert\",\n info: \"lucide-info\",\n success: \"lucide-circle-check\",\n };\n return icons[variant] ?? \"lucide-info\";\n}\n\nfunction dismissBanner(banner: IBladeBanner) {\n if (!bannersRef) return;\n // If dismissing the error banner, clear the error source too\n if (banner.id === ERROR_BANNER_ID && descriptor && bladeStack) {\n bladeStack.clearBladeError(descriptor.value.id);\n }\n bannersRef.value = bannersRef.value.filter((b) => b.id !== banner.id);\n}\n</script>\n\n<style lang=\"scss\">\n// ── Banner entrance/exit (TransitionGroup) ────────────────────────────────\n.banner-reveal-enter-active {\n transition:\n opacity 0.2s ease-out,\n transform 0.2s ease-out;\n}\n\n.banner-reveal-leave-active {\n transition:\n opacity 0.15s ease-in,\n transform 0.15s ease-in;\n}\n\n.banner-reveal-enter-from {\n opacity: 0;\n transform: translateY(-8px);\n}\n\n.banner-reveal-leave-to {\n opacity: 0;\n transform: translateY(-4px);\n}\n\n// ── Shared banner layout ──────────────────────────────────────────────────\n.vc-blade-status-banners {\n &__banner {\n @apply tw-relative tw-overflow-hidden;\n border-bottom: 1px solid transparent;\n }\n\n &__banner--danger {\n background: var(--danger-50);\n border-bottom-color: var(--danger-100);\n\n .vc-blade-status-banners__accent {\n background: var(--danger-500);\n }\n\n .vc-blade-status-banners__icon {\n color: var(--danger-500);\n }\n\n .vc-blade-status-banners__text {\n color: var(--danger-800);\n }\n\n .vc-blade-status-banners__chevron {\n color: var(--danger-400);\n }\n\n .vc-blade-status-banners__header--clickable:hover {\n background: var(--danger-100);\n }\n\n .vc-blade-status-banners__action {\n color: var(--danger-600);\n &:hover {\n color: var(--danger-800);\n }\n }\n }\n\n &__banner--warning {\n background: var(--warning-50);\n border-bottom-color: color-mix(in srgb, var(--warning-200) 60%, transparent);\n\n .vc-blade-status-banners__accent {\n background: var(--warning-500);\n }\n\n .vc-blade-status-banners__icon {\n color: var(--warning-600);\n }\n\n .vc-blade-status-banners__text {\n color: var(--warning-800);\n }\n\n .vc-blade-status-banners__action {\n color: var(--warning-600);\n &:hover {\n color: var(--warning-800);\n }\n }\n }\n\n &__banner--info {\n background: var(--info-50);\n border-bottom-color: color-mix(in srgb, var(--info-200) 60%, transparent);\n\n .vc-blade-status-banners__accent {\n background: var(--info-500);\n }\n\n .vc-blade-status-banners__icon {\n color: var(--info-500);\n }\n\n .vc-blade-status-banners__text {\n color: var(--info-800);\n }\n\n .vc-blade-status-banners__action {\n color: var(--info-600);\n &:hover {\n color: var(--info-800);\n }\n }\n }\n\n &__banner--success {\n background: var(--success-50);\n border-bottom-color: color-mix(in srgb, var(--success-200) 60%, transparent);\n\n .vc-blade-status-banners__accent {\n background: var(--success-500);\n }\n\n .vc-blade-status-banners__icon {\n color: var(--success-500);\n }\n\n .vc-blade-status-banners__text {\n color: var(--success-800);\n }\n\n .vc-blade-status-banners__action {\n color: var(--success-600);\n &:hover {\n color: var(--success-800);\n }\n }\n }\n\n // ── Shared structural classes ───────────────────────────────────────\n\n &__accent {\n @apply tw-absolute tw-left-0 tw-top-0 tw-bottom-0;\n width: 3px;\n }\n\n &__header {\n @apply tw-flex tw-items-center tw-select-none;\n @apply tw-py-2 tw-pl-3 tw-pr-3;\n }\n\n &__header--clickable {\n @apply tw-cursor-pointer;\n }\n\n &__icon {\n @apply tw-shrink-0 tw-mr-2;\n }\n\n &__text {\n @apply tw-flex-1 tw-min-w-0 tw-text-xs tw-font-medium tw-leading-snug tw-line-clamp-1;\n }\n\n &__chevron {\n @apply tw-shrink-0 tw-ml-2;\n }\n\n &__action {\n @apply tw-shrink-0 tw-ml-2 tw-text-xs tw-font-medium tw-border-0 tw-bg-transparent tw-cursor-pointer tw-underline;\n @apply tw-p-0;\n }\n\n &__dismiss {\n @apply tw-shrink-0 tw-ml-2 tw-flex tw-rounded tw-border-0 tw-cursor-pointer;\n @apply tw-bg-transparent;\n color: inherit;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n\n &:hover {\n opacity: 1;\n }\n }\n\n // ── Error details (collapsible) ─────────────────────────────────────────\n\n &__error-details-wrapper {\n @apply tw-overflow-hidden;\n transition: max-height 0.25s ease;\n }\n\n &__error-details {\n @apply tw-relative tw-rounded tw-overflow-hidden;\n margin: 0 12px 8px;\n background: var(--neutrals-50);\n border: 1px solid var(--neutrals-200);\n }\n\n &__error-details-text {\n @apply tw-text-[11px] tw-leading-relaxed tw-p-3 tw-pr-9;\n @apply tw-whitespace-pre-wrap tw-break-words tw-overflow-y-auto;\n @apply tw-m-0;\n max-height: 120px;\n color: var(--neutrals-700);\n font-family: ui-monospace, \"Cascadia Code\", \"Source Code Pro\", Menlo, Consolas, monospace;\n }\n\n &__error-copy {\n @apply tw-absolute tw-top-2 tw-right-2 tw-p-1 tw-rounded;\n @apply tw-border-0 tw-cursor-pointer;\n background: var(--neutrals-100);\n color: var(--neutrals-500);\n transition:\n color 0.15s ease,\n background-color 0.15s ease;\n\n &:hover {\n color: var(--neutrals-800);\n background: var(--neutrals-200);\n }\n }\n}\n</style>\n","import { getCurrentInstance, inject, provide, getCurrentScope, onScopeDispose } from \"vue\";\nimport {\n createWidgetService,\n IWidgetService,\n registerWidget,\n registerExternalWidget,\n widgetBus,\n} from \"@core/services/widget-service\";\nimport { WidgetServiceKey } from \"@framework/injection-keys\";\nimport { createLogger, InjectionError } from \"@core/utilities\";\n\nexport type UseWidgetsReturn = IWidgetService;\n\nconst logger = createLogger(\"use-widgets\");\n\nexport function provideWidgetService(): IWidgetService {\n const existingService = inject(WidgetServiceKey, null);\n if (existingService) {\n return existingService;\n }\n\n const service = createWidgetService();\n provide(WidgetServiceKey, service);\n\n if (getCurrentScope()) {\n onScopeDispose(() => widgetBus.dispose(service));\n }\n\n return service;\n}\n\n/**\n * Returns the WidgetService instance. For blade-level widget registration,\n * prefer `useBladeWidgets()` which handles lifecycle automatically.\n */\nexport function useWidgets(): UseWidgetsReturn {\n const service = inject(WidgetServiceKey);\n if (!service) {\n logger.error(\"Widget service not found in current context. Injection chain:\", getCurrentInstance());\n throw new InjectionError(\"WidgetService\");\n }\n return service;\n}\n\nexport { registerWidget, registerExternalWidget };\n","<template>\n <slot />\n</template>\n\n<script setup lang=\"ts\">\nimport { provide, inject } from \"vue\";\nimport { WidgetServiceKey, WidgetScopeKey } from \"@framework/injection-keys\";\nimport { BladeDescriptorKey } from \"@core/blade-navigation/types\";\nimport type { IWidgetTrigger, IWidgetScope } from \"@core/services/widget-service\";\n\nconst props = defineProps<{ widgetId: string }>();\n\nconst widgetService = inject(WidgetServiceKey)!;\nconst descriptor = inject(BladeDescriptorKey, undefined);\nconst bladeId = descriptor?.value.id ?? \"\";\n\nconst scope: IWidgetScope = {\n setTrigger: (trigger: IWidgetTrigger) => {\n widgetService.updateWidget({ id: props.widgetId, bladeId, widget: { trigger } });\n },\n};\n\nprovide(WidgetScopeKey, scope);\n</script>\n","import { toValue } from \"vue\";\r\nimport { useI18n } from \"vue-i18n\";\r\nimport { IWidget } from \"@core/services/widget-service\";\r\n\r\nexport function useHeadlessWidgetHelpers() {\r\n const { t } = useI18n({ useScope: \"global\" });\r\n\r\n function resolveBadge(widget: IWidget): string | number | undefined {\r\n const badge = widget.headless?.badge;\r\n if (badge === undefined) return undefined;\r\n return toValue(badge);\r\n }\r\n\r\n function resolveLoading(widget: IWidget): boolean {\r\n const loading = widget.headless?.loading;\r\n if (loading === undefined) return false;\r\n return toValue(loading);\r\n }\r\n\r\n function resolveDisabled(widget: IWidget): boolean {\r\n const disabled = widget.headless?.disabled;\r\n if (disabled === undefined) return false;\r\n return typeof disabled === \"boolean\" ? disabled : toValue(disabled);\r\n }\r\n\r\n function resolveTitle(widget: IWidget): string {\r\n const title = widget.title ?? \"\";\r\n return widget.headless ? t(title) : title;\r\n }\r\n\r\n function handleHeadlessClick(widget: IWidget) {\r\n widget.headless?.onClick?.();\r\n }\r\n\r\n return { resolveBadge, resolveLoading, resolveDisabled, resolveTitle, handleHeadlessClick };\r\n}\r\n","<template>\n <div class=\"vc-widget-container-desktop\">\n <div class=\"vc-widget-container-desktop__content\">\n <template\n v-for=\"widget in displayedItems\"\n :key=\"widget.id\"\n >\n <!-- Headless: framework renders VcWidget from config -->\n <div\n v-if=\"widget.headless && resolveLoading(widget)\"\n class=\"vc-widget-container-desktop__widget-skeleton\"\n >\n <VcSkeleton\n variant=\"circle\"\n :width=\"18\"\n :height=\"18\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"36\"\n :height=\"10\"\n class=\"tw-mt-1\"\n />\n </div>\n <VcWidget\n v-else-if=\"widget.headless\"\n :icon=\"widget.headless?.icon\"\n :title=\"resolveTitle(widget)\"\n :value=\"resolveBadge(widget)\"\n :disabled=\"resolveDisabled(widget)\"\n :widget-id=\"widget.id\"\n @click=\"handleHeadlessClick(widget)\"\n />\n\n <!-- Component-based: external widgets / legacy -->\n <WidgetScope\n v-else\n :widget-id=\"widget.id\"\n >\n <component\n :is=\"widget.component\"\n v-bind=\"widget.props || {}\"\n :widget-id=\"widget.id\"\n v-on=\"widget.events || {}\"\n />\n </WidgetScope>\n </template>\n\n <VcDropdown\n v-if=\"showMoreButton\"\n :model-value=\"showToolbar\"\n :items=\"overflowItems\"\n floating\n placement=\"bottom-end\"\n variant=\"secondary\"\n @update:model-value=\"showToolbar = $event\"\n >\n <template #trigger=\"{ isActive }\">\n <div\n class=\"vc-widget-container-desktop__more\"\n :class=\"{ 'vc-widget-container-desktop__more--active': isActive }\"\n @click=\"showToolbar = !showToolbar\"\n >\n <VcIcon icon=\"lucide-chevron-down\" />\n </div>\n </template>\n\n <template #item=\"{ item }\">\n <VcSkeleton\n v-if=\"item.headless && resolveLoading(item)\"\n variant=\"block\"\n width=\"100%\"\n :height=\"32\"\n />\n <VcWidget\n v-else-if=\"item.headless\"\n class=\"tw-w-full\"\n :icon=\"item.headless?.icon\"\n :title=\"resolveTitle(item)\"\n :value=\"resolveBadge(item)\"\n :disabled=\"resolveDisabled(item)\"\n :widget-id=\"item.id\"\n horizontal\n @click=\"\n handleHeadlessClick(item);\n showToolbar = false;\n \"\n />\n <WidgetScope\n v-else\n :widget-id=\"item.id\"\n >\n <component\n :is=\"item.component\"\n class=\"tw-w-full\"\n v-bind=\"item.props || {}\"\n horizontal\n :widget-id=\"item.id\"\n v-on=\"item.events || {}\"\n @click=\"showToolbar = false\"\n />\n </WidgetScope>\n </template>\n </VcDropdown>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from \"vue\";\nimport { IWidget } from \"@core/services/widget-service\";\nimport { VcDropdown } from \"@ui/components/molecules/vc-dropdown\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcWidget } from \"@ui/components/atoms/vc-widget\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport WidgetScope from \"./WidgetScope.vue\";\nimport { useHeadlessWidgetHelpers } from \"./useHeadlessWidgetHelpers\";\n\ninterface Props {\n widgets: IWidget[];\n bladeId: string;\n}\n\nconst props = defineProps<Props>();\nconst showToolbar = ref(false);\nconst { resolveBadge, resolveLoading, resolveDisabled, resolveTitle, handleHeadlessClick } = useHeadlessWidgetHelpers();\n\nconst displayedItems = computed(() => props.widgets.slice(0, 3));\nconst overflowItems = computed(() => props.widgets.slice(3));\nconst showMoreButton = computed(() => props.widgets.length > 3);\n</script>\n\n<style lang=\"scss\">\n:root {\n --blade-toolbar-widgets-bg-color: var(--neutrals-100);\n --blade-toolbar-widgets-bg-hover-color: var(--neutrals-200);\n}\n\n.vc-widget-container-desktop {\n @apply tw-relative tw-flex tw-select-none tw-shrink-0;\n width: fit-content;\n background-color: var(--blade-toolbar-widgets-bg-color);\n\n &__content {\n @apply tw-flex tw-flex-row tw-gap-1;\n }\n\n // Style widgets inside dropdown to match VcDropdownItem appearance\n .vc-dropdown__item {\n // Suppress widget's own hover — the dropdown item wrapper provides hover feedback\n --widget-bg-hover-color: transparent;\n --widget-bg-color: transparent;\n --widget-icon-hover-color: var(--widget-icon-color);\n --widget-title-hover-color: var(--widget-title-color);\n --widget-border-radius: 0;\n\n .vc-widget--horizontal {\n @apply tw-px-2 tw-py-[6px] tw-gap-2;\n\n .vc-widget__icon-container {\n @apply tw-flex tw-items-center tw-justify-center;\n }\n\n .vc-widget__icon {\n font-size: 14px;\n }\n\n .vc-widget__content {\n @apply tw-ml-0;\n }\n\n .vc-widget__title {\n @apply tw-mt-0 tw-text-xs tw-font-normal;\n }\n }\n }\n\n &__widget-skeleton {\n @apply tw-shrink-0 tw-px-2 tw-py-1.5 tw-flex tw-flex-col tw-items-center tw-justify-center;\n }\n\n &__more {\n @apply tw-flex tw-items-center tw-justify-center tw-px-2 tw-h-full tw-cursor-pointer;\n color: var(--blade-toolbar-icon-color);\n\n &:hover,\n &--active {\n color: var(--blade-toolbar-icon-hover-color);\n background-color: var(--blade-toolbar-widgets-bg-hover-color);\n }\n }\n}\n</style>\n","<template>\n <Teleport\n :to=\"teleportTarget\"\n defer\n :disabled=\"!teleport\"\n >\n <div\n class=\"vc-sidebar\"\n :style=\"containerStyle\"\n :aria-hidden=\"!modelValue\"\n >\n <Transition name=\"vc-sidebar-overlay\">\n <div\n v-if=\"modelValue && showOverlay\"\n class=\"vc-sidebar__overlay\"\n @click=\"handleOverlayClick\"\n />\n </Transition>\n\n <Transition :name=\"panelTransitionName\">\n <aside\n v-if=\"modelValue\"\n ref=\"panelEl\"\n class=\"vc-sidebar__panel\"\n :class=\"panelClasses\"\n :style=\"panelStyle\"\n role=\"dialog\"\n :aria-modal=\"showOverlay\"\n :aria-label=\"ariaDialogLabel\"\n :aria-labelledby=\"ariaDialogLabelledBy\"\n tabindex=\"-1\"\n @touchstart=\"handleTouchStart\"\n @touchmove=\"handleTouchMove\"\n @touchend=\"handleTouchEnd\"\n >\n <!-- Drag handle for bottom sheet -->\n <div\n v-if=\"dragHandle && isBottom\"\n class=\"vc-sidebar__handle\"\n >\n <div class=\"vc-sidebar__handle-bar\" />\n </div>\n\n <slot\n v-if=\"hasHeader\"\n name=\"header\"\n :close=\"close\"\n >\n <div class=\"vc-sidebar__header\">\n <div class=\"vc-sidebar__title-wrap\">\n <h3\n v-if=\"title\"\n :id=\"titleId\"\n class=\"vc-sidebar__title\"\n >\n {{ title }}\n </h3>\n <p\n v-if=\"subtitle\"\n class=\"vc-sidebar__subtitle\"\n >\n {{ subtitle }}\n </p>\n </div>\n\n <div class=\"vc-sidebar__header-actions\">\n <slot\n name=\"actions\"\n :close=\"close\"\n />\n <button\n v-if=\"closeButton\"\n type=\"button\"\n class=\"vc-sidebar__close\"\n :aria-label=\"closeAriaLabel\"\n @click=\"closeByReason('action')\"\n >\n <VcIcon\n icon=\"lucide-x\"\n size=\"m\"\n />\n </button>\n </div>\n </div>\n </slot>\n\n <div class=\"vc-sidebar__content\">\n <slot />\n </div>\n\n <div\n v-if=\"$slots.footer\"\n class=\"vc-sidebar__footer\"\n >\n <slot name=\"footer\" />\n </div>\n </aside>\n </Transition>\n </div>\n </Teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, nextTick, onBeforeUnmount, ref, useSlots, watch } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useTeleportTarget } from \"@ui/composables\";\n\nexport type SidebarCloseReason = \"overlay\" | \"escape\" | \"action\";\nexport type SidebarPosition = \"left\" | \"right\" | \"bottom\";\nexport type SidebarSize = \"sm\" | \"md\" | \"lg\" | \"full\";\nexport type SidebarVariant = \"default\" | \"elevated\" | \"minimal\";\n\nconst FOCUSABLE_SELECTOR =\n 'a[href], area[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]), [contenteditable=\"true\"]';\n\n/**\n * Scroll lock state is stored on window via Symbol.for() so it survives HMR module reloads.\n * Without this, HMR resets the counter to 0 while sidebars remain open, causing mismatched lock/unlock.\n */\nconst SCROLL_LOCK_KEY = Symbol.for(\"vc-sidebar-scroll-lock\");\n\ninterface ScrollLockState {\n counter: number;\n cachedOverflow: string;\n cachedPaddingRight: string;\n}\n\nfunction getScrollLockState(): ScrollLockState | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n const win = window as any;\n\n if (!win[SCROLL_LOCK_KEY]) {\n win[SCROLL_LOCK_KEY] = { counter: 0, cachedOverflow: \"\", cachedPaddingRight: \"\" };\n }\n\n return win[SCROLL_LOCK_KEY];\n}\n\nfunction acquireBodyScrollLock() {\n const state = getScrollLockState();\n\n if (!state || typeof document === \"undefined\") {\n return;\n }\n\n if (state.counter === 0) {\n const { body, documentElement } = document;\n state.cachedOverflow = body.style.overflow;\n state.cachedPaddingRight = body.style.paddingRight;\n\n const scrollbarWidth = window.innerWidth - documentElement.clientWidth;\n body.style.overflow = \"hidden\";\n\n if (scrollbarWidth > 0) {\n body.style.paddingRight = `${scrollbarWidth}px`;\n }\n }\n\n state.counter += 1;\n}\n\nfunction releaseBodyScrollLock() {\n const state = getScrollLockState();\n\n if (!state || typeof document === \"undefined\" || state.counter === 0) {\n return;\n }\n\n state.counter -= 1;\n\n if (state.counter === 0) {\n const { body } = document;\n body.style.overflow = state.cachedOverflow;\n body.style.paddingRight = state.cachedPaddingRight;\n }\n}\n\nexport interface Props {\n modelValue: boolean;\n position?: SidebarPosition;\n size?: SidebarSize;\n variant?: SidebarVariant;\n width?: number | string;\n height?: number | string;\n showOverlay?: boolean;\n closeOnOverlay?: boolean;\n closeOnEscape?: boolean;\n trapFocus?: boolean;\n lockScroll?: boolean;\n returnFocus?: boolean;\n autoFocus?: boolean;\n teleport?: boolean;\n teleportTo?: string | HTMLElement;\n title?: string;\n subtitle?: string;\n ariaLabel?: string;\n closeAriaLabel?: string;\n closeButton?: boolean;\n inset?: boolean;\n zIndex?: number;\n /** Enable swipe-to-dismiss gesture (only for position=\"bottom\") */\n draggable?: boolean;\n /** Show iOS-style drag handle bar at top of panel */\n dragHandle?: boolean;\n /** Fraction of panel height user must swipe to trigger close (0-1) */\n closeThreshold?: number;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n position: \"right\",\n size: \"sm\",\n variant: \"default\",\n width: undefined,\n height: undefined,\n showOverlay: true,\n closeOnOverlay: true,\n closeOnEscape: true,\n trapFocus: true,\n lockScroll: true,\n returnFocus: true,\n autoFocus: true,\n teleport: true,\n title: \"\",\n subtitle: \"\",\n ariaLabel: \"\",\n closeAriaLabel: \"Close sidebar\",\n closeButton: true,\n inset: true,\n zIndex: 9200,\n draggable: false,\n dragHandle: false,\n closeThreshold: 0.3,\n});\n\nconst emit = defineEmits<{\n (event: \"update:modelValue\", value: boolean): void;\n (event: \"close\", reason: SidebarCloseReason): void;\n}>();\n\ndefineSlots<{\n default?: () => unknown;\n header?: (args: { close: () => void }) => unknown;\n actions?: (args: { close: () => void }) => unknown;\n footer?: () => unknown;\n}>();\n\nconst slots = useSlots();\nconst panelEl = ref<HTMLElement | null>(null);\nconst sideEffectsActive = ref(false);\nconst lastFocusedElement = ref<HTMLElement | null>(null);\n\nconst { teleportTarget } = useTeleportTarget({\n to: computed(() => props.teleportTo),\n});\n\nconst uid = Math.round(Math.random() * 100_000);\nconst titleId = `vc-sidebar-title-${uid}`;\n\nconst panelWidths: Record<SidebarSize, string> = {\n sm: \"300px\",\n md: \"380px\",\n lg: \"520px\",\n full: \"100vw\",\n};\n\nconst panelHeights: Record<SidebarSize, string> = {\n sm: \"40dvh\",\n md: \"56dvh\",\n lg: \"72dvh\",\n full: \"100dvh\",\n};\n\nconst normalizedWidth = computed(() => (typeof props.width === \"number\" ? `${props.width}px` : props.width));\nconst normalizedHeight = computed(() => (typeof props.height === \"number\" ? `${props.height}px` : props.height));\n\nconst hasHeader = computed(() => !!props.title || props.closeButton || !!slots.header);\nconst hasFooter = computed(() => !!slots.footer);\n\nconst isBottom = computed(() => props.position === \"bottom\");\nconst isFullSize = computed(() => props.size === \"full\");\nconst panelTransitionName = computed(() => {\n if (props.position === \"left\") {\n return \"vc-sidebar-panel-left\";\n }\n\n if (props.position === \"bottom\") {\n return \"vc-sidebar-panel-bottom\";\n }\n\n return \"vc-sidebar-panel-right\";\n});\n\nconst panelStyle = computed(() => {\n if (isBottom.value) {\n return {\n height: normalizedHeight.value ?? panelHeights[props.size],\n };\n }\n\n return {\n width: normalizedWidth.value ?? panelWidths[props.size],\n };\n});\n\nconst containerStyle = computed(() => ({\n zIndex: props.zIndex,\n}));\n\nconst panelClasses = computed(() => [\n `vc-sidebar__panel--${props.position}`,\n `vc-sidebar__panel--${props.variant}`,\n `vc-sidebar__panel--size-${props.size}`,\n {\n \"vc-sidebar__panel--with-header\": hasHeader.value,\n \"vc-sidebar__panel--with-footer\": hasFooter.value,\n \"vc-sidebar__panel--inset\": props.inset && !isFullSize.value,\n \"vc-sidebar__panel--draggable\": props.draggable && isBottom.value,\n },\n]);\n\nconst ariaDialogLabel = computed(() => props.ariaLabel || undefined);\nconst ariaDialogLabelledBy = computed(() => (props.ariaLabel || !props.title ? undefined : titleId));\n\nfunction closeByReason(reason: SidebarCloseReason) {\n emit(\"update:modelValue\", false);\n emit(\"close\", reason);\n}\n\nfunction close() {\n closeByReason(\"action\");\n}\n\nfunction open() {\n emit(\"update:modelValue\", true);\n}\n\nfunction handleOverlayClick() {\n if (!props.closeOnOverlay) {\n return;\n }\n\n closeByReason(\"overlay\");\n}\n\n// --- Swipe-to-dismiss gesture (bottom position only) ---\nconst touchStartY = ref(0);\nconst isDragging = ref(false);\n\nfunction handleTouchStart(event: TouchEvent) {\n if (!props.draggable || !isBottom.value) return;\n touchStartY.value = event.touches[0].clientY;\n isDragging.value = true;\n}\n\nfunction handleTouchMove(event: TouchEvent) {\n if (!isDragging.value || !panelEl.value) return;\n\n const delta = event.touches[0].clientY - touchStartY.value;\n\n // Only allow dragging downward (positive delta)\n if (delta > 0) {\n panelEl.value.style.transform = `translateY(${delta}px)`;\n panelEl.value.style.transition = \"none\";\n }\n}\n\nfunction handleTouchEnd(event: TouchEvent) {\n if (!isDragging.value || !panelEl.value) return;\n isDragging.value = false;\n\n const delta = event.changedTouches[0].clientY - touchStartY.value;\n const panelHeight = panelEl.value.offsetHeight;\n const threshold = panelHeight * props.closeThreshold;\n\n if (delta > threshold) {\n // Animate out then close\n panelEl.value.style.transition = \"transform 0.2s ease\";\n panelEl.value.style.transform = `translateY(${panelHeight}px)`;\n setTimeout(() => {\n closeByReason(\"action\");\n }, 200);\n } else {\n // Snap back\n panelEl.value.style.transition = \"transform 0.2s ease\";\n panelEl.value.style.transform = \"\";\n setTimeout(() => {\n if (panelEl.value) {\n panelEl.value.style.transition = \"\";\n }\n }, 200);\n }\n}\n\nfunction getFocusableElements() {\n if (!panelEl.value) {\n return [];\n }\n\n return Array.from(panelEl.value.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter((element) => {\n if (element.hasAttribute(\"disabled\") || element.getAttribute(\"aria-hidden\") === \"true\") {\n return false;\n }\n\n const style = window.getComputedStyle(element);\n return style.display !== \"none\" && style.visibility !== \"hidden\";\n });\n}\n\nlet isRedirectingFocus = false;\n\nfunction focusFirstFocusable() {\n if (isRedirectingFocus) return;\n isRedirectingFocus = true;\n\n const firstFocusable = getFocusableElements()[0];\n if (firstFocusable) {\n firstFocusable.focus();\n } else {\n panelEl.value?.focus();\n }\n\n isRedirectingFocus = false;\n}\n\nfunction handleDocumentFocusIn(event: FocusEvent) {\n if (isRedirectingFocus || !props.modelValue || !props.trapFocus || !panelEl.value) {\n return;\n }\n\n if (event.target instanceof Node && !panelEl.value.contains(event.target)) {\n focusFirstFocusable();\n }\n}\n\nfunction handleDocumentKeydown(event: KeyboardEvent) {\n if (!props.modelValue) {\n return;\n }\n\n if (event.key === \"Escape\") {\n if (props.closeOnEscape) {\n closeByReason(\"escape\");\n }\n return;\n }\n\n if (!props.trapFocus || event.key !== \"Tab\" || !panelEl.value) {\n return;\n }\n\n const focusables = getFocusableElements();\n if (!focusables.length) {\n event.preventDefault();\n panelEl.value.focus();\n return;\n }\n\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey) {\n if (active === first || !active || !panelEl.value.contains(active)) {\n event.preventDefault();\n last.focus();\n }\n return;\n }\n\n if (active === last) {\n event.preventDefault();\n first.focus();\n }\n}\n\nfunction restoreFocus() {\n if (!props.returnFocus || !lastFocusedElement.value) {\n lastFocusedElement.value = null;\n return;\n }\n\n const elementToFocus = lastFocusedElement.value;\n lastFocusedElement.value = null;\n\n nextTick(() => {\n try {\n elementToFocus.focus({ preventScroll: true });\n } catch {\n elementToFocus.focus();\n }\n });\n}\n\nfunction activateSideEffects() {\n if (sideEffectsActive.value || typeof document === \"undefined\") {\n return;\n }\n\n sideEffectsActive.value = true;\n lastFocusedElement.value = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n\n document.addEventListener(\"keydown\", handleDocumentKeydown);\n document.addEventListener(\"focusin\", handleDocumentFocusIn);\n\n if (props.lockScroll) {\n acquireBodyScrollLock();\n }\n\n if (props.autoFocus) {\n nextTick(() => {\n focusFirstFocusable();\n });\n }\n}\n\nfunction deactivateSideEffects() {\n if (!sideEffectsActive.value || typeof document === \"undefined\") {\n return;\n }\n\n sideEffectsActive.value = false;\n document.removeEventListener(\"keydown\", handleDocumentKeydown);\n document.removeEventListener(\"focusin\", handleDocumentFocusIn);\n\n if (props.lockScroll) {\n releaseBodyScrollLock();\n }\n\n restoreFocus();\n}\n\nwatch(\n () => props.modelValue,\n (opened) => {\n if (opened) {\n // Reset any leftover drag transform when re-opening\n nextTick(() => {\n if (panelEl.value) {\n panelEl.value.style.transform = \"\";\n panelEl.value.style.transition = \"\";\n }\n });\n activateSideEffects();\n return;\n }\n\n deactivateSideEffects();\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n deactivateSideEffects();\n});\n\ndefineExpose({\n close,\n open,\n});\n</script>\n\n<style lang=\"scss\">\n.vc-sidebar {\n --vc-sidebar-bg-color: var(--additional-50);\n --vc-sidebar-bg-elevated: color-mix(in srgb, var(--additional-50) 90%, white 10%);\n --vc-sidebar-title-color: var(--additional-950);\n --vc-sidebar-subtitle-color: var(--neutrals-600);\n --vc-sidebar-overlay-color: var(--overlay-bg);\n --vc-sidebar-close-color: var(--neutrals-600);\n --vc-sidebar-border-color: var(--surface-border);\n --vc-sidebar-shadow: var(--shadow-md);\n --vc-sidebar-radius: 16px;\n --vc-sidebar-inset-gap: 12px;\n --vc-sidebar-header-height: 72px;\n --vc-sidebar-footer-height: 72px;\n\n @apply tw-fixed tw-inset-0 tw-pointer-events-none;\n\n &__overlay {\n @apply tw-absolute tw-inset-0 tw-pointer-events-auto;\n backdrop-filter: blur(var(--overlay-blur));\n -webkit-backdrop-filter: blur(var(--overlay-blur));\n background: var(--vc-sidebar-overlay-color);\n }\n\n &__panel {\n @apply tw-fixed tw-flex tw-flex-col tw-pointer-events-auto tw-overflow-hidden;\n @apply tw-bg-[color:var(--vc-sidebar-bg-color)] tw-border tw-border-solid tw-border-[color:var(--vc-sidebar-border-color)];\n box-shadow: var(--vc-sidebar-shadow);\n max-width: 100vw;\n max-height: 100dvh;\n\n &--left {\n @apply tw-left-0 tw-top-0 tw-bottom-0;\n }\n\n &--right {\n @apply tw-right-0 tw-top-0 tw-bottom-0;\n }\n\n &--bottom {\n @apply tw-left-0 tw-right-0 tw-bottom-0 tw-top-auto;\n border-radius: var(--vc-sidebar-radius) var(--vc-sidebar-radius) 0 0;\n border-bottom-width: 0;\n max-height: 96dvh;\n }\n\n &--size-full {\n @apply tw-rounded-none;\n width: 100vw !important;\n height: 100dvh !important;\n inset: 0 !important;\n border-radius: 0 !important;\n border: 0;\n }\n\n &--default {\n background: var(--vc-sidebar-bg-color);\n }\n\n &--elevated {\n background: var(--vc-sidebar-bg-elevated);\n box-shadow: var(--shadow-lg);\n }\n\n &--minimal {\n box-shadow: var(--shadow-sm);\n border-color: color-mix(in srgb, var(--neutrals-200) 86%, white 14%);\n }\n\n &--draggable {\n touch-action: none;\n }\n\n &:focus {\n outline: none;\n }\n\n &:focus-visible {\n @apply tw-ring-2 tw-ring-primary-500 tw-ring-offset-2;\n }\n }\n\n &__panel {\n &--inset.vc-sidebar__panel--left {\n top: var(--vc-sidebar-inset-gap);\n bottom: var(--vc-sidebar-inset-gap);\n left: var(--vc-sidebar-inset-gap);\n border-radius: var(--vc-sidebar-radius);\n }\n\n &--inset.vc-sidebar__panel--right {\n top: var(--vc-sidebar-inset-gap);\n bottom: var(--vc-sidebar-inset-gap);\n right: var(--vc-sidebar-inset-gap);\n border-radius: var(--vc-sidebar-radius);\n }\n\n &--inset.vc-sidebar__panel--bottom {\n left: var(--vc-sidebar-inset-gap);\n right: var(--vc-sidebar-inset-gap);\n bottom: var(--vc-sidebar-inset-gap);\n border-radius: var(--vc-sidebar-radius);\n border-bottom-width: 1px;\n }\n }\n\n &__header {\n @apply tw-flex tw-items-center tw-justify-between tw-gap-4 tw-px-5 tw-py-4 tw-border-b tw-border-solid;\n @apply tw-border-b-[color:var(--vc-sidebar-border-color)] tw-sticky tw-top-0 tw-z-[var(--z-local-above)];\n min-height: var(--vc-sidebar-header-height);\n background: inherit;\n backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-blur));\n -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-blur));\n }\n\n &__title-wrap {\n @apply tw-flex tw-flex-col tw-min-w-0;\n }\n\n &__title {\n @apply tw-text-lg tw-font-semibold tw-truncate tw-text-[color:var(--vc-sidebar-title-color)];\n }\n\n &__subtitle {\n @apply tw-text-sm tw-truncate tw-text-[color:var(--vc-sidebar-subtitle-color)] tw-mt-0.5;\n }\n\n &__header-actions {\n @apply tw-flex tw-items-center tw-gap-2 tw-shrink-0;\n }\n\n &__close {\n @apply tw-border-0 tw-bg-transparent tw-cursor-pointer tw-flex tw-items-center tw-justify-center;\n @apply tw-h-9 tw-w-9 tw-rounded-md tw-p-0;\n @apply tw-text-[color:var(--vc-sidebar-close-color)];\n\n &:hover {\n @apply tw-bg-neutrals-200;\n }\n\n &:focus-visible {\n @apply tw-outline-none tw-ring-2 tw-ring-primary-500 tw-ring-offset-1;\n }\n }\n\n &__handle {\n @apply tw-flex tw-justify-center tw-py-3 tw-cursor-grab tw-shrink-0;\n\n &:active {\n @apply tw-cursor-grabbing;\n }\n }\n\n &__handle-bar {\n @apply tw-w-[100px] tw-h-1.5 tw-rounded-full;\n background: var(--neutrals-300);\n }\n\n &__content {\n @apply tw-flex tw-flex-col tw-flex-1 tw-relative tw-overflow-auto;\n min-height: 0;\n padding: max(0px, env(safe-area-inset-top)) max(0px, env(safe-area-inset-right))\n max(0px, env(safe-area-inset-bottom)) max(0px, env(safe-area-inset-left));\n }\n\n &__footer {\n @apply tw-mt-auto tw-sticky tw-bottom-0 tw-z-[var(--z-local-above)] tw-border-t tw-border-solid tw-border-t-[color:var(--vc-sidebar-border-color)];\n min-height: var(--vc-sidebar-footer-height);\n background: inherit;\n backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-blur));\n -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-blur));\n }\n}\n\n.vc-sidebar-overlay-enter-active,\n.vc-sidebar-overlay-leave-active {\n transition: opacity 0.22s ease;\n}\n\n.vc-sidebar-overlay-enter-from,\n.vc-sidebar-overlay-leave-to {\n opacity: 0;\n}\n\n.vc-sidebar-panel-right-enter-active,\n.vc-sidebar-panel-right-leave-active,\n.vc-sidebar-panel-left-enter-active,\n.vc-sidebar-panel-left-leave-active {\n transition:\n transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1),\n opacity 0.22s ease;\n}\n\n.vc-sidebar-panel-bottom-enter-active,\n.vc-sidebar-panel-bottom-leave-active {\n transition: transform 0.32s cubic-bezier(0.32, 0.72, 0, 1);\n}\n\n.vc-sidebar-panel-right-enter-from,\n.vc-sidebar-panel-right-leave-to {\n transform: translateX(24px);\n opacity: 0;\n}\n\n.vc-sidebar-panel-left-enter-from,\n.vc-sidebar-panel-left-leave-to {\n transform: translateX(-24px);\n opacity: 0;\n}\n\n.vc-sidebar-panel-bottom-enter-from,\n.vc-sidebar-panel-bottom-leave-to {\n transform: translateY(100%);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .vc-sidebar-overlay-enter-active,\n .vc-sidebar-overlay-leave-active,\n .vc-sidebar-panel-right-enter-active,\n .vc-sidebar-panel-right-leave-active,\n .vc-sidebar-panel-left-enter-active,\n .vc-sidebar-panel-left-leave-active,\n .vc-sidebar-panel-bottom-enter-active,\n .vc-sidebar-panel-bottom-leave-active {\n transition: none !important;\n }\n}\n</style>\n","<template>\n <div\n v-show=\"isAnyVisible\"\n class=\"vc-widget-container-mobile\"\n >\n <div\n ref=\"containerRef\"\n class=\"vc-widget-container-mobile__content\"\n >\n <template\n v-for=\"widget in visibleItems\"\n :key=\"widget.id\"\n >\n <div\n v-if=\"widget.headless && resolveLoading(widget)\"\n class=\"vc-widget-container-mobile__widget-skeleton\"\n :data-item-key=\"widget.id\"\n >\n <VcSkeleton\n variant=\"circle\"\n :width=\"18\"\n :height=\"18\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"36\"\n :height=\"10\"\n class=\"tw-mt-1\"\n />\n </div>\n <VcWidget\n v-else-if=\"widget.headless\"\n :icon=\"widget.headless?.icon\"\n :title=\"resolveTitle(widget)\"\n :value=\"resolveBadge(widget)\"\n :disabled=\"resolveDisabled(widget)\"\n :data-item-key=\"widget.id\"\n :widget-id=\"widget.id\"\n @click=\"handleHeadlessClick(widget)\"\n />\n <WidgetScope\n v-else\n :widget-id=\"widget.id\"\n >\n <component\n :is=\"widget.component\"\n v-bind=\"widget.props || {}\"\n :data-item-key=\"widget.id\"\n :widget-id=\"widget.id\"\n v-on=\"widget.events || {}\"\n />\n </WidgetScope>\n </template>\n\n <div\n v-if=\"showMoreButton\"\n data-more-button\n class=\"vc-widget-container-mobile__more\"\n @click=\"showOverflow = true\"\n >\n <VcIcon icon=\"lucide-chevron-up\" />\n </div>\n </div>\n\n <VcSidebar\n :model-value=\"showOverflow\"\n position=\"bottom\"\n size=\"sm\"\n draggable\n drag-handle\n :close-button=\"false\"\n :inset=\"false\"\n @update:model-value=\"showOverflow = $event\"\n >\n <div class=\"vc-widget-container-mobile__overflow-list\">\n <template\n v-for=\"item in hiddenItems\"\n :key=\"item.id\"\n >\n <VcSkeleton\n v-if=\"item.headless && resolveLoading(item)\"\n variant=\"block\"\n width=\"100%\"\n :height=\"32\"\n />\n <VcWidget\n v-else-if=\"item.headless\"\n class=\"tw-w-full\"\n :icon=\"item.headless?.icon\"\n :title=\"resolveTitle(item)\"\n :value=\"resolveBadge(item)\"\n :disabled=\"resolveDisabled(item)\"\n :widget-id=\"item.id\"\n horizontal\n @click=\"\n handleHeadlessClick(item);\n showOverflow = false;\n \"\n />\n <WidgetScope\n v-else\n :widget-id=\"item.id\"\n >\n <component\n :is=\"item.component\"\n class=\"tw-w-full\"\n v-bind=\"item.props || {}\"\n horizontal\n :widget-id=\"item.id\"\n v-on=\"item.events || {}\"\n @click=\"showOverflow = false\"\n />\n </WidgetScope>\n </template>\n </div>\n </VcSidebar>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\nimport { useAdaptiveItems } from \"@ui/composables/useAdaptiveItems\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcWidget } from \"@ui/components/atoms/vc-widget\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { VcSidebar } from \"@ui/components/organisms/vc-sidebar\";\nimport { IWidget } from \"@core/services/widget-service\";\nimport { useHeadlessWidgetHelpers } from \"./useHeadlessWidgetHelpers\";\nimport WidgetScope from \"./WidgetScope.vue\";\n\ninterface Props {\n widgets: IWidget[];\n bladeId: string;\n}\n\nconst props = defineProps<Props>();\nconst containerRef = ref<HTMLElement | null>(null);\nconst showOverflow = ref(false);\nconst isAnyVisible = computed(() => props.widgets.length > 0);\nconst { resolveBadge, resolveLoading, resolveDisabled, resolveTitle, handleHeadlessClick } = useHeadlessWidgetHelpers();\n\nconst { visibleItems, showMoreButton, hiddenItems } = useAdaptiveItems<IWidget>({\n containerRef,\n items: computed(() => props.widgets),\n getItemKey: (item: IWidget) => item.id ?? \"\",\n moreButtonWidth: 70,\n initialItemWidth: 80,\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --blade-toolbar-widgets-bg-color-mobile: var(--additional-50);\n --blade-toolbar-widgets-mobile-height: 80px;\n}\n\n.vc-widget-container-mobile {\n @apply tw-fixed tw-bottom-0 tw-left-0 tw-right-0 tw-w-full tw-z-[var(--z-layout-widget)];\n height: var(--blade-toolbar-widgets-mobile-height);\n background-color: var(--blade-toolbar-widgets-bg-color-mobile);\n\n &__content {\n @apply tw-flex tw-flex-row tw-items-center tw-gap-1 tw-px-[22px] tw-w-full tw-overflow-hidden;\n height: var(--blade-toolbar-widgets-mobile-height);\n }\n\n &__widget-skeleton {\n @apply tw-shrink-0 tw-px-2 tw-py-1.5 tw-flex tw-flex-col tw-items-center tw-justify-center;\n }\n\n &__more {\n @apply tw-flex tw-items-center tw-justify-center tw-px-2 tw-h-full tw-cursor-pointer tw-ml-auto;\n color: var(--blade-toolbar-icon-color);\n\n &:hover,\n &--active {\n color: var(--blade-toolbar-icon-hover-color);\n background-color: var(--blade-toolbar-widgets-bg-hover-color);\n }\n }\n\n &__overflow-list {\n @apply tw-flex tw-flex-col tw-gap-2 tw-p-4;\n }\n}\n</style>\n","<template>\n <WidgetContainerMobile\n v-if=\"visibleWidgets.length > 0 && isMobile\"\n :widgets=\"visibleWidgets\"\n :blade-id=\"normalizedBladeId\"\n />\n <WidgetContainerDesktop\n v-else-if=\"visibleWidgets.length > 0\"\n :widgets=\"visibleWidgets\"\n :blade-id=\"normalizedBladeId\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, onMounted, onUnmounted } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { useWidgets } from \"@core/composables/useWidgets\";\nimport WidgetContainerDesktop from \"@ui/components/organisms/vc-blade/_internal/widgets/WidgetContainerDesktop.vue\";\nimport WidgetContainerMobile from \"@ui/components/organisms/vc-blade/_internal/widgets/WidgetContainerMobile.vue\";\nimport { BladeDescriptorKey } from \"@core/blade-navigation/types\";\nimport { IWidget } from \"@core/services/widget-service\";\nimport { resolveVisibility } from \"@ui/components/organisms/vc-blade/utils\";\nimport { createLogger } from \"@core/utilities\";\n\ninterface Props {\n bladeId: string;\n}\n\nconst props = defineProps<Props>();\nconst { isMobile } = useResponsive();\nconst logger = createLogger(\"widget-container\");\n\nconst normalizedBladeId = computed(() => props.bladeId.toLowerCase());\nconst widgetService = useWidgets();\n\nconst descriptor = inject(BladeDescriptorKey, undefined);\n\n// ── External widget auto-resolution ─────────────────────────────────────────\n\nconst bladeName = computed(() => descriptor?.value.name?.toLowerCase() ?? \"\");\nconst registeredExternalWidgetIds = new Set<string>();\n\nfunction registerExternalWidgets() {\n if (!bladeName.value) return;\n\n const allExternalWidgets = widgetService.getAllExternalWidgets();\n\n const matchingWidgets = allExternalWidgets.filter(\n (widget) => widget.targetBlades?.some((t) => t.toLowerCase() === bladeName.value) ?? false,\n );\n\n matchingWidgets.forEach((externalWidget) => {\n if (registeredExternalWidgetIds.has(externalWidget.id)) return;\n\n try {\n widgetService.registerWidget(\n {\n id: externalWidget.id,\n component: externalWidget.component,\n isVisible: externalWidget.isVisible,\n title: externalWidget.title,\n },\n normalizedBladeId.value,\n );\n registeredExternalWidgetIds.add(externalWidget.id);\n } catch (error) {\n logger.error(`Failed to register external widget '${externalWidget.id}':`, error);\n }\n });\n}\n\nfunction unregisterExternalWidgets() {\n registeredExternalWidgetIds.forEach((widgetId) => {\n try {\n widgetService.unregisterWidget(widgetId, normalizedBladeId.value);\n } catch (error) {\n logger.error(`Failed to unregister external widget '${widgetId}':`, error);\n }\n });\n registeredExternalWidgetIds.clear();\n}\n\nonMounted(registerExternalWidgets);\nonUnmounted(unregisterExternalWidgets);\n\n// ── Standard widget rendering ───────────────────────────────────────────────\n\nconst widgets = computed(() => widgetService.getWidgets(normalizedBladeId.value));\n\nconst visibleWidgets = computed(() =>\n widgets.value.filter((widget: IWidget) => resolveVisibility(widget.isVisible, descriptor?.value)),\n);\n</script>\n","import * as veeValidate from \"vee-validate\";\nimport { i18n } from \"@core/plugins/i18n\";\nimport { setLocale as setVeeI18nLocale, localize } from \"@vee-validate/i18n\";\nimport { useLocalStorage } from \"@vueuse/core\";\nimport { ComputedRef, computed } from \"vue\";\nimport ISO6391 from \"iso-639-1\";\nimport { languageToCountryMap } from \"@core/constants\";\n\nexport interface ILanguageService {\n setLocale: (locale: string) => void;\n currentLocale: ComputedRef<string>;\n getLocaleByTag: (localeTag: string) => string | undefined;\n resolveCamelCaseLocale: (locale: string) => string;\n getFlag: (language: string) => Promise<string>;\n getCountryCode: (language: string) => string;\n}\n\n/**\n * Language service implementation\n * Handles locale management, validation, and language utilities\n */\nexport function createLanguageService(): ILanguageService {\n const savedLocale = useLocalStorage(\"VC_LANGUAGE_SETTINGS\", \"\");\n\n function resolveSupportedLocale(locale: string): string {\n if (!locale) {\n return \"en\";\n }\n\n const normalizedLocale = locale.replace(/([a-z]+)([A-Z]+)/g, \"$1-$2\").toLowerCase();\n return i18n.global.availableLocales.includes(normalizedLocale) ? normalizedLocale : \"en\";\n }\n\n // Initialize locale from localStorage on service creation\n if (savedLocale.value && i18n.global.availableLocales.includes(savedLocale.value)) {\n i18n.global.locale.value = savedLocale.value;\n }\n\n const currentLocale = computed(() => {\n if (i18n.global.availableLocales.includes(savedLocale.value)) {\n return savedLocale.value;\n }\n\n return i18n.global.locale.value;\n });\n\n function setLocale(locale: string) {\n const resolvedLocale = resolveSupportedLocale(locale);\n\n // Update the global i18n locale\n i18n.global.locale.value = resolvedLocale;\n\n const localeMessages = (i18n.global.getLocaleMessage(resolvedLocale) as { messages?: Record<string, string> })\n ?.messages;\n\n veeValidate.configure({\n generateMessage: localize(resolvedLocale, {\n messages: localeMessages ?? {},\n }),\n });\n\n setVeeI18nLocale(resolvedLocale);\n savedLocale.value = resolvedLocale;\n }\n\n function getLocaleByTag(localeTag: string) {\n if (!localeTag) return;\n\n const twoLetterLanguageName = localeTag.split(\"-\")[0];\n\n // For regional tags (e.g. \"en-US\", \"de-CH\") use Intl.DisplayNames to produce\n // region-qualified native names (\"American English\", \"British English\").\n // Otherwise tags differing only by region collapse into identical labels.\n if (localeTag.includes(\"-\")) {\n try {\n const displayName = new Intl.DisplayNames([localeTag], { type: \"language\" }).of(localeTag);\n if (displayName && displayName !== localeTag) {\n return displayName;\n }\n } catch {\n // Invalid locale tag — fall back to the base language name below\n }\n }\n\n return ISO6391.getNativeName(twoLetterLanguageName);\n }\n\n function resolveCamelCaseLocale(locale: string) {\n return resolveSupportedLocale(locale);\n }\n\n function getCountryCode(language: string): string {\n return (\n languageToCountryMap[language.toLowerCase()] || languageToCountryMap[language.slice(0, 2)] || \"xx\" // placeholder for unknown country\n );\n }\n\n async function getFlag(language: string): Promise<string> {\n if (!language) return \"\";\n const countryCode = getCountryCode(language);\n return new URL(`../../assets/icons/flags/${countryCode}.svg`, import.meta.url).href;\n }\n\n return {\n setLocale,\n currentLocale,\n getLocaleByTag,\n resolveCamelCaseLocale,\n getFlag,\n getCountryCode,\n };\n}\n","import { hasInjectionContext, inject, provide } from \"vue\";\nimport { LanguageServiceKey } from \"@framework/injection-keys\";\nimport { ILanguageService, createLanguageService } from \"@core/services/language-service\";\nimport { createLogger, InjectionError } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-languages\");\nlet fallbackLanguageService: ILanguageService | null = null;\n\nexport interface UseLanguagesReturn extends ILanguageService {}\n\n/** @deprecated Use UseLanguagesReturn instead */\nexport type IUseLanguages = UseLanguagesReturn;\n\nfunction getOrCreateFallbackLanguageService(): ILanguageService {\n if (!fallbackLanguageService) {\n fallbackLanguageService = createLanguageService();\n }\n\n return fallbackLanguageService;\n}\n\nexport function provideLanguages(): ILanguageService {\n if (!hasInjectionContext()) {\n logger.warn(\"No injection context for provideLanguages; using fallback language service\");\n return getOrCreateFallbackLanguageService();\n }\n\n const existingService = inject(LanguageServiceKey, null);\n if (existingService) {\n return existingService;\n }\n\n const service = createLanguageService();\n provide(LanguageServiceKey, service);\n return service;\n}\n\nexport function useLanguages(): UseLanguagesReturn {\n if (!hasInjectionContext()) {\n return getOrCreateFallbackLanguageService();\n }\n\n const languageService = inject(LanguageServiceKey, null);\n\n if (!languageService) {\n logger.error(\"Language service not found\");\n throw new InjectionError(\"LanguageService\");\n }\n\n return languageService;\n}\n","import { inject, provide, getCurrentScope, onScopeDispose } from \"vue\";\nimport { createAppBarWidgetService, IAppBarWidgetService, appBarWidgetBus } from \"@core/services/app-bar-menu-service\";\nimport { AppBarWidgetServiceKey } from \"@framework/injection-keys\";\nimport { createLogger, InjectionError } from \"@core/utilities\";\n\nexport type UseAppBarWidgetReturn = IAppBarWidgetService;\n\nconst logger = createLogger(\"use-app-bar-widget\");\n\nexport function provideAppBarWidget(): IAppBarWidgetService {\n const existingService = inject(AppBarWidgetServiceKey, null);\n if (existingService) {\n return existingService;\n }\n\n const service = createAppBarWidgetService();\n provide(AppBarWidgetServiceKey, service);\n\n if (getCurrentScope()) {\n onScopeDispose(() => appBarWidgetBus.dispose(service));\n }\n\n return service;\n}\n\nexport function useAppBarWidget(): UseAppBarWidgetReturn {\n const service = inject(AppBarWidgetServiceKey);\n if (!service) {\n logger.error(\"AppBarWidgetService not found\");\n throw new InjectionError(\"AppBarWidgetService\");\n }\n return service;\n}\n","import { useLocalStorage } from \"@vueuse/core\";\nimport { ref, onScopeDispose, type Ref } from \"vue\";\n\nexport interface UseMenuExpandedReturn {\n isExpanded: Ref<boolean>;\n toggleExpanded: () => void;\n isHoverExpanded: Ref<boolean>;\n toggleHoverExpanded: (shouldExpand?: boolean) => void;\n}\n\nconst STORAGE_KEY_PREFIX = \"VC_APP_MENU_EXPANDED\";\nconst HOVER_DELAY = 200;\n\n/**\n * Get unique storage key for current application based on URL path\n * This ensures each application has its own menu state\n */\nfunction getStorageKey(): string {\n // Extract app name from pathname (e.g., \"/vendor-portal/\" -> \"vendor-portal\")\n const pathSegments = window.location.pathname.split(\"/\").filter(Boolean);\n const appName = pathSegments[0] || \"default\";\n return `${STORAGE_KEY_PREFIX}_${appName}`;\n}\n\nexport const useMenuExpanded = (): UseMenuExpandedReturn => {\n const isExpanded = useLocalStorage(getStorageKey(), true);\n const isHoverExpanded = ref(false);\n\n let expandTimeout: ReturnType<typeof setTimeout> | null = null;\n\n const toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n };\n\n const toggleHoverExpanded = (shouldExpand?: boolean) => {\n if (expandTimeout) {\n clearTimeout(expandTimeout);\n }\n\n if (shouldExpand) {\n expandTimeout = setTimeout(() => {\n if (isHoverExpanded.value !== shouldExpand) {\n isHoverExpanded.value = shouldExpand;\n }\n }, HOVER_DELAY);\n } else if (shouldExpand === false) {\n isHoverExpanded.value = shouldExpand;\n }\n };\n\n /**\n * Cleanup timeout when the effect scope is disposed\n * This prevents memory leaks when component using this composable is unmounted\n */\n const cleanup = () => {\n if (expandTimeout) {\n clearTimeout(expandTimeout);\n expandTimeout = null;\n }\n };\n\n // Register cleanup function to be called when effect scope is disposed\n onScopeDispose(cleanup);\n\n return {\n isExpanded,\n toggleExpanded,\n isHoverExpanded,\n toggleHoverExpanded,\n };\n};\n","import { ref, computed, provide, inject } from \"vue\";\nimport type { Ref, ComputedRef, InjectionKey } from \"vue\";\nimport { useMenuExpanded } from \"@core/composables/useMenuExpanded\";\n\nexport interface SidebarState {\n /** Sidebar is pinned open by user (persisted to localStorage) */\n isPinned: Ref<boolean>;\n /** Sidebar is temporarily expanded on mouse hover (desktop only) */\n isHoverExpanded: Ref<boolean>;\n /** Mobile menu overlay is visible */\n isMenuOpen: Ref<boolean>;\n /** Derived: sidebar content should render in expanded mode (pinned OR hovered) */\n isExpanded: ComputedRef<boolean>;\n}\n\nexport interface SidebarActions {\n /** Toggle the pinned state (persists to localStorage) */\n togglePin: () => void;\n /** Set hover expansion state with delay for opening */\n setHoverExpanded: (value: boolean) => void;\n /** Open the mobile menu / widget overlay */\n openMenu: () => void;\n /** Close the mobile menu / widget overlay */\n closeMenu: () => void;\n}\n\nexport type UseSidebarStateReturn = SidebarState & SidebarActions;\n\n/** @deprecated Use UseSidebarStateReturn instead */\nexport type SidebarStateReturn = UseSidebarStateReturn;\n\nconst SIDEBAR_STATE_KEY: InjectionKey<UseSidebarStateReturn> = Symbol(\"SidebarState\");\n\n/**\n * Provides sidebar state to the component tree. Must be called once in VcApp setup.\n * Idempotent: returns existing instance if already provided in the current tree.\n * Internally delegates to useMenuExpanded() for shared reactive state,\n * ensuring UserDropdownButton (which uses useMenuExpanded directly) stays in sync.\n */\nexport function provideSidebarState(): UseSidebarStateReturn {\n const existing = inject(SIDEBAR_STATE_KEY, null);\n if (existing) return existing;\n\n // Delegate to shared useMenuExpanded composable for reactive state sync\n const { isExpanded: isPinned, isHoverExpanded, toggleExpanded: togglePin, toggleHoverExpanded } = useMenuExpanded();\n\n const isMenuOpen = ref(false);\n\n const isExpanded = computed(() => isPinned.value || isHoverExpanded.value);\n\n const setHoverExpanded = (value: boolean) => {\n toggleHoverExpanded(value);\n };\n\n const openMenu = () => {\n isMenuOpen.value = true;\n };\n\n const closeMenu = () => {\n isMenuOpen.value = false;\n };\n\n const instance: UseSidebarStateReturn = {\n isPinned,\n isHoverExpanded,\n isMenuOpen,\n isExpanded,\n togglePin,\n setHoverExpanded,\n openMenu,\n closeMenu,\n };\n\n provide(SIDEBAR_STATE_KEY, instance);\n return instance;\n}\n\n/**\n * Access sidebar state from any descendant of VcApp.\n * Throws if called outside the VcApp component tree.\n */\nexport function useSidebarState(): UseSidebarStateReturn {\n const injected = inject(SIDEBAR_STATE_KEY);\n if (!injected) {\n throw new Error(\"useSidebarState() requires provideSidebarState() in a parent component\");\n }\n return injected;\n}\n","import { createSharedComposable } from \"@vueuse/core\";\n\n// Mirrors the platform environment banner (environment-banner.js): the current\n// environment is derived client-side from the hostname, so it works before login\n// and yields rich names (QA / UAT / Demo) without any API call.\n\nconst PRESET_TO_LABEL: Record<string, string> = {\n prod: \"Production\",\n dev: \"Development\",\n test: \"QA\",\n staging: \"UAT\",\n demo: \"Demo\",\n};\n\n// vc-shell theme tokens matching the platform vc-env-badge hues.\nconst PRESET_TO_COLOR: Record<string, string> = {\n prod: \"danger\",\n dev: \"success\",\n test: \"warning\",\n staging: \"secondary\",\n demo: \"info\",\n};\n\nconst PRESETS_TO_IGNORE = [\"prod\"];\nconst FALLBACK_COLOR = \"neutral\";\n\nexport interface UseEnvironmentNameReturn {\n environmentName: string;\n isIgnored: boolean;\n color: string;\n}\n\n/**\n * Detect the environment preset from a hostname/env string, mirroring the\n * platform banner's detectThemePreset (environment-banner.js). Order matters:\n * prod is checked first so a \"prod-qa\" host resolves to prod.\n */\nexport function detectThemePreset(input: string): string {\n const s = (input || \"\").toLowerCase();\n if (s.includes(\"prod\")) return \"prod\";\n if (s.includes(\"localhost\") || /\\b\\d{1,3}(\\.\\d{1,3}){3}\\b/.test(s) || s.includes(\"dev\")) return \"dev\";\n if (s.includes(\"qa\") || s.includes(\"test\")) return \"test\";\n if (s.includes(\"stage\") || s.includes(\"staging\") || s.includes(\"uat\")) return \"staging\";\n if (s.includes(\"demo\")) return \"demo\";\n return \"default\";\n}\n\n/**\n * Resolve the banner state from a host string. Pure: no window/env access, so\n * it is unit-testable in isolation. `fallbackHost` is shown as the label when\n * the host carries no recognizable environment marker (preset \"default\").\n */\nexport function resolveEnvironment(hostString: string, fallbackHost = \"\"): UseEnvironmentNameReturn {\n const preset = detectThemePreset(hostString);\n const environmentName = PRESET_TO_LABEL[preset] ?? fallbackHost;\n const isIgnored = PRESETS_TO_IGNORE.includes(preset) || !environmentName;\n const color = PRESET_TO_COLOR[preset] ?? FALLBACK_COLOR;\n return { environmentName, isIgnored, color };\n}\n\n/**\n * Combine the browser hostname with the platform API hostname (APP_PLATFORM_URL).\n * Covers the case where the admin app is served from a neutral domain but the\n * backend it talks to carries the environment marker.\n */\nfunction resolveHostString(): string {\n const locationHost = typeof window !== \"undefined\" ? window.location.hostname : \"\";\n let platformHost = \"\";\n try {\n const url = import.meta.env.APP_PLATFORM_URL;\n if (url) {\n platformHost = new URL(url).hostname;\n }\n } catch {\n // ignore a malformed APP_PLATFORM_URL\n }\n return `${locationHost} ${platformHost}`.trim();\n}\n\n/**\n * Internal factory. Exported for unit tests so they bypass the shared\n * composable cache (mirrors `_createInternalUserLogic` in useUser).\n * @internal — not public API; use `useEnvironmentName`.\n */\nexport function _createEnvironmentNameLogic(): UseEnvironmentNameReturn {\n const fallbackHost = typeof window !== \"undefined\" ? window.location.hostname : \"\";\n return resolveEnvironment(resolveHostString(), fallbackHost);\n}\n\nexport const useEnvironmentName = createSharedComposable(_createEnvironmentNameLogic);\n","<template>\n <div\n ref=\"bladeRef\"\n v-bind=\"rootAttrs\"\n class=\"vc-blade\"\n role=\"region\"\n :class=\"[\n $attrs.class,\n {\n 'vc-blade--mobile': isMobile,\n 'vc-blade--expanded': isExpanded,\n 'vc-blade--maximized': renderingState?.maximized,\n },\n ]\"\n :style=\"{ width: typeof width === 'number' ? `${width}px` : width }\"\n :aria-labelledby=\"props.title && !showSkeleton ? bladeTitleId : undefined\"\n :aria-label=\"!props.title || showSkeleton ? $t('COMPONENTS.ORGANISMS.VC_BLADE.PANEL') : undefined\"\n >\n <!-- Header zone -->\n <BladeHeader\n v-if=\"!(isMobile && blades.length === 1 && !$slots['actions'])\"\n class=\"vc-blade__header\"\n :closable=\"isClosable\"\n :icon=\"icon\"\n :title=\"title\"\n :subtitle=\"subtitle\"\n :modified=\"effectiveModified\"\n :title-id=\"bladeTitleId\"\n :loading=\"showSkeleton\"\n @close=\"handleClose\"\n @expand=\"handleExpand\"\n @collapse=\"handleCollapse\"\n >\n <template #prepend>\n <component\n :is=\"backButton\"\n v-if=\"backButton && isMobile\"\n class=\"vc-blade__back-button\"\n />\n\n <div\n v-if=\"!showSkeleton && renderingState?.breadcrumbs?.length && isDesktop\"\n class=\"vc-blade__breadcrumbs\"\n >\n <VcBreadcrumbs\n :items=\"renderingState?.breadcrumbs\"\n collapsed\n >\n <template #trigger=\"{ click, isActive }\">\n <VcButton\n text\n icon=\"lucide-ellipsis-vertical\"\n icon-size=\"xl\"\n class=\"vc-blade__breadcrumbs-button\"\n :class=\"{\n 'vc-blade__breadcrumbs-button--active': isActive,\n }\"\n @click=\"click\"\n />\n </template>\n </VcBreadcrumbs>\n </div>\n </template>\n\n <template\n v-if=\"$slots['actions']\"\n #actions\n >\n <slot name=\"actions\"></slot>\n </template>\n </BladeHeader>\n\n <BladeStatusBanners\n v-if=\"!showSkeleton\"\n :modified=\"effectiveModified\"\n />\n\n <!-- Toolbar zone -->\n <BladeToolbar\n data-test-id=\"blade-toolbar\"\n class=\"vc-blade__toolbar\"\n :items=\"toolbarItems\"\n :loading=\"showSkeleton\"\n >\n <template #widgets-container>\n <WidgetContainer :blade-id=\"bladeId\" />\n </template>\n </BladeToolbar>\n\n <!-- Content zone -->\n <div\n ref=\"contentRef\"\n class=\"vc-blade__content\"\n tabindex=\"0\"\n >\n <div\n class=\"vc-blade__main\"\n :class=\"{ 'vc-blade__main--mobile': isMobile }\"\n >\n <div\n class=\"vc-blade__slot\"\n :class=\"{\n 'vc-blade__slot--desktop': isDesktop,\n 'vc-blade__slot--mobile': isMobile,\n }\"\n >\n <slot></slot>\n </div>\n </div>\n </div>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport { ref, inject, provide, computed, getCurrentInstance, useAttrs, watchEffect } from \"vue\";\nimport { IBladeToolbar } from \"@core/types\";\nimport { useBladeStack } from \"@core/blade-navigation\";\nimport BladeHeader from \"@ui/components/organisms/vc-blade/_internal/BladeHeader.vue\";\nimport BladeToolbar from \"@ui/components/organisms/vc-blade/_internal/BladeToolbar.vue\";\nimport BladeStatusBanners from \"@ui/components/organisms/vc-blade/_internal/BladeStatusBanners.vue\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { VcBreadcrumbs } from \"@ui/components/molecules/vc-breadcrumbs\";\nimport { BladeBackButtonKey, BladeFormKey, BladeLoadingKey } from \"@framework/injection-keys\";\nimport WidgetContainer from \"@ui/components/organisms/vc-blade/_internal/widgets/WidgetContainer.vue\";\nimport { useBlade } from \"../../../../core/composables\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { BladeDescriptorKey, BladeMaximizedKey, BladeRenderingStateKey } from \"@core/blade-navigation/types\";\n\nexport interface Props {\n icon?: string;\n title?: string;\n subtitle?: string;\n width?: number | string;\n /**\n * @deprecated Managed by the navigation stack — ignored inside blade navigation, where the\n * active (rightmost) blade is expanded automatically. Read the live value from `useBlade().expanded`.\n * Retained only as a standalone/Storybook fallback (when no blade context is present).\n */\n expanded?: boolean;\n /**\n * @deprecated Managed by the navigation stack — ignored inside blade navigation, where closability\n * is derived from stack position (a workspace root is not closable). Read the live value from\n * `useBlade().closable`. Retained only as a standalone/Storybook fallback (when no blade context is present).\n */\n closable?: boolean;\n toolbarItems?: IBladeToolbar[];\n modified?: boolean;\n /** When true, shows skeleton placeholders for all blade zones */\n loading?: boolean;\n}\n\nexport interface Emits {\n (event: \"close\"): void;\n (event: \"expand\"): void;\n (event: \"collapse\"): void;\n}\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(defineProps<Props>(), {\n width: \"30%\",\n closable: true,\n toolbarItems: () => [],\n modified: undefined,\n});\n\n// Auto-detect form state from useBladeForm (if present in this blade)\nconst bladeForm = inject(BladeFormKey, null);\n\nconst effectiveModified = computed(() => {\n // Explicit prop takes priority (backward compatibility)\n if (props.modified !== undefined) return props.modified;\n // Auto-inject from useBladeForm (undefined if no form → indicator hidden)\n if (!bladeForm) return undefined;\n return bladeForm.isModified.value;\n});\n\nconst instanceUid = getCurrentInstance()?.uid ?? 0;\nconst bladeTitleId = `blade-title-${instanceUid}`;\n\nconst showSkeleton = computed(() => Boolean(props.loading));\n\nprovide(BladeLoadingKey, showSkeleton);\n\nconst _slots = defineSlots<{\n actions(): void;\n default(): void;\n}>();\n\nconst emit = defineEmits<Emits>();\n\nconst { isMobile, isDesktop } = useResponsive();\n\n// Single useBlade() call — reuse for both bladeId and context-aware features\nconst bladeFull = useBlade();\nconst { id: bladeId } = bladeFull;\n\n// Context detection: are we inside blade navigation (VcBladeSlot)?\nconst hasBladeContext = !!inject(BladeDescriptorKey, undefined);\nconst maximizedRef = inject(BladeMaximizedKey, undefined);\n\n// Rendering state (maximized/breadcrumbs) — provided by VcBladeSlot separately\n// from the immutable descriptor. Undefined when rendered standalone (Storybook).\nconst renderingState = inject(BladeRenderingStateKey, undefined);\n\n// When inside blade navigation, read from BladeDescriptor (ignoring props).\n// When standalone (Storybook), fall back to props.\nconst isExpanded = computed(() => {\n if (hasBladeContext) return bladeFull.expanded.value;\n return props.expanded;\n});\n\nconst isClosable = computed(() => {\n if (hasBladeContext) return bladeFull.closable.value;\n return props.closable;\n});\n\nconst attrs = useAttrs();\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, onClose: _onClose, ...rest } = attrs;\n return rest;\n});\n\nfunction handleClose() {\n if (attrs.onClose) {\n // Legacy: blade page has @close listener on <VcBlade>\n emit(\"close\");\n } else if (hasBladeContext) {\n // New: VcBlade closes directly via blade stack\n bladeFull.closeSelf();\n } else {\n // Standalone (Storybook): emit for argTypes action handlers\n emit(\"close\");\n }\n}\n\nfunction handleExpand() {\n if (maximizedRef) {\n maximizedRef.value = true;\n } else {\n emit(\"expand\");\n }\n}\n\nfunction handleCollapse() {\n if (maximizedRef) {\n maximizedRef.value = false;\n } else {\n emit(\"collapse\");\n }\n}\n\n// One-time deprecation warning in dev mode\nif (import.meta.env.DEV && attrs.onClose && hasBladeContext) {\n console.warn(\n \"[VcBlade] @close listener is deprecated when used inside blade navigation. \" +\n \"VcBlade now handles close automatically. \" +\n \"Remove @close=\\\"$emit('close:blade')\\\" from your template.\",\n );\n}\n\nconst backButton = inject(BladeBackButtonKey);\n\nconst { blades, setBladeTitle } = useBladeStack();\n\n// Register title with BladeStack for navigation/breadcrumbs\nwatchEffect(() => {\n if (hasBladeContext && bladeId.value && props.title) {\n setBladeTitle(bladeId.value, props.title);\n }\n});\n\nconst bladeRef = ref<HTMLElement | null>(null);\nconst contentRef = ref<HTMLElement | null>(null);\n</script>\n\n<style lang=\"scss\">\n:root {\n --blade-background-color: var(--additional-50);\n --blade-color-error: var(--danger-500);\n --blade-color-unsaved-changes: var(--secondary-600);\n --blade-border-color: var(--neutrals-200);\n --blade-shadow-color: var(--primary-700);\n --blade-shadow: 2px 2px 8px rgb(from var(--blade-shadow-color) r g b / 14%);\n --blade-text-color: var(--additional-50);\n}\n\n.vc-blade {\n @apply tw-relative tw-flex tw-shrink-0 tw-flex-col tw-overflow-hidden;\n @apply tw-bg-[color:var(--blade-background-color)] tw-border tw-border-solid tw-border-[--blade-border-color];\n // Use shared transition timing for synchronized animations with AI panel\n transition: width var(--app-panel-transition-duration, 0.3s)\n var(--app-panel-transition-timing, cubic-bezier(0.4, 0, 0.2, 1));\n\n &__back-button {\n @apply tw-mr-[14px];\n flex: none;\n }\n\n &--mobile {\n @apply tw-w-full !important;\n }\n\n &--expanded {\n @apply tw-w-full tw-shrink !important;\n }\n\n &--maximized {\n @apply tw-absolute tw-z-[var(--z-local-above)] tw-top-0 tw-bottom-0 tw-left-0 tw-shrink !important;\n width: -webkit-fill-available !important;\n width: -moz-available !important;\n width: stretch !important;\n }\n\n &__header {\n @apply tw-shrink-0;\n\n &--hidden {\n @apply tw-hidden;\n }\n }\n\n &__toolbar {\n @apply tw-shrink-0;\n\n &--hidden {\n @apply tw-hidden;\n }\n }\n\n &__content {\n @apply tw-flex-1 tw-overflow-auto;\n }\n\n &__main {\n @apply tw-flex tw-flex-row tw-h-full;\n\n &--mobile {\n @apply tw-flex-col;\n }\n }\n\n &__slot {\n @apply tw-flex tw-flex-auto tw-flex-col tw-relative;\n\n &--desktop {\n @apply tw-w-0;\n }\n\n &--mobile {\n @apply tw-h-0;\n }\n }\n\n &__breadcrumbs {\n @apply tw-mr-[10px];\n\n &-button {\n @apply tw-text-[color:var(--blade-header-breadcrumbs-button-color)] tw-cursor-pointer hover:tw-text-[color:var(--blade-header-breadcrumbs-button-color-hover)] !important;\n\n &--active {\n @apply tw-text-[color:var(--blade-header-breadcrumbs-button-color-hover)] !important;\n }\n }\n }\n}\n\n.vc-app--mobile .vc-blade {\n @apply tw-m-0 tw-rounded-none;\n}\n\n// When mobile widgets are visible (fixed at bottom), offset content so it isn't hidden\n.vc-blade--mobile:has(.vc-widget-container-mobile) {\n .vc-blade__content {\n padding-bottom: var(--blade-toolbar-widgets-mobile-height);\n }\n}\n</style>\n","<template>\n <form\n class=\"vc-form\"\n novalidate\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n @submit.prevent=\"submit\"\n >\n <slot>vc-form</slot>\n </form>\n</template>\n\n<script lang=\"ts\" setup>\nexport interface Props {\n ariaLabel?: string;\n ariaLabelledby?: string;\n}\n\ndefineProps<Props>();\n\nconst emit = defineEmits<{\n (e: \"submit\"): void;\n}>();\n\nconst submit = () => {\n emit(\"submit\");\n};\n</script>\n\n<style lang=\"scss\">\n:root {\n --form-gap: 1rem;\n}\n\n.vc-form {\n @apply tw-flex tw-flex-col;\n}\n</style>\n","import { VNode } from \"vue\";\r\nimport _Form from \"@ui/components/molecules/vc-form/vc-form.vue\";\r\n\r\nexport const VcForm = _Form as typeof _Form & {\r\n new (): {\r\n $slots: {\r\n default: () => VNode[];\r\n };\r\n };\r\n};\r\n","<template>\n <!-- Skeleton mode -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-textarea vc-textarea--skeleton\"\n >\n <VcSkeleton\n v-if=\"label\"\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"11\"\n />\n <VcSkeleton\n variant=\"block\"\n width=\"100%\"\n :height=\"120\"\n />\n </div>\n\n <!-- Normal mode -->\n <div\n v-else\n class=\"vc-textarea\"\n :class=\"{\n 'vc-textarea--error': invalid,\n 'vc-textarea--disabled': resolvedDisabled,\n 'vc-textarea--focus': isFocused,\n }\"\n >\n <!-- Textarea label -->\n <VcLabel\n v-if=\"label\"\n :id=\"labelId\"\n :html-for=\"textareaId\"\n class=\"vc-textarea__label\"\n :required=\"required\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :error=\"invalid\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >\n <span>{{ tooltip }}</span>\n </template>\n </VcLabel>\n\n <!-- Textarea field -->\n <div class=\"vc-textarea__field-wrapper\">\n <textarea\n :id=\"textareaId\"\n ref=\"textareaRef\"\n class=\"vc-textarea__field\"\n :placeholder=\"placeholder\"\n :value=\"modelValue\"\n :disabled=\"resolvedDisabled\"\n :maxlength=\"maxlength\"\n :aria-invalid=\"invalid || undefined\"\n :aria-required=\"ariaRequired\"\n :aria-describedby=\"ariaDescribedBy\"\n :aria-labelledby=\"label ? labelId : undefined\"\n tabindex=\"0\"\n @input=\"onInput\"\n @focus=\"isFocused = true\"\n @blur=\"isFocused = false\"\n ></textarea>\n </div>\n\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"invalid && errorMessage\">\n <slot name=\"error\">\n <VcHint\n v-if=\"errorMessage\"\n :id=\"errorId\"\n class=\"vc-textarea__hint-error\"\n :error=\"true\"\n >\n {{ errorMessage }}\n </VcHint>\n </slot>\n </div>\n <div v-else>\n <slot name=\"hint\">\n <VcHint\n v-if=\"hint\"\n :id=\"hintId\"\n class=\"vc-textarea__desc\"\n >\n {{ hint }}\n </VcHint>\n </slot>\n </div>\n </Transition>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport { ref, type VNode } from \"vue\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useFormField } from \"@ui/composables/useFormField\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport type { IFormFieldProps } from \"@ui/types\";\n\nexport interface Props extends IFormFieldProps {\n placeholder?: string;\n modelValue?: string;\n /** Helper text displayed below the textarea */\n hint?: string;\n maxlength?: string;\n multilanguage?: boolean;\n currentLanguage?: string;\n}\n\nexport interface Emits {\n (event: \"update:modelValue\", value: string | undefined): void;\n}\n\ndefineSlots<{\n error: (props: Record<string, never>) => VNode[];\n hint: (props: Record<string, never>) => VNode[];\n}>();\n\nconst props = withDefaults(defineProps<Props>(), {\n name: \"Field\",\n maxlength: \"1024\",\n});\n\nconst bladeLoading = useBladeLoading();\n\nconst emit = defineEmits<Emits>();\n\nconst {\n fieldId: textareaId,\n labelId,\n errorId,\n hintId,\n invalid,\n resolvedDisabled,\n ariaRequired,\n ariaDescribedBy,\n} = useFormField(props);\n\nconst textareaRef = ref<HTMLTextAreaElement>();\nconst isFocused = ref(false);\n\nfunction onInput(e: Event) {\n const newValue = (e.target as HTMLInputElement).value;\n emit(\"update:modelValue\", newValue);\n}\n\ndefineExpose({\n focus: () => textareaRef.value?.focus(),\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --textarea-height: 120px;\n --textarea-border-color: var(--neutrals-300);\n --textarea-text-color: var(--neutrals-800);\n --textarea-border-radius: 6px;\n --textarea-background-color: transparent;\n --textarea-placeholder-color: var(--neutrals-400);\n\n // Error\n --textarea-text-color-error: var(--danger-500);\n --textarea-border-color-error: var(--danger-500);\n --textarea-error-ring-color: var(--danger-100);\n\n // Focus\n --textarea-border-color-focus: var(--primary-500);\n --textarea-focus-ring-color: var(--primary-100);\n\n // Disabled\n --textarea-disabled-text-color: var(--neutrals-500);\n}\n\n.vc-textarea {\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-1.5;\n }\n\n &__label {\n @apply tw-mb-2;\n }\n\n &__field-wrapper {\n @apply tw-border tw-border-solid\n tw-border-[color:var(--textarea-border-color)]\n tw-rounded-[var(--textarea-border-radius)] tw-box-border\n tw-bg-[color:var(--textarea-background-color)] tw-flex tw-items-stretch\n tw-shadow-sm tw-transition-[color,box-shadow] tw-duration-150 tw-ease-in-out\n tw-outline-none;\n\n textarea {\n @apply tw-text-[color:var(--textarea-text-color)];\n }\n }\n\n &--error &__field-wrapper {\n @apply tw-border tw-border-solid tw-border-[color:var(--textarea-border-color-error)]\n tw-ring-[3px] tw-ring-[color:var(--textarea-error-ring-color)];\n }\n\n &--error &__field-wrapper textarea {\n @apply tw-text-[color:var(--textarea-text-color-error)];\n }\n\n &__hint-error {\n @apply tw-mt-1 [--hint-error-color:var(--textarea-text-color-error)];\n }\n\n &__desc {\n @apply tw-text-[color:var(--textarea-placeholder-color)] tw-text-sm tw-mt-1;\n }\n\n &__field {\n @apply tw-w-full tw-resize-y tw-box-border tw-border-none tw-outline-none\n tw-min-h-32\n placeholder:tw-text-[color:var(--textarea-placeholder-color)]\n tw-px-3 tw-py-2 tw-bg-[color:var(--textarea-background-color)] tw-text-sm tw-rounded-[var(--textarea-border-radius)];\n\n &::-webkit-input-placeholder {\n @apply tw-text-[color:var(--textarea-placeholder-color)];\n }\n\n &::-moz-placeholder {\n @apply tw-text-[color:var(--textarea-placeholder-color)];\n }\n\n &::-ms-placeholder {\n @apply tw-text-[color:var(--textarea-placeholder-color)];\n }\n }\n\n &--disabled &__field-wrapper {\n @apply tw-opacity-50;\n }\n\n &--disabled &__field-wrapper,\n &--disabled &__field {\n @apply tw-cursor-not-allowed tw-pointer-events-none;\n }\n\n &--focus &__field-wrapper {\n @apply tw-border-[color:var(--textarea-border-color-focus)]\n tw-ring-[3px] tw-ring-[color:var(--textarea-focus-ring-color)]\n tw-outline-none;\n }\n\n /* Respond to aria-invalid on child textarea (future-proof for form systems) */\n &__field-wrapper:has(textarea[aria-invalid=\"true\"]) {\n @apply tw-border-[color:var(--textarea-border-color-error)]\n tw-ring-[3px] tw-ring-[color:var(--textarea-error-ring-color)];\n }\n}\n</style>\n","<template>\n <div\n v-if=\"bladeLoading\"\n class=\"vc-field\"\n :class=\"[`vc-field--${orientation}`]\"\n >\n <div\n v-if=\"label || orientation === 'horizontal'\"\n class=\"vc-field__label\"\n :class=\"{ 'vc-field__label--empty': !label }\"\n :style=\"orientation === 'horizontal' ? { flex: `${aspectRatio[0]} 1 0%` } : undefined\"\n >\n <VcSkeleton\n v-if=\"label\"\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"11\"\n />\n </div>\n <div\n class=\"vc-field__value\"\n :style=\"orientation === 'horizontal' ? { flex: `${aspectRatio[1]} 1 0%` } : undefined\"\n >\n <VcSkeleton\n variant=\"block\"\n :width=\"120\"\n :height=\"14\"\n />\n </div>\n </div>\n <div\n v-else\n class=\"vc-field\"\n :class=\"[`vc-field--${orientation}`]\"\n >\n <!-- Label -->\n <div\n v-if=\"label || orientation === 'horizontal'\"\n class=\"vc-field__label\"\n :class=\"{ 'vc-field__label--empty': !label }\"\n :style=\"orientation === 'horizontal' ? { flex: `${aspectRatio[0]} 1 0%` } : undefined\"\n >\n <VcLabel v-if=\"label\">\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >\n {{ tooltip }}\n </template>\n </VcLabel>\n </div>\n\n <!-- Value -->\n <div\n class=\"vc-field__value\"\n :style=\"orientation === 'horizontal' ? { flex: `${aspectRatio[1]} 1 0%` } : undefined\"\n >\n <div class=\"vc-field__content\">\n <VcLink\n v-if=\"type === 'link' && modelValue\"\n class=\"vc-field__link\"\n @click=\"onLinkClick\"\n >{{ displayValue || modelValue }}</VcLink\n >\n\n <a\n v-else-if=\"type === 'email' && modelValue\"\n :href=\"`mailto:${modelValue}`\"\n class=\"vc-field__link\"\n >{{ displayValue || modelValue }}</a\n >\n\n <span\n v-else\n class=\"vc-field__text\"\n >{{ formattedValue }}</span\n >\n </div>\n\n <VcButton\n v-if=\"copyable\"\n :icon=\"copyIcon\"\n size=\"icon-sm\"\n icon-size=\"s\"\n class=\"vc-field__copy\"\n text\n :aria-label=\"$t('COMPONENTS.CONTROLS.COPY_TO_CLIPBOARD')\"\n @click=\"onCopy\"\n />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, ref } from \"vue\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcLink } from \"@ui/components/atoms/vc-link\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { formatDateRelative } from \"@core/utilities/date\";\n\nconst bladeLoading = useBladeLoading();\n\nexport interface VcFieldProps {\n label?: string;\n tooltip?: string;\n type?: \"text\" | \"date\" | \"date-ago\" | \"link\" | \"email\";\n modelValue?: string | number | Date;\n /** Text to display instead of modelValue. modelValue is still used for copy/link actions. */\n displayValue?: string;\n copyable?: boolean;\n orientation?: \"horizontal\" | \"vertical\";\n aspectRatio?: [number, number];\n}\n\nconst props = withDefaults(defineProps<VcFieldProps>(), {\n type: \"text\",\n orientation: \"vertical\",\n aspectRatio: () => [1, 1],\n});\n\nconst formattedValue = computed(() => {\n const val = props.modelValue;\n if (val == null || val === \"\") {\n return props.type === \"date\" || props.type === \"date-ago\" ? \"N/A\" : \"\";\n }\n\n if (props.type === \"date\") {\n return val instanceof Date ? val.toLocaleDateString() : String(val);\n }\n if (props.type === \"date-ago\") {\n return formatDateRelative(val) || \"N/A\";\n }\n return String(val);\n});\n\nconst copyIcon = ref(\"lucide-copy\");\n\nfunction onCopy() {\n navigator.clipboard?.writeText(String(props.modelValue ?? \"\"));\n copyIcon.value = \"lucide-check\";\n setTimeout(() => {\n copyIcon.value = \"lucide-copy\";\n }, 1000);\n}\n\nfunction onLinkClick() {\n const url = String(props.modelValue ?? \"\");\n if (url) {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n }\n}\n</script>\n\n<style lang=\"scss\">\n.vc-field {\n @apply tw-min-w-0 tw-max-w-full tw-overflow-hidden;\n\n &--vertical {\n @apply tw-flex tw-flex-col;\n gap: 0.25rem;\n }\n\n &--horizontal {\n @apply tw-flex tw-flex-row tw-items-baseline;\n gap: 0.5rem;\n }\n\n &__label {\n @apply tw-min-w-0;\n }\n\n &__value {\n @apply tw-flex tw-items-center tw-gap-1;\n }\n\n &__content {\n @apply tw-overflow-hidden tw-flex-1;\n }\n\n &__text {\n @apply tw-text-sm tw-text-[color:var(--neutrals-600)];\n @apply tw-whitespace-normal tw-break-words;\n }\n\n &__link {\n @apply tw-text-sm tw-text-[color:var(--link-text-color)] tw-no-underline tw-cursor-pointer tw-transition tw-duration-200 tw-max-w-full tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap;\n @apply hover:tw-text-[color:var(--link-text-color-hover)] hover:tw-underline;\n @apply focus-visible:tw-outline-none focus-visible:tw-ring-[3px] focus-visible:tw-ring-[color:var(--link-focus-ring-color)] focus-visible:tw-rounded-sm;\n }\n\n &__label--empty {\n @apply tw-min-h-0;\n }\n\n &__copy {\n @apply tw-flex-shrink-0;\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-accordion-item\"\n :class=\"{\n 'vc-accordion-item--expanded': isExpandedInternal,\n 'vc-accordion-item--disabled': disabled,\n 'vc-accordion-item--has-overflow': hasOverflow,\n }\"\n >\n <button\n :id=\"triggerId\"\n type=\"button\"\n class=\"vc-accordion-item__header\"\n :aria-expanded=\"isExpandedInternal ? 'true' : 'false'\"\n :aria-controls=\"panelId\"\n :disabled=\"disabled || !hasOverflow\"\n @click=\"toggle\"\n >\n <span class=\"vc-accordion-item__title\">\n <slot name=\"title\">\n {{ title }}\n </slot>\n </span>\n <VcIcon\n v-if=\"hasOverflow\"\n class=\"vc-accordion-item__icon\"\n :class=\"{ 'vc-accordion-item__icon--rotated': isExpandedInternal }\"\n icon=\"lucide-chevron-down\"\n />\n </button>\n\n <div\n :id=\"panelId\"\n role=\"region\"\n :aria-labelledby=\"triggerId\"\n class=\"vc-accordion-item__content-wrapper\"\n :class=\"{\n 'vc-accordion-item__content-wrapper--faded': hasOverflow && !isExpandedInternal,\n 'vc-accordion-item__content-wrapper--scrollable': isExpandedInternal && hasScrollInExpandedState,\n }\"\n :style=\"contentWrapperStyle\"\n >\n <div\n ref=\"contentRef\"\n class=\"vc-accordion-item__content\"\n >\n <slot></slot>\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { watch, useId } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useCollapsible } from \"@ui/composables/useCollapsible\";\n\nexport interface Props {\n title?: string;\n collapsedHeight?: number;\n maxExpandedHeight?: number;\n isExpanded?: boolean;\n disabled?: boolean;\n}\n\nexport interface Emits {\n (event: \"toggle\", value: boolean): void;\n (event: \"update:isExpanded\", value: boolean): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n collapsedHeight: 0,\n isExpanded: false,\n disabled: false,\n});\n\nconst emit = defineEmits<Emits>();\n\ndefineOptions({\n name: \"VcAccordionItem\",\n});\n\ndefineSlots<{\n default: (props?: any) => any;\n title: (props?: any) => any;\n}>();\n\n// Accessibility IDs\nconst uid = useId();\nconst triggerId = `vc-accordion-trigger-${uid}`;\nconst panelId = `vc-accordion-panel-${uid}`;\n\nconst {\n contentRef,\n isExpanded: isExpandedInternal,\n hasOverflow,\n hasScroll: hasScrollInExpandedState,\n wrapperStyle: contentWrapperStyle,\n} = useCollapsible({\n collapsedHeight: props.collapsedHeight,\n maxExpandedHeight: props.maxExpandedHeight,\n expanded: props.isExpanded,\n});\n\nfunction toggle() {\n isExpandedInternal.value = !isExpandedInternal.value;\n emit(\"toggle\", isExpandedInternal.value);\n emit(\"update:isExpanded\", isExpandedInternal.value);\n}\n\nwatch(\n () => props.isExpanded,\n (newValue) => {\n isExpandedInternal.value = newValue;\n },\n);\n</script>\n\n<style lang=\"scss\">\n:root {\n // Border & shape\n --accordion-item-border-color: var(--neutrals-200);\n --accordion-item-border-radius: 6px;\n\n // Header\n --accordion-item-header-padding: 12px 16px;\n --accordion-item-header-background: var(--additional-50);\n --accordion-item-header-background-hover: var(--neutrals-50);\n --accordion-item-header-color: var(--secondary-950);\n --accordion-item-header-font-size: 14px;\n --accordion-item-header-font-weight: 500;\n --accordion-item-header-line-height: 20px;\n --accordion-item-header-text-transform: none;\n --accordion-item-header-gap: 0;\n\n // Icon\n --accordion-item-icon-margin-left: 12px;\n --accordion-item-icon-size: 20px;\n\n // Content\n --accordion-item-content-padding: 16px;\n --accordion-item-content-background: var(--additional-50);\n --accordion-item-content-color: var(--secondary-950);\n --accordion-item-content-font-size: 14px;\n --accordion-item-content-line-height: 20px;\n\n // Animation\n --accordion-item-transition-duration: 300ms;\n\n // Fade overlay\n --accordion-item-fade-height: 60px;\n\n // Focus\n --accordion-item-focus-ring-color: var(--primary-100);\n}\n\n.vc-accordion-item {\n position: relative;\n background: var(--accordion-item-header-background);\n border-radius: var(--accordion-item-border-radius);\n overflow: hidden;\n\n &__header {\n @apply tw-flex tw-items-center tw-justify-between tw-w-full;\n @apply tw-border-none tw-outline-none tw-select-none tw-text-left;\n padding: var(--accordion-item-header-padding);\n gap: var(--accordion-item-header-gap);\n background: var(--accordion-item-header-background);\n color: var(--accordion-item-header-color);\n font-size: var(--accordion-item-header-font-size);\n font-weight: var(--accordion-item-header-font-weight);\n line-height: var(--accordion-item-header-line-height);\n text-transform: var(--accordion-item-header-text-transform);\n transition: background-color var(--accordion-item-transition-duration) ease;\n border-radius: inherit;\n\n &:not(:disabled) {\n @apply tw-cursor-pointer;\n\n &:hover {\n background: var(--accordion-item-header-background-hover);\n }\n }\n\n &:disabled {\n @apply tw-cursor-not-allowed;\n }\n\n &:focus-visible {\n @apply tw-ring-[3px] tw-ring-[color:var(--accordion-item-focus-ring-color)] tw-outline-none;\n }\n }\n\n &__title {\n flex: 1;\n font-weight: inherit;\n font-size: inherit;\n line-height: inherit;\n }\n\n &__icon {\n margin-left: var(--accordion-item-icon-margin-left);\n transition: transform var(--accordion-item-transition-duration) ease;\n flex-shrink: 0;\n\n &--rotated {\n transform: rotate(180deg);\n }\n }\n\n &__content-wrapper {\n position: relative;\n overflow: hidden;\n transition: max-height var(--accordion-item-transition-duration) ease;\n\n &--faded::after {\n content: \"\";\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: var(--accordion-item-fade-height);\n background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, var(--accordion-item-content-background) 100%);\n pointer-events: none;\n }\n\n &--scrollable {\n overflow-y: auto;\n overflow-x: hidden;\n }\n }\n\n &__content {\n background: var(--accordion-item-content-background);\n color: var(--accordion-item-content-color);\n padding: var(--accordion-item-content-padding);\n font-size: var(--accordion-item-content-font-size);\n line-height: var(--accordion-item-content-line-height);\n }\n\n &--disabled {\n @apply tw-opacity-50;\n }\n}\n</style>\n","<template>\n <div\n v-if=\"bladeLoading\"\n class=\"vc-accordion vc-accordion--skeleton\"\n >\n <div\n v-for=\"i in 3\"\n :key=\"i\"\n class=\"vc-accordion__item\"\n >\n <VcSkeleton\n variant=\"block\"\n width=\"100%\"\n :height=\"44\"\n />\n </div>\n </div>\n <div\n v-else\n class=\"vc-accordion\"\n :class=\"`vc-accordion--${variant}`\"\n >\n <VcAccordionItem\n v-for=\"(item, index) in items\"\n :key=\"item.id || index\"\n :title=\"item.title\"\n :collapsed-height=\"item.collapsedHeight ?? collapsedHeight\"\n :max-expanded-height=\"item.maxExpandedHeight ?? maxExpandedHeight\"\n :is-expanded=\"isItemExpanded(item.id || index)\"\n :disabled=\"item.disabled\"\n class=\"vc-accordion__item\"\n @toggle=\"(expanded) => handleToggle(item.id || index, expanded)\"\n >\n <template\n v-if=\"item.titleSlot\"\n #title\n >\n <component :is=\"item.titleSlot\" />\n </template>\n <template v-if=\"typeof item.content === 'string'\">\n {{ item.content }}\n </template>\n <component\n :is=\"item.content\"\n v-else-if=\"item.content\"\n />\n </VcAccordionItem>\n\n <slot></slot>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, watch, computed } from \"vue\";\nimport type { VNode, Component } from \"vue\";\nimport VcAccordionItem from \"@ui/components/molecules/vc-accordion/_internal/vc-accordion-item/vc-accordion-item.vue\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\n\nconst bladeLoading = useBladeLoading();\n\nexport interface AccordionItem {\n id?: string | number;\n title: string;\n content?: string | Component;\n titleSlot?: Component;\n collapsedHeight?: number;\n maxExpandedHeight?: number;\n disabled?: boolean;\n}\n\nexport interface VcAccordionProps {\n items?: AccordionItem[];\n modelValue?: (string | number) | (string | number)[];\n multiple?: boolean;\n variant?: \"default\" | \"bordered\" | \"separated\" | \"ghost\";\n collapsedHeight?: number;\n maxExpandedHeight?: number;\n}\n\nexport interface VcAccordionEmits {\n (event: \"update:modelValue\", value: (string | number) | (string | number)[]): void;\n}\n\nconst props = withDefaults(defineProps<VcAccordionProps>(), {\n items: () => [],\n multiple: false,\n variant: \"default\",\n collapsedHeight: 0,\n});\n\nconst emit = defineEmits<VcAccordionEmits>();\n\ndefineOptions({\n name: \"VcAccordion\",\n});\n\ndefineSlots<{\n default: (props?: Record<string, never>) => VNode[];\n}>();\n\nconst expandedItems = ref<(string | number)[]>([]);\n\nconst isItemExpanded = computed(() => {\n return (id: string | number) => expandedItems.value.includes(id);\n});\n\nfunction handleToggle(id: string | number, expanded: boolean) {\n if (expanded) {\n if (props.multiple) {\n expandedItems.value.push(id);\n } else {\n expandedItems.value = [id];\n }\n } else {\n expandedItems.value = expandedItems.value.filter((itemId) => itemId !== id);\n }\n\n emitModelValue();\n}\n\nfunction emitModelValue() {\n if (props.multiple) {\n emit(\"update:modelValue\", expandedItems.value);\n } else {\n emit(\"update:modelValue\", expandedItems.value[0] ?? null);\n }\n}\n\nfunction initializeExpandedItems() {\n if (props.modelValue !== undefined && props.modelValue !== null) {\n if (Array.isArray(props.modelValue)) {\n expandedItems.value = [...props.modelValue];\n } else {\n expandedItems.value = [props.modelValue];\n }\n } else {\n expandedItems.value = [];\n }\n}\n\nwatch(\n () => props.modelValue,\n () => {\n initializeExpandedItems();\n },\n { immediate: true },\n);\n</script>\n\n<style lang=\"scss\">\n.vc-accordion {\n display: flex;\n flex-direction: column;\n\n &--default {\n gap: 0;\n\n .vc-accordion__item {\n border-bottom: 1px solid var(--accordion-item-border-color);\n\n &:first-child {\n border-top: 1px solid var(--accordion-item-border-color);\n }\n\n &:not(:first-child) {\n .vc-accordion-item {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n }\n\n &:not(:last-child) {\n .vc-accordion-item {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n }\n }\n }\n\n &--bordered {\n border: 1px solid var(--accordion-item-border-color);\n border-radius: var(--accordion-item-border-radius);\n overflow: hidden;\n\n .vc-accordion__item {\n &:not(:last-child) {\n border-bottom: 1px solid var(--accordion-item-border-color);\n }\n\n .vc-accordion-item {\n border-radius: 0;\n }\n }\n }\n\n &--separated {\n gap: 12px;\n\n .vc-accordion__item {\n border: 1px solid var(--accordion-item-border-color);\n }\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-1;\n }\n\n &--ghost {\n gap: 0;\n\n .vc-accordion-item {\n --accordion-item-border-radius: 0;\n --accordion-item-header-background: transparent;\n --accordion-item-header-background-hover: transparent;\n --accordion-item-icon-margin-left: 0;\n --accordion-item-content-padding: 0;\n --accordion-item-content-background: transparent;\n --accordion-item-transition-duration: 200ms;\n }\n }\n}\n</style>\n","import _Accordion from \"@ui/components/molecules/vc-accordion/vc-accordion.vue\";\nimport _AccordionItem from \"@ui/components/molecules/vc-accordion/_internal/vc-accordion-item/vc-accordion-item.vue\";\n\nexport const VcAccordion = _Accordion as typeof _Accordion;\nexport const VcAccordionItem = _AccordionItem as typeof _AccordionItem;\n\nexport type {\n AccordionItem,\n VcAccordionProps,\n VcAccordionEmits,\n} from \"@ui/components/molecules/vc-accordion/vc-accordion.vue\";\n\n/** @deprecated Use VcAccordionProps instead */\nexport type { VcAccordionProps as AccordionProps } from \"@ui/components/molecules/vc-accordion/vc-accordion.vue\";\n/** @deprecated Use VcAccordionEmits instead */\nexport type { VcAccordionEmits as AccordionEmits } from \"@ui/components/molecules/vc-accordion/vc-accordion.vue\";\n\nexport type {\n Props as AccordionItemProps,\n Emits as AccordionItemEmits,\n} from \"@ui/components/molecules/vc-accordion/_internal/vc-accordion-item/vc-accordion-item.vue\";\n","<template>\n <div\n v-if=\"bladeLoading\"\n class=\"vc-file-upload__container vc-file-upload--skeleton\"\n >\n <VcSkeleton\n variant=\"block\"\n width=\"100%\"\n :height=\"120\"\n />\n </div>\n <div\n v-else\n class=\"vc-file-upload__container\"\n :class=\"{ 'vc-file-upload__container--error': !!resolvedErrorMessage }\"\n >\n <div\n class=\"vc-file-upload__drop-zone\"\n :class=\"{\n 'vc-file-upload__drop-zone--dragging': isDragging,\n 'vc-file-upload__drop-zone--disabled': resolvedDisabled,\n 'vc-file-upload__drop-zone--loading': loading,\n 'vc-file-upload__drop-zone--mobile': isMobile,\n }\"\n role=\"button\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n :aria-label=\"customText?.dragHere || 'Upload files'\"\n :aria-describedby=\"ariaDescribedBy\"\n :aria-disabled=\"resolvedDisabled || undefined\"\n :aria-required=\"ariaRequired\"\n @drop.stop.prevent=\"onDrop\"\n @drag.stop.prevent\n @dragstart.stop.prevent\n @dragend.stop.prevent\n @dragover.stop.prevent=\"dragOver\"\n @dragenter.stop.prevent\n @dragleave.stop.prevent=\"dragLeave\"\n @click=\"toggleUploader\"\n @keydown.enter=\"toggleUploader\"\n @keydown.space.prevent=\"toggleUploader\"\n >\n <!-- Loading spinner -->\n <div\n v-if=\"loading\"\n class=\"vc-file-upload__loading\"\n >\n <VcIcon\n icon=\"lucide-loader-2\"\n size=\"xl\"\n class=\"vc-file-upload__spinner\"\n />\n <span class=\"vc-file-upload__loading-text\">{{ t(\"COMPONENTS.MOLECULES.VC_FILE_UPLOAD.UPLOADING\") }}</span>\n </div>\n\n <template v-else>\n <VcIcon\n class=\"vc-file-upload__icon\"\n :icon=\"icon\"\n size=\"xl\"\n />\n\n <div class=\"vc-file-upload__text\">\n <template v-if=\"isMobile\">\n <span class=\"vc-file-upload__link\">\n {{ customText?.browse || t(\"COMPONENTS.MOLECULES.VC_FILE_UPLOAD.TAP_TO_UPLOAD\") }}\n </span>\n </template>\n <template v-else>\n <span>{{ customText?.dragHere || t(\"COMPONENTS.MOLECULES.VC_FILE_UPLOAD.DRAG_HERE\") }}</span>\n <br />\n <span class=\"vc-file-upload__link\">\n {{ customText?.browse || t(\"COMPONENTS.MOLECULES.VC_FILE_UPLOAD.BROWSE\") }}\n </span>\n </template>\n </div>\n </template>\n\n <input\n ref=\"uploader\"\n type=\"file\"\n hidden\n :accept=\"accept\"\n :multiple=\"multiple\"\n :name=\"resolvedName\"\n :disabled=\"resolvedDisabled\"\n @change=\"upload\"\n />\n </div>\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"resolvedErrorMessage\">\n <slot name=\"error\">\n <VcHint\n :id=\"errorId\"\n class=\"vc-file-upload__error\"\n :error=\"true\"\n >\n {{ resolvedErrorMessage }}\n </VcHint>\n </slot>\n </div>\n </Transition>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport { ref, unref, computed, type VNode } from \"vue\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\n\nconst bladeLoading = useBladeLoading();\nimport { useField } from \"vee-validate\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { useI18n } from \"vue-i18n\";\nimport { IValidationRules } from \"@core/types\";\nimport { useFormField } from \"@ui/composables/useFormField\";\nimport type { IFormFieldProps } from \"@ui/types/form-field\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\n\nexport interface Props extends IFormFieldProps {\n loading?: boolean;\n accept?: string;\n multiple?: boolean;\n rules?: keyof IValidationRules | IValidationRules;\n icon?: string;\n customText?: {\n dragHere: string;\n browse: string;\n };\n}\n\nexport interface Emits {\n (event: \"upload\", files: FileList): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n accept: \".jpg, .png, .jpeg, .webp, .heic, .svg\",\n name: \"Gallery\",\n icon: \"lucide-cloud-upload\",\n});\nconst emit = defineEmits<Emits>();\n\ndefineSlots<{\n error: (props: Record<string, never>) => VNode[];\n}>();\n\nconst { t } = useI18n({ useScope: \"global\" });\n\nconst { fieldId, errorId, resolvedDisabled, resolvedName, ariaRequired, groupContext } = useFormField(props);\n\nconst internalRules = unref(props.rules) || \"\";\nconst isDragging = ref(false);\nconst { isMobile } = useResponsive();\n\nconst {\n errorMessage: veeErrorMessage,\n handleChange,\n validate,\n} = useField(`${props.name === \"Gallery\" ? fieldId.value : props.name}`, internalRules as IValidationRules);\n\nconst resolvedErrorMessage = computed(() => props.errorMessage || veeErrorMessage.value);\n\nconst ariaDescribedBy = computed(() => {\n const ids = new Set<string>();\n\n if (groupContext?.describedBy.value) {\n groupContext.describedBy.value.split(/\\s+/).forEach((id) => ids.add(id));\n }\n\n if (resolvedErrorMessage.value) {\n ids.add(errorId.value);\n }\n\n return ids.size ? Array.from(ids).join(\" \") : undefined;\n});\n\nconst uploader = ref<HTMLInputElement | null>(null);\n\nconst upload = async (event: Event) => {\n if (resolvedDisabled.value) return;\n\n await handleChange(event.target);\n\n const isValid = await validate();\n\n if (isValid.valid) {\n const target = event.target as HTMLInputElement;\n const fileList = target.files;\n\n if (fileList && fileList.length) {\n emit(\"upload\", fileList);\n }\n }\n};\n\nfunction toggleUploader() {\n if (resolvedDisabled.value) return;\n if (uploader.value) {\n uploader.value.value = \"\";\n uploader.value.click();\n }\n}\n\nfunction onDrop(event: DragEvent) {\n if (resolvedDisabled.value) return;\n dragLeave();\n const fileList = event.dataTransfer?.files;\n\n if (fileList && fileList.length) {\n emit(\"upload\", fileList);\n }\n}\n\nfunction dragOver() {\n if (resolvedDisabled.value) return;\n isDragging.value = true;\n}\n\nfunction dragLeave() {\n isDragging.value = false;\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --file-upload-border-color: var(--secondary-300);\n --file-upload-border-color-hover: var(--secondary-400);\n --file-upload-border-color-dragover: var(--primary-400);\n --file-upload-border-color-error: var(--danger-500);\n --file-upload-border-width: 1.5px;\n --file-upload-border-radius: 6px;\n --file-upload-drag-bg: var(--primary-50);\n --file-upload-icon-color: var(--secondary-400);\n --file-upload-text-color: var(--secondary-500);\n --file-upload-error-color: var(--danger-500);\n --file-upload-error-ring-color: var(--danger-100);\n --file-upload-focus-ring-color: var(--primary-100);\n}\n\n.vc-file-upload {\n &__container {\n display: flex;\n flex-direction: column;\n flex: 1;\n }\n\n &__container--error &__drop-zone {\n border-color: var(--file-upload-border-color-error);\n box-shadow: 0 0 0 3px var(--file-upload-error-ring-color);\n }\n\n &__drop-zone {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n box-sizing: border-box;\n padding: 24px;\n gap: 8px;\n min-height: 120px;\n border-width: var(--file-upload-border-width);\n border-style: dashed;\n border-color: var(--file-upload-border-color);\n border-radius: var(--file-upload-border-radius);\n background: transparent;\n outline: none;\n cursor: pointer;\n transition:\n border-color 0.2s,\n background 0.2s,\n box-shadow 0.2s;\n\n &--dragging {\n cursor: copy;\n border-style: solid;\n border-color: var(--file-upload-border-color-dragover);\n background: var(--file-upload-drag-bg);\n }\n\n &--disabled {\n opacity: 0.5;\n pointer-events: none;\n cursor: default;\n }\n\n &--loading {\n pointer-events: none;\n }\n\n &--mobile {\n border-color: transparent;\n }\n\n &:hover {\n border-color: var(--file-upload-border-color-hover);\n }\n\n &:focus-within {\n border-color: var(--file-upload-border-color-dragover);\n box-shadow: 0 0 0 3px var(--file-upload-focus-ring-color);\n outline: none;\n }\n }\n\n &__icon {\n color: var(--file-upload-icon-color);\n }\n\n &__text {\n color: var(--file-upload-text-color);\n text-align: center;\n font-size: 12px;\n line-height: 1.625;\n }\n\n &__link {\n font-size: 12px;\n }\n\n &__loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n }\n\n &__spinner {\n color: var(--primary-500);\n animation: file-upload-spin 1s linear infinite;\n }\n\n &__loading-text {\n font-size: 12px;\n font-weight: 500;\n color: var(--file-upload-text-color);\n }\n\n &--skeleton {\n .vc-skeleton__shape {\n border: 2px dashed var(--vc-skeleton-bg);\n background: transparent;\n }\n }\n\n &__error {\n margin-top: 4px;\n --hint-error-color: var(--file-upload-error-color);\n }\n}\n\n@keyframes file-upload-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n","<template>\r\n <button\r\n type=\"button\"\r\n class=\"vc-editor-button\"\r\n :class=\"{ 'vc-editor-button--active': active }\"\r\n :disabled=\"disabled\"\r\n :aria-pressed=\"active != null ? active : undefined\"\r\n :aria-label=\"ariaLabel\"\r\n @click=\"$emit('action')\"\r\n >\r\n <VcIcon\r\n :icon=\"icon\"\r\n size=\"s\"\r\n :use-container=\"false\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { VcIcon } from \"@ui/components/atoms\";\r\n\r\ninterface Props {\r\n icon: string;\r\n active?: boolean;\r\n disabled?: boolean;\r\n ariaLabel?: string;\r\n}\r\n\r\nwithDefaults(defineProps<Props>(), {\r\n disabled: false,\r\n});\r\n\r\ndefineEmits<{\r\n action: [];\r\n}>();\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n // Button color variables\r\n --vc-button-text: var(--neutrals-600);\r\n --vc-button-text-hover: var(--neutrals-800);\r\n --vc-button-text-active: var(--primary-600);\r\n --vc-button-text-disabled: var(--neutrals-400);\r\n --vc-button-bg: transparent;\r\n --vc-button-bg-hover: var(--neutrals-100);\r\n --vc-button-bg-active: var(--primary-100);\r\n --vc-button-bg-disabled: transparent;\r\n --vc-button-border-radius: 6px;\r\n --vc-editor-focus-ring-color: color-mix(in srgb, var(--primary-500) 30%, transparent);\r\n}\r\n\r\n.vc-editor-button {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 2rem;\r\n height: 2rem;\r\n border: none;\r\n border-radius: var(--vc-button-border-radius);\r\n background-color: var(--vc-button-bg);\r\n color: var(--vc-button-text);\r\n cursor: pointer;\r\n transition:\r\n background-color 0.2s ease,\r\n color 0.2s ease,\r\n transform 0.1s ease;\r\n\r\n &:hover:not(:disabled) {\r\n background-color: var(--vc-button-bg-hover);\r\n color: var(--vc-button-text-hover);\r\n transform: translateY(-1px);\r\n }\r\n\r\n &:active:not(:disabled) {\r\n transform: translateY(0);\r\n }\r\n\r\n &--active {\r\n background-color: var(--vc-button-bg-active);\r\n color: var(--vc-button-text-active);\r\n font-weight: 600;\r\n\r\n &:hover {\r\n background-color: var(--primary-200);\r\n color: var(--primary-700);\r\n }\r\n }\r\n\r\n &:disabled {\r\n color: var(--vc-button-text-disabled);\r\n background-color: var(--vc-button-bg-disabled);\r\n cursor: not-allowed;\r\n opacity: 0.5;\r\n transform: none;\r\n }\r\n\r\n &:focus-visible {\r\n @apply tw-ring-[3px] tw-ring-[color:var(--vc-editor-focus-ring-color)] tw-outline-none;\r\n }\r\n}\r\n</style>\r\n","import type { Editor } from \"@tiptap/vue-3\";\n\nexport interface CustomToolbarButton {\n /** Unique identifier for the button */\n id: string;\n /** Button label or title */\n label: string;\n /** Icon name (lucide icon) */\n icon: string;\n /** Action to execute when button is clicked */\n action: (editor: Editor) => void;\n /** Check if button should be active */\n isActive?: (editor: Editor) => boolean;\n /** Check if button should be disabled */\n isDisabled?: (editor: Editor) => boolean;\n /** Custom component to render instead of default button */\n component?: any;\n /** Props to pass to custom component */\n componentProps?: Record<string, any>;\n /** Button group for organizing buttons */\n group?: string;\n /** Sort order within group */\n order?: number;\n}\n\nexport interface CustomToolbarDropdown {\n /** Unique identifier for the dropdown */\n id: string;\n /** Dropdown label */\n label: string;\n /** Dropdown options */\n options: Array<{\n value: string;\n label: string;\n action: (editor: Editor, value: string) => void;\n }>;\n /** Get current value */\n getValue?: (editor: Editor) => string;\n /** Check if dropdown should be disabled */\n isDisabled?: (editor: Editor) => boolean;\n /** Custom styles for dropdown */\n style?: Record<string, any>;\n /** Button group for organizing dropdowns */\n group?: string;\n /** Sort order within group */\n order?: number;\n}\n\nexport type CustomToolbarItem = CustomToolbarButton | CustomToolbarDropdown;\n\nexport function isDropdown(item: CustomToolbarItem): item is CustomToolbarDropdown {\n return \"options\" in item;\n}\n\nexport function isButton(item: CustomToolbarItem): item is CustomToolbarButton {\n return !(\"options\" in item);\n}\n","<template>\n <component\n :is=\"customButton.component\"\n v-if=\"isButton(customButton) && customButton.component\"\n :editor=\"editor\"\n :disabled=\"disabled || isDisabled\"\n v-bind=\"customButton.componentProps || {}\"\n />\n <VcEditorButton\n v-else-if=\"isButton(customButton)\"\n :icon=\"customButton.icon\"\n :aria-label=\"customButton.label\"\n :active=\"isActive\"\n :disabled=\"disabled || isDisabled\"\n @action=\"handleAction\"\n />\n <div\n v-else-if=\"isDropdown(customButton)\"\n class=\"vc-editor-dropdown\"\n >\n <select\n :disabled=\"disabled || isDisabled\"\n :aria-label=\"customButton.label\"\n @change=\"handleDropdownChange\"\n >\n <option\n v-for=\"option in customButton.options\"\n :key=\"option.value\"\n :value=\"option.value\"\n >\n {{ option.label }}\n </option>\n </select>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Editor } from \"@tiptap/vue-3\";\nimport { computed } from \"vue\";\nimport VcEditorButton from \"@ui/components/molecules/vc-editor/_internal/vc-editor-button.vue\";\nimport type { CustomToolbarItem } from \"@ui/components/molecules/vc-editor/_internal/toolbar-types\";\nimport { isButton, isDropdown } from \"@ui/components/molecules/vc-editor/_internal/toolbar-types\";\n\ninterface Props {\n editor: Editor;\n customButton: CustomToolbarItem;\n disabled: boolean;\n}\n\nconst props = defineProps<Props>();\n\nconst isActive = computed(() => {\n if (isButton(props.customButton) && props.customButton.isActive) {\n return props.customButton.isActive(props.editor);\n }\n return false;\n});\n\nconst isDisabled = computed(() => {\n if (props.customButton.isDisabled) {\n return props.customButton.isDisabled(props.editor);\n }\n return false;\n});\n\nfunction handleAction() {\n if (isButton(props.customButton)) {\n props.customButton.action(props.editor);\n }\n}\n\nfunction handleDropdownChange(event: Event) {\n const target = event.target as HTMLSelectElement;\n if (isDropdown(props.customButton)) {\n const option = props.customButton.options.find((opt) => opt.value === target.value);\n if (option) {\n option.action(props.editor, target.value);\n }\n }\n}\n</script>\n","<template>\n <div class=\"vc-editor-font-selector\">\n <!-- Font Size Dropdown -->\n <div class=\"vc-editor-font-selector__dropdown\">\n <button\n type=\"button\"\n class=\"vc-editor-font-selector__button\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.FONT_SIZE')\"\n :disabled=\"disabled\"\n @click=\"toggleSizeDropdown\"\n >\n <VcIcon\n icon=\"lucide-a-large-small\"\n size=\"s\"\n :use-container=\"false\"\n />\n <span\n v-if=\"currentFontSize\"\n class=\"vc-editor-font-selector__size-value\"\n >{{ currentFontSize }}px</span\n >\n <VcIcon\n icon=\"lucide-chevron-down\"\n size=\"xs\"\n :use-container=\"false\"\n />\n </button>\n <div\n v-if=\"showSizeDropdown\"\n class=\"vc-editor-font-selector__menu\"\n @click.stop\n >\n <div\n v-for=\"size in fontSizes\"\n :key=\"size\"\n class=\"vc-editor-font-selector__option\"\n :class=\"{ 'vc-editor-font-selector__option--active': currentFontSize === size }\"\n @click=\"selectFontSize(size)\"\n >\n {{ size }}px\n </div>\n <div class=\"vc-editor-font-selector__custom\">\n <input\n v-model=\"customSize\"\n type=\"number\"\n min=\"8\"\n max=\"72\"\n placeholder=\"Custom\"\n class=\"vc-editor-font-selector__input\"\n @keydown.enter=\"selectCustomFontSize\"\n @blur=\"selectCustomFontSize\"\n />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Editor } from \"@tiptap/vue-3\";\nimport { ref, computed, onMounted, onUnmounted } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms\";\n\ninterface Props {\n editor: Editor;\n disabled: boolean;\n}\n\nconst props = defineProps<Props>();\n\nconst showSizeDropdown = ref(false);\nconst customSize = ref<number | null>(null);\n\nconst fontSizes = [8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72];\n\nconst currentFontSize = computed(() => {\n const attrs = props.editor.getAttributes(\"textStyle\");\n return attrs.fontSize ? parseInt(attrs.fontSize.replace(\"px\", \"\")) : null;\n});\n\nfunction toggleSizeDropdown() {\n showSizeDropdown.value = !showSizeDropdown.value;\n}\n\nfunction selectFontSize(size: number) {\n props.editor.chain().focus().setFontSize(`${size}px`).run();\n showSizeDropdown.value = false;\n}\n\nfunction selectCustomFontSize() {\n if (customSize.value && customSize.value >= 8 && customSize.value <= 72) {\n props.editor.chain().focus().setFontSize(`${customSize.value}px`).run();\n customSize.value = null;\n showSizeDropdown.value = false;\n }\n}\n\nfunction closeDropdown() {\n showSizeDropdown.value = false;\n}\n\nfunction handleClickOutside(event: MouseEvent) {\n const target = event.target as HTMLElement;\n if (!target.closest(\".vc-editor-font-selector\")) {\n closeDropdown();\n }\n}\n\nonMounted(() => {\n document.addEventListener(\"click\", handleClickOutside);\n});\n\nonUnmounted(() => {\n document.removeEventListener(\"click\", handleClickOutside);\n});\n</script>\n\n<style lang=\"scss\">\n.vc-editor-font-selector {\n display: flex;\n gap: 0.25rem;\n\n &__dropdown {\n position: relative;\n }\n\n &__button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.25rem;\n height: 2rem;\n padding: 0 0.5rem;\n border: none;\n border-radius: 6px;\n background-color: transparent;\n color: var(--neutrals-600);\n cursor: pointer;\n transition:\n background-color 0.2s ease,\n color 0.2s ease,\n transform 0.1s ease;\n\n &:hover:not(:disabled) {\n background-color: var(--neutrals-100);\n color: var(--neutrals-800);\n transform: translateY(-1px);\n }\n\n &:active:not(:disabled) {\n transform: translateY(0);\n }\n\n &:disabled {\n color: var(--neutrals-400);\n cursor: not-allowed;\n opacity: 0.5;\n transform: none;\n }\n\n &:focus-visible {\n outline: 2px solid var(--primary-500);\n outline-offset: 2px;\n }\n }\n\n &__size-value {\n font-size: 0.75rem;\n font-weight: 500;\n min-width: 2rem;\n text-align: center;\n }\n\n &__menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: var(--z-overlay-dropdown);\n min-width: 160px;\n max-height: 240px;\n overflow-y: auto;\n background: white;\n border: 1px solid var(--neutrals-300);\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n margin-top: 0.25rem;\n }\n\n &__option {\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n border-bottom: 1px solid var(--neutrals-100);\n transition: background-color 0.15s ease;\n\n &:last-child {\n border-bottom: none;\n }\n\n &:hover {\n background-color: var(--neutrals-50);\n }\n\n &--active {\n background-color: var(--primary-100);\n color: var(--primary-700);\n font-weight: 500;\n }\n }\n\n &__custom {\n padding: 0.5rem 0.75rem;\n border-top: 1px solid var(--neutrals-200);\n }\n\n &__input {\n width: 100%;\n padding: 0.25rem 0.5rem;\n border: 1px solid var(--neutrals-300);\n border-radius: 4px;\n font-size: 0.875rem;\n\n &:focus {\n outline: none;\n border-color: var(--primary-500);\n }\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-editor-toolbar\"\n role=\"toolbar\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.LABEL')\"\n >\n <!-- Render buttons based on toolbar prop -->\n <template\n v-for=\"(item, index) in toolbarItems\"\n :key=\"index\"\n >\n <!-- Separator -->\n <div\n v-if=\"item === 'separator'\"\n class=\"vc-editor-toolbar__separator\"\n />\n\n <!-- Bold -->\n <VcEditorButton\n v-else-if=\"item === 'bold'\"\n icon=\"lucide-bold\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.BOLD')\"\n :active=\"editor.isActive('bold')\"\n :disabled=\"!editor.can().toggleBold() || disabled\"\n @action=\"editor.chain().focus().toggleBold().run()\"\n />\n\n <!-- Italic -->\n <VcEditorButton\n v-else-if=\"item === 'italic'\"\n icon=\"lucide-italic\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.ITALIC')\"\n :active=\"editor.isActive('italic')\"\n :disabled=\"!editor.can().toggleItalic() || disabled\"\n @action=\"editor.chain().focus().toggleItalic().run()\"\n />\n\n <!-- Underline -->\n <VcEditorButton\n v-else-if=\"item === 'underline'\"\n icon=\"lucide-underline\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.UNDERLINE')\"\n :active=\"editor.isActive('underline')\"\n :disabled=\"!editor.can().toggleUnderline() || disabled\"\n @action=\"editor.chain().focus().toggleUnderline().run()\"\n />\n\n <!-- Strikethrough -->\n <VcEditorButton\n v-else-if=\"item === 'strikethrough'\"\n icon=\"lucide-strikethrough\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.STRIKETHROUGH')\"\n :active=\"editor.isActive('strike')\"\n :disabled=\"!editor.can().toggleStrike() || disabled\"\n @action=\"editor.chain().focus().toggleStrike().run()\"\n />\n\n <!-- Heading 1 -->\n <VcEditorButton\n v-else-if=\"item === 'heading1'\"\n icon=\"lucide-heading-1\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.HEADING_1')\"\n :active=\"editor.isActive('heading', { level: 1 })\"\n :disabled=\"!editor.can().toggleHeading({ level: 1 }) || disabled\"\n @action=\"editor.chain().focus().toggleHeading({ level: 1 }).run()\"\n />\n\n <!-- Heading 2 -->\n <VcEditorButton\n v-else-if=\"item === 'heading2'\"\n icon=\"lucide-heading-2\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.HEADING_2')\"\n :active=\"editor.isActive('heading', { level: 2 })\"\n :disabled=\"!editor.can().toggleHeading({ level: 2 }) || disabled\"\n @action=\"editor.chain().focus().toggleHeading({ level: 2 }).run()\"\n />\n\n <!-- Heading 3 -->\n <VcEditorButton\n v-else-if=\"item === 'heading3'\"\n icon=\"lucide-heading-3\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.HEADING_3')\"\n :active=\"editor.isActive('heading', { level: 3 })\"\n :disabled=\"!editor.can().toggleHeading({ level: 3 }) || disabled\"\n @action=\"editor.chain().focus().toggleHeading({ level: 3 }).run()\"\n />\n\n <!-- Bullet List -->\n <VcEditorButton\n v-else-if=\"item === 'bulletList'\"\n icon=\"lucide-list\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.BULLET_LIST')\"\n :active=\"editor.isActive('bulletList')\"\n :disabled=\"!editor.can().toggleBulletList() || disabled\"\n @action=\"editor.chain().focus().toggleBulletList().run()\"\n />\n\n <!-- Ordered List -->\n <VcEditorButton\n v-else-if=\"item === 'orderedList'\"\n icon=\"lucide-list-ordered\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.NUMBERED_LIST')\"\n :active=\"editor.isActive('orderedList')\"\n :disabled=\"!editor.can().toggleOrderedList() || disabled\"\n @action=\"editor.chain().focus().toggleOrderedList().run()\"\n />\n\n <!-- Blockquote -->\n <VcEditorButton\n v-else-if=\"item === 'blockquote'\"\n icon=\"lucide-quote\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.BLOCKQUOTE')\"\n :active=\"editor.isActive('blockquote')\"\n :disabled=\"!editor.can().toggleBlockquote() || disabled\"\n @action=\"editor.chain().focus().toggleBlockquote().run()\"\n />\n\n <!-- Link -->\n <VcEditorButton\n v-else-if=\"item === 'link'\"\n icon=\"lucide-link\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.INSERT_LINK')\"\n :active=\"editor.isActive('link')\"\n :disabled=\"disabled\"\n @action=\"setLink\"\n />\n\n <!-- Image -->\n <VcEditorButton\n v-else-if=\"item === 'image'\"\n icon=\"lucide-image\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.INSERT_IMAGE')\"\n :disabled=\"disabled\"\n @action=\"triggerImageUpload\"\n />\n\n <!-- Table -->\n <VcEditorButton\n v-else-if=\"item === 'table'\"\n icon=\"lucide-table\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.INSERT_TABLE')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()\"\n />\n\n <!-- Font Selector -->\n <VcEditorFontSelector\n v-else-if=\"item === 'fontSize'\"\n :editor=\"editor\"\n :disabled=\"disabled\"\n />\n </template>\n\n <!-- Custom buttons -->\n <template v-if=\"props.customButtons.length > 0\">\n <div class=\"vc-editor-toolbar__separator\" />\n <VcEditorCustomButton\n v-for=\"customButton in sortedCustomButtons\"\n :key=\"customButton.id\"\n :editor=\"editor\"\n :custom-button=\"customButton\"\n :disabled=\"disabled\"\n />\n </template>\n\n <!-- Table controls (always show when table is active) -->\n <template v-if=\"editor.isActive('table')\">\n <div class=\"vc-editor-toolbar__separator\" />\n <VcEditorButton\n icon=\"lucide-delete\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.DELETE_TABLE')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().deleteTable().run()\"\n />\n <VcEditorButton\n icon=\"lucide-arrow-left-from-line\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.ADD_COLUMN_BEFORE')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().addColumnBefore().run()\"\n />\n <VcEditorButton\n icon=\"lucide-arrow-right-from-line\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.ADD_COLUMN_AFTER')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().addColumnAfter().run()\"\n />\n <VcEditorButton\n icon=\"lucide-arrow-up-from-line\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.ADD_ROW_BEFORE')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().addRowBefore().run()\"\n />\n <VcEditorButton\n icon=\"lucide-arrow-down-from-line\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.ADD_ROW_AFTER')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().addRowAfter().run()\"\n />\n <VcEditorButton\n icon=\"lucide-trash-2\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.DELETE_COLUMN')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().deleteColumn().run()\"\n />\n <VcEditorButton\n icon=\"lucide-trash\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.TOOLBAR.DELETE_ROW')\"\n :disabled=\"disabled\"\n @action=\"editor.chain().focus().deleteRow().run()\"\n />\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Editor } from \"@tiptap/vue-3\";\nimport { computed } from \"vue\";\nimport VcEditorButton from \"@ui/components/molecules/vc-editor/_internal/vc-editor-button.vue\";\nimport VcEditorCustomButton from \"@ui/components/molecules/vc-editor/_internal/vc-editor-custom-button.vue\";\nimport VcEditorFontSelector from \"@ui/components/molecules/vc-editor/_internal/vc-editor-font-selector.vue\";\nimport type { CustomToolbarItem } from \"@ui/components/molecules/vc-editor/_internal/toolbar-types\";\n\nexport interface Props {\n editor: Editor;\n disabled: boolean;\n contentType?: \"html\" | \"markdown\";\n toolbar: ToolbarNames[];\n customButtons?: CustomToolbarItem[];\n}\n\n// Define toolbar button types\ntype ToolbarNames =\n | \"bold\"\n | \"italic\"\n | \"underline\"\n | \"strikethrough\"\n | \"heading1\"\n | \"heading2\"\n | \"heading3\"\n | \"bulletList\"\n | \"orderedList\"\n | \"blockquote\"\n | \"link\"\n | \"image\"\n | \"table\"\n | \"fontSize\"\n | \"separator\";\n\nconst props = withDefaults(defineProps<Props>(), {\n contentType: \"html\",\n customButtons: () => [],\n});\n\nconst emit = defineEmits([\"uploadImage\"]);\n\n// Computed property to get toolbar items\nconst toolbarItems = computed(() => {\n return props.toolbar || [];\n});\n\n// Computed property to sort custom buttons\nconst sortedCustomButtons = computed(() => {\n return [...props.customButtons].sort((a, b) => {\n const groupA = a.group || \"default\";\n const groupB = b.group || \"default\";\n const orderA = a.order || 0;\n const orderB = b.order || 0;\n\n if (groupA !== groupB) {\n return groupA.localeCompare(groupB);\n }\n\n return orderA - orderB;\n });\n});\n\nfunction setLink() {\n const previousUrl = props.editor.getAttributes(\"link\").href;\n const url = window.prompt(\"URL\", previousUrl);\n\n if (url === null) return;\n if (url === \"\") {\n props.editor.chain().focus().extendMarkRange(\"link\").unsetLink().run();\n return;\n }\n props.editor.chain().focus().extendMarkRange(\"link\").setLink({ href: url }).run();\n}\n\nfunction triggerImageUpload() {\n emit(\"uploadImage\");\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n // Toolbar color variables\n --vc-toolbar-bg: var(--neutrals-50);\n --vc-toolbar-separator: var(--neutrals-200);\n}\n\n.vc-editor-toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.25rem;\n\n &__separator {\n width: 1px;\n height: 1.5rem;\n background-color: var(--vc-toolbar-separator);\n margin: 0 0.5rem;\n flex-shrink: 0;\n }\n}\n</style>\n","<template>\n <div\n v-if=\"bladeLoading\"\n class=\"vc-editor vc-editor--skeleton\"\n >\n <VcSkeleton\n v-if=\"label\"\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"11\"\n />\n <VcSkeleton\n variant=\"block\"\n width=\"100%\"\n :height=\"320\"\n />\n </div>\n <div\n v-else\n class=\"vc-editor\"\n :class=\"{\n 'vc-editor--error': !!errorMessage,\n 'vc-editor--disabled': disabled,\n 'vc-editor--focused': isFocused,\n 'vc-editor--fullscreen': isFullscreen,\n 'vc-editor--side-by-side': currentMode === 'split',\n }\"\n :aria-label=\"label\"\n :aria-invalid=\"!!errorMessage || undefined\"\n :aria-disabled=\"disabled || undefined\"\n >\n <VcLabel\n v-if=\"label && !isFullscreen\"\n class=\"vc-editor__label\"\n :required=\"required\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :error=\"!!errorMessage\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >{{ tooltip }}</template\n >\n </VcLabel>\n\n <div\n v-if=\"editor\"\n class=\"vc-editor__header\"\n >\n <VcEditorToolbar\n v-if=\"currentMode === 'editor' || currentMode === 'split'\"\n :editor=\"editor\"\n :disabled=\"disabled\"\n :content-type=\"detectedType\"\n :toolbar=\"filteredToolbar\"\n :custom-buttons=\"props.customButtons || []\"\n @upload-image=\"triggerImageUpload\"\n />\n\n <div class=\"vc-editor__header-actions\">\n <VcEditorButton\n icon=\"lucide-eye\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.VIEW.PREVIEW')\"\n :active=\"currentMode === 'preview'\"\n :disabled=\"disabled\"\n @action=\"togglePreview\"\n />\n <VcEditorButton\n icon=\"lucide-columns-2\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.VIEW.SPLIT')\"\n :active=\"currentMode === 'split'\"\n @action=\"toggleSideBySideView\"\n />\n <VcEditorButton\n icon=\"lucide-code\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_EDITOR.VIEW.SOURCE')\"\n :active=\"currentMode === 'source'\"\n :disabled=\"disabled\"\n @action=\"toggleSourceView\"\n />\n <VcEditorButton\n :icon=\"isFullscreen ? 'lucide-shrink' : 'lucide-expand'\"\n :aria-label=\"isFullscreen ? 'Exit fullscreen' : 'Fullscreen'\"\n @action=\"isFullscreen = !isFullscreen\"\n />\n </div>\n </div>\n\n <div class=\"vc-editor__body\">\n <!-- Normal editor view -->\n <editor-content\n v-if=\"currentMode === 'editor'\"\n :editor=\"editor\"\n class=\"vc-editor__content\"\n />\n\n <!-- Full preview view -->\n <div\n v-if=\"currentMode === 'preview'\"\n class=\"vc-editor__preview ProseMirror\"\n v-html=\"previewContent\"\n />\n\n <!-- Source code view -->\n <textarea\n v-if=\"currentMode === 'source'\"\n class=\"vc-editor__source ProseMirror\"\n :value=\"formattedSource\"\n :maxlength=\"maxlength\"\n @input=\"handleSourceInput\"\n @focus=\"isFocused = true\"\n @blur=\"isFocused = false\"\n />\n\n <!-- Side-by-side view: Editor left, Code right -->\n <div\n v-if=\"currentMode === 'split'\"\n class=\"vc-editor__split-view\"\n >\n <div class=\"vc-editor__split-editor\">\n <editor-content\n :editor=\"editor\"\n class=\"vc-editor__content\"\n />\n </div>\n <div class=\"vc-editor__split-preview\">\n <textarea\n class=\"vc-editor__source ProseMirror\"\n :value=\"formattedSource\"\n :maxlength=\"maxlength\"\n @input=\"handleSourceInput\"\n @focus=\"isFocused = true\"\n @blur=\"isFocused = false\"\n />\n </div>\n </div>\n </div>\n\n <!-- Character count display -->\n <div\n v-if=\"maxlength && (currentMode === 'source' || currentMode === 'split')\"\n class=\"vc-editor__char-count\"\n :class=\"{ 'vc-editor__char-count--warning': isNearLimit }\"\n >\n {{ characterCount }} / {{ maxlength }}\n </div>\n\n <input\n ref=\"imageInput\"\n type=\"file\"\n hidden\n multiple\n accept=\"image/*\"\n @change=\"handleImageSelection\"\n />\n\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"errorMessage && !isFullscreen\">\n <slot name=\"error\">\n <VcHint\n class=\"vc-editor__error-hint\"\n :error=\"true\"\n >\n {{ errorMessage }}\n </VcHint>\n </slot>\n </div>\n </Transition>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport { ref, watch, onBeforeUnmount, computed } from \"vue\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\n\nconst bladeLoading = useBladeLoading();\nimport { useEditor, EditorContent } from \"@tiptap/vue-3\";\nimport { StarterKit } from \"@tiptap/starter-kit\";\nimport { Underline } from \"@tiptap/extension-underline\";\nimport { Table } from \"@tiptap/extension-table\";\nimport { TableRow } from \"@tiptap/extension-table-row\";\nimport { TableHeader } from \"@tiptap/extension-table-header\";\nimport { TableCell } from \"@tiptap/extension-table-cell\";\nimport { Link } from \"@tiptap/extension-link\";\nimport { Image } from \"@tiptap/extension-image\";\nimport { Placeholder } from \"@tiptap/extension-placeholder\";\nimport { TextStyle } from \"@tiptap/extension-text-style\";\nimport { Markdown } from \"tiptap-markdown\";\nimport type { Extension } from \"@tiptap/core\";\nimport { FontSize } from \"@ui/components/molecules/vc-editor/_internal/extensions/font-size\";\nimport beautify from \"js-beautify\";\nimport DOMPurify from \"dompurify\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport VcEditorToolbar from \"@ui/components/molecules/vc-editor/_internal/vc-editor-toolbar.vue\";\nimport VcEditorButton from \"@ui/components/molecules/vc-editor/_internal/vc-editor-button.vue\";\nimport type { CustomToolbarItem } from \"@ui/components/molecules/vc-editor/_internal/toolbar-types\";\nimport type { IFormFieldProps } from \"@ui/types/form-field\";\n\n// Export types for external use\nexport type {\n CustomToolbarItem,\n CustomToolbarButton,\n CustomToolbarDropdown,\n} from \"@ui/components/molecules/vc-editor/_internal/toolbar-types\";\n\n// Define toolbar button types\nexport type ToolbarNames =\n | \"bold\"\n | \"italic\"\n | \"underline\"\n | \"strikethrough\"\n | \"heading1\"\n | \"heading2\"\n | \"heading3\"\n | \"bulletList\"\n | \"orderedList\"\n | \"blockquote\"\n | \"link\"\n | \"image\"\n | \"table\"\n | \"fontSize\"\n | \"separator\";\n\nexport interface VcEditorProps extends IFormFieldProps {\n placeholder?: string;\n modelValue?: string;\n assetsFolder?: string;\n multilanguage?: boolean;\n currentLanguage?: string;\n maxlength?: number;\n toolbar?: ToolbarNames[];\n extensions?: Extension[];\n customButtons?: CustomToolbarItem[];\n}\n\nexport interface VcEditorEmits {\n (event: \"update:modelValue\", value?: string): void;\n (event: \"upload-image\"): void;\n}\n\nconst props = withDefaults(defineProps<VcEditorProps>(), {\n modelValue: \"\",\n disabled: false,\n});\n\nconst emit = defineEmits<VcEditorEmits>();\n\nconst isFocused = ref(false);\nconst isFullscreen = ref(false);\nconst imageInput = ref<HTMLInputElement | null>(null);\nconst detectedType = ref<\"html\" | \"markdown\">(\"markdown\");\n\n// Computed property for filtered toolbar based on props\nconst filteredToolbar = computed(() => {\n if (!props.toolbar) {\n // Default toolbar if none specified\n return [\n \"bold\",\n \"italic\",\n \"underline\",\n \"strikethrough\",\n \"separator\",\n \"heading1\",\n \"heading2\",\n \"heading3\",\n \"separator\",\n \"bulletList\",\n \"orderedList\",\n \"blockquote\",\n \"separator\",\n \"link\",\n \"image\",\n \"table\",\n \"fontSize\",\n ] as ToolbarNames[];\n }\n return props.toolbar;\n});\n\n// Character count for maxlength\nconst characterCount = computed(() => {\n return (props.modelValue || \"\").length;\n});\n\nconst isNearLimit = computed(() => {\n if (!props.maxlength) return false;\n return characterCount.value > props.maxlength * 0.9;\n});\n\n// Function to detect content type\nfunction detectContentType(content: string): \"html\" | \"markdown\" {\n if (!content || content.trim() === \"\") return \"markdown\";\n\n // HTML indicators\n const htmlPatterns = [\n /<[^>]+>/g, // HTML tags\n /&[a-zA-Z]+;/g, // HTML entities\n ];\n\n // Markdown indicators\n const markdownPatterns = [\n /^#{1,6}\\s/m, // Headers\n /^\\*\\s/m, // Bullet lists\n /^\\d+\\.\\s/m, // Numbered lists\n /\\*\\*[^*]+\\*\\*/g, // Bold\n /\\*[^*]+\\*/g, // Italic\n /\\[[^\\]]+\\]\\([^)]+\\)/g, // Links\n /```[\\s\\S]*?```/g, // Code blocks\n /`[^`]+`/g, // Inline code\n /^>/m, // Blockquotes\n ];\n\n let htmlScore = 0;\n let markdownScore = 0;\n\n // Count HTML patterns\n htmlPatterns.forEach((pattern) => {\n const matches = content.match(pattern);\n if (matches) htmlScore += matches.length;\n });\n\n // Count Markdown patterns\n markdownPatterns.forEach((pattern) => {\n const matches = content.match(pattern);\n if (matches) markdownScore += matches.length;\n });\n\n // Only switch to HTML if there are significantly more HTML patterns\n if (htmlScore > markdownScore * 2) {\n return \"html\";\n }\n\n // Default to Markdown for most cases\n return \"markdown\";\n}\n\nconst extensions = computed(() => {\n const baseExtensions: any[] = [\n StarterKit,\n Underline,\n TextStyle,\n FontSize,\n Table.configure({ resizable: true }),\n TableRow,\n TableHeader,\n TableCell,\n Link.configure({ openOnClick: false }),\n Image,\n Placeholder.configure({ placeholder: props.placeholder }),\n Markdown.configure({\n html: true, // Allow HTML input/output\n tightLists: true, // No <p> inside <li> in markdown output\n tightListClass: \"tight\", // Add class to <ul> allowing you to remove <p> margins when tight\n bulletListMarker: \"-\", // <li> prefix in markdown output\n linkify: false, // Create links from \"https://...\" text\n breaks: true, // New lines (\\n) in markdown input are converted to <br>\n transformPastedText: false, // Allow to paste markdown text in the editor\n transformCopiedText: false, // Copied text is transformed to markdown\n }),\n ];\n\n // Merge custom extensions: custom ones override base ones with the same name\n if (props.extensions && props.extensions.length > 0) {\n const customNames = new Set(props.extensions.map((ext: Extension) => ext.name).filter(Boolean));\n const filtered = baseExtensions.filter((ext: Extension) => !customNames.has(ext.name));\n return [...filtered, ...props.extensions];\n }\n\n return baseExtensions;\n});\n\nconst formattedSource = ref(props.modelValue || \"\");\n\nwatch(\n () => props.modelValue,\n (value) => {\n // Detect content type\n detectedType.value = detectContentType(value || \"\");\n\n if (detectedType.value === \"html\") {\n try {\n formattedSource.value = beautify.html(value || \"\", {\n indent_size: 2,\n wrap_line_length: 0,\n preserve_newlines: true,\n max_preserve_newlines: 1,\n });\n } catch (_e) {\n formattedSource.value = value || \"\";\n }\n } else {\n formattedSource.value = value || \"\";\n }\n },\n { immediate: true },\n);\n\nconst previewContent = computed(() => {\n let htmlContent = \"\";\n\n if (detectedType.value === \"markdown\" && editor.value) {\n // Use Tiptap's built-in HTML conversion from Markdown\n htmlContent = editor.value.getHTML();\n } else {\n htmlContent = props.modelValue || \"\";\n }\n\n // Sanitize HTML to prevent XSS attacks\n return DOMPurify.sanitize(htmlContent, {\n // Allow safe HTML tags and attributes\n ALLOWED_TAGS: [\n \"p\",\n \"br\",\n \"strong\",\n \"em\",\n \"u\",\n \"s\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"a\",\n \"img\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n \"hr\",\n \"div\",\n \"span\",\n ],\n ALLOWED_ATTR: [\"href\", \"src\", \"alt\", \"title\", \"class\", \"id\", \"style\", \"colspan\", \"rowspan\", \"align\", \"valign\"],\n // Remove dangerous protocols\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.-]+(?:[^a-z+.-:]|$))/i,\n // Keep relative URLs\n KEEP_CONTENT: true,\n // Remove script tags and event handlers\n FORBID_TAGS: [\"script\", \"object\", \"embed\", \"form\", \"input\"],\n FORBID_ATTR: [\"onerror\", \"onload\", \"onclick\", \"onmouseover\", \"onfocus\", \"onblur\"],\n });\n});\n\n// Single reactive state for editor mode\nconst editorMode = ref<\"editor\" | \"preview\" | \"source\" | \"split\">(\"editor\");\n\n// Computed property for current mode\nconst currentMode = computed(() => editorMode.value);\n\nfunction togglePreview() {\n editorMode.value = editorMode.value === \"preview\" ? \"editor\" : \"preview\";\n}\n\nfunction toggleSourceView() {\n editorMode.value = editorMode.value === \"source\" ? \"editor\" : \"source\";\n}\n\nfunction toggleSideBySideView() {\n editorMode.value = editorMode.value === \"split\" ? \"editor\" : \"split\";\n}\n\n// Guard flag: prevents emitting update:modelValue when content is set\n// programmatically from prop watcher (e.g., language switch), not from user input.\nlet settingContentFromProp = false;\n\nconst editor = useEditor({\n content: props.modelValue,\n editable: !props.disabled,\n extensions: extensions.value,\n editorProps: {\n // Expose the contenteditable region as a named multiline textbox\n // (WCAG 4.1.2 / aria-input-field-name). Without an explicit role the\n // plain <div> is treated as generic, which prohibits aria-label.\n attributes: {\n role: \"textbox\",\n \"aria-multiline\": \"true\",\n \"aria-label\": props.label || \"Rich text editor\",\n },\n },\n onUpdate: ({ editor: tipTapEditor }) => {\n // Skip emit when content was set programmatically from prop change\n if (settingContentFromProp) return;\n\n // Always output in Markdown by default, unless HTML is detected\n const output =\n detectedType.value === \"html\"\n ? tipTapEditor.getHTML()\n : ((tipTapEditor.storage as any).markdown?.getMarkdown?.() ?? tipTapEditor.getHTML());\n\n // Check maxlength if specified\n if (props.maxlength && output.length > props.maxlength) {\n return; // Don't emit if exceeds maxlength\n }\n\n // tiptap-markdown normalizes content on round-trip (e.g. adds trailing \\n).\n // Skip emit when the only difference is trailing whitespace — otherwise\n // useBladeForm sees a phantom modification after undo back to original.\n if ((output || \"\").trimEnd() === (props.modelValue || \"\").trimEnd()) {\n return;\n }\n\n emit(\"update:modelValue\", output);\n },\n onFocus: () => {\n isFocused.value = true;\n },\n onBlur: () => {\n isFocused.value = false;\n },\n});\n\nwatch(\n () => props.modelValue,\n (value) => {\n if (!editor.value) return;\n\n const editorContent =\n detectedType.value === \"html\"\n ? editor.value.getHTML()\n : ((editor.value.storage as any).markdown?.getMarkdown?.() ?? editor.value.getHTML());\n\n if ((editorContent || \"\").trimEnd() !== (value || \"\").trimEnd()) {\n settingContentFromProp = true;\n editor.value.commands.setContent(value || \"\");\n settingContentFromProp = false;\n }\n },\n);\n\nwatch(\n () => props.disabled,\n (isDisabled) => {\n editor.value?.setEditable(!isDisabled);\n },\n);\n\nonBeforeUnmount(() => {\n editor.value?.destroy();\n});\n\nfunction triggerImageUpload() {\n imageInput.value?.click();\n}\n\nfunction handleSourceInput(event: Event) {\n const target = event.target as HTMLTextAreaElement;\n const value = target.value;\n\n // Check maxlength if specified\n if (props.maxlength && value.length > props.maxlength) {\n target.value = value.substring(0, props.maxlength);\n return;\n }\n\n emit(\"update:modelValue\", value);\n}\n\nasync function handleImageSelection(event: Event) {\n const target = event.target as HTMLInputElement;\n if (!target.files?.length || !props.assetsFolder) return;\n\n const files = Array.from(target.files);\n const formData = new FormData();\n files.forEach((file) => formData.append(\"image\", file));\n\n try {\n const result = await fetch(`/api/assets?folderUrl=/${props.assetsFolder}`, {\n method: \"POST\",\n body: formData,\n });\n const response = await result.json();\n\n response.forEach((item: { url: string }) => {\n if (item.url) {\n editor.value?.chain().focus().setImage({ src: item.url }).run();\n }\n });\n } catch (error) {\n console.error(\"Image upload failed:\", error);\n }\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n // Editor color variables\n --vc-editor-border: var(--neutrals-300);\n --vc-editor-background: transparent;\n --vc-editor-surface: var(--additional-50);\n --vc-editor-text-primary: var(--neutrals-900);\n --vc-editor-text-secondary: var(--neutrals-500);\n --vc-editor-text-muted: var(--neutrals-400);\n --vc-editor-text-disabled: var(--neutrals-500);\n --vc-editor-background-disabled: var(--neutrals-200);\n --vc-editor-focus-border: var(--primary-500);\n --vc-editor-focus-shadow: var(--primary-500);\n --vc-editor-focus-ring-color: color-mix(in srgb, var(--primary-500) 30%, transparent);\n --vc-editor-error-border: var(--danger-500);\n --vc-editor-error-text: var(--danger-500);\n --vc-editor-error-ring-color: rgba(239, 68, 68, 0.2);\n --vc-editor-table-header: var(--neutrals-100);\n --vc-editor-separator: var(--neutrals-200);\n}\n\n.vc-editor {\n display: flex;\n flex-direction: column;\n\n &__label {\n margin-bottom: 0.5rem;\n }\n\n &__header {\n display: flex;\n border: 1px solid var(--vc-editor-border);\n border-bottom: none;\n border-radius: 6px 6px 0 0;\n background-color: var(--vc-toolbar-bg);\n padding: 0.5rem;\n }\n\n &__source {\n font-family: monospace;\n resize: vertical;\n }\n\n &__header-actions {\n margin-left: auto;\n display: flex;\n gap: 0.25rem;\n }\n\n &__body {\n flex-grow: 1;\n display: flex;\n }\n\n &__content,\n &__preview {\n flex: 1;\n }\n\n &__split-view {\n display: flex;\n width: 100%;\n gap: 1px;\n }\n\n &__split-editor,\n &__split-preview {\n flex: 1;\n }\n\n &__split-editor .ProseMirror {\n border-radius: 0 0 0 6px;\n border-right: none;\n }\n\n &__split-preview .ProseMirror {\n border-radius: 0 0 6px 0;\n border-left: none;\n }\n\n &--side-by-side {\n .vc-editor__body {\n flex-direction: row;\n }\n }\n\n .ProseMirror {\n border: 1px solid var(--vc-editor-border);\n border-radius: 0 0 6px 6px;\n padding: 0.5rem 0.75rem;\n min-height: 20rem;\n outline: none;\n transition: border-color 0.2s;\n background-color: var(--vc-editor-surface);\n color: var(--vc-editor-text-primary);\n width: 100%;\n\n p.is-editor-empty:first-child::before {\n content: attr(data-placeholder);\n float: left;\n color: var(--vc-editor-text-muted);\n pointer-events: none;\n height: 0;\n }\n\n h1,\n h2,\n h3 {\n line-height: 1.1;\n margin-top: 1.25em;\n margin-bottom: 0.5em;\n font-weight: bold;\n color: var(--vc-editor-text-primary);\n }\n\n h1 {\n font-size: 2em;\n margin-top: 0.67em;\n margin-bottom: 0.67em;\n }\n\n h2 {\n font-size: 1.5em;\n margin-top: 0.83em;\n margin-bottom: 0.83em;\n }\n\n h3 {\n font-size: 1.17em;\n margin-top: 1em;\n margin-bottom: 1em;\n }\n\n ul,\n ol {\n padding: 0 1rem;\n list-style: disc;\n }\n\n ul {\n list-style: disc;\n }\n\n ol {\n list-style: decimal;\n }\n\n blockquote {\n padding-left: 1rem;\n border-left: 2px solid var(--vc-editor-separator);\n color: var(--vc-editor-text-secondary);\n }\n\n hr {\n border: none;\n border-top: 1px solid var(--vc-editor-separator);\n margin: 1rem 0;\n }\n\n table {\n border-collapse: collapse;\n table-layout: fixed;\n width: 100%;\n }\n\n td,\n th {\n border: 1px solid var(--vc-editor-separator);\n padding: 0.5rem;\n text-align: left;\n }\n\n th {\n background-color: var(--vc-editor-table-header);\n font-weight: 600;\n color: var(--vc-editor-text-primary);\n }\n\n // Links\n a {\n color: var(--primary-600);\n text-decoration: underline;\n\n &:hover {\n color: var(--primary-700);\n }\n }\n\n // Code blocks\n pre {\n background-color: var(--vc-editor-background);\n border: 1px solid var(--vc-editor-border);\n border-radius: 6px;\n padding: 0.75rem;\n overflow-x: auto;\n }\n\n code {\n background-color: var(--vc-editor-background);\n color: var(--vc-editor-text-primary);\n padding: 0.125rem 0.25rem;\n border-radius: 2px;\n font-size: 0.875em;\n }\n }\n\n &--focused .ProseMirror {\n border-color: var(--vc-editor-focus-border);\n box-shadow: 0 0 0 3px var(--vc-editor-focus-ring-color);\n }\n\n &--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n &--disabled .ProseMirror {\n background-color: var(--vc-editor-background-disabled);\n cursor: not-allowed;\n color: var(--vc-editor-text-disabled);\n }\n\n &--error .ProseMirror {\n border-color: var(--vc-editor-error-border);\n box-shadow: 0 0 0 3px var(--vc-editor-error-ring-color);\n }\n\n &__error-hint {\n @apply tw-mt-1 [--hint-error-color:var(--vc-editor-error-text)];\n }\n\n &__char-count {\n font-size: 0.75rem;\n color: var(--vc-editor-text-secondary);\n text-align: right;\n padding: 0.25rem 0.5rem;\n border: 1px solid var(--vc-editor-border);\n border-top: none;\n border-radius: 0 0 6px 6px;\n background-color: var(--vc-editor-background);\n\n &--warning {\n color: var(--warning-600);\n font-weight: 600;\n }\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-1.5;\n }\n\n &--fullscreen {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background-color: var(--vc-editor-surface);\n z-index: var(--z-overlay-editor-bubble);\n padding: 1rem;\n display: flex;\n flex-direction: column;\n\n .vc-editor__body {\n height: 100%;\n }\n\n .ProseMirror {\n height: 100%;\n min-height: 0;\n }\n }\n}\n</style>\n","<template>\n <div\n :id=\"String(notificationId)\"\n ref=\"toastRef\"\n class=\"vc-notification\"\n :class=\"[`vc-notification--${type || 'default'}`]\"\n :data-mounted=\"mounted\"\n :data-removed=\"removed\"\n :data-y-position=\"yPosition\"\n :data-front=\"isFront\"\n :data-expanded=\"expanded ?? true\"\n :data-visible=\"isVisible\"\n :data-swiping=\"isSwiping\"\n :data-swiped-out=\"swipedOut\"\n :role=\"type === 'error' ? 'alert' : 'status'\"\n @mouseenter=\"onMouseEnter\"\n @mouseleave=\"onMouseLeave\"\n @pointerdown=\"onPointerDown\"\n @pointermove=\"onPointerMove\"\n @pointerup=\"onPointerUp\"\n >\n <div class=\"vc-notification__content-wrapper\">\n <VcIcon\n :icon=\"types[type ?? 'default']?.icon\"\n :style=\"{ color: types[type ?? 'default']?.color }\"\n size=\"l\"\n class=\"vc-notification__icon\"\n aria-hidden=\"true\"\n ></VcIcon>\n <div\n v-if=\"typeof content === 'string'\"\n class=\"vc-notification__content\"\n tabindex=\"0\"\n >\n {{ content }}\n </div>\n <div v-else>\n <component :is=\"content\"></component>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"vc-notification__dismiss-button\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_TOAST.DISMISS')\"\n @click.stop=\"handleClose\"\n @keydown.escape=\"handleClose\"\n >\n <VcIcon\n icon=\"lucide-x\"\n size=\"s\"\n aria-hidden=\"true\"\n ></VcIcon>\n </button>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Content, NotificationType, NotificationPosition } from \"@core/notifications/toast-types\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { Ref, computed, onMounted, onBeforeUnmount, ref, toRefs, watch } from \"vue\";\n\nexport interface Props {\n content?: Content;\n notificationId?: number | string;\n updateId?: number | string;\n type?: NotificationType;\n timeout?: number | boolean;\n pauseOnHover?: boolean;\n limit?: number;\n position?: NotificationPosition;\n dismissing?: boolean;\n /** Sonner-style index: 0 = front (newest), higher = older */\n toastIndex?: number;\n /** Total number of toasts in the position stack */\n toastsCount?: number;\n /** Whether the toast group is expanded (hovered or single toast) */\n expanded?: boolean;\n /** Max visible toasts in collapsed stack */\n visibleToasts?: number;\n /** Callback to report measured height to container */\n onReportHeight?: (id: string | number, height: number) => void;\n}\n\nconst emit = defineEmits<{\n (e: \"close\", id: number | string | undefined): void;\n}>();\n\nconst props = defineProps<Props>();\n\nconst types: Record<NotificationType, { icon: string; color: string }> = {\n default: { icon: \"lucide-info\", color: \"var(--notification-info)\" },\n success: { icon: \"lucide-check-circle\", color: \"var(--notification-success)\" },\n error: { icon: \"lucide-alert-circle\", color: \"var(--notification-error)\" },\n warning: { icon: \"lucide-alert-triangle\", color: \"var(--notification-warning)\" },\n};\n\nconst { timeout } = toRefs(props);\n\nconst toastRef = ref<HTMLElement | null>(null);\nconst mounted = ref(false);\nconst removed = ref(false);\n\n// Sonner: remove from DOM while CSS exit transition is still running\nconst TIME_BEFORE_UNMOUNT = 200;\n\n// Position\nconst yPosition = computed(() => {\n const pos = props.position || \"top-center\";\n return pos.startsWith(\"top\") ? \"top\" : \"bottom\";\n});\n\n// Stacking (sonner-style: index 0 = front)\nconst isFront = computed(() => (props.toastIndex ?? 0) === 0);\nconst isVisible = computed(() => (props.toastIndex ?? 0) < (props.visibleToasts ?? 3));\n\n// Timer\ninterface NotificationTimer {\n pause: () => void;\n resume: () => void;\n start: () => void;\n clear: () => void;\n}\n\nconst timer = ref<NotificationTimer | null>(null);\n\nfunction handleClose() {\n if (removed.value) return;\n removed.value = true;\n timer.value?.clear();\n\n // Pure CSS exit — data-removed=\"true\" triggers CSS transition.\n // After TIME_BEFORE_UNMOUNT, emit close to remove from reactive list.\n setTimeout(() => {\n emit(\"close\", props.notificationId);\n }, TIME_BEFORE_UNMOUNT);\n}\n\n// Watch for programmatic dismissal\nwatch(\n () => props.dismissing,\n (val) => {\n if (val) handleClose();\n },\n);\n\nwatch(\n timeout as Ref<number | boolean>,\n (newVal) => {\n if (newVal) {\n timer.value = Timer(() => handleClose(), props.timeout as number);\n timer.value.start();\n }\n },\n { immediate: true },\n);\n\n// Report height to container\nconst resizeObserver = ref<ResizeObserver | null>(null);\n\nfunction reportHeight() {\n if (toastRef.value && props.notificationId !== undefined && !removed.value) {\n const el = toastRef.value;\n const originalHeight = el.style.height;\n el.style.height = \"auto\";\n const height = el.getBoundingClientRect().height;\n el.style.height = originalHeight;\n props.onReportHeight?.(props.notificationId, height);\n }\n}\n\nonMounted(() => {\n // Double-rAF ensures browser paints initial (unmounted) state before transition\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n mounted.value = true;\n reportHeight();\n });\n });\n\n if (toastRef.value) {\n resizeObserver.value = new ResizeObserver(() => reportHeight());\n resizeObserver.value.observe(toastRef.value);\n }\n});\n\nfunction Timer(callback: (...args: unknown[]) => unknown, delay: number): NotificationTimer {\n let timerId: number;\n let from: number;\n let remaining = delay;\n\n function pause() {\n window.clearTimeout(timerId);\n remaining -= Date.now() - from;\n }\n\n function resume() {\n from = Date.now();\n window.clearTimeout(timerId);\n timerId = window.setTimeout(callback, remaining);\n }\n\n function start() {\n remaining = delay;\n resume();\n }\n\n function clear() {\n window.clearTimeout(timerId);\n }\n\n return { pause, resume, start, clear };\n}\n\nonBeforeUnmount(() => {\n timer.value?.clear();\n resizeObserver.value?.disconnect();\n});\n\nfunction onMouseEnter() {\n if (props.timeout && props.pauseOnHover !== false) {\n timer.value?.pause();\n }\n}\n\nfunction onMouseLeave() {\n if (props.timeout && props.pauseOnHover !== false) {\n timer.value?.resume();\n }\n}\n\n// --- Swipe-to-dismiss ---\nconst SWIPE_THRESHOLD = 45;\n\nconst swipeStartX = ref(0);\nconst swipeStartY = ref(0);\nconst isSwiping = ref(false);\nconst swipedOut = ref(false);\nconst dragStartTime = ref(0);\n\nfunction onPointerDown(e: PointerEvent) {\n if (removed.value || swipedOut.value) return;\n if ((e.target as HTMLElement)?.closest(\".vc-notification__dismiss-button\")) return;\n\n swipeStartX.value = e.clientX;\n swipeStartY.value = e.clientY;\n dragStartTime.value = Date.now();\n isSwiping.value = false;\n\n const el = toastRef.value;\n if (el) {\n el.setPointerCapture(e.pointerId);\n }\n}\n\nfunction onPointerMove(e: PointerEvent) {\n if (removed.value || swipedOut.value) return;\n if (swipeStartX.value === 0 && swipeStartY.value === 0) return;\n\n const deltaX = e.clientX - swipeStartX.value;\n const deltaY = e.clientY - swipeStartY.value;\n\n if (!isSwiping.value) {\n if (Math.abs(deltaX) > 1 && Math.abs(deltaX) > Math.abs(deltaY)) {\n isSwiping.value = true;\n timer.value?.pause();\n } else if (Math.abs(deltaY) > 1) {\n swipeStartX.value = 0;\n swipeStartY.value = 0;\n return;\n } else {\n return;\n }\n }\n\n toastRef.value?.style.setProperty(\"--swipe-amount-x\", `${deltaX}px`);\n}\n\nfunction onPointerUp(e: PointerEvent) {\n const el = toastRef.value;\n if (el) {\n if (el.hasPointerCapture(e.pointerId)) {\n el.releasePointerCapture(e.pointerId);\n }\n }\n\n if (!isSwiping.value) {\n toastRef.value?.style.setProperty(\"--swipe-amount-x\", \"0px\");\n swipeStartX.value = 0;\n swipeStartY.value = 0;\n return;\n }\n\n const swipeAmountX = parseFloat(toastRef.value?.style.getPropertyValue(\"--swipe-amount-x\")?.replace(\"px\", \"\") || \"0\");\n const timeTaken = Date.now() - dragStartTime.value;\n const velocity = Math.abs(swipeAmountX) / timeTaken;\n\n if (Math.abs(swipeAmountX) >= SWIPE_THRESHOLD || velocity > 0.11) {\n removed.value = true;\n timer.value?.clear();\n swipedOut.value = true;\n const direction = swipeAmountX > 0 ? 1 : -1;\n toastRef.value?.style.setProperty(\"--swipe-amount-x\", `${direction * window.innerWidth}px`);\n setTimeout(() => emit(\"close\", props.notificationId), TIME_BEFORE_UNMOUNT);\n } else {\n toastRef.value?.style.setProperty(\"--swipe-amount-x\", \"0px\");\n timer.value?.resume();\n }\n\n isSwiping.value = false;\n swipeStartX.value = 0;\n swipeStartY.value = 0;\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n /* Main colors and styles */\n --notification-background: var(--additional-50);\n --notification-border-radius: 6px;\n --notification-border-color: var(--neutrals-200);\n --notification-dismiss-color: var(--neutrals-400);\n --notification-dismiss-hover-color: var(--neutrals-600);\n --notification-content-color: var(--neutrals-800);\n\n /* Color indicators for types */\n --notification-warning: var(--warning-500);\n --notification-error: var(--danger-500);\n --notification-success: var(--success-500);\n --notification-info: var(--info-500);\n\n /* Effects */\n --notification-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n --notification-hover-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n\n /* Focus */\n --notification-focus-ring-color: var(--primary-100);\n\n /* Left accent border */\n --notification-accent-width: 3px;\n}\n\n.vc-notification {\n @apply tw-flex tw-items-center tw-box-border;\n @apply tw-border tw-border-solid tw-overflow-hidden tw-py-3 tw-px-4;\n @apply tw-justify-between;\n width: var(--width, 356px);\n max-width: 600px;\n background-color: var(--notification-background);\n border-color: var(--notification-border-color);\n border-radius: var(--notification-border-radius);\n box-shadow: var(--notification-shadow);\n border-left: var(--notification-accent-width) solid var(--notification-info);\n\n /* Sonner: absolute positioning, transform via --y variable */\n position: absolute;\n z-index: var(--z-index);\n opacity: 0;\n transform: var(--y);\n will-change: transform, opacity;\n touch-action: none;\n overflow-wrap: anywhere;\n pointer-events: all;\n\n /* Compute lift-amount from inherited --lift and --gap */\n --lift-amount: calc(var(--lift, 1) * var(--gap, 14px));\n\n /* Sonner transition: standard ease (NOT bouncy) */\n transition:\n transform 400ms,\n opacity 400ms,\n box-shadow 200ms;\n\n /* Position anchor + initial off-screen --y */\n &[data-y-position=\"top\"] {\n top: 0;\n --y: translateY(-100%);\n --lift: 1;\n }\n\n &[data-y-position=\"bottom\"] {\n bottom: 0;\n --y: translateY(100%);\n --lift: -1;\n }\n\n /* Mounted: enter animation */\n &[data-mounted=\"true\"] {\n --y: translateY(0);\n opacity: 1;\n }\n\n /* Collapsed stacking: back toasts */\n &[data-expanded=\"false\"][data-front=\"false\"] {\n --y: translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--toasts-before) * 0.05 + 1));\n height: var(--front-toast-height);\n }\n\n /* Hide content of collapsed back toasts */\n &[data-expanded=\"false\"][data-front=\"false\"] > * {\n opacity: 0;\n }\n\n /* Content opacity transition */\n > * {\n transition: opacity 400ms;\n }\n\n /* Expanded: each toast at computed offset */\n &[data-mounted=\"true\"][data-expanded=\"true\"] {\n --y: translateY(calc(var(--lift, 1) * var(--offset)));\n height: var(--initial-height);\n }\n\n /* Not visible: beyond visible limit */\n &[data-visible=\"false\"] {\n opacity: 0;\n pointer-events: none;\n }\n\n /* --- Exit animations (sonner-style, context-dependent) --- */\n\n /* Front toast exit: slide away from viewport */\n &[data-removed=\"true\"][data-front=\"true\"][data-swiped-out=\"false\"] {\n --y: translateY(calc(var(--lift, 1) * -100%));\n opacity: 0;\n }\n\n /* Back toast exit (expanded): slide away from current offset */\n &[data-removed=\"true\"][data-front=\"false\"][data-swiped-out=\"false\"][data-expanded=\"true\"] {\n --y: translateY(calc(var(--lift, 1) * var(--offset) + var(--lift, 1) * -100%));\n opacity: 0;\n }\n\n /* Back toast exit (collapsed): sink away */\n &[data-removed=\"true\"][data-front=\"false\"][data-swiped-out=\"false\"][data-expanded=\"false\"] {\n --y: translateY(40%);\n opacity: 0;\n transition:\n transform 500ms,\n opacity 200ms;\n }\n\n /* Hover effect */\n &:hover {\n box-shadow: var(--notification-hover-shadow);\n }\n\n /* Type-specific left accent border */\n &--success {\n border-left-color: var(--notification-success);\n }\n\n &--error {\n border-left-color: var(--notification-error);\n }\n\n &--warning {\n border-left-color: var(--notification-warning);\n }\n\n &--default {\n border-left-color: var(--notification-info);\n }\n\n &__content-wrapper {\n @apply tw-flex tw-items-center tw-flex-row tw-gap-2;\n }\n\n &__icon {\n @apply tw-shrink-0;\n }\n\n &__content {\n @apply tw-whitespace-pre-line tw-overflow-auto tw-text-sm tw-leading-5;\n @apply tw-max-h-[100px];\n color: var(--notification-content-color);\n }\n\n &__dismiss-button {\n @apply tw-cursor-pointer tw-ml-2\n tw-border-none tw-bg-transparent tw-outline-none tw-p-1 tw-rounded tw-flex tw-items-center tw-justify-center;\n @apply tw-transition-colors tw-duration-150;\n color: var(--notification-dismiss-color);\n\n &:hover {\n color: var(--notification-dismiss-hover-color);\n }\n\n &:focus-visible {\n @apply tw-ring-[3px] tw-outline-none;\n ring-color: var(--notification-focus-ring-color);\n }\n }\n\n /* Expanded hover gap pseudo — extends hit area between toasts */\n &[data-expanded=\"true\"]::after {\n content: \"\";\n position: absolute;\n left: 0;\n height: calc(var(--gap, 14px) + 1px);\n bottom: 100%;\n width: 100%;\n }\n\n /* Swipe-to-dismiss */\n &[data-swiping=\"true\"] {\n transform: var(--y) translateX(var(--swipe-amount-x, 0px));\n transition: none;\n cursor: grabbing;\n user-select: none;\n }\n\n &[data-swiped-out=\"true\"] {\n pointer-events: none;\n }\n\n /* Swiping pseudo — extends hit area to prevent accidental mouse-leave */\n &[data-swiping=\"true\"]::before {\n content: \"\";\n position: absolute;\n left: -100%;\n right: -100%;\n height: 100%;\n z-index: var(--z-local-below);\n }\n\n /* Reduced motion */\n @media (prefers-reduced-motion: reduce) {\n transition: none !important;\n animation: none !important;\n }\n}\n</style>\n","<template>\n <nav\n class=\"vc-pagination\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_PAGINATION.LABEL')\"\n >\n <!-- Pagination Controls -->\n <div class=\"vc-pagination__controls\">\n <!-- First page button -->\n <button\n v-if=\"effectiveShowFirstLast\"\n type=\"button\"\n class=\"vc-pagination__item\"\n :class=\"{ 'vc-pagination__item--disabled': localCurrentPage === 1 }\"\n :disabled=\"localCurrentPage === 1\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_PAGINATION.FIRST')\"\n @click=\"setPage(1)\"\n >\n <VcIcon\n icon=\"lucide-chevrons-left\"\n aria-hidden=\"true\"\n ></VcIcon>\n </button>\n\n <!-- Previous page button -->\n <button\n type=\"button\"\n class=\"vc-pagination__item\"\n :class=\"{ 'vc-pagination__item--disabled': localCurrentPage === 1 }\"\n :disabled=\"localCurrentPage === 1\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_PAGINATION.PREVIOUS')\"\n @click=\"setPage(localCurrentPage - 1)\"\n >\n <VcIcon\n icon=\"lucide-chevron-left\"\n aria-hidden=\"true\"\n ></VcIcon>\n </button>\n\n <button\n v-for=\"page in pagesToShow\"\n :key=\"page\"\n type=\"button\"\n class=\"vc-pagination__item\"\n :class=\"{\n 'vc-pagination__item--current': page === localCurrentPage,\n 'vc-pagination__item--hover': page !== localCurrentPage,\n }\"\n :aria-current=\"page === localCurrentPage ? 'page' : undefined\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_PAGINATION.PAGE', { page })\"\n @click=\"setPage(page)\"\n >\n {{ page }}\n </button>\n\n <!-- Next page button -->\n <button\n type=\"button\"\n class=\"vc-pagination__item\"\n :class=\"{ 'vc-pagination__item--disabled': localCurrentPage === pages }\"\n :disabled=\"localCurrentPage === pages\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_PAGINATION.NEXT')\"\n @click=\"setPage(localCurrentPage + 1)\"\n >\n <VcIcon\n icon=\"lucide-chevron-right\"\n aria-hidden=\"true\"\n ></VcIcon>\n </button>\n\n <!-- Last page button -->\n <button\n v-if=\"effectiveShowFirstLast\"\n type=\"button\"\n class=\"vc-pagination__item\"\n :class=\"{ 'vc-pagination__item--disabled': localCurrentPage === pages }\"\n :disabled=\"localCurrentPage === pages\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_PAGINATION.LAST')\"\n @click=\"setPage(pages)\"\n >\n <VcIcon\n icon=\"lucide-chevrons-right\"\n aria-hidden=\"true\"\n ></VcIcon>\n </button>\n </div>\n </nav>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed, watch } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\nexport interface Props {\n expanded?: boolean;\n pages?: number;\n currentPage?: number;\n variant?: \"default\" | \"minimal\";\n /** Override the number of page buttons to show. When set, takes priority over the isMobile-based default (3 mobile / 5 desktop). */\n maxPages?: number;\n /** Whether to show first/last page navigation buttons (« »). Defaults to true. */\n showFirstLast?: boolean;\n}\n\nexport interface Emits {\n (event: \"itemClick\", pages: number): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n pages: 1,\n currentPage: 1,\n variant: \"default\",\n maxPages: undefined,\n showFirstLast: undefined,\n});\n\nconst emit = defineEmits<Emits>();\n\nconst { isMobile } = useResponsive();\n\n/** Number of page buttons to show on mobile devices */\nconst MAX_PAGES_MOBILE = 3;\n/** Number of page buttons to show on desktop devices */\nconst MAX_PAGES_DESKTOP = 5;\n\nconst localCurrentPage = ref(props.currentPage);\n\nwatch(\n () => props.currentPage,\n (newValue) => {\n localCurrentPage.value = newValue;\n },\n { immediate: true },\n);\n\n/** Resolved showFirstLast — prop wins, otherwise true by default */\nconst effectiveShowFirstLast = computed(() => props.showFirstLast ?? true);\n\nconst setPage = (page: number | string) => {\n if (typeof page === \"undefined\" || (typeof page === \"number\" && isNaN(page))) return;\n const pageNumber = typeof page === \"string\" ? parseInt(page) : page;\n if (pageNumber < 1 || pageNumber > props.pages) return;\n localCurrentPage.value = pageNumber;\n emit(\"itemClick\", pageNumber);\n};\n\nconst pagesToShow = computed(() => {\n const pages = [];\n const totalPages = props.pages;\n const current = localCurrentPage.value;\n const maxPages = props.maxPages ?? (isMobile.value ? MAX_PAGES_MOBILE : MAX_PAGES_DESKTOP);\n\n if (maxPages === 0) return [];\n\n if (totalPages <= maxPages) {\n for (let i = 1; i <= totalPages; i++) {\n pages.push(i);\n }\n } else {\n let start = Math.max(1, current - Math.floor(maxPages / 2));\n const end = Math.min(start + maxPages - 1, totalPages);\n\n if (end - start + 1 < maxPages) {\n start = Math.max(1, end - maxPages + 1);\n }\n\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n }\n\n return pages;\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --pagination-item-width: 29px;\n --pagination-item-height: 29px;\n --pagination-item-color: var(--neutrals-500);\n --pagination-item-color-hover: var(--primary-500);\n --pagination-item-color-current: var(--additional-50);\n --pagination-item-color-disabled: var(--neutrals-400);\n --pagination-item-background-color: var(--additional-50);\n --pagination-item-background-color-hover: var(--primary-100);\n --pagination-item-background-color-current: var(--primary-500);\n --pagination-item-background-color-disabled: var(--neutrals-100);\n --pagination-item-border-color: var(--secondary-100);\n --pagination-item-border-color-hover: var(--neutrals-200);\n --pagination-item-border-color-current: var(--neutrals-200);\n --pagination-item-border-color-disabled: var(--neutrals-200);\n --pagination-focus-ring-color: var(--primary-100);\n}\n\n.vc-pagination {\n display: flex;\n align-items: center;\n\n &__controls {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n &__item {\n @apply tw-flex tw-items-center tw-justify-center tw-w-[var(--pagination-item-width)]\n tw-h-[var(--pagination-item-height)]\n tw-rounded-full\n tw-text-[color:var(--pagination-item-color)]\n tw-box-border tw-border-none tw-bg-transparent tw-outline-none\n tw-transition tw-duration-200\n tw-select-none tw-text-xs tw-cursor-pointer tw-shrink-0 tw-font-semibold;\n\n &:hover:not(:disabled) {\n @apply tw-bg-[color:var(--pagination-item-background-color-hover)]\n tw-text-[color:var(--pagination-item-color-hover)]\n tw-cursor-pointer;\n }\n\n &:focus-visible {\n @apply tw-ring-[3px] tw-ring-[color:var(--pagination-focus-ring-color)] tw-outline-none;\n }\n\n &--current,\n &--current:hover {\n @apply tw-bg-[color:var(--pagination-item-background-color-current)]\n tw-text-[color:var(--pagination-item-color-current)]\n tw-cursor-auto;\n }\n\n &:disabled,\n &--disabled {\n @apply tw-bg-[color:var(--pagination-item-background-color-disabled)]\n tw-text-[color:var(--pagination-item-color-disabled)]\n tw-cursor-not-allowed tw-opacity-50;\n }\n\n &--hover {\n @apply hover:tw-bg-[color:var(--pagination-item-background-color-hover)]\n hover:tw-text-[color:var(--pagination-item-color-hover)] tw-cursor-pointer;\n }\n }\n}\n</style>\n","import _Pagination from \"@ui/components/molecules/vc-pagination/vc-pagination.vue\";\r\n\r\nexport const VcPagination = _Pagination as typeof _Pagination;\r\n","<template>\n <div\n v-if=\"bladeLoading\"\n class=\"vc-rating vc-rating--skeleton\"\n >\n <VcSkeleton\n v-for=\"i in 5\"\n :key=\"i\"\n variant=\"circle\"\n :width=\"20\"\n :height=\"20\"\n />\n </div>\n <div\n v-else\n class=\"vc-rating\"\n >\n <!-- Rating label -->\n <VcLabel\n v-if=\"label\"\n class=\"vc-rating__label\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >\n <span>{{ tooltip }}</span>\n </template>\n </VcLabel>\n\n <!-- Rating display -->\n <div\n class=\"vc-rating__content\"\n role=\"img\"\n :aria-label=\"modelValue ? `Rating: ${modelValue} out of ${max}` : placeholder || 'No rating'\"\n >\n <template v-if=\"modelValue\">\n <template v-if=\"variant === 'stars'\">\n <div class=\"vc-rating__stars\">\n <VcIcon\n v-for=\"index in modelValue\"\n :key=\"index\"\n icon=\"lucide-star\"\n class=\"vc-rating__icon\"\n ></VcIcon>\n <VcIcon\n v-for=\"index in max - modelValue\"\n :key=\"index\"\n icon=\"lucide-star\"\n class=\"vc-rating__icon vc-rating__icon--empty\"\n ></VcIcon>\n </div>\n </template>\n <template v-else>\n <div class=\"vc-rating__text-container\">\n <VcIcon\n v-if=\"variant === 'star-and-text'\"\n icon=\"lucide-star\"\n class=\"vc-rating__icon\"\n ></VcIcon>\n <span class=\"vc-rating__rating\">{{ modelValue }}/{{ max }}</span>\n <slot name=\"details\"></slot>\n </div>\n </template>\n </template>\n <template v-else>\n <span class=\"vc-rating__placeholder\">{{ placeholder }}</span>\n </template>\n </div>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport { VNode } from \"vue\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\n\nconst bladeLoading = useBladeLoading();\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport type { IFormFieldProps } from \"@ui/types/form-field\";\n\nexport interface VcRatingProps extends IFormFieldProps {\n placeholder?: string;\n modelValue?: number;\n max?: number;\n variant?: \"stars\" | \"star-and-text\" | \"text\";\n}\n\nwithDefaults(defineProps<VcRatingProps>(), { max: 5, variant: \"stars\" });\n\ndefineSlots<{\n details: (props: Record<string, never>) => VNode[];\n}>();\n</script>\n\n<style lang=\"scss\">\n:root {\n --rating-placeholder-color: var(--neutrals-400);\n --rating-star-size: 1em;\n --rating-gap: 2px;\n\n --rating-special-color: var(--warning-500);\n --rating-special-color-hover: var(--warning-600);\n --rating-special-color-disabled: var(--warning-200);\n}\n\n.vc-rating {\n @apply tw-flex tw-flex-col tw-align-middle;\n\n &--skeleton {\n @apply tw-flex tw-flex-row tw-gap-1;\n }\n\n &__content {\n @apply tw-flex tw-flex-row tw-items-center;\n }\n\n &__stars {\n @apply tw-flex tw-flex-row tw-items-center;\n gap: var(--rating-gap);\n }\n\n &__text-container {\n @apply tw-flex tw-flex-row tw-items-center;\n }\n\n &__placeholder {\n @apply tw-text-[color:var(--rating-placeholder-color)];\n }\n\n &__icon {\n @apply tw-text-[color:var(--rating-special-color)];\n font-size: var(--rating-star-size);\n\n &--empty {\n @apply tw-opacity-40;\n }\n }\n\n &__rating {\n @apply tw-mr-1;\n }\n\n &__label {\n @apply tw-mb-1;\n }\n}\n</style>\n","<template>\n <div\n v-if=\"bladeLoading\"\n class=\"vc-slider vc-slider--skeleton\"\n >\n <VcSkeleton\n variant=\"block\"\n width=\"100%\"\n :height=\"20\"\n />\n </div>\n <div\n v-else\n class=\"vc-slider tw-relative\"\n role=\"region\"\n :aria-label=\"ariaLabel || 'Content carousel'\"\n >\n <!-- eslint-disable vue/no-deprecated-filter -- TS union type, not a Vue 2 filter -->\n <swiper\n class=\"vc-slider__swiper\"\n :class=\"{\n 'vc-slider__swiper_overflow-visible': overflow,\n 'vc-slider__swiper_navigation': navigation,\n }\"\n :modules=\"modules\"\n :space-between=\"spaceBetweenSlides\"\n :navigation=\"navigation ? buttonsList : false\"\n :slides-per-view=\"slidesPerView as number | 'auto' | undefined\"\n :observer=\"true\"\n :observe-parents=\"true\"\n >\n <!-- eslint-enable vue/no-deprecated-filter -->\n <swiper-slide\n v-for=\"(slide, i) in slides\"\n :key=\"i\"\n >\n <slot :slide=\"slide\"></slot>\n </swiper-slide>\n </swiper>\n <!-- Navigation buttons-->\n <div v-show=\"navigation\">\n <div class=\"vc-slider__prev tw-left-0\">\n <slot name=\"prevBtn\">\n <button\n type=\"button\"\n class=\"vc-slider__btn\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_SLIDER.PREVIOUS')\"\n >\n <VcIcon\n icon=\"lucide-chevron-left\"\n aria-hidden=\"true\"\n ></VcIcon>\n </button>\n </slot>\n </div>\n <div class=\"vc-slider__next tw-right-0\">\n <slot name=\"nextBtn\">\n <button\n type=\"button\"\n class=\"vc-slider__btn\"\n :aria-label=\"$t('COMPONENTS.MOLECULES.VC_SLIDER.NEXT')\"\n >\n <VcIcon\n icon=\"lucide-chevron-right\"\n aria-hidden=\"true\"\n ></VcIcon>\n </button>\n </slot>\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\n\nconst bladeLoading = useBladeLoading();\nimport { computed } from \"vue\";\nimport { Swiper, SwiperSlide } from \"swiper/vue\";\nimport { Navigation } from \"swiper/modules\";\nimport \"swiper/css\";\nimport \"swiper/css/navigation\";\n\nexport interface Props {\n slides?: Record<string, unknown>[] | unknown[];\n navigation?: boolean;\n overflow?: boolean;\n slidesPerView?: string | \"auto\";\n spaceBetweenSlides?: number;\n ariaLabel?: string;\n}\n\nwithDefaults(defineProps<Props>(), {\n slides: () => [],\n slidesPerView: \"auto\",\n spaceBetweenSlides: 10,\n});\n\nconst modules = [Navigation];\n\nconst buttonsList = computed(() => ({\n nextEl: \".vc-slider__next\",\n prevEl: \".vc-slider__prev\",\n}));\n</script>\n\n<style lang=\"scss\">\n:root {\n --slider-button-background: var(--additional-50);\n --slider-button-border: var(--neutrals-300);\n --slider-button-text: var(--primary-500);\n --slider-button-text-disabled: var(--neutrals-400);\n --slider-button-border-radius: 6px;\n --slider-focus-ring-color: var(--primary-100);\n}\n\n.vc-slider {\n &__swiper {\n .swiper-slide {\n @apply tw-w-auto;\n }\n\n &.vc-slider__swiper_overflow-visible {\n @apply tw-overflow-visible;\n }\n\n &.vc-slider__swiper_navigation {\n @apply tw-px-10;\n }\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-1.5;\n }\n\n &__next,\n &__prev {\n @apply tw-absolute tw-top-2/4 -tw-translate-y-2/4 tw-z-[var(--z-local-above)];\n\n &.swiper-button-disabled .vc-slider__btn {\n @apply tw-text-[var(--slider-button-text-disabled)];\n }\n }\n\n &__btn {\n @apply tw-bg-[var(--slider-button-background)] tw-border tw-border-solid tw-border-[var(--slider-button-border)];\n @apply tw-box-border tw-flex tw-items-center tw-justify-center tw-cursor-pointer tw-outline-none;\n @apply tw-text-[var(--slider-button-text)] tw-w-8 tw-h-8;\n @apply tw-transition tw-duration-200;\n border-radius: var(--slider-button-border-radius);\n\n &:focus-visible {\n @apply tw-ring-[3px] tw-ring-[color:var(--slider-focus-ring-color)] tw-outline-none;\n }\n\n &:disabled {\n @apply tw-opacity-50 tw-cursor-not-allowed;\n }\n }\n\n &__prev {\n }\n\n &__next {\n }\n}\n</style>\n","import { VNode } from \"vue\";\nimport _Slider from \"@ui/components/molecules/vc-slider/vc-slider.vue\";\n\nexport const VcSlider = _Slider as typeof _Slider & {\n new (): {\n $slots: {\n default: (args: { slide: Record<string, unknown> }) => VNode[];\n prevBtn: () => VNode[];\n nextBtn: () => VNode[];\n };\n };\n};\n","<template>\n <div\n ref=\"triggerRef\"\n class=\"vc-multivalue__field-wrapper\"\n :role=\"isDictionaryMode ? 'combobox' : undefined\"\n :tabindex=\"isDictionaryMode ? 0 : undefined\"\n :aria-expanded=\"isDictionaryMode ? isOpened : undefined\"\n :aria-haspopup=\"isDictionaryMode ? 'listbox' : undefined\"\n :aria-controls=\"isDictionaryMode && isOpened ? listboxId : undefined\"\n :aria-labelledby=\"labelId\"\n :aria-describedby=\"ariaDescribedBy\"\n :aria-required=\"ariaRequired\"\n :aria-invalid=\"error || undefined\"\n >\n <div\n v-if=\"$slots['prepend']\"\n class=\"vc-multivalue__prepend\"\n >\n <slot name=\"prepend\" />\n </div>\n\n <div class=\"vc-multivalue__control\">\n <div class=\"vc-multivalue__content\">\n <!-- Selected chips -->\n <div\n v-for=\"(item, i) in modelValue\"\n :key=\"item?.[optionValue as keyof typeof item] ?? i\"\n class=\"vc-multivalue__chip-wrapper\"\n >\n <div\n v-if=\"item\"\n class=\"vc-multivalue__chip\"\n >\n <!-- Color square for color type -->\n <div\n v-if=\"type === 'color'\"\n class=\"vc-multivalue__color-square\"\n :style=\"{ backgroundColor: (item as any).colorCode || '#cccccc' }\"\n @click=\"emit('openColorPicker', i)\"\n >\n <input\n :ref=\"(el) => emit('setColorPickerRef', el as HTMLInputElement, i)\"\n type=\"color\"\n class=\"vc-multivalue__color-picker-hidden\"\n :value=\"(item as any).colorCode || '#000000'\"\n @change=\"(e) => emit('colorChange', e, i)\"\n />\n </div>\n\n <slot\n name=\"selected-item\"\n :value=\"formatValue(item)\"\n :item=\"item\"\n :index=\"i\"\n :remove=\"() => emit('remove', i)\"\n >\n <span class=\"vc-multivalue__chip-label\">{{ formatValue(item) }}</span>\n </slot>\n <VcIcon\n v-if=\"!disabled\"\n class=\"vc-multivalue__chip-remove\"\n icon=\"lucide-x\"\n size=\"xs\"\n tabindex=\"0\"\n role=\"button\"\n :aria-label=\"$t('COMPONENTS.CONTROLS.DELETE_ITEM')\"\n @click=\"emit('remove', i)\"\n @keydown.enter=\"emit('remove', i)\"\n @keydown.space=\"emit('remove', i)\"\n />\n </div>\n </div>\n\n <!-- Dictionary mode: Add button -->\n <template v-if=\"isDictionaryMode\">\n <button\n class=\"vc-multivalue__add-button\"\n :disabled=\"disabled\"\n tabindex=\"0\"\n type=\"button\"\n @click.stop=\"emit('toggleDropdown')\"\n >\n <VcIcon\n icon=\"lucide-plus\"\n size=\"xs\"\n />\n <span>{{ $t(\"COMPONENTS.MOLECULES.VC_MULTIVALUE.ADD\") }}</span>\n </button>\n </template>\n\n <!-- Input mode: text input -->\n <template v-else>\n <input\n :value=\"inputValue\"\n class=\"vc-multivalue__input\"\n :placeholder=\"placeholder\"\n :type=\"htmlInputType\"\n :disabled=\"disabled\"\n :aria-invalid=\"error || undefined\"\n :aria-required=\"ariaRequired\"\n :aria-labelledby=\"labelId\"\n :aria-describedby=\"ariaDescribedBy\"\n tabindex=\"0\"\n @input=\"emit('inputChange', ($event.target as HTMLInputElement).value)\"\n @keypress.enter.stop.prevent=\"emit('inputSubmit', $event)\"\n @blur=\"onInputBlur\"\n @keydown=\"emit('keyDown', $event)\"\n @focus=\"emit('focus')\"\n />\n </template>\n </div>\n\n <!-- Clearable button -->\n <div\n v-if=\"clearable && modelValue && modelValue.length > 0 && !disabled\"\n class=\"vc-multivalue__clear\"\n role=\"button\"\n :aria-label=\"$t('COMPONENTS.CONTROLS.CLEAR_ALL')\"\n tabindex=\"0\"\n @click=\"emit('clearAll')\"\n @keydown.enter=\"emit('clearAll')\"\n @keydown.space=\"emit('clearAll')\"\n >\n <VcIcon\n size=\"xs\"\n icon=\"lucide-x\"\n />\n </div>\n\n <!-- Loading -->\n <div\n v-if=\"loading\"\n class=\"vc-multivalue__loading\"\n >\n <VcIcon\n icon=\"lucide-loader-2\"\n class=\"tw-animate-spin\"\n size=\"m\"\n />\n </div>\n </div>\n\n <div\n v-if=\"$slots['append']\"\n class=\"vc-multivalue__append\"\n >\n <slot name=\"append\" />\n </div>\n </div>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { ref } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\ndefineProps<{\n modelValue?: any[];\n isDictionaryMode: boolean;\n type: string;\n htmlInputType: string;\n placeholder?: string;\n disabled?: boolean;\n error?: boolean;\n loading?: boolean;\n clearable?: boolean;\n optionValue: string;\n inputValue?: string;\n formatValue: (item: any) => any;\n isOpened?: boolean;\n labelId?: string;\n listboxId?: string;\n ariaDescribedBy?: string;\n ariaRequired?: boolean | undefined;\n}>();\n\nconst emit = defineEmits<{\n remove: [index: number];\n toggleDropdown: [];\n inputSubmit: [event: KeyboardEvent | FocusEvent];\n inputChange: [value: string];\n keyDown: [event: KeyboardEvent];\n focus: [];\n blur: [];\n clearAll: [];\n openColorPicker: [index: number];\n setColorPickerRef: [el: HTMLInputElement, index: number];\n colorChange: [event: Event, index: number];\n}>();\n\ndefineSlots<{\n \"selected-item\": (scope: { value: any; item: any; index: number; remove: () => void }) => any;\n prepend: (props: any) => any;\n append: (props: any) => any;\n}>();\n\nconst triggerRef = ref<HTMLElement | null>(null);\n\nfunction onInputBlur(e: FocusEvent) {\n emit(\"inputSubmit\", e);\n emit(\"blur\");\n}\n\ndefineExpose({\n triggerRef,\n});\n</script>\n","<template>\n <teleport :to=\"teleportTarget\">\n <Transition name=\"multivalue-dropdown\">\n <div\n v-if=\"isOpened\"\n :id=\"listboxId\"\n ref=\"dropdownElRef\"\n v-on-click-outside=\"[() => emit('clickOutside'), { ignore: [dropdownToggleRef] }]\"\n class=\"vc-multivalue__dropdown\"\n role=\"listbox\"\n :aria-label=\"ariaLabel\"\n :style=\"dropdownStyle\"\n @wheel=\"onDropdownWheel\"\n >\n <input\n ref=\"searchInputRef\"\n class=\"vc-multivalue__search\"\n tabindex=\"0\"\n :aria-label=\"$t('COMPONENTS.CONTROLS.SEARCH_OPTIONS')\"\n autocomplete=\"off\"\n @input=\"emit('search', $event)\"\n @keydown.space.stop\n @keydown.enter.stop\n />\n\n <!-- Scroll up button -->\n <div\n class=\"vc-multivalue__scroll-button\"\n :class=\"{ 'tw-opacity-0 tw-pointer-events-none': !canScrollUp }\"\n aria-hidden=\"true\"\n @pointerenter=\"startScroll('up')\"\n @pointerleave=\"stopScroll\"\n >\n <VcIcon\n icon=\"lucide-chevron-up\"\n size=\"xs\"\n />\n </div>\n\n <!-- Scrollable viewport -->\n <div\n ref=\"viewportRef\"\n class=\"vc-multivalue__viewport\"\n @scroll=\"updateScrollState\"\n >\n <div\n v-for=\"(item, i) in availableOptions\"\n :key=\"i\"\n class=\"vc-multivalue__item\"\n tabindex=\"0\"\n role=\"option\"\n :data-index=\"i\"\n @click=\"emit('select', item)\"\n >\n <slot\n name=\"option\"\n :item=\"item\"\n :index=\"i\"\n >\n {{ item[optionLabel as keyof typeof item] }}\n </slot>\n </div>\n\n <!-- No options message -->\n <div\n v-if=\"availableOptions.length === 0\"\n class=\"vc-multivalue__no-options\"\n >\n {{ $t(\"COMPONENTS.MOLECULES.VC_SELECT.NO_OPTIONS\") }}\n </div>\n </div>\n\n <!-- Scroll down button -->\n <div\n class=\"vc-multivalue__scroll-button\"\n :class=\"{ 'tw-opacity-0 tw-pointer-events-none': !canScrollDown }\"\n aria-hidden=\"true\"\n @pointerenter=\"startScroll('down')\"\n @pointerleave=\"stopScroll\"\n >\n <VcIcon\n icon=\"lucide-chevron-down\"\n size=\"xs\"\n />\n </div>\n </div>\n </Transition>\n </teleport>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { ref, watch, onBeforeUnmount, nextTick } from \"vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useTeleportTarget } from \"@ui/composables\";\n\nconst props = defineProps<{\n isOpened: boolean;\n dropdownStyle: Record<string, string | undefined>;\n availableOptions: any[];\n optionLabel: string;\n ariaLabel: string;\n listboxId?: string;\n dropdownToggleRef: HTMLElement | null;\n}>();\n\nconst emit = defineEmits<{\n select: [item: any];\n search: [event: Event];\n clickOutside: [];\n}>();\n\ndefineSlots<{\n option: (scope: { item: any; index: number }) => any;\n}>();\n\nconst dropdownElRef = ref<HTMLElement | null>(null);\nconst searchInputRef = ref<HTMLInputElement | null>(null);\nconst viewportRef = ref<HTMLElement | null>(null);\nconst { teleportTarget } = useTeleportTarget();\n\n// --- Scroll arrow state ---\nconst canScrollUp = ref(false);\nconst canScrollDown = ref(false);\nlet scrollAnimationId: number | null = null;\n\nfunction updateScrollState() {\n const el = viewportRef.value;\n if (!el) {\n canScrollUp.value = false;\n canScrollDown.value = false;\n return;\n }\n canScrollUp.value = el.scrollTop > 0;\n canScrollDown.value = Math.ceil(el.scrollTop) < el.scrollHeight - el.clientHeight;\n}\n\nfunction startScroll(direction: \"up\" | \"down\") {\n stopScroll();\n const el = viewportRef.value;\n if (!el) return;\n\n const speed = 2; // px per frame (~120px/s at 60fps) — smooth\n function tick() {\n if (!el) return;\n el.scrollTop += direction === \"up\" ? -speed : speed;\n updateScrollState();\n scrollAnimationId = requestAnimationFrame(tick);\n }\n scrollAnimationId = requestAnimationFrame(tick);\n}\n\nfunction stopScroll() {\n if (scrollAnimationId !== null) {\n cancelAnimationFrame(scrollAnimationId);\n scrollAnimationId = null;\n }\n}\n\nfunction onDropdownWheel(event: WheelEvent) {\n const el = viewportRef.value;\n if (!el) return;\n\n const isInViewport = el.contains(event.target as Node);\n\n if (isInViewport) {\n // Native scroll handles viewport scrolling.\n // Only prevent page scroll at boundaries.\n const atTop = el.scrollTop <= 0 && event.deltaY < 0;\n const atBottom = Math.ceil(el.scrollTop) >= el.scrollHeight - el.clientHeight && event.deltaY > 0;\n if (atTop || atBottom) {\n event.preventDefault();\n }\n } else {\n // Cursor is on scroll buttons, search, or other non-viewport area —\n // forward the wheel event to the viewport manually.\n event.preventDefault();\n el.scrollTop += event.deltaY;\n }\n updateScrollState();\n}\n\nwatch(\n () => props.isOpened,\n (opened) => {\n if (opened) {\n nextTick(updateScrollState);\n } else {\n stopScroll();\n canScrollUp.value = false;\n canScrollDown.value = false;\n }\n },\n);\n\nwatch(\n () => props.availableOptions.length,\n () => {\n if (props.isOpened) {\n nextTick(updateScrollState);\n }\n },\n);\n\nonBeforeUnmount(() => {\n stopScroll();\n});\n\ndefineExpose({\n dropdownElRef,\n searchInputRef,\n viewportRef,\n});\n</script>\n","import { computed } from \"vue\";\r\n\r\nexport type MultivalueType = \"text\" | \"number\" | \"integer\" | \"color\";\r\n\r\ninterface UseMultivalueModeOptions {\r\n multivalue: () => boolean | undefined;\r\n type: () => MultivalueType;\r\n}\r\n\r\n/**\r\n * Determines the operating mode of vc-multivalue:\r\n * - dictionary mode (multivalue=true): select from dropdown options\r\n * - input mode (multivalue=false): type values manually\r\n *\r\n * Also resolves the HTML input type from the logical type.\r\n */\r\nexport function useMultivalueMode(options: UseMultivalueModeOptions) {\r\n const isDictionaryMode = computed(() => options.multivalue() === true);\r\n\r\n /** Maps logical type → HTML input type */\r\n const htmlInputType = computed(() => {\r\n const t = options.type();\r\n if (t === \"integer\") return \"number\";\r\n if (t === \"color\") return \"text\";\r\n return t;\r\n });\r\n\r\n return {\r\n isDictionaryMode,\r\n htmlInputType,\r\n };\r\n}\r\n","import { computed, type ComputedRef } from \"vue\";\r\nimport type { MultivalueType } from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueMode\";\r\n\r\ninterface UseMultivalueValuesOptions<T> {\r\n modelValue: () => T[];\r\n optionLabel: () => string;\r\n type: () => MultivalueType;\r\n emit: {\r\n updateModelValue: (val: T[]) => void;\r\n };\r\n}\r\n\r\n/**\r\n * Manages the value list: formatting display values, adding, removing, and clearing items.\r\n */\r\nexport function useMultivalueValues<T>(options: UseMultivalueValuesOptions<T>) {\r\n const formatValue: ComputedRef<(item: T) => string | number | T[keyof T]> = computed(() => {\r\n return (item: T) => {\r\n const label = item[options.optionLabel() as keyof T];\r\n const t = options.type();\r\n if (t === \"number\") {\r\n return Number(label).toFixed(3);\r\n } else if (t === \"integer\") {\r\n return Math.trunc(+label);\r\n }\r\n return label;\r\n };\r\n });\r\n\r\n function removeAtIndex(index: number) {\r\n const result = [...options.modelValue()];\r\n result.splice(index, 1);\r\n options.emit.updateModelValue(result);\r\n }\r\n\r\n function clearAll() {\r\n options.emit.updateModelValue([]);\r\n }\r\n\r\n function addItem(item: T) {\r\n options.emit.updateModelValue([...options.modelValue(), item]);\r\n }\r\n\r\n return {\r\n formatValue,\r\n removeAtIndex,\r\n clearAll,\r\n addItem,\r\n };\r\n}\r\n","import { ref } from \"vue\";\r\nimport { convertColorNameToHex } from \"@core/utilities\";\r\nimport type { MultivalueType } from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueMode\";\r\n\r\ninterface UseMultivalueInputOptions<T> {\r\n type: () => MultivalueType;\r\n optionLabel: () => string;\r\n addItem: (item: T) => void;\r\n}\r\n\r\n/**\r\n * Handles manual text input mode (multivalue=false):\r\n * - Input value state\r\n * - Enter key to add\r\n * - Blur to add\r\n * - Key filtering for number/integer types\r\n * - Color name → hex conversion for color type\r\n */\r\nexport function useMultivalueInput<T>(options: UseMultivalueInputOptions<T>) {\r\n const inputValue = ref<string>();\r\n\r\n function onInputSubmit(e: KeyboardEvent | FocusEvent) {\r\n const newValue = (e.target as HTMLInputElement).value;\r\n if (newValue === \"\" || newValue === undefined || newValue === null) {\r\n return;\r\n }\r\n\r\n const t = options.type();\r\n if (t === \"color\") {\r\n const hexColor = convertColorNameToHex(newValue);\r\n options.addItem({\r\n [options.optionLabel()]: newValue,\r\n colorCode: hexColor || \"#000000\",\r\n } as unknown as T);\r\n } else {\r\n options.addItem({ [options.optionLabel()]: newValue } as T);\r\n }\r\n inputValue.value = undefined;\r\n }\r\n\r\n function onKeyDown(e: KeyboardEvent) {\r\n const key = e.key;\r\n const t = options.type();\r\n const allowedKeys = [\"Backspace\", \"Delete\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\", \"Enter\", \"Tab\"];\r\n\r\n if (t === \"number\" || t === \"integer\") {\r\n if (key === \"-\" || key === \"e\" || key === \"+\") {\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n if (t === \"integer\") {\r\n if (!/^\\d$/.test(key) && !allowedKeys.includes(key)) {\r\n e.preventDefault();\r\n }\r\n }\r\n }\r\n\r\n return {\r\n inputValue,\r\n onInputSubmit,\r\n onKeyDown,\r\n };\r\n}\r\n","import { ref } from \"vue\";\r\n\r\ninterface UseMultivalueColorOptions<T> {\r\n modelValue: () => T[];\r\n emit: {\r\n updateModelValue: (val: T[]) => void;\r\n };\r\n}\r\n\r\n/**\r\n * Manages color picker logic for color-type multivalue:\r\n * - Stores refs to hidden <input type=\"color\"> elements\r\n * - Opens native color picker on color square click\r\n * - Updates colorCode on color change\r\n */\r\nexport function useMultivalueColor<T>(options: UseMultivalueColorOptions<T>) {\r\n const colorPickerRefs = ref<Map<number, HTMLInputElement>>(new Map());\r\n\r\n function setColorPickerRef(el: HTMLInputElement | null, index: number) {\r\n if (el) {\r\n colorPickerRefs.value.set(index, el);\r\n } else {\r\n colorPickerRefs.value.delete(index);\r\n }\r\n }\r\n\r\n function openColorPicker(index: number) {\r\n const picker = colorPickerRefs.value.get(index);\r\n picker?.click();\r\n }\r\n\r\n function handleColorChange(event: Event, index: number) {\r\n const target = event.target as HTMLInputElement;\r\n if (target?.value) {\r\n const updatedValues = [...options.modelValue()];\r\n updatedValues[index] = {\r\n ...updatedValues[index],\r\n colorCode: target.value,\r\n };\r\n options.emit.updateModelValue(updatedValues);\r\n }\r\n }\r\n\r\n return {\r\n colorPickerRefs,\r\n setColorPickerRef,\r\n openColorPicker,\r\n handleColorChange,\r\n };\r\n}\r\n","import { ref, computed, watch, nextTick, type Ref } from \"vue\";\nimport { offset, flip, shift, type Middleware } from \"@floating-ui/vue\";\nimport { useKeyboardNavigation } from \"@core/composables/useKeyboardNavigation\";\nimport { useFloatingPosition } from \"@ui/composables\";\n\ntype FloatingInstanceType = ReturnType<typeof useFloatingPosition> & {\n middlewareData: Ref<{\n sameWidth?: {\n width?: string;\n };\n }>;\n};\n\ninterface UseMultivalueDropdownOptions {\n disabled: () => boolean;\n onItemSelect: (index: number) => void;\n emit: {\n close: () => void;\n };\n}\n\n/**\n * Manages dropdown visibility, Floating UI positioning, and keyboard navigation.\n * Mirrors the pattern from useSelectDropdown.\n */\nexport function useMultivalueDropdown(options: UseMultivalueDropdownOptions) {\n const isOpened = ref(false);\n const isFocused = ref(false);\n const dropdownToggleRef = ref<HTMLElement | null>(null);\n const dropdownRef = ref<HTMLElement | null>(null);\n const searchRef = ref<HTMLInputElement | null>(null);\n\n function sameWidth(): Middleware {\n return {\n name: \"sameWidth\",\n fn({ rects }) {\n return {\n data: {\n width: `${rects.reference.width}px`,\n },\n };\n },\n };\n }\n\n const popper = useFloatingPosition(dropdownToggleRef, dropdownRef, {\n placement: \"bottom\",\n middleware: computed(() => [\n flip({ fallbackPlacements: [\"top\", \"bottom\"] }),\n shift({ mainAxis: false }),\n sameWidth(),\n offset({ mainAxis: 4 }),\n ]),\n }) as FloatingInstanceType;\n\n const dropdownStyle = computed(() => ({\n top: `${popper.y.value ?? 0}px`,\n left: `${popper.x.value ?? 0}px`,\n width: popper.middlewareData.value.sameWidth?.width,\n }));\n\n // Ensure dropdown repositions correctly after initial placement\n watch(\n () => popper.isPositioned.value,\n (newVal) => {\n if (newVal) {\n popper.update();\n }\n },\n );\n\n const keyboardNavigation = useKeyboardNavigation({\n onEnter: (element: HTMLElement) => {\n const index = parseInt(element.getAttribute(\"data-index\") || \"0\", 10);\n options.onItemSelect(index);\n },\n onEscape: () => {\n closeDropdown();\n },\n });\n\n function openDropdown() {\n if (options.disabled()) return;\n\n isOpened.value = true;\n isFocused.value = true;\n\n nextTick(() => {\n if (dropdownRef.value) {\n keyboardNavigation.initKeyboardNavigation(dropdownRef.value);\n searchRef.value?.focus();\n }\n });\n }\n\n function closeDropdown() {\n isOpened.value = false;\n isFocused.value = false;\n keyboardNavigation.cleanupKeyboardNavigation();\n options.emit.close();\n nextTick(() => {\n dropdownToggleRef.value?.focus();\n });\n }\n\n function toggleDropdown() {\n if (isOpened.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n }\n\n return {\n isOpened,\n isFocused,\n dropdownToggleRef,\n dropdownRef,\n searchRef,\n popper,\n dropdownStyle,\n toggleDropdown,\n openDropdown,\n closeDropdown,\n };\n}\n","import { computed } from \"vue\";\r\n\r\ninterface UseMultivalueOptionsOptions<T> {\r\n options: () => T[];\r\n modelValue: () => T[];\r\n optionValue: () => string;\r\n}\r\n\r\n/**\r\n * Filters available options by excluding already-selected items.\r\n * In dictionary mode, only unselected options appear in the dropdown.\r\n */\r\nexport function useMultivalueOptions<T>(options: UseMultivalueOptionsOptions<T>) {\r\n const availableOptions = computed(() => {\r\n const currentOptions = options.options();\r\n const currentValue = options.modelValue();\r\n const valueKey = options.optionValue() as keyof T;\r\n\r\n return currentOptions.filter((opt) => {\r\n return !currentValue.find((selected) => selected[valueKey] === opt[valueKey]);\r\n });\r\n });\r\n\r\n return {\r\n availableOptions,\r\n };\r\n}\r\n","<template>\n <!-- Skeleton mode -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-multivalue vc-multivalue--skeleton\"\n >\n <VcSkeleton\n v-if=\"label\"\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"11\"\n />\n <VcSkeleton\n variant=\"block\"\n width=\"100%\"\n :height=\"36\"\n />\n </div>\n\n <!-- Normal mode -->\n <div\n v-else\n class=\"vc-multivalue\"\n :class=\"[\n `vc-multivalue--${type}`,\n {\n 'vc-multivalue--opened': isOpened,\n 'vc-multivalue--error': invalid,\n 'vc-multivalue--disabled': resolvedDisabled,\n 'vc-multivalue--focused': isFocused,\n 'vc-multivalue--has-hint-or-error': invalid || hint,\n },\n ]\"\n >\n <!-- Label -->\n <VcLabel\n v-if=\"label\"\n :id=\"labelId\"\n class=\"vc-multivalue__label\"\n :required=\"required\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :error=\"invalid\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >\n {{ tooltip }}\n </template>\n </VcLabel>\n\n <!-- Field -->\n <MultivalueTrigger\n ref=\"triggerComponentRef\"\n :model-value=\"modelValue\"\n :is-dictionary-mode=\"isDictionaryMode\"\n :type=\"type\"\n :html-input-type=\"htmlInputType\"\n :placeholder=\"placeholder\"\n :disabled=\"resolvedDisabled\"\n :error=\"invalid\"\n :loading=\"loading\"\n :clearable=\"clearable\"\n :option-value=\"optionValue\"\n :input-value=\"inputValue\"\n :format-value=\"formatValue\"\n :is-opened=\"isOpened\"\n :label-id=\"label ? labelId : undefined\"\n :listbox-id=\"listboxId\"\n :aria-described-by=\"ariaDescribedBy\"\n :aria-required=\"ariaRequired\"\n @remove=\"removeAtIndex\"\n @toggle-dropdown=\"toggleDropdown\"\n @input-submit=\"onInputSubmit\"\n @input-change=\"inputValue = $event\"\n @key-down=\"onKeyDown\"\n @focus=\"isFocused = true\"\n @blur=\"isFocused = false\"\n @clear-all=\"clearAll\"\n @open-color-picker=\"openColorPicker\"\n @set-color-picker-ref=\"setColorPickerRef\"\n @color-change=\"handleColorChange\"\n >\n <template\n v-if=\"$slots['selected-item']\"\n #selected-item=\"scope\"\n >\n <slot\n name=\"selected-item\"\n v-bind=\"scope\"\n />\n </template>\n <template\n v-if=\"$slots['prepend']\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template\n v-if=\"$slots['append']\"\n #append\n >\n <slot name=\"append\" />\n </template>\n </MultivalueTrigger>\n\n <!-- Dropdown (dictionary mode) -->\n <MultivalueDropdown\n v-if=\"isDictionaryMode\"\n ref=\"dropdownComponentRef\"\n :is-opened=\"isOpened\"\n :dropdown-style=\"dropdownStyle\"\n :available-options=\"availableOptions\"\n :option-label=\"optionLabel\"\n v-bind=\"{ ariaLabel: label || name }\"\n :listbox-id=\"listboxId\"\n :dropdown-toggle-ref=\"triggerComponentRef?.triggerRef ?? null\"\n @select=\"onItemSelect\"\n @search=\"onSearch\"\n @click-outside=\"closeDropdown\"\n >\n <template\n v-if=\"$slots['option']\"\n #option=\"scope\"\n >\n <slot\n name=\"option\"\n v-bind=\"scope\"\n />\n </template>\n </MultivalueDropdown>\n\n <!-- Hint / Error -->\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"invalid && errorMessage\">\n <slot name=\"error\">\n <VcHint\n :id=\"errorId\"\n class=\"vc-multivalue__error\"\n :error=\"true\"\n >\n {{ errorMessage }}\n </VcHint>\n </slot>\n </div>\n <div v-else>\n <slot name=\"hint\">\n <VcHint\n v-if=\"hint\"\n :id=\"hintId\"\n class=\"vc-multivalue__hint\"\n >\n {{ hint }}\n </VcHint>\n </slot>\n </div>\n </Transition>\n </div>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup generic=\"T extends { id?: string; colorCode?: string }\">\nimport { ref, computed, watchEffect } from \"vue\";\nimport { useFormField } from \"@ui/composables/useFormField\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport MultivalueTrigger from \"@ui/components/molecules/vc-multivalue/_internal/MultivalueTrigger.vue\";\nimport MultivalueDropdown from \"@ui/components/molecules/vc-multivalue/_internal/MultivalueDropdown.vue\";\nimport {\n useMultivalueMode,\n type MultivalueType,\n} from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueMode\";\nimport { useMultivalueValues } from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueValues\";\nimport { useMultivalueInput } from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueInput\";\nimport { useMultivalueColor } from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueColor\";\nimport { useMultivalueDropdown } from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueDropdown\";\nimport { useMultivalueOptions } from \"@ui/components/molecules/vc-multivalue/composables/useMultivalueOptions\";\nimport type { IFormFieldProps } from \"@ui/types\";\n\nexport interface Props<T> extends IFormFieldProps {\n placeholder?: string;\n modelValue?: T[];\n type?: MultivalueType;\n hint?: string;\n options?: T[];\n optionValue?: string;\n optionLabel?: string;\n multivalue?: boolean;\n multilanguage?: boolean;\n currentLanguage?: string;\n loading?: boolean;\n clearable?: boolean;\n}\n\nexport interface Emits<T> {\n (event: \"update:model-value\", value: T[]): void;\n (event: \"close\"): void;\n (event: \"search\", value: string): void;\n}\n\nconst props = withDefaults(defineProps<Props<T>>(), {\n modelValue: () => [],\n type: \"text\",\n name: \"Field\",\n options: () => [],\n optionValue: \"id\",\n optionLabel: \"title\",\n clearable: false,\n});\n\nconst emit = defineEmits<Emits<T>>();\n\ndefineSlots<{\n option: (args: { item: T; index: number }) => any;\n \"selected-item\": (args: { value: string | number | T[keyof T]; item: T; index: number; remove: () => void }) => any;\n hint: (props: any) => any;\n error: (props: any) => any;\n prepend: (props: any) => any;\n append: (props: any) => any;\n}>();\n\nconst bladeLoading = useBladeLoading();\nconst { fieldId, labelId, errorId, hintId, invalid, resolvedDisabled, ariaRequired, ariaDescribedBy } =\n useFormField(props);\nconst listboxId = computed(() => `${fieldId.value}-listbox`);\n\n// --- Sub-component refs ---\nconst triggerComponentRef = ref<InstanceType<typeof MultivalueTrigger> | null>(null);\nconst dropdownComponentRef = ref<InstanceType<typeof MultivalueDropdown> | null>(null);\n\n// --- Composables ---\n\nconst { isDictionaryMode, htmlInputType } = useMultivalueMode({\n multivalue: () => props.multivalue ?? false,\n type: () => props.type,\n});\n\nconst { formatValue, removeAtIndex, clearAll, addItem } = useMultivalueValues<T>({\n modelValue: () => props.modelValue,\n optionLabel: () => props.optionLabel,\n type: () => props.type,\n emit: {\n updateModelValue: (val: T[]) => emit(\"update:model-value\", val),\n },\n});\n\nconst { inputValue, onInputSubmit, onKeyDown } = useMultivalueInput<T>({\n type: () => props.type,\n optionLabel: () => props.optionLabel,\n addItem,\n});\n\nconst { setColorPickerRef, openColorPicker, handleColorChange } = useMultivalueColor<T>({\n modelValue: () => props.modelValue,\n emit: {\n updateModelValue: (val: T[]) => emit(\"update:model-value\", val),\n },\n});\n\nconst { availableOptions } = useMultivalueOptions<T>({\n options: () => props.options,\n modelValue: () => props.modelValue,\n optionValue: () => props.optionValue,\n});\n\nconst { isOpened, isFocused, dropdownToggleRef, dropdownRef, searchRef, dropdownStyle, toggleDropdown, closeDropdown } =\n useMultivalueDropdown({\n disabled: () => props.disabled ?? false,\n onItemSelect: (index: number) => {\n if (availableOptions.value[index]) {\n onItemSelect(availableOptions.value[index]);\n }\n },\n emit: {\n close: () => emit(\"close\"),\n },\n });\n\n// --- Sync DOM refs from sub-components → composable ---\nwatchEffect(() => {\n dropdownToggleRef.value = triggerComponentRef.value?.triggerRef ?? null;\n dropdownRef.value = dropdownComponentRef.value?.dropdownElRef ?? null;\n searchRef.value = dropdownComponentRef.value?.searchInputRef ?? null;\n});\n\n// --- Event handlers ---\n\nfunction onItemSelect(item: T) {\n addItem(item);\n closeDropdown();\n}\n\nfunction onSearch(event: Event) {\n emit(\"search\", (event.target as HTMLInputElement).value);\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --multivalue-height: 36px;\n --multivalue-border-radius: var(--select-border-radius, 6px);\n --multivalue-border-color: var(--select-border-color, var(--neutrals-300));\n --multivalue-background-color: var(--select-background-color, transparent);\n --multivalue-placeholder-color: var(--select-placeholder-color, var(--neutrals-400));\n --multivalue-text-color: var(--select-text-color, var(--neutrals-800));\n --multivalue-padding: 10px;\n\n // Dropdown — reuse select tokens\n --multivalue-dropdown-bg: var(--select-dropdown-bg, var(--additional-50));\n --multivalue-dropdown-border: var(--select-dropdown-border, var(--neutrals-200));\n --multivalue-dropdown-shadow: var(\n --select-dropdown-shadow,\n 0 4px 6px -1px rgba(0, 0, 0, 0.1),\n 0 2px 4px -2px rgba(0, 0, 0, 0.1)\n );\n\n // Search — reuse select tokens\n --multivalue-search-border-color: var(--select-search-border-color, var(--neutrals-200));\n\n // Options — reuse select tokens\n --multivalue-item-hover-background-color: var(--select-option-background-color-hover, var(--neutrals-100));\n\n // Chips — reuse select multi tokens\n --multivalue-chip-background-color: var(--select-multiple-options-background-color, var(--neutrals-100));\n --multivalue-chip-border-color: var(--select-multiple-options-border-color, var(--neutrals-200));\n --multivalue-clear-icon-color: var(--select-clear-color, var(--neutrals-400));\n --multivalue-clear-icon-color-hover: var(--select-clear-color-hover, var(--neutrals-600));\n\n // Error — reuse select tokens\n --multivalue-border-color-error: var(--select-border-color-error, var(--danger-500));\n --multivalue-error-ring-color: var(--select-error-ring-color, var(--danger-100));\n --multivalue-hint-color: var(--danger-500);\n\n // Focus — reuse select tokens\n --multivalue-border-color-focus: var(--select-border-color-focus, var(--primary-500));\n --multivalue-focus-ring-color: var(--select-focus-ring-color, var(--primary-100));\n\n // Disabled\n --multivalue-disabled-text-color: var(--neutrals-500);\n\n // Loading\n --multivalue-loading-color: var(--select-loading-color, var(--info-500));\n}\n\n.vc-multivalue {\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-1.5;\n }\n\n &--date,\n &--datetime-local {\n @apply tw-max-w-[220px];\n\n .vc-app--mobile & {\n @apply tw-max-w-full;\n }\n }\n\n &__label {\n @apply tw-mb-2;\n }\n\n &__field-wrapper {\n @apply tw-border tw-border-solid\n tw-border-[color:var(--multivalue-border-color)]\n tw-rounded-[var(--multivalue-border-radius)]\n tw-flex tw-items-stretch tw-min-h-[var(--multivalue-height)]\n tw-bg-[color:var(--multivalue-background-color)] tw-text-[color:var(--multivalue-text-color)]\n tw-shadow-sm tw-transition-[color,box-shadow] tw-duration-150 tw-ease-in-out\n tw-outline-none;\n }\n\n &__control {\n @apply tw-flex tw-flex-auto tw-items-center tw-min-w-0;\n }\n\n &__content {\n @apply tw-items-center tw-flex tw-flex-wrap tw-flex-grow tw-min-w-0;\n }\n\n &__chip-wrapper {\n @apply tw-ml-2 tw-flex tw-items-center tw-py-1;\n }\n\n &__chip {\n @apply tw-bg-[color:var(--multivalue-chip-background-color)] tw-border tw-border-solid tw-border-[color:var(--multivalue-chip-border-color)]\n tw-rounded-[4px] tw-flex tw-items-center tw-h-6 tw-box-border tw-px-2 tw-text-xs tw-gap-1 tw-max-w-[150px];\n }\n\n &__chip-label {\n @apply tw-truncate tw-text-sm;\n }\n\n &__chip-remove {\n @apply tw-text-[color:var(--multivalue-clear-icon-color)] tw-cursor-pointer\n hover:tw-text-[color:var(--multivalue-clear-icon-color-hover)] tw-flex-shrink-0;\n }\n\n &__prepend,\n &__append {\n @apply tw-flex tw-items-center tw-flex-nowrap tw-px-3;\n }\n\n &__clear {\n @apply tw-cursor-pointer tw-flex tw-items-center tw-px-3 tw-flex-shrink-0\n tw-text-[color:var(--multivalue-clear-icon-color)]\n hover:tw-text-[color:var(--multivalue-clear-icon-color-hover)];\n }\n\n &__add-button {\n @apply tw-flex tw-items-center tw-gap-1 tw-px-2 tw-py-0\n tw-border-none tw-bg-transparent\n tw-text-xs tw-text-[color:var(--multivalue-clear-icon-color)]\n tw-cursor-pointer tw-select-none tw-whitespace-nowrap\n tw-rounded-[4px] tw-h-6 tw-my-auto tw-ml-1\n tw-transition-colors tw-duration-150\n hover:tw-text-[color:var(--multivalue-text-color)]\n hover:tw-bg-[color:var(--multivalue-chip-background-color)]\n disabled:tw-cursor-not-allowed disabled:tw-opacity-50;\n }\n\n &__input {\n @apply tw-border-none tw-outline-none tw-min-h-[var(--multivalue-height)] tw-bg-[color:var(--multivalue-background-color)]\n tw-flex-grow tw-flex-shrink tw-w-auto tw-box-border tw-px-[var(--multivalue-padding)]\n placeholder:tw-text-[color:var(--multivalue-placeholder-color)] tw-text-sm\n tw-rounded-[var(--multivalue-border-radius)];\n\n &::-webkit-input-placeholder {\n @apply tw-text-[color:var(--multivalue-placeholder-color)];\n }\n\n &[type=\"number\"]::-webkit-inner-spin-button,\n &[type=\"number\"]::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n }\n }\n\n &__loading {\n @apply tw-flex tw-items-center tw-flex-nowrap tw-px-3 tw-text-[color:var(--multivalue-loading-color)] tw-flex-shrink-0;\n }\n\n &__dropdown {\n @apply tw-flex tw-flex-col tw-box-border\n tw-max-h-[300px] tw-z-[var(--z-critical-dropdown-panel)] tw-overflow-hidden\n tw-absolute tw-bg-[color:var(--multivalue-dropdown-bg)]\n tw-border tw-border-solid tw-border-[color:var(--multivalue-dropdown-border)]\n tw-rounded-[var(--multivalue-border-radius)]\n tw-p-1;\n box-shadow: var(--multivalue-dropdown-shadow);\n }\n\n &__viewport {\n @apply tw-overflow-y-auto tw-overflow-x-hidden tw-flex-1;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n }\n\n &__scroll-button {\n @apply tw-flex tw-items-center tw-justify-center tw-py-1\n tw-cursor-default tw-shrink-0\n tw-text-[color:var(--multivalue-placeholder-color)]\n tw-transition-opacity tw-duration-150;\n }\n\n &__search {\n @apply tw-w-full tw-box-border tw-border tw-border-solid\n tw-border-[color:var(--multivalue-search-border-color)]\n tw-bg-transparent tw-rounded-[var(--multivalue-border-radius)] tw-h-8 tw-leading-8\n tw-outline-none tw-mb-2 tw-px-2 tw-text-sm\n focus:tw-border-[color:var(--multivalue-border-color-focus)] focus:tw-ring-[3px] focus:tw-ring-[color:var(--multivalue-focus-ring-color)]\n tw-transition-[color,box-shadow] tw-duration-150 tw-ease-in-out;\n }\n\n &__item {\n @apply tw-flex tw-items-center tw-min-h-8 tw-py-1.5 tw-px-2 tw-rounded-[4px] tw-cursor-pointer tw-text-sm tw-select-none\n hover:tw-bg-[color:var(--multivalue-item-hover-background-color)];\n }\n\n &__no-options {\n @apply tw-w-full tw-box-border tw-flex tw-items-center tw-justify-center tw-p-4 tw-text-sm tw-text-[color:var(--multivalue-placeholder-color)];\n }\n\n // Focus state\n &--focused &__field-wrapper {\n @apply tw-border-[color:var(--multivalue-border-color-focus)]\n tw-ring-[3px] tw-ring-[color:var(--multivalue-focus-ring-color)]\n tw-outline-none;\n }\n\n // Opened state\n &--opened &__field-wrapper {\n @apply tw-border-[color:var(--multivalue-border-color-focus)]\n tw-ring-[3px] tw-ring-[color:var(--multivalue-focus-ring-color)]\n tw-outline-none;\n }\n\n // Error state\n &--error &__field-wrapper {\n @apply tw-border tw-border-solid tw-border-[color:var(--multivalue-border-color-error)]\n tw-ring-[3px] tw-ring-[color:var(--multivalue-error-ring-color)];\n }\n\n &__error {\n @apply tw-mt-1 [--hint-color:var(--multivalue-hint-color)];\n }\n\n &__hint {\n @apply tw-text-[color:var(--multivalue-placeholder-color)] tw-mt-1 tw-break-words tw-p-0;\n }\n\n // Disabled state\n &--disabled &__field-wrapper {\n @apply tw-opacity-50;\n }\n\n &--disabled &__field-wrapper,\n &--disabled &__input {\n @apply tw-cursor-not-allowed tw-pointer-events-none;\n }\n\n // Hint/error spacing\n &--has-hint-or-error {\n @apply tw-pb-5;\n }\n\n // Color square\n &__color-square {\n @apply tw-w-5 tw-h-5 tw-rounded tw-border tw-border-solid tw-border-neutrals-300\n tw-cursor-pointer tw-mr-2 tw-flex-shrink-0 tw-relative;\n }\n\n &__color-picker-hidden {\n @apply tw-opacity-0 tw-absolute tw-w-0 tw-h-0 tw-pointer-events-none;\n }\n}\n\n// Dropdown enter/leave transition\n.multivalue-dropdown-enter-active {\n transition:\n opacity 0.15s ease,\n transform 0.15s ease;\n}\n\n.multivalue-dropdown-leave-active {\n transition:\n opacity 0.1s ease,\n transform 0.1s ease;\n}\n\n.multivalue-dropdown-enter-from {\n opacity: 0;\n transform: scale(0.95) translateY(-4px);\n}\n\n.multivalue-dropdown-leave-to {\n opacity: 0;\n transform: scale(0.95) translateY(-4px);\n}\n</style>\n","<template>\n <!-- Skeleton mode -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-radio-button vc-radio-button--skeleton\"\n >\n <VcSkeleton\n variant=\"circle\"\n :width=\"16\"\n :height=\"16\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"12\"\n />\n </div>\n\n <div\n v-else\n class=\"vc-radio-button\"\n >\n <label class=\"vc-radio-button__label\">\n <input\n :id=\"radioId\"\n type=\"radio\"\n :name=\"resolvedName\"\n :value=\"value\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :aria-invalid=\"invalid || undefined\"\n :aria-required=\"ariaRequired\"\n :aria-describedby=\"ariaDescribedBy\"\n :aria-label=\"!label ? ariaLabel : undefined\"\n :class=\"{ 'vc-radio-button--error': invalid }\"\n tabindex=\"0\"\n @change=\"onChange\"\n />\n\n {{ label }}\n </label>\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"invalid && errorMessage\">\n <slot name=\"error\">\n <VcHint\n :id=\"errorId\"\n class=\"vc-radio-button__error\"\n :error=\"true\"\n >\n {{ errorMessage }}\n </VcHint>\n </slot>\n </div>\n </Transition>\n </div>\n</template>\n\n<script lang=\"ts\" setup generic=\"T extends string | number | boolean = string\">\nimport { isEqual } from \"lodash-es\";\nimport { computed, type VNode } from \"vue\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useFormField } from \"@ui/composables/useFormField\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport type { IFormFieldProps } from \"@ui/types\";\n\nconst props = withDefaults(\n defineProps<\n IFormFieldProps & {\n /** Value of the radio button. */\n value?: T;\n /** Value binding of the radio button. */\n modelValue?: T;\n /** Allows to select a boolean value. */\n binary?: boolean;\n /** Accessible name for the radio when no visible `label` is provided. */\n ariaLabel?: string;\n }\n >(),\n {\n name: \"RadioField\",\n },\n);\nconst emit = defineEmits<{\n /** Emits when the radio button is changed. */\n (event: \"update:modelValue\", value: T): void;\n}>();\n\ndefineSlots<{\n error: (props: Record<string, never>) => VNode[];\n}>();\n\nconst {\n fieldId: radioId,\n errorId,\n invalid,\n resolvedDisabled,\n resolvedName,\n ariaRequired,\n ariaDescribedBy,\n} = useFormField(props);\n\nconst bladeLoading = useBladeLoading();\n\nconst checked = computed(() => {\n return props.modelValue != null && (props.binary ? !!props.modelValue : isEqual(props.modelValue, props.value));\n});\n\nfunction onChange() {\n if (!resolvedDisabled.value) {\n const model = props.binary ? !checked.value : props.value;\n\n emit(\"update:modelValue\", model as T);\n }\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --radio-size: 16px;\n --radio-dot-size: 8px;\n --radio-border-color: var(--neutrals-300);\n --radio-border-color-hover: var(--neutrals-400);\n --radio-background: var(--additional-50);\n --radio-active: var(--primary-500);\n --radio-active-inner: var(--additional-50);\n --radio-disabled-bg: var(--neutrals-100);\n --radio-disabled-opacity: 0.5;\n --radio-error: var(--danger-500);\n --radio-error-ring-color: var(--danger-100);\n --radio-focus-ring-color: var(--primary-100);\n}\n\n.vc-radio-button {\n &__label {\n @apply tw-text-sm tw-flex tw-items-center tw-gap-2 tw-cursor-pointer tw-select-none;\n }\n\n input[type=\"radio\"] {\n flex-shrink: 0;\n border-radius: 9999px;\n appearance: none;\n height: var(--radio-size);\n width: var(--radio-size);\n outline: none;\n display: inline-block;\n vertical-align: top;\n position: relative;\n margin: 0;\n cursor: pointer;\n border: 1px solid var(--radio-border-color);\n background: var(--radio-background);\n transition:\n border-color 200ms ease,\n box-shadow 200ms ease;\n\n &::after {\n width: var(--radio-dot-size);\n height: var(--radio-dot-size);\n border-radius: 9999px;\n background: var(--radio-active);\n transform: scale(0);\n opacity: 0;\n content: \"\";\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n margin-left: calc(var(--radio-dot-size) / -2);\n margin-top: calc(var(--radio-dot-size) / -2);\n transition:\n transform 200ms cubic-bezier(0.2, 0.85, 0.32, 1.2),\n opacity 200ms ease;\n }\n\n &:checked {\n border-color: var(--radio-active);\n\n &::after {\n transform: scale(1);\n opacity: 1;\n }\n }\n\n &:disabled {\n background: var(--radio-disabled-bg);\n cursor: not-allowed;\n opacity: var(--radio-disabled-opacity);\n\n & + label {\n cursor: not-allowed;\n }\n }\n\n &:hover:not(:disabled):not(:checked) {\n border-color: var(--radio-border-color-hover);\n }\n\n &:focus-visible {\n @apply tw-ring-[3px] tw-ring-[color:var(--radio-focus-ring-color)] tw-outline-none;\n }\n\n &.vc-radio-button--error {\n border-color: var(--radio-error);\n @apply tw-ring-[3px] tw-ring-[color:var(--radio-error-ring-color)];\n }\n }\n\n &__error {\n @apply tw-mt-1 [--hint-error-color:var(--radio-error)];\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-row tw-items-center tw-gap-2;\n }\n}\n</style>\n","<template>\n <fieldset\n class=\"vc-input-group\"\n :class=\"[\n {\n 'vc-input-group--horizontal': orientation === 'horizontal',\n 'vc-input-group--vertical': orientation === 'vertical',\n 'vc-input-group--error': invalid,\n 'vc-input-group--disabled': disabled,\n },\n ]\"\n :disabled=\"disabled\"\n :role=\"role\"\n :aria-invalid=\"invalid || undefined\"\n :aria-describedby=\"describedBy\"\n :aria-labelledby=\"ariaLabelledBy\"\n :aria-label=\"ariaLabel\"\n >\n <legend\n v-if=\"label\"\n :id=\"labelId\"\n class=\"vc-input-group__legend\"\n >\n <VcLabel\n :required=\"required\"\n :error=\"invalid\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >{{ tooltip }}</template\n >\n </VcLabel>\n </legend>\n\n <div class=\"vc-input-group__controls\">\n <slot />\n </div>\n\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"invalid && errorMessage\">\n <slot name=\"error\">\n <VcHint\n :id=\"errorId\"\n class=\"vc-input-group__error\"\n :error=\"true\"\n >\n {{ errorMessage }}\n </VcHint>\n </slot>\n </div>\n <div v-else-if=\"hint\">\n <slot name=\"hint\">\n <VcHint\n :id=\"hintId\"\n class=\"vc-input-group__hint\"\n >\n {{ hint }}\n </VcHint>\n </slot>\n </div>\n </Transition>\n </fieldset>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, provide, toRef, useId } from \"vue\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { InputGroupContextKey } from \"@ui/components/molecules/vc-input-group/context\";\n\nexport interface Props {\n label?: string;\n tooltip?: string;\n hint?: string;\n error?: boolean;\n errorMessage?: string;\n required?: boolean;\n disabled?: boolean;\n orientation?: \"vertical\" | \"horizontal\";\n role?: \"group\" | \"radiogroup\";\n name?: string;\n ariaLabel?: string;\n ariaLabelledby?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n orientation: \"vertical\",\n role: \"group\",\n});\n\nconst uid = useId();\nconst labelId = computed(() => `vc-input-group-${uid}-label`);\nconst hintId = computed(() => `vc-input-group-${uid}-hint`);\nconst errorId = computed(() => `vc-input-group-${uid}-error`);\n\nconst invalid = computed(() => !!props.error || !!props.errorMessage);\n\nconst describedBy = computed(() => {\n if (invalid.value && props.errorMessage) {\n return errorId.value;\n }\n\n if (props.hint) {\n return hintId.value;\n }\n\n return undefined;\n});\n\nconst ariaLabelledBy = computed(() => {\n if (props.label) {\n return labelId.value;\n }\n\n return props.ariaLabelledby;\n});\n\nprovide(InputGroupContextKey, {\n name: toRef(props, \"name\"),\n disabled: computed(() => !!props.disabled),\n invalid,\n describedBy,\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --input-group-gap: 0.5rem;\n --input-group-horizontal-gap: 1rem;\n --input-group-legend-spacing: 0.375rem;\n}\n\n.vc-input-group {\n @apply tw-flex tw-flex-col tw-gap-[var(--input-group-gap)] tw-min-w-0;\n\n border: 0;\n margin: 0;\n padding: 0;\n\n &__legend {\n @apply tw-p-0 tw-m-0 tw-mb-[var(--input-group-legend-spacing)];\n }\n\n &__controls {\n @apply tw-flex tw-flex-col tw-gap-[var(--input-group-gap)];\n }\n\n &__hint,\n &__error {\n @apply tw-mt-1;\n }\n\n &__error {\n @apply [--hint-error-color:var(--danger-500)];\n }\n\n &--horizontal {\n .vc-input-group__controls {\n @apply tw-flex-row tw-flex-wrap tw-items-start tw-gap-[var(--input-group-horizontal-gap)];\n }\n }\n\n &--disabled {\n @apply tw-opacity-50;\n }\n}\n</style>\n","<template>\n <!-- Skeleton mode -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-radio-group vc-radio-group--skeleton\"\n >\n <div\n v-for=\"i in options?.length || 3\"\n :key=\"i\"\n class=\"vc-radio-group__skeleton-item\"\n >\n <VcSkeleton\n variant=\"circle\"\n :width=\"16\"\n :height=\"16\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"60 + i * 12\"\n :height=\"12\"\n />\n </div>\n </div>\n\n <VcInputGroup\n v-else\n class=\"vc-radio-group\"\n :label=\"label\"\n :tooltip=\"tooltip\"\n :hint=\"hint\"\n :error=\"error\"\n :error-message=\"errorMessage\"\n :required=\"required\"\n :disabled=\"disabled\"\n :orientation=\"orientation\"\n role=\"radiogroup\"\n :name=\"resolvedName\"\n >\n <slot v-if=\"$slots.default\" />\n\n <template v-else>\n <VcRadioButton\n v-for=\"(option, index) in options\"\n :key=\"getOptionKey(option, index)\"\n :model-value=\"modelValue\"\n :value=\"option.value\"\n :label=\"option.label\"\n :disabled=\"option.disabled\"\n :name=\"resolvedName\"\n @update:model-value=\"onUpdate\"\n />\n </template>\n </VcInputGroup>\n</template>\n\n<script lang=\"ts\" setup generic=\"T extends string | number | boolean = string\">\nimport { computed, useId } from \"vue\";\nimport { VcInputGroup } from \"@ui/components/molecules/vc-input-group\";\nimport { VcRadioButton } from \"@ui/components/molecules/vc-radio-button\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport type { IFormFieldProps } from \"@ui/types/form-field\";\n\nexport interface RadioGroupOption<V = string | number | boolean> {\n label: string;\n value: V;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<\n IFormFieldProps & {\n modelValue?: T;\n options?: RadioGroupOption<T>[];\n hint?: string;\n orientation?: \"vertical\" | \"horizontal\";\n }\n >(),\n {\n options: () => [],\n orientation: \"vertical\",\n },\n);\n\nconst emit = defineEmits<{\n (event: \"update:modelValue\", value: T): void;\n}>();\n\nconst bladeLoading = useBladeLoading();\n\nconst uid = useId();\nconst generatedName = computed(() => `vc-radio-group-${uid}`);\nconst resolvedName = computed(() => props.name || generatedName.value);\n\nfunction onUpdate(value: T) {\n emit(\"update:modelValue\", value);\n}\n\nfunction getOptionKey(option: RadioGroupOption<T>, index: number) {\n if (typeof option.value === \"string\" || typeof option.value === \"number\") {\n return `${option.value}`;\n }\n\n return `${index}`;\n}\n</script>\n\n<style lang=\"scss\">\n.vc-radio-group {\n .vc-radio-button {\n @apply tw-min-h-5;\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-2;\n }\n\n &__skeleton-item {\n @apply tw-flex tw-flex-row tw-items-center tw-gap-2;\n }\n}\n</style>\n","<template>\n <!-- Skeleton mode -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-checkbox vc-checkbox--skeleton\"\n >\n <VcSkeleton\n variant=\"block\"\n :width=\"20\"\n :height=\"20\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"12\"\n />\n </div>\n\n <div\n v-else\n class=\"vc-checkbox\"\n :class=\"{\n 'vc-checkbox--disabled': resolvedDisabled,\n 'vc-checkbox--error': invalid,\n 'vc-checkbox--indeterminate': indeterminate,\n [`vc-checkbox--size-${size}`]: true,\n }\"\n >\n <VcLabel\n v-if=\"label\"\n :html-for=\"checkboxId\"\n class=\"vc-checkbox__label\"\n :required=\"required\"\n :error=\"invalid\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"tooltip\"\n #tooltip\n >{{ tooltip }}</template\n >\n </VcLabel>\n\n <label class=\"vc-checkbox__container\">\n <input\n :id=\"checkboxId\"\n ref=\"checkboxRef\"\n v-model=\"model\"\n :value=\"value\"\n type=\"checkbox\"\n class=\"vc-checkbox__input\"\n :name=\"resolvedName\"\n :disabled=\"resolvedDisabled\"\n :true-value=\"trueValue\"\n :false-value=\"falseValue\"\n :aria-invalid=\"invalid || undefined\"\n :aria-required=\"ariaRequired\"\n :aria-describedby=\"ariaDescribedBy\"\n :aria-label=\"!label ? ariaLabel : undefined\"\n tabindex=\"0\"\n />\n\n <span class=\"vc-checkbox__custom-input\">\n <slot name=\"icon\">\n <Transition name=\"vc-checkbox-check\">\n <svg\n v-if=\"checked && !indeterminate\"\n class=\"vc-checkbox__check-icon\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M9.90927 3.80151C10.3113 3.3995 10.9631 3.3995 11.3651 3.80151C11.7671 4.20352 11.7671 4.85531 11.3651 5.25732L6.35527 10.2671C5.95326 10.6691 5.30148 10.6691 4.89947 10.2671L2.63476 8.00241C2.23275 7.6004 2.23275 6.94862 2.63476 6.54661C3.03677 6.14459 3.68856 6.14459 4.09057 6.54661L5.62737 8.08341L9.90927 3.80151Z\"\n fill=\"var(--additional-50)\"\n />\n </svg>\n </Transition>\n\n <Transition name=\"vc-checkbox-check\">\n <span\n v-if=\"indeterminate\"\n class=\"vc-checkbox__indeterminate-line\"\n ></span>\n </Transition>\n </slot>\n </span>\n\n <span\n v-if=\"$slots.default\"\n class=\"vc-checkbox__text\"\n >\n <slot></slot>\n </span>\n\n <span\n v-if=\"!label && required\"\n class=\"vc-checkbox__required\"\n aria-hidden=\"true\"\n >*</span\n >\n </label>\n\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"invalid && errorMessage\">\n <slot name=\"error\">\n <VcHint\n :id=\"errorId\"\n class=\"vc-checkbox__error\"\n :error=\"true\"\n >\n {{ errorMessage }}\n </VcHint>\n </slot>\n </div>\n </Transition>\n </div>\n</template>\n<script lang=\"ts\" setup generic=\"T extends string | number | boolean = boolean\">\nimport { computed, ref, watch, onMounted, type VNode } from \"vue\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useFormField } from \"@ui/composables/useFormField\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport type { IFormFieldProps } from \"@ui/types\";\n\nconst props = withDefaults(\n defineProps<\n IFormFieldProps & {\n modelValue?: boolean | T[];\n value?: T;\n trueValue?: boolean;\n falseValue?: boolean;\n size?: \"s\" | \"m\" | \"l\";\n outline?: boolean;\n indeterminate?: boolean;\n /** Accessible name for the checkbox when no visible `label` is provided. */\n ariaLabel?: string;\n }\n >(),\n {\n name: \"Field\",\n trueValue: true,\n falseValue: false,\n size: \"s\",\n indeterminate: false,\n },\n);\nconst emit = defineEmits<{\n (event: \"update:modelValue\", value: boolean | T[]): void;\n}>();\n\ndefineSlots<{\n default: (props: Record<string, never>) => VNode[];\n error: (props: Record<string, never>) => VNode[];\n icon: (props: Record<string, never>) => VNode[];\n}>();\n\nconst {\n fieldId: checkboxId,\n errorId,\n invalid,\n resolvedDisabled,\n resolvedName,\n ariaRequired,\n ariaDescribedBy,\n} = useFormField(props);\n\nconst bladeLoading = useBladeLoading();\n\nconst checkboxRef = ref<HTMLInputElement | null>(null);\n\nconst model = computed({\n get() {\n return props.modelValue;\n },\n set(newValue) {\n emit(\"update:modelValue\", newValue as boolean | T[]);\n },\n});\n\nconst checked = computed(() => {\n const modelVal = props.modelValue;\n if (Array.isArray(modelVal)) {\n return modelVal.includes(props.value as T);\n }\n return modelVal === props.trueValue;\n});\n\n// Managing indeterminate state\nwatch(\n () => props.indeterminate,\n (val) => {\n if (checkboxRef.value) {\n checkboxRef.value.indeterminate = val;\n }\n },\n { immediate: true },\n);\n\nonMounted(() => {\n if (checkboxRef.value && props.indeterminate) {\n checkboxRef.value.indeterminate = props.indeterminate;\n }\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n /* Checkbox size */\n --checkbox-size-s: 16px;\n --checkbox-size-m: 20px;\n --checkbox-size-l: 24px;\n\n /* Main colors */\n --checkbox-border-color: var(--neutrals-300);\n --checkbox-border-color-hover: var(--neutrals-400);\n --checkbox-bg-color: var(--additional-50);\n --checkbox-text-color: var(--neutrals-900);\n\n /* Checkbox checked state */\n --checkbox-checked-bg-color: var(--primary-500);\n --checkbox-checked-border-color: var(--primary-500);\n --checkbox-icon-color: var(--additional-50);\n\n /* Indeterminate state */\n --checkbox-indeterminate-bg-color: var(--primary-500);\n --checkbox-indeterminate-border-color: var(--primary-500);\n --checkbox-indeterminate-line-color: var(--additional-50);\n\n /* Error state */\n --checkbox-error-border-color: var(--danger-500);\n --checkbox-error-text-color: var(--danger-500);\n --checkbox-error-ring-color: var(--danger-100);\n\n /* Disabled state */\n --checkbox-disabled-opacity: 0.5;\n\n /* Focus */\n --checkbox-focus-ring-color: var(--primary-100);\n\n /* Other */\n --checkbox-border-radius: 4px;\n --checkbox-required-color: var(--danger-500);\n --checkbox-transition-duration: 200ms;\n --checkbox-label-spacing: 0.5rem;\n --checkbox-text-margin: 0.5rem;\n}\n\n.vc-checkbox {\n @apply tw-flex tw-flex-col;\n\n &__label {\n @apply tw-mb-[var(--checkbox-label-spacing)];\n }\n\n &__container {\n @apply tw-inline-flex tw-items-center tw-cursor-pointer tw-select-none;\n }\n\n &__input {\n @apply tw-absolute tw-opacity-0 tw-w-0 tw-h-0;\n\n &:focus-visible + .vc-checkbox__custom-input {\n @apply tw-ring-[3px] tw-ring-[color:var(--checkbox-focus-ring-color)] tw-outline-none;\n }\n\n &:not(:disabled):not(:checked) + .vc-checkbox__custom-input:hover {\n border-color: var(--checkbox-border-color-hover);\n }\n\n &:disabled + .vc-checkbox__custom-input {\n @apply tw-cursor-not-allowed;\n }\n }\n\n &__custom-input {\n @apply tw-flex tw-items-center tw-justify-center tw-shrink-0\n tw-border tw-border-solid\n tw-rounded-[var(--checkbox-border-radius)]\n tw-transition-all tw-duration-200 tw-ease-in-out;\n border-color: var(--checkbox-border-color);\n background-color: var(--checkbox-bg-color);\n color: var(--checkbox-icon-color);\n\n .vc-checkbox--size-s & {\n @apply tw-w-[var(--checkbox-size-s)] tw-h-[var(--checkbox-size-s)];\n }\n\n .vc-checkbox--size-m & {\n @apply tw-w-[var(--checkbox-size-m)] tw-h-[var(--checkbox-size-m)];\n }\n\n .vc-checkbox--size-l & {\n @apply tw-w-[var(--checkbox-size-l)] tw-h-[var(--checkbox-size-l)];\n }\n\n .vc-checkbox__input:checked + & {\n background-color: var(--checkbox-checked-bg-color);\n border-color: var(--checkbox-checked-border-color);\n }\n\n .vc-checkbox--indeterminate & {\n background-color: var(--checkbox-indeterminate-bg-color);\n border-color: var(--checkbox-indeterminate-border-color);\n }\n }\n\n &__check-icon {\n @apply tw-w-full tw-h-full;\n }\n\n &__indeterminate-line {\n @apply tw-block tw-rounded-full;\n width: 65%;\n height: 2px;\n background-color: var(--checkbox-indeterminate-line-color);\n }\n\n &__text {\n @apply tw-text-sm tw-leading-[21px];\n color: var(--checkbox-text-color);\n margin-left: var(--checkbox-text-margin);\n }\n\n &__required {\n @apply tw-ml-1;\n color: var(--checkbox-required-color);\n }\n\n &__error {\n @apply tw-mt-1 [--hint-error-color:var(--checkbox-error-text-color)];\n }\n\n &--error {\n .vc-checkbox__custom-input {\n @apply tw-ring-[3px] tw-ring-[color:var(--checkbox-error-ring-color)];\n border-color: var(--checkbox-error-border-color);\n }\n }\n\n &--disabled {\n @apply tw-cursor-not-allowed tw-pointer-events-none;\n opacity: var(--checkbox-disabled-opacity);\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-row tw-items-center tw-gap-2;\n }\n}\n\n@keyframes checkbox-check-in {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n 50% {\n transform: scale(1.1);\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes checkbox-check-out {\n 0% {\n transform: scale(1);\n opacity: 1;\n }\n 100% {\n transform: scale(0);\n opacity: 0;\n }\n}\n\n.vc-checkbox-check-enter-active {\n animation: checkbox-check-in var(--checkbox-transition-duration, 200ms) ease-out;\n}\n\n.vc-checkbox-check-leave-active {\n animation: checkbox-check-out calc(var(--checkbox-transition-duration, 200ms) * 0.6) ease-in;\n}\n</style>\n","<template>\n <!-- Skeleton mode -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-checkbox-group vc-checkbox-group--skeleton\"\n >\n <div\n v-for=\"i in options?.length || 3\"\n :key=\"i\"\n class=\"vc-checkbox-group__skeleton-item\"\n >\n <VcSkeleton\n variant=\"block\"\n :width=\"16\"\n :height=\"16\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"60 + i * 12\"\n :height=\"12\"\n />\n </div>\n </div>\n\n <VcInputGroup\n v-else\n class=\"vc-checkbox-group\"\n :label=\"label\"\n :tooltip=\"tooltip\"\n :hint=\"hint\"\n :error=\"error\"\n :error-message=\"errorMessage\"\n :required=\"required\"\n :disabled=\"disabled\"\n :orientation=\"orientation\"\n role=\"group\"\n :name=\"resolvedName\"\n >\n <slot v-if=\"$slots.default\" />\n\n <template v-else>\n <VcCheckbox\n v-for=\"(option, index) in options\"\n :key=\"getOptionKey(option, index)\"\n :model-value=\"normalizedModelValue\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n :name=\"resolvedName\"\n :size=\"size\"\n @update:model-value=\"onUpdate\"\n >\n {{ option.label }}\n </VcCheckbox>\n </template>\n </VcInputGroup>\n</template>\n\n<script lang=\"ts\" setup generic=\"T extends string | number | boolean = string\">\nimport { computed, useId } from \"vue\";\nimport { VcCheckbox } from \"@ui/components/molecules/vc-checkbox\";\nimport { VcInputGroup } from \"@ui/components/molecules/vc-input-group\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport type { IFormFieldProps } from \"@ui/types/form-field\";\n\nexport interface CheckboxGroupOption<V = string | number | boolean> {\n label: string;\n value: V;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<\n IFormFieldProps & {\n modelValue?: T[];\n options?: CheckboxGroupOption<T>[];\n hint?: string;\n orientation?: \"vertical\" | \"horizontal\";\n size?: \"s\" | \"m\" | \"l\";\n }\n >(),\n {\n modelValue: () => [],\n options: () => [],\n orientation: \"vertical\",\n size: \"s\",\n },\n);\n\nconst emit = defineEmits<{\n (event: \"update:modelValue\", value: T[]): void;\n}>();\n\nconst bladeLoading = useBladeLoading();\n\nconst uid = useId();\nconst generatedName = computed(() => `vc-checkbox-group-${uid}`);\nconst resolvedName = computed(() => props.name || generatedName.value);\nconst normalizedModelValue = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));\n\nfunction onUpdate(value: boolean | T[]) {\n if (Array.isArray(value)) {\n emit(\"update:modelValue\", value as T[]);\n return;\n }\n\n emit(\"update:modelValue\", normalizedModelValue.value);\n}\n\nfunction getOptionKey(option: CheckboxGroupOption<T>, index: number) {\n if (typeof option.value === \"string\" || typeof option.value === \"number\") {\n return `${option.value}`;\n }\n\n return `${index}`;\n}\n</script>\n\n<style lang=\"scss\">\n.vc-checkbox-group {\n .vc-checkbox {\n @apply tw-min-h-5;\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-2;\n }\n\n &__skeleton-item {\n @apply tw-flex tw-flex-row tw-items-center tw-gap-2;\n }\n}\n</style>\n","<template>\n <!-- Skeleton mode -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-switch vc-switch--skeleton\"\n >\n <VcSkeleton\n variant=\"block\"\n :width=\"36\"\n :height=\"20\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"12\"\n />\n </div>\n\n <div\n v-else\n class=\"vc-switch\"\n :class=\"{\n 'vc-switch--disabled': resolvedDisabled,\n 'vc-switch--error': invalid,\n }\"\n >\n <!-- Switch label -->\n <VcLabel\n v-if=\"label\"\n :html-for=\"switchId\"\n class=\"vc-switch__label\"\n :required=\"required\"\n :error=\"invalid\"\n >\n <span>{{ label }}</span>\n <template\n v-if=\"labelTooltip\"\n #tooltip\n >{{ labelTooltip }}</template\n >\n </VcLabel>\n\n <div class=\"vc-switch__track-wrapper\">\n <label class=\"vc-switch__track-label\">\n <input\n :id=\"switchId\"\n type=\"checkbox\"\n class=\"vc-switch__input\"\n role=\"switch\"\n :checked=\"invertValue(modelValue)\"\n :disabled=\"resolvedDisabled\"\n :aria-label=\"!label ? ariaLabel : undefined\"\n :aria-checked=\"!!invertValue(modelValue)\"\n :aria-invalid=\"invalid || undefined\"\n :aria-required=\"ariaRequired\"\n :aria-describedby=\"ariaDescribedBy\"\n tabindex=\"0\"\n @input=\"onInput\"\n />\n <span class=\"vc-switch__slider\"></span>\n </label>\n </div>\n\n <Transition\n name=\"slide-up\"\n mode=\"out-in\"\n >\n <div v-if=\"invalid && errorMessage\">\n <slot name=\"error\">\n <VcHint\n :id=\"errorId\"\n class=\"vc-switch__error\"\n :error=\"true\"\n >\n {{ errorMessage }}\n </VcHint>\n </slot>\n </div>\n <div v-else-if=\"hintText\">\n <VcHint\n :id=\"hintId\"\n class=\"vc-switch__hint\"\n >\n {{ hintText }}\n </VcHint>\n </div>\n </Transition>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, onMounted } from \"vue\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useFormField } from \"@ui/composables/useFormField\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport type { IFormFieldProps } from \"@ui/types\";\n\nexport interface Props extends IFormFieldProps {\n modelValue: boolean | undefined;\n /** Hint text displayed below the switch */\n hint?: string;\n /**\n * @deprecated Use `hint` instead. Kept for backward compatibility.\n * @override Overrides IFormFieldProps.tooltip — here it acts as hint text, not label tooltip.\n */\n tooltip?: string;\n /** Tooltip text shown on the label's info icon */\n labelTooltip?: string;\n trueValue?: boolean;\n falseValue?: boolean;\n /** Accessible name for the switch when no visible `label` is provided. */\n ariaLabel?: string;\n}\n\nexport interface Emits {\n (event: \"update:modelValue\", value: boolean | undefined): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n trueValue: true,\n falseValue: false,\n});\n\nconst emit = defineEmits<Emits>();\n\ndefineSlots<{\n error: (props: Record<string, never>) => any;\n}>();\n\nconst {\n fieldId: switchId,\n errorId,\n hintId,\n invalid,\n resolvedDisabled,\n ariaRequired,\n ariaDescribedBy,\n} = useFormField(props);\n\nconst bladeLoading = useBladeLoading();\n\n// `tooltip` prop is kept for backward compat — treat as hint text\nconst hintText = computed(() => props.hint || props.tooltip);\n\nif (import.meta.env.DEV) {\n onMounted(() => {\n if (props.tooltip) {\n console.warn(\n '[VcSwitch] The \"tooltip\" prop is deprecated. Use \"hint\" for hint text or \"labelTooltip\" for the label info icon.',\n );\n }\n });\n}\n\nconst invertValue = (value: boolean | undefined) => {\n if (typeof value !== \"undefined\") {\n return props.trueValue ? value : !value;\n }\n};\n\nfunction onInput(e: Event) {\n const newValue = (e.target as HTMLInputElement).checked;\n emit(\"update:modelValue\", invertValue(newValue));\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --switch-width: 36px;\n --switch-height: 20px;\n --switch-thumb-size: 16px;\n --switch-translate: 16px;\n\n --switch-active-color: var(--primary-500);\n --switch-inactive-color: var(--neutrals-300);\n --switch-hover-active-color: var(--primary-600);\n --switch-hover-inactive-color: var(--neutrals-400);\n --switch-thumb-color: var(--additional-50);\n --switch-thumb-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n --switch-focus-ring-color: var(--primary-100);\n --switch-error-ring-color: var(--danger-100);\n --switch-error-border-color: var(--danger-500);\n --switch-border-radius: 9999px;\n --switch-disabled-opacity: 0.5;\n}\n\n.vc-switch {\n @apply tw-flex tw-flex-col;\n\n &__label {\n @apply tw-mb-2;\n }\n\n &__track-wrapper {\n @apply tw-inline-flex tw-items-center;\n }\n\n &__track-label {\n @apply tw-relative tw-inline-block tw-cursor-pointer;\n width: var(--switch-width);\n height: var(--switch-height);\n }\n\n &__hint {\n @apply tw-mt-1;\n }\n\n &__error {\n @apply tw-mt-1 [--hint-error-color:var(--danger-500)];\n }\n\n &__input {\n @apply tw-w-0 tw-h-0 tw-opacity-0 tw-cursor-pointer;\n\n &:checked + .vc-switch__slider {\n background-color: var(--switch-active-color);\n\n &::before {\n @apply [transform:translateX(var(--switch-translate))_translateY(-50%)];\n }\n }\n\n &:checked:not(:disabled) + .vc-switch__slider:hover {\n background-color: var(--switch-hover-active-color);\n }\n\n &:not(:checked):not(:disabled) + .vc-switch__slider:hover {\n background-color: var(--switch-hover-inactive-color);\n }\n\n &:focus-visible + .vc-switch__slider {\n @apply tw-ring-[3px] tw-ring-[color:var(--switch-focus-ring-color)] tw-outline-none;\n }\n\n &:disabled + .vc-switch__slider {\n @apply tw-cursor-not-allowed;\n opacity: var(--switch-disabled-opacity);\n }\n\n &:disabled {\n @apply tw-cursor-not-allowed;\n }\n }\n\n &__slider {\n @apply tw-absolute tw-inset-0 tw-rounded-[var(--switch-border-radius)] tw-cursor-pointer;\n background-color: var(--switch-inactive-color);\n transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);\n\n &::before {\n @apply tw-absolute tw-left-[2px] tw-top-1/2 tw-rounded-full tw-w-[var(--switch-thumb-size)] tw-h-[var(--switch-thumb-size)] [content:''] [transform:translateX(0)_translateY(-50%)];\n background-color: var(--switch-thumb-color);\n box-shadow: var(--switch-thumb-shadow);\n transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n }\n\n &--error {\n .vc-switch__slider {\n @apply tw-ring-[3px] tw-ring-[color:var(--switch-error-ring-color)];\n }\n }\n\n &--disabled {\n @apply tw-pointer-events-none;\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-row tw-items-center tw-gap-2;\n }\n}\n</style>\n","/**\n * Shared registry for opened dropdown panels and their anchor elements.\n * Must be module-scoped so nested panel instances can see each other.\n */\nexport const panelAnchorRegistry = new WeakMap<Element, Element | null>();\n","<template>\n <Teleport :to=\"teleportTarget\">\n <Transition name=\"vc-dropdown-panel-fade\">\n <div\n v-if=\"show\"\n ref=\"floatingRef\"\n class=\"vc-dropdown-panel\"\n :style=\"[floatingStyle, panelStyle]\"\n @click.stop\n >\n <!-- Header -->\n <div\n v-if=\"title || $slots.header\"\n class=\"vc-dropdown-panel__header\"\n >\n <slot\n name=\"header\"\n :close=\"close\"\n >\n <span class=\"vc-dropdown-panel__title\">{{ title }}</span>\n <button\n type=\"button\"\n class=\"vc-dropdown-panel__close\"\n :aria-label=\"$t('COMPONENTS.CONTROLS.CLOSE')\"\n @click=\"close\"\n >\n <VcIcon\n icon=\"lucide-x\"\n size=\"s\"\n />\n </button>\n </slot>\n </div>\n\n <!-- Content (scrollable) -->\n <div\n class=\"vc-dropdown-panel__content\"\n :class=\"{ 'vc-dropdown-panel__content--scrollable': contentScrollable }\"\n :tabindex=\"contentScrollable ? 0 : undefined\"\n >\n <slot />\n </div>\n\n <!-- Footer (optional) -->\n <div\n v-if=\"$slots.footer\"\n class=\"vc-dropdown-panel__footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * VcDropdownPanel - Reusable floating dropdown panel\n *\n * A Teleported floating panel positioned relative to an anchor element.\n * Features: document-level click-outside close, Escape key close, header with title + close button,\n * scrollable content, optional footer. Built on @floating-ui/vue.\n */\nimport { ref, computed, watch, onBeforeUnmount, nextTick } from \"vue\";\nimport { offset, flip, shift, size, type Placement, type ReferenceElement } from \"@floating-ui/vue\";\nimport { VcIcon } from \"@ui/components/atoms\";\nimport { useFloatingPosition, useTeleportTarget } from \"@ui/composables\";\nimport { panelAnchorRegistry } from \"@ui/components/molecules/vc-dropdown-panel/panel-anchor-registry\";\n\ninterface Props {\n /** Whether the panel is visible (v-model:show) */\n show: boolean;\n /** Anchor for positioning — accepts an HTMLElement or a floating-ui VirtualElement (`{ getBoundingClientRect, contextElement? }`). Use a VirtualElement when the underlying DOM root can swap dynamically (e.g. wrapping a component whose root element changes via v-if). */\n anchorRef?: ReferenceElement | null;\n /** Panel header title (hidden if empty and no #header slot) */\n title?: string;\n /** Floating UI placement */\n placement?: Placement;\n /** Panel min-width */\n width?: string;\n /** Panel max-width */\n maxWidth?: string;\n /** Max panel height in pixels (clamped by viewport available height) */\n maxHeight?: number;\n /** Enable internal content scrolling for the panel body */\n contentScrollable?: boolean;\n /** Close when clicking outside */\n closeOnClickOutside?: boolean;\n /** Close on Escape key */\n closeOnEscape?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n anchorRef: null,\n title: \"\",\n placement: \"bottom-start\",\n width: \"280px\",\n maxWidth: \"400px\",\n maxHeight: 350,\n contentScrollable: true,\n closeOnClickOutside: true,\n closeOnEscape: true,\n});\n\nconst emit = defineEmits<{\n \"update:show\": [value: boolean];\n}>();\n\nconst { teleportTarget } = useTeleportTarget();\n\n// Floating UI positioning\nconst floatingRef = ref<HTMLElement | null>(null);\nconst registeredPanelEl = ref<HTMLElement | null>(null);\nconst anchorRefAsRef = computed<ReferenceElement | null>(() => props.anchorRef ?? null);\n\n// Resolve the underlying DOM anchor for click-outside checks and the child-panel registry.\n// For an HTMLElement, that's the element itself; for a VirtualElement, use its `contextElement`.\nconst anchorEl = computed<Element | null>(() => {\n const a = props.anchorRef;\n if (!a) return null;\n if (a instanceof Element) return a;\n return (a as { contextElement?: Element }).contextElement ?? null;\n});\n\nconst { floatingStyle } = useFloatingPosition(anchorRefAsRef, floatingRef, {\n strategy: \"fixed\",\n placement: computed(() => props.placement),\n middleware: computed(() => [\n offset(4),\n flip(),\n shift({ padding: 16 }),\n size({\n padding: 16,\n apply({ availableHeight, elements }) {\n Object.assign(elements.floating.style, {\n maxHeight: `${Math.min(availableHeight, props.maxHeight)}px`,\n });\n },\n }),\n ]),\n});\n\nconst panelStyle = computed(() => ({\n minWidth: props.width,\n maxWidth: props.maxWidth,\n}));\n\nconst close = () => {\n emit(\"update:show\", false);\n};\n\nconst registerPanel = () => {\n const panel = floatingRef.value;\n if (!panel) return;\n panelAnchorRegistry.set(panel, anchorEl.value);\n registeredPanelEl.value = panel;\n};\n\nconst unregisterPanel = () => {\n if (!registeredPanelEl.value) return;\n panelAnchorRegistry.delete(registeredPanelEl.value);\n registeredPanelEl.value = null;\n};\n\n// Click-outside detection via pointerdown on document.\n// Unlike a backdrop overlay, this works regardless of z-index stacking —\n// clicks on high-z-index siblings (sidebar, other panels) are caught too.\nconst handlePointerDownOutside = (e: PointerEvent) => {\n const target = e.target as Element;\n // Click inside the floating panel — ignore\n if (floatingRef.value?.contains(target)) {\n return;\n }\n // Click on the anchor element — let parent handle the toggle\n if (anchorEl.value?.contains(target)) {\n return;\n }\n // Handle nested panels (e.g. sub-menus teleported outside this panel).\n // If the click is inside another .vc-dropdown-panel that does NOT contain\n // our anchor, it's a \"child\" panel (its anchor lives inside us) — don't close.\n // If that panel DOES contain our anchor, it's a parent/sibling — close as usual.\n const enclosingPanel = target.closest?.(\".vc-dropdown-panel\");\n if (enclosingPanel && floatingRef.value && enclosingPanel !== floatingRef.value) {\n const enclosingAnchor = panelAnchorRegistry.get(enclosingPanel);\n const clickedInsideChildPanel = Boolean(enclosingAnchor && floatingRef.value.contains(enclosingAnchor));\n if (clickedInsideChildPanel) {\n return;\n }\n }\n // Handle teleported child dropdowns (e.g. VcSelect dropdown inside this panel).\n // VcSelect teleports its dropdown to <body>, so it's outside our DOM tree.\n // We identify ownership via the ARIA contract: the dropdown has id=\"listboxId\"\n // and the trigger inside our panel has aria-controls=\"listboxId\".\n const selectDropdown = target.closest?.(\".vc-select__dropdown\");\n if (selectDropdown && floatingRef.value) {\n const listboxId = selectDropdown.getAttribute(\"id\");\n if (listboxId && floatingRef.value.querySelector(`[aria-controls=\"${listboxId}\"]`)) {\n return;\n }\n }\n close();\n};\n\n// Escape key handler\nconst handleKeydown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && props.show) {\n close();\n }\n};\n\nwatch(\n () => props.show,\n (newShow) => {\n if (newShow) {\n nextTick(registerPanel);\n if (props.closeOnClickOutside) {\n document.addEventListener(\"pointerdown\", handlePointerDownOutside);\n }\n if (props.closeOnEscape) {\n document.addEventListener(\"keydown\", handleKeydown);\n }\n } else {\n unregisterPanel();\n document.removeEventListener(\"pointerdown\", handlePointerDownOutside);\n document.removeEventListener(\"keydown\", handleKeydown);\n }\n },\n { immediate: true },\n);\n\nwatch(anchorEl, (el) => {\n if (registeredPanelEl.value) {\n panelAnchorRegistry.set(registeredPanelEl.value, el);\n }\n});\n\nonBeforeUnmount(() => {\n unregisterPanel();\n document.removeEventListener(\"pointerdown\", handlePointerDownOutside);\n document.removeEventListener(\"keydown\", handleKeydown);\n});\n\ndefineExpose({ close });\n</script>\n\n<style lang=\"scss\">\n:root {\n --dropdown-panel-bg: var(--additional-50);\n --dropdown-panel-border-color: var(--neutrals-200);\n --dropdown-panel-border-radius: 6px;\n --dropdown-panel-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n --dropdown-panel-title-color: var(--neutrals-900);\n --dropdown-panel-close-color: var(--neutrals-400);\n --dropdown-panel-close-hover-color: var(--neutrals-600);\n --dropdown-panel-footer-bg: var(--neutrals-50);\n}\n\n.vc-dropdown-panel {\n z-index: var(--z-critical-dropdown-panel);\n @apply tw-overflow-hidden tw-flex tw-flex-col;\n @apply tw-border tw-border-solid;\n background-color: var(--dropdown-panel-bg);\n border-color: var(--dropdown-panel-border-color);\n border-radius: var(--dropdown-panel-border-radius);\n box-shadow: var(--dropdown-panel-shadow);\n\n &__header {\n @apply tw-flex tw-items-center tw-justify-between;\n @apply tw-px-4 tw-py-3;\n @apply tw-border-b tw-border-solid;\n border-color: var(--dropdown-panel-border-color);\n }\n\n &__title {\n @apply tw-font-semibold tw-text-sm;\n color: var(--dropdown-panel-title-color);\n }\n\n &__close {\n @apply tw-p-1 tw-bg-transparent tw-border-none tw-cursor-pointer;\n @apply tw-transition-colors tw-duration-150;\n color: var(--dropdown-panel-close-color);\n border-radius: var(--dropdown-panel-border-radius);\n\n &:hover {\n color: var(--dropdown-panel-close-hover-color);\n }\n }\n\n &__content {\n @apply tw-flex-1 tw-overflow-hidden;\n\n &--scrollable {\n @apply tw-overflow-y-auto;\n }\n }\n\n &__footer {\n @apply tw-flex tw-justify-end tw-gap-2;\n @apply tw-px-4 tw-py-3;\n @apply tw-border-t tw-border-solid;\n border-color: var(--dropdown-panel-border-color);\n background-color: var(--dropdown-panel-footer-bg);\n border-bottom-left-radius: var(--dropdown-panel-border-radius);\n border-bottom-right-radius: var(--dropdown-panel-border-radius);\n }\n}\n\n// Panel transition\n.vc-dropdown-panel-fade-enter-active {\n transition:\n opacity 0.18s cubic-bezier(0.16, 1, 0.3, 1),\n transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.vc-dropdown-panel-fade-leave-active {\n transition:\n opacity 0.12s ease-in,\n transform 0.12s ease-in;\n}\n\n.vc-dropdown-panel-fade-enter-from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n}\n\n.vc-dropdown-panel-fade-leave-to {\n opacity: 0;\n transform: translateY(-2px) scale(0.99);\n}\n</style>\n","import type { InjectionKey, Ref } from \"vue\";\r\n\r\nexport const VcMenuExpandedKey: InjectionKey<Ref<boolean>> = Symbol(\"VcMenuExpanded\");\r\n","<template>\n <div class=\"vc-menu\">\n <!-- Loading skeleton -->\n <div\n v-if=\"loading\"\n class=\"vc-menu__skeleton\"\n >\n <div\n v-for=\"(section, sIdx) in skeletonSections\"\n :key=\"sIdx\"\n class=\"vc-menu__skeleton-section\"\n >\n <!-- Section header -->\n <div class=\"tw-flex tw-items-center tw-h-[30px] tw-px-1.5\">\n <VcSkeleton\n variant=\"block\"\n :width=\"section.titleWidth\"\n :height=\"12\"\n />\n </div>\n\n <!-- Items -->\n <div class=\"tw-flex tw-flex-col tw-gap-1\">\n <template\n v-for=\"(item, iIdx) in section.items\"\n :key=\"iIdx\"\n >\n <!-- Group/item row: icon + text -->\n <div class=\"tw-flex tw-items-center tw-gap-1.5 tw-h-7 tw-px-1.5\">\n <VcSkeleton\n variant=\"circle\"\n :width=\"18\"\n :height=\"18\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"item.width\"\n :height=\"14\"\n />\n </div>\n\n <!-- Nested children -->\n <div\n v-if=\"item.children\"\n class=\"tw-flex tw-flex-col tw-gap-1 tw-pl-3\"\n >\n <div\n v-for=\"(child, cIdx) in item.children\"\n :key=\"cIdx\"\n class=\"tw-flex tw-items-center tw-gap-1.5 tw-h-6 tw-px-1.5\"\n >\n <VcSkeleton\n variant=\"circle\"\n :width=\"16\"\n :height=\"16\"\n />\n <VcSkeleton\n variant=\"block\"\n :width=\"child.width\"\n :height=\"12\"\n />\n </div>\n </div>\n </template>\n </div>\n </div>\n </div>\n\n <!-- Menu content -->\n <div\n v-else-if=\"$slots.default\"\n class=\"vc-menu__items\"\n >\n <slot />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, provide } from \"vue\";\nimport { VcMenuExpandedKey } from \"@ui/components/molecules/vc-menu/constants\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\n\ninterface VcMenuProps {\n expanded?: boolean;\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<VcMenuProps>(), {\n expanded: true,\n loading: false,\n});\n\ndefineOptions({\n name: \"VcMenu\",\n});\n\ndefineSlots<{\n default: () => unknown;\n}>();\n\nprovide(\n VcMenuExpandedKey,\n computed(() => props.expanded),\n);\n\n// Skeleton layout mimicking a realistic menu structure\nconst skeletonSections = [\n {\n titleWidth: 70,\n items: [{ width: 90, children: [{ width: 65 }, { width: 80 }] }, { width: 75 }, { width: 100 }],\n },\n {\n titleWidth: 55,\n items: [{ width: 85 }, { width: 110, children: [{ width: 70 }, { width: 55 }] }],\n },\n];\n</script>\n\n<style lang=\"scss\">\n:root {\n --vc-menu-gap: 8px;\n}\n.vc-menu {\n @apply tw-h-full;\n font-family: \"Lato\", sans-serif;\n\n &__items {\n @apply tw-flex tw-flex-col tw-h-full tw-pb-4;\n }\n\n &__skeleton {\n @apply tw-flex tw-flex-col tw-gap-5 tw-py-2 tw-pr-2;\n }\n\n &__skeleton-section + &__skeleton-section {\n @apply tw-border-t tw-border-neutrals-100 tw-pt-5;\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-menu-item\"\n @click=\"$emit('click')\"\n >\n <VcTooltip :placement=\"menuExpanded ? 'bottom' : 'right'\">\n <template\n v-if=\"!menuExpanded\"\n #tooltip\n >\n {{ title }}\n </template>\n\n <div\n class=\"vc-menu-item__content\"\n :class=\"{\n 'vc-menu-item__content--active': active,\n 'vc-menu-item__content--nested': nested,\n 'vc-menu-item__content--collapsed': !menuExpanded,\n }\"\n >\n <!-- Icon -->\n <div\n v-if=\"icon\"\n class=\"vc-menu-item__icon\"\n >\n <VcIcon\n class=\"vc-menu-item__icon-content\"\n :icon=\"icon\"\n size=\"m\"\n />\n </div>\n\n <!-- Letter abbreviation when collapsed and no icon -->\n <div\n v-else-if=\"!menuExpanded\"\n class=\"vc-menu-item__letters\"\n >\n {{ abbreviation }}\n </div>\n\n <!-- Title + badge (shown when expanded) -->\n <Transition name=\"vc-menu-opacity\">\n <div\n v-show=\"menuExpanded\"\n class=\"vc-menu-item__title\"\n >\n <span class=\"vc-menu-item__title-text\">{{ title }}</span>\n <VcBadge\n v-if=\"badge && badgeVisible\"\n :content=\"badge.isDot ? undefined : badge.content\"\n :variant=\"badge.variant ?? 'primary'\"\n :is-dot=\"badge.isDot\"\n size=\"s\"\n inline\n class=\"vc-menu-item__badge\"\n />\n <slot name=\"suffix\" />\n </div>\n </Transition>\n </div>\n </VcTooltip>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, inject } from \"vue\";\nimport type { Component } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcBadge } from \"@ui/components/atoms/vc-badge\";\nimport { VcTooltip } from \"@ui/components/atoms/vc-tooltip\";\nimport { VcMenuExpandedKey } from \"@ui/components/molecules/vc-menu/constants\";\n\ninterface VcMenuItemBadge {\n content?: string | number;\n variant?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"info\" | \"secondary\";\n isDot?: boolean;\n}\n\ninterface VcMenuItemProps {\n icon?: string | Component;\n title?: string;\n active?: boolean;\n nested?: boolean;\n badge?: VcMenuItemBadge;\n expanded?: boolean | null;\n}\n\nconst props = withDefaults(defineProps<VcMenuItemProps>(), {\n active: false,\n nested: false,\n expanded: null,\n});\n\ndefineEmits<{\n (event: \"click\"): void;\n}>();\n\ndefineSlots<{\n suffix: () => unknown;\n}>();\n\ndefineOptions({\n name: \"VcMenuItem\",\n});\n\nconst injectedExpanded = inject(VcMenuExpandedKey, undefined);\n\nconst menuExpanded = computed(() => {\n if (props.expanded != null) return props.expanded;\n return injectedExpanded?.value ?? true;\n});\n\nconst abbreviation = computed(() => {\n return props.title\n ?.split(\" \")\n .slice(0, 2)\n .map((word) => word[0])\n .join(\"\");\n});\n\nconst badgeVisible = computed(() => {\n if (!props.badge) return false;\n if (props.badge.isDot) return true;\n const c = props.badge.content;\n return c != null && c !== \"\" && c !== 0;\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --vc-menu-item-height: 28px;\n --vc-menu-item-padding-x: 6px;\n --vc-menu-item-border-radius: 6px 0 0 6px;\n --vc-menu-item-icon-size: 18px;\n --vc-menu-item-icon-gap: 6px;\n --vc-menu-item-text-color: var(--neutrals-700);\n --vc-menu-item-icon-color: var(--secondary-700);\n --vc-menu-item-icon-color-active: var(--secondary-700);\n --vc-menu-item-hover-bg: var(--neutrals-100);\n --vc-menu-item-active-bg: var(--secondary-100);\n --vc-menu-item-active-text-color: var(--neutrals-700);\n --vc-menu-item-active-icon-color: var(--secondary-700);\n\n // Nested sub-items (L3)\n --vc-menu-subitem-height: 28px;\n --vc-menu-subitem-icon-size: 16px;\n --vc-menu-subitem-bg-inset: 8px;\n}\n\n.vc-menu-item {\n @apply tw-cursor-pointer tw-w-full;\n padding: 2px 0;\n\n &:hover .vc-menu-item__content:not(.vc-menu-item__content--active) {\n background: var(--vc-menu-item-hover-bg);\n border-radius: var(--vc-menu-item-border-radius);\n\n .vc-menu-item__title {\n @apply tw-text-[color:var(--vc-menu-item-active-text-color)];\n }\n\n .vc-menu-item__icon {\n @apply tw-text-[color:var(--vc-menu-item-icon-color-active)];\n }\n }\n\n &__content {\n @apply tw-flex tw-items-center tw-w-full tw-border-none tw-flex-nowrap\n tw-box-border tw-cursor-pointer tw-relative tw-select-none;\n height: var(--vc-menu-item-height);\n padding: 0 10px 0 var(--vc-menu-item-padding-x);\n gap: var(--vc-menu-item-icon-gap);\n border-radius: var(--vc-menu-item-border-radius);\n transition:\n padding var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease),\n gap var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease),\n background 0.15s ease;\n\n &--active {\n background: var(--vc-menu-item-active-bg);\n\n .vc-menu-item__icon {\n @apply tw-text-[color:var(--vc-menu-item-active-icon-color)];\n }\n\n .vc-menu-item__title {\n @apply tw-text-[color:var(--vc-menu-item-active-text-color)] #{!important};\n }\n }\n\n // Collapsed state: center icon by collapsing title width (smooth transition)\n &--collapsed {\n @apply tw-relative tw-justify-center;\n padding: 0;\n gap: 0;\n height: var(--vc-menu-item-height);\n border-radius: 6px;\n\n .vc-menu-item__icon {\n width: 20px;\n }\n\n // Collapse title so justify-center works immediately (not after v-show delay)\n .vc-menu-item__title {\n @apply tw-w-0 tw-overflow-hidden tw-opacity-0;\n flex: 0 0 0px;\n }\n\n &.vc-menu-item__content--active {\n border-radius: 6px;\n\n // Active indicator: accent bar on the left\n &::after {\n content: \"\";\n @apply tw-absolute tw-left-[-4px] tw-top-1/2;\n transform: translateY(-50%);\n width: 3px;\n height: 18px;\n border-radius: 0 3px 3px 0;\n background: var(--primary-500);\n }\n }\n }\n\n &--nested {\n // Structural offset via margin — separates item from track zone\n margin-left: calc(var(--vc-menu-track-offset, 7px) + var(--vc-menu-subitem-bg-inset, 8px));\n width: calc(100% - var(--vc-menu-track-offset, 7px) - var(--vc-menu-subitem-bg-inset, 8px));\n height: var(--vc-menu-subitem-height);\n // Inner padding — same as regular items, controls bg-to-icon distance\n padding-left: var(--vc-menu-item-padding-x);\n\n .vc-menu-item__icon {\n width: var(--vc-menu-subitem-icon-size);\n }\n\n &.vc-menu-item__content--active {\n @apply tw-font-medium;\n // Direct background — just like regular items\n background: var(--vc-menu-item-active-bg);\n\n // Accent bar on the track line (expanded only)\n &:not(.vc-menu-item__content--collapsed)::after {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n left: calc(-1 * (var(--vc-menu-track-offset, 7px) + var(--vc-menu-subitem-bg-inset, 8px)));\n width: 3px;\n border-radius: 1px;\n background: var(--secondary-300);\n z-index: var(--z-local-above);\n }\n }\n\n // Collapsed + nested: behave like a regular collapsed item\n &.vc-menu-item__content--collapsed {\n @apply tw-justify-center;\n margin-left: 0;\n width: 100%;\n padding: 0;\n gap: 0;\n height: var(--vc-menu-item-height);\n border-radius: 6px;\n\n .vc-menu-item__icon {\n width: var(--vc-menu-subitem-icon-size);\n }\n\n &.vc-menu-item__content--active {\n background: var(--vc-menu-item-active-bg);\n\n &::after {\n content: \"\";\n @apply tw-absolute tw-left-[-4px] tw-top-1/2;\n transform: translateY(-50%);\n width: 3px;\n height: 14px;\n border-radius: 0 3px 3px 0;\n background: var(--primary-500);\n }\n }\n }\n }\n }\n\n &__icon {\n @apply tw-text-[color:var(--vc-menu-item-icon-color)]\n tw-overflow-hidden tw-flex tw-justify-center tw-shrink-0\n tw-transition-[color] tw-duration-200;\n width: var(--vc-menu-item-icon-size);\n }\n\n &__icon-content {\n @apply tw-text-center;\n }\n\n &__letters {\n @apply tw-shrink-0 tw-w-[24px] tw-h-[24px] tw-rounded-full\n tw-flex tw-items-center tw-justify-center\n tw-text-xxs tw-leading-[10px] tw-font-extrabold\n tw-text-neutrals-500 tw-border-[2px] tw-border-neutrals-500;\n }\n\n &__title {\n @apply tw-text-[color:var(--vc-menu-item-text-color)] tw-truncate\n tw-text-sm tw-font-normal tw-normal-case\n tw-opacity-100 tw-w-full tw-flex tw-justify-between tw-items-center;\n transition:\n color 0.2s ease,\n width var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease),\n flex var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease),\n opacity var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease);\n }\n\n &__title-text {\n @apply tw-truncate;\n }\n\n &__badge {\n @apply tw-shrink-0 tw-ml-auto;\n }\n}\n\n.vc-menu-opacity-enter-active,\n.vc-menu-opacity-leave-active {\n transition: opacity 0.3s ease;\n}\n\n.vc-menu-opacity-enter-from,\n.vc-menu-opacity-leave-to {\n opacity: 0;\n}\n</style>\n","<template>\r\n <div\r\n class=\"vc-menu-group\"\r\n :class=\"{\r\n 'vc-menu-group--section': variant === 'section',\r\n 'vc-menu-group--open': isOpen,\r\n }\"\r\n >\r\n <!-- Section variant header -->\r\n <button\r\n v-if=\"variant === 'section'\"\r\n class=\"vc-menu-group__section-header\"\r\n :class=\"{ 'vc-menu-group__section-header--hidden': !menuExpanded }\"\r\n @click=\"toggle\"\r\n >\r\n <div\r\n v-if=\"icon\"\r\n class=\"vc-menu-group__section-icon\"\r\n >\r\n <VcIcon\r\n :icon=\"icon\"\r\n size=\"m\"\r\n />\r\n </div>\r\n <span class=\"vc-menu-group__section-title\">{{ title }}</span>\r\n <VcIcon\r\n class=\"vc-menu-group__chevron\"\r\n :class=\"{ 'vc-menu-group__chevron--open': isOpen }\"\r\n icon=\"lucide-chevron-down\"\r\n size=\"s\"\r\n />\r\n </button>\r\n\r\n <!-- Default variant header (uses VcMenuItem) -->\r\n <VcMenuItem\r\n v-else\r\n :icon=\"icon\"\r\n :title=\"title\"\r\n :badge=\"badge\"\r\n :active=\"active\"\r\n @click=\"toggle\"\r\n >\r\n <template #suffix>\r\n <VcIcon\r\n v-if=\"menuExpanded\"\r\n class=\"vc-menu-group__chevron\"\r\n :class=\"{ 'vc-menu-group__chevron--open': isOpen }\"\r\n icon=\"lucide-chevron-down\"\r\n size=\"xs\"\r\n />\r\n </template>\r\n </VcMenuItem>\r\n\r\n <!-- Children with grid animation -->\r\n <div\r\n class=\"vc-menu-group__children-wrapper\"\r\n :class=\"{\r\n 'vc-menu-group__children-wrapper--open': isOpen,\r\n 'vc-menu-group__children-wrapper--collapsed': !menuExpanded,\r\n }\"\r\n >\r\n <div class=\"vc-menu-group__children\">\r\n <slot />\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { computed, inject } from \"vue\";\r\nimport type { Component } from \"vue\";\r\nimport { useLocalStorage } from \"@vueuse/core\";\r\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\r\nimport VcMenuItem from \"@ui/components/molecules/vc-menu/vc-menu-item.vue\";\r\nimport { VcMenuExpandedKey } from \"@ui/components/molecules/vc-menu/constants\";\r\nimport type { VcMenuItemBadge } from \"@ui/components/molecules/vc-menu/types\";\r\n\r\ninterface VcMenuGroupProps {\r\n groupId: string;\r\n icon?: string | Component;\r\n title?: string;\r\n badge?: VcMenuItemBadge;\r\n active?: boolean;\r\n open?: boolean;\r\n variant?: \"default\" | \"section\";\r\n}\r\n\r\nconst props = withDefaults(defineProps<VcMenuGroupProps>(), {\r\n active: false,\r\n variant: \"default\",\r\n});\r\n\r\ndefineEmits<{\r\n (event: \"update:open\", value: boolean): void;\r\n}>();\r\n\r\ndefineOptions({\r\n name: \"VcMenuGroup\",\r\n});\r\n\r\ndefineSlots<{\r\n default: () => unknown;\r\n}>();\r\n\r\nconst injectedExpanded = inject(VcMenuExpandedKey, undefined);\r\n\r\nconst menuExpanded = computed(() => {\r\n return injectedExpanded?.value ?? true;\r\n});\r\n\r\nconst storageKey = (() => {\r\n if (typeof window === \"undefined\") {\r\n return `vc_menu_${props.groupId}_open`;\r\n }\r\n const pathSegments = window.location.pathname.split(\"/\").filter(Boolean);\r\n const appName = pathSegments[0] || \"default\";\r\n return `vc_menu_${appName}_${props.groupId}_open`;\r\n})();\r\n\r\nconst isOpen = useLocalStorage(storageKey, props.open ?? false);\r\n\r\nconst toggle = () => {\r\n isOpen.value = !isOpen.value;\r\n};\r\n\r\ndefineExpose({\r\n setOpen(value: boolean) {\r\n isOpen.value = value;\r\n },\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n // Default variant (L2 group)\r\n --vc-menu-group-active-bg: var(--secondary-100);\r\n --vc-menu-group-active-radius: 6px;\r\n --vc-menu-group-chevron-size: 14px;\r\n --vc-menu-group-animation-duration: 200ms;\r\n\r\n // Section variant (L1)\r\n --vc-menu-section-height: 30px;\r\n --vc-menu-section-padding-left: 12px;\r\n --vc-menu-section-text-color: var(--neutrals-400);\r\n --vc-menu-section-font-size: 14px;\r\n --vc-menu-section-chevron-size: 16px;\r\n --vc-menu-section-divider-color: var(--neutrals-100);\r\n\r\n // Track line for nested groups (L2 → L3)\r\n --vc-menu-track-offset: 7px;\r\n}\r\n\r\n.vc-menu-group {\r\n // Default (non-section) groups: flex column with 4px gap between header and children\r\n &:not(&--section) {\r\n @apply tw-flex tw-flex-col;\r\n }\r\n\r\n // Chevron transition (shared by both variants)\r\n &__chevron {\r\n @apply tw-text-[color:var(--vc-menu-item-icon-color)] tw-ml-auto tw-shrink-0;\r\n transition: transform var(--vc-menu-group-animation-duration) ease;\r\n\r\n &--open {\r\n transform: rotate(180deg);\r\n }\r\n }\r\n\r\n // Children grid animation\r\n &__children-wrapper {\r\n display: grid;\r\n grid-template-rows: 0fr;\r\n transition: grid-template-rows var(--vc-menu-group-animation-duration) ease;\r\n\r\n &--open {\r\n grid-template-rows: 1fr;\r\n }\r\n\r\n // When sidebar collapsed: always show children (no expand/collapse toggle)\r\n &--collapsed {\r\n grid-template-rows: 1fr;\r\n }\r\n }\r\n\r\n &__children {\r\n @apply tw-overflow-hidden tw-min-h-0 tw-flex tw-flex-col;\r\n }\r\n\r\n // In collapsed mode, allow overflow for active indicators (::after at left: -4px)\r\n &__children-wrapper--collapsed > &__children {\r\n @apply tw-overflow-visible;\r\n }\r\n\r\n // Track line for non-section groups (L2 → L3 sub-items)\r\n &:not(&--section) > &__children-wrapper > &__children {\r\n @apply tw-relative;\r\n\r\n &::before {\r\n content: \"\";\r\n @apply tw-absolute tw-top-0 tw-bottom-0;\r\n left: 1px;\r\n width: 1px;\r\n background: var(--neutrals-200);\r\n }\r\n }\r\n\r\n // Active group header: border-radius left only + wider right padding (Figma spec)\r\n // Applies when group has explicit `active` prop\r\n > .vc-menu-item .vc-menu-item__content--active {\r\n border-radius: var(--vc-menu-group-active-radius) 0 0 var(--vc-menu-group-active-radius);\r\n padding-right: 10px;\r\n }\r\n\r\n // ── Section variant (L1) ──────────────────────────────────\r\n &--section {\r\n // Container-level indent (separates \"group padding\" from \"item padding\")\r\n padding-left: var(--vc-menu-section-padding-left);\r\n\r\n // Section chevron inherits section text color, not item icon color\r\n .vc-menu-group__chevron {\r\n @apply tw-text-[color:var(--vc-menu-section-text-color)];\r\n }\r\n\r\n // Divider between sections (not first, only when expanded)\r\n & + &:not(:has(> .vc-menu-group__section-header--hidden)) {\r\n border-top: 1px solid var(--vc-menu-section-divider-color);\r\n @apply tw-pt-3 tw-mt-3;\r\n }\r\n }\r\n\r\n &__section-header {\r\n @apply tw-flex tw-items-center tw-w-full tw-cursor-pointer\r\n tw-border-none tw-bg-transparent tw-select-none tw-outline-none;\r\n height: var(--vc-menu-section-height);\r\n padding: 0 10px 0 var(--vc-menu-item-padding-x, 6px);\r\n gap: 8px;\r\n\r\n &--hidden {\r\n @apply tw-hidden;\r\n }\r\n }\r\n\r\n &__section-icon {\r\n @apply tw-text-[color:var(--vc-menu-section-text-color)] tw-shrink-0;\r\n }\r\n\r\n &__section-title {\r\n @apply tw-flex-1 tw-text-left tw-uppercase tw-font-normal tw-truncate;\r\n font-size: var(--vc-menu-section-font-size);\r\n line-height: 16px;\r\n color: var(--vc-menu-section-text-color);\r\n }\r\n}\r\n</style>\r\n","import _VcMenu from \"@ui/components/molecules/vc-menu/vc-menu.vue\";\r\nimport _VcMenuItem from \"@ui/components/molecules/vc-menu/vc-menu-item.vue\";\r\nimport _VcMenuGroup from \"@ui/components/molecules/vc-menu/vc-menu-group.vue\";\r\n\r\nexport const VcMenu = _VcMenu as typeof _VcMenu;\r\nexport const VcMenuItem = _VcMenuItem as typeof _VcMenuItem;\r\nexport const VcMenuGroup = _VcMenuGroup as typeof _VcMenuGroup;\r\n\r\nexport type {\r\n VcMenuProps,\r\n VcMenuItemProps,\r\n VcMenuItemBadge,\r\n VcMenuGroupProps,\r\n} from \"@ui/components/molecules/vc-menu/types\";\r\n\r\nexport { VcMenuExpandedKey } from \"@ui/components/molecules/vc-menu/constants\";\r\n","import { ref, watch, MaybeRef, toValue } from \"vue\";\n\nexport function useImageLoad(src: MaybeRef<string | undefined>) {\n const isLoaded = ref(false);\n const hasError = ref(false);\n\n function onLoad() {\n isLoaded.value = true;\n hasError.value = false;\n }\n\n function onError() {\n hasError.value = true;\n isLoaded.value = false;\n }\n\n watch(\n () => toValue(src),\n () => {\n isLoaded.value = false;\n hasError.value = false;\n },\n );\n\n return { isLoaded, hasError, onLoad, onError };\n}\n","<template>\r\n <div\r\n v-on-click-outside=\"deactivate\"\r\n class=\"vc-image-tile\"\r\n :class=\"{\r\n 'vc-image-tile--active': isActive,\r\n 'vc-image-tile--mobile': isMobile,\r\n }\"\r\n @click=\"onTileClick\"\r\n >\r\n <!-- Skeleton shimmer -->\r\n <div\r\n v-if=\"!imageState.isLoaded.value && !imageState.hasError.value\"\r\n class=\"vc-image-tile__skeleton\"\r\n />\r\n\r\n <!-- Error placeholder -->\r\n <div\r\n v-if=\"imageState.hasError.value\"\r\n class=\"vc-image-tile__error\"\r\n >\r\n <VcIcon\r\n icon=\"lucide-image-off\"\r\n size=\"xl\"\r\n />\r\n </div>\r\n\r\n <!-- Image -->\r\n <img\r\n v-if=\"src && !imageState.hasError.value\"\r\n :src=\"resolvedSrc\"\r\n :alt=\"alt ?? name ?? ''\"\r\n class=\"vc-image-tile__image\"\r\n :class=\"{ 'vc-image-tile__image--loaded': imageState.isLoaded.value }\"\r\n :style=\"{ objectFit: imageFit }\"\r\n @load=\"imageState.onLoad\"\r\n @error=\"onImageError\"\r\n />\r\n\r\n <!-- Top bar: name + overlay (drag handle) -->\r\n <div class=\"vc-image-tile__topbar\">\r\n <slot name=\"overlay\" />\r\n <div\r\n v-if=\"name\"\r\n class=\"vc-image-tile__name\"\r\n :title=\"name\"\r\n >\r\n {{ name }}\r\n </div>\r\n </div>\r\n\r\n <!-- Bottom tray: action buttons -->\r\n <div class=\"vc-image-tile__tray\">\r\n <div class=\"vc-image-tile__tray-actions\">\r\n <button\r\n v-if=\"actions?.preview !== false\"\r\n type=\"button\"\r\n class=\"vc-image-tile-action\"\r\n :title=\"t('COMPONENTS.ORGANISMS.VC_GALLERY.INTERNAL.VC_GALLERY_ITEM.FULLSCREEN')\"\r\n @click.stop=\"$emit('preview')\"\r\n >\r\n <VcIcon\r\n icon=\"lucide-maximize\"\r\n size=\"s\"\r\n />\r\n </button>\r\n <button\r\n v-if=\"actions?.edit\"\r\n type=\"button\"\r\n class=\"vc-image-tile-action\"\r\n :title=\"t('COMPONENTS.ORGANISMS.VC_GALLERY.INTERNAL.VC_GALLERY_ITEM.EDIT')\"\r\n @click.stop=\"$emit('edit')\"\r\n >\r\n <VcIcon\r\n icon=\"lucide-pencil\"\r\n size=\"s\"\r\n />\r\n </button>\r\n <button\r\n v-if=\"actions?.remove\"\r\n type=\"button\"\r\n class=\"vc-image-tile-action vc-image-tile-action--danger\"\r\n :title=\"t('COMPONENTS.ORGANISMS.VC_GALLERY.INTERNAL.VC_GALLERY_ITEM.DELETE')\"\r\n @click.stop=\"$emit('remove')\"\r\n >\r\n <VcIcon\r\n icon=\"lucide-trash-2\"\r\n size=\"s\"\r\n />\r\n </button>\r\n <slot name=\"actions\" />\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { computed, ref, toRef, watch } from \"vue\";\r\nimport { vOnClickOutside } from \"@vueuse/components\";\r\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\r\nimport { useI18n } from \"vue-i18n\";\r\nimport { useImageLoad } from \"@ui/components/organisms/vc-gallery/composables/useImageLoad\";\r\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\r\nimport { getThumbnailUrl, type ThumbnailSize } from \"@core/utilities/thumbnail\";\r\n\r\nexport interface VcImageTileActions {\r\n preview?: boolean;\r\n edit?: boolean;\r\n remove?: boolean;\r\n}\r\n\r\nexport interface VcImageTileProps {\r\n src?: string;\r\n alt?: string;\r\n name?: string;\r\n imageFit?: \"contain\" | \"cover\";\r\n actions?: VcImageTileActions;\r\n /** Load a thumbnail variant instead of the full-size image */\r\n thumbnailSize?: ThumbnailSize;\r\n}\r\n\r\nconst props = withDefaults(defineProps<VcImageTileProps>(), {\r\n imageFit: \"contain\",\r\n});\r\n\r\ndefineEmits<{\r\n (e: \"preview\"): void;\r\n (e: \"edit\"): void;\r\n (e: \"remove\"): void;\r\n}>();\r\n\r\nconst { t } = useI18n({ useScope: \"global\" });\r\nconst { isMobile } = useResponsive();\r\n\r\nconst thumbnailSrc = computed(() => getThumbnailUrl(props.src, props.thumbnailSize) ?? props.src);\r\nconst useFallback = ref(false);\r\nconst resolvedSrc = computed(() => (useFallback.value ? props.src : thumbnailSrc.value));\r\nconst imageState = useImageLoad(toRef(() => resolvedSrc.value));\r\nconst isActive = ref(false);\r\n\r\n// Reset fallback when src or thumbnailSize changes\r\nwatch(\r\n () => [props.src, props.thumbnailSize],\r\n () => {\r\n useFallback.value = false;\r\n },\r\n);\r\n\r\nfunction onImageError(event: Event) {\r\n // If thumbnail failed and original URL is different — try original\r\n if (!useFallback.value && thumbnailSrc.value !== props.src) {\r\n useFallback.value = true;\r\n // Directly set src on DOM element to avoid waiting for Vue re-render\r\n const img = event.target as HTMLImageElement;\r\n if (props.src) {\r\n img.src = props.src;\r\n }\r\n return;\r\n }\r\n imageState.onError();\r\n}\r\n\r\nfunction onTileClick() {\r\n if (isMobile.value) {\r\n isActive.value = !isActive.value;\r\n }\r\n}\r\n\r\nfunction deactivate() {\r\n isActive.value = false;\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --image-tile-radius: 8px;\r\n --image-tile-border: var(--secondary-200);\r\n --image-tile-shadow: 0 1px 2px rgb(0 0 0 / 0.05);\r\n --image-tile-shadow-hover: 0 4px 12px rgb(0 0 0 / 0.1);\r\n --image-tile-tray-bg: rgba(255, 255, 255, 0.85);\r\n --image-tile-tray-blur: 12px;\r\n --image-tile-skeleton-from: var(--secondary-100);\r\n --image-tile-skeleton-to: var(--secondary-200);\r\n --image-tile-action-color: var(--secondary-600);\r\n --image-tile-action-hover: var(--primary-500);\r\n --image-tile-action-danger: var(--danger-500);\r\n}\r\n\r\n.vc-image-tile {\r\n @apply tw-relative tw-overflow-hidden tw-box-border tw-border tw-border-solid\r\n tw-bg-[var(--base-1,#fff)]\r\n tw-border-[var(--image-tile-border)]\r\n tw-rounded-[var(--image-tile-radius)]\r\n tw-aspect-square\r\n tw-transition-all tw-duration-200 tw-ease-out;\r\n box-shadow: var(--image-tile-shadow);\r\n -webkit-mask-image: radial-gradient(white, black);\r\n\r\n &__image {\r\n @apply tw-w-full tw-h-full tw-block tw-opacity-0 tw-transition-opacity tw-duration-300;\r\n\r\n &--loaded {\r\n @apply tw-opacity-100;\r\n }\r\n }\r\n\r\n &__skeleton {\r\n @apply tw-absolute tw-inset-0;\r\n background: linear-gradient(\r\n 90deg,\r\n var(--image-tile-skeleton-from) 25%,\r\n var(--image-tile-skeleton-to) 50%,\r\n var(--image-tile-skeleton-from) 75%\r\n );\r\n background-size: 200% 100%;\r\n animation: image-tile-shimmer 1.5s infinite ease-in-out;\r\n }\r\n\r\n &__error {\r\n @apply tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center;\r\n color: var(--secondary-300);\r\n background: var(--image-tile-skeleton-from);\r\n }\r\n\r\n // ── Top bar: name + drag handle ──\r\n &__topbar {\r\n @apply tw-absolute tw-top-0 tw-left-0 tw-right-0 tw-z-[var(--z-local-above)]\r\n tw-flex tw-items-center tw-gap-1 tw-px-1.5 tw-py-1\r\n -tw-translate-y-full tw-transition-transform tw-duration-200 tw-ease-out;\r\n background: var(--image-tile-tray-bg);\r\n backdrop-filter: blur(var(--image-tile-tray-blur)) saturate(1.5);\r\n }\r\n\r\n &__name {\r\n @apply tw-truncate tw-text-[10px] tw-leading-tight tw-ml-auto;\r\n color: var(--image-tile-action-color);\r\n }\r\n\r\n // ── Bottom tray: action buttons ──\r\n &__tray {\r\n @apply tw-absolute tw-bottom-0 tw-left-0 tw-right-0\r\n tw-flex tw-items-center tw-justify-center tw-gap-1 tw-px-2 tw-py-1.5\r\n tw-translate-y-full tw-transition-transform tw-duration-200 tw-ease-out;\r\n background: var(--image-tile-tray-bg);\r\n backdrop-filter: blur(var(--image-tile-tray-blur)) saturate(1.5);\r\n }\r\n\r\n &__tray-actions {\r\n @apply tw-flex tw-gap-1 tw-shrink-0;\r\n }\r\n\r\n // Desktop: hover effects\r\n &:not(&--mobile):hover {\r\n transform: translateY(-2px);\r\n box-shadow: var(--image-tile-shadow-hover);\r\n }\r\n\r\n &:not(&--mobile):hover &__tray,\r\n &:not(&--mobile):hover &__topbar {\r\n @apply tw-translate-y-0;\r\n }\r\n\r\n &--active &__tray,\r\n &--active &__topbar {\r\n @apply tw-translate-y-0;\r\n }\r\n\r\n // Mobile: compact layout (shown on tap via --active)\r\n &--mobile &__tray,\r\n &--mobile &__topbar {\r\n padding: 4px;\r\n gap: 2px;\r\n }\r\n\r\n &--mobile .vc-image-tile-action {\r\n width: 28px;\r\n height: 28px;\r\n min-width: 28px;\r\n }\r\n}\r\n\r\n.vc-image-tile-action {\r\n @apply tw-flex tw-items-center tw-justify-center tw-w-7 tw-h-7\r\n tw-rounded tw-cursor-pointer tw-transition-colors tw-duration-150\r\n tw-border-0 tw-bg-transparent;\r\n color: var(--image-tile-action-color);\r\n\r\n &:hover {\r\n color: var(--image-tile-action-hover);\r\n @apply tw-bg-[var(--primary-50)];\r\n }\r\n\r\n &--danger:hover {\r\n color: var(--image-tile-action-danger);\r\n @apply tw-bg-[var(--danger-50)];\r\n }\r\n}\r\n\r\n@keyframes image-tile-shimmer {\r\n 0% {\r\n background-position: 200% 0;\r\n }\r\n 100% {\r\n background-position: -200% 0;\r\n }\r\n}\r\n</style>\r\n","<template>\n <div class=\"vc-language-selector\">\n <VcDropdown\n :model-value=\"isOpened\"\n :items=\"options\"\n :floating=\"true\"\n placement=\"bottom-end\"\n :offset=\"{ mainAxis: 8, crossAxis: 0 }\"\n :empty-text=\"t('common.no_options', 'No options')\"\n :is-item-active=\"(item: any) => item.value === modelValue\"\n role=\"listbox\"\n :padded=\"true\"\n @item-click=\"onItemClick\"\n @update:model-value=\"isOpened = $event\"\n >\n <template #trigger>\n <button\n type=\"button\"\n class=\"vc-language-selector__trigger\"\n :class=\"{\n 'vc-language-selector__trigger--active': isOpened,\n 'vc-language-selector__trigger--disabled': disabled,\n }\"\n :disabled=\"disabled\"\n :aria-expanded=\"isOpened\"\n aria-haspopup=\"listbox\"\n @click=\"onTriggerClick\"\n >\n <img\n v-if=\"currentLanguageOption?.flag\"\n :src=\"currentLanguageOption.flag\"\n :alt=\"currentLanguageOption.label\"\n class=\"vc-language-selector__flag\"\n />\n <VcIcon\n v-else\n icon=\"lucide-globe\"\n size=\"xs\"\n class=\"tw-text-[color:var(--neutrals-400)]\"\n />\n </button>\n </template>\n <template #item=\"{ item }\">\n <div\n class=\"vc-language-selector__item\"\n :class=\"{\n 'vc-language-selector__item--active': item.value === modelValue,\n }\"\n >\n <VcIcon\n v-if=\"item.value === modelValue\"\n icon=\"lucide-check\"\n size=\"xs\"\n class=\"vc-language-selector__item-icon\"\n />\n <span\n v-else\n class=\"vc-language-selector__item-icon-placeholder\"\n />\n <img\n v-if=\"item.flag\"\n :src=\"item.flag\"\n :alt=\"item.label\"\n class=\"vc-language-selector__item-flag\"\n />\n <span class=\"vc-language-selector__item-label\">{{ item.label }}</span>\n </div>\n </template>\n <template #empty>\n <div class=\"tw-p-2 tw-text-sm tw-text-[color:var(--neutrals-400)]\">\n {{ t(\"common.no_options\", \"No options\") }}\n </div>\n </template>\n </VcDropdown>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, ref, type PropType } from \"vue\";\nimport { VcDropdown } from \"@ui/components/molecules/vc-dropdown\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useI18n } from \"vue-i18n\";\n\ntype LanguageOption = {\n value: string;\n label: string;\n flag?: string;\n};\n\nconst props = defineProps({\n options: {\n type: Array as PropType<LanguageOption[]>,\n default: () => [],\n },\n modelValue: {\n type: String,\n default: \"\",\n },\n disabled: {\n type: Boolean,\n default: false,\n },\n});\n\nconst emit = defineEmits([\"update:modelValue\"]);\n\nconst { t } = useI18n({ useScope: \"global\" });\nconst isOpened = ref(false);\n\nconst currentLanguageOption = computed(() => {\n return props.options.find((option) => option.value === props.modelValue);\n});\n\nconst onTriggerClick = () => {\n if (props.disabled) return;\n isOpened.value = !isOpened.value;\n};\n\nconst onItemClick = (item: LanguageOption) => {\n isOpened.value = false;\n emit(\"update:modelValue\", item.value);\n};\n</script>\n\n<style lang=\"scss\">\n.vc-language-selector {\n @apply tw-inline-flex;\n\n &__trigger {\n @apply tw-flex tw-items-center tw-justify-center\n tw-w-8 tw-h-8 tw-rounded-full\n tw-border tw-border-solid tw-border-[color:var(--neutrals-300)]\n tw-bg-[color:var(--additional-50)]\n tw-cursor-pointer tw-transition-all tw-duration-150\n tw-outline-none tw-p-0;\n\n &:hover:not(:disabled) {\n border-color: var(--neutrals-400);\n background: var(--neutrals-50);\n }\n\n &:focus-visible {\n border-color: var(--primary-500);\n box-shadow: 0 0 0 3px var(--primary-100);\n }\n\n &--active {\n border-color: var(--primary-500);\n box-shadow: 0 0 0 3px var(--primary-100);\n }\n\n &--disabled {\n @apply tw-opacity-50 tw-cursor-not-allowed;\n }\n }\n\n &__flag {\n @apply tw-w-6 tw-h-6 tw-rounded-full tw-object-cover;\n }\n\n &__item {\n @apply tw-flex tw-items-center tw-gap-2 tw-w-full tw-px-2 tw-py-[6px] tw-rounded-md\n tw-text-sm tw-cursor-pointer tw-transition-colors tw-duration-150;\n\n &:hover {\n background: var(--neutrals-100);\n }\n\n &--active {\n @apply tw-font-medium;\n }\n }\n\n &__item-icon {\n @apply tw-w-3.5 tw-shrink-0;\n color: var(--primary-500);\n }\n\n &__item-icon-placeholder {\n @apply tw-w-3.5 tw-shrink-0;\n }\n\n &__item-flag {\n @apply tw-w-5 tw-h-5 tw-rounded-full tw-object-cover tw-shrink-0;\n }\n\n &__item-label {\n @apply tw-truncate;\n }\n}\n</style>\n","<template>\n <div\n v-if=\"isVisible\"\n class=\"sidebar-header\"\n :class=\"{\n 'sidebar-header--collapsed': !expanded,\n 'sidebar-header--mobile': isMobile,\n }\"\n >\n <div class=\"sidebar-header__logo-container\">\n <div class=\"sidebar-header__logo\">\n <img\n class=\"sidebar-header__logo-image\"\n :class=\"{ 'sidebar-header__logo-image--mobile': isMobile }\"\n alt=\"logo\"\n :src=\"logo\"\n @click=\"$emit('logo:click')\"\n />\n <div\n v-if=\"hasUnread && !expanded && !isMobile\"\n class=\"sidebar-header__accent sidebar-header__accent--logo\"\n />\n </div>\n\n <template v-if=\"isMobile && showMobileTitle\">\n <p class=\"sidebar-header__blade-title\">\n {{ mobileTitle }}\n </p>\n </template>\n </div>\n\n <div\n v-if=\"expanded && !isMobile\"\n class=\"sidebar-header__toolbar\"\n >\n <button\n class=\"sidebar-header__notification-bell\"\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_APP.NOTIFICATIONS')\"\n @click=\"$emit('toggle-notifications', $event)\"\n >\n <div class=\"sidebar-header__notification-bell-wrap\">\n <Transition\n name=\"burger-fade\"\n mode=\"out-in\"\n >\n <VcIcon\n v-if=\"isNotificationsOpen\"\n key=\"close\"\n icon=\"lucide-x\"\n size=\"m\"\n />\n <VcIcon\n v-else\n key=\"bell\"\n icon=\"lucide-bell\"\n size=\"m\"\n />\n </Transition>\n <div\n v-if=\"hasUnread && !isNotificationsOpen\"\n class=\"sidebar-header__accent\"\n />\n </div>\n </button>\n\n <div\n v-if=\"$slots.actions\"\n class=\"sidebar-header__actions\"\n >\n <slot name=\"actions\" />\n </div>\n\n <button\n v-if=\"showBurger\"\n class=\"sidebar-header__menu-button\"\n :aria-label=\"isMenuOpen ? 'Close menu' : 'Open menu'\"\n :aria-expanded=\"isMenuOpen\"\n @click=\"$emit('toggle-menu', $event)\"\n >\n <div class=\"sidebar-header__menu-button-wrap\">\n <Transition\n name=\"burger-fade\"\n mode=\"out-in\"\n >\n <VcIcon\n v-if=\"isMenuOpen\"\n key=\"close\"\n icon=\"lucide-x\"\n size=\"m\"\n />\n <VcIcon\n v-else\n key=\"burger\"\n icon=\"lucide-menu\"\n size=\"m\"\n />\n </Transition>\n </div>\n </button>\n </div>\n\n <!-- Mobile actions (rendered outside desktop toolbar) -->\n <div\n v-if=\"isMobile && $slots.actions\"\n class=\"sidebar-header__actions\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { inject, ref } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { ShellIndicatorsKey } from \"@framework/injection-keys\";\n\nexport interface Props {\n logo?: string;\n expanded?: boolean;\n showBurger?: boolean;\n isMenuOpen?: boolean;\n isNotificationsOpen?: boolean;\n isVisible?: boolean;\n isMobile?: boolean;\n mobileTitle?: string;\n showMobileTitle?: boolean;\n}\n\nwithDefaults(defineProps<Props>(), {\n expanded: true,\n showBurger: false,\n isMenuOpen: false,\n isNotificationsOpen: false,\n isVisible: true,\n isMobile: false,\n mobileTitle: \"\",\n showMobileTitle: false,\n});\n\ndefineEmits<{\n (e: \"logo:click\"): void;\n (e: \"toggle-menu\", event: MouseEvent): void;\n (e: \"toggle-notifications\", event: MouseEvent): void;\n}>();\n\nconst hasUnread = inject(ShellIndicatorsKey, ref(false));\n</script>\n\n<style lang=\"scss\">\n:root {\n --app-bar-header-padding-top: 18px;\n --app-bar-header-blade-title: var(--neutrals-950);\n --app-bar-accent-color: var(--danger-500);\n\n --app-bar-header-actions-button-color: var(--neutrals-500);\n --app-bar-header-actions-button-active-color: var(--primary-500);\n}\n\n.sidebar-header {\n @apply tw-flex tw-flex-row tw-items-center tw-justify-between\n tw-px-[var(--app-bar-padding)] tw-h-[var(--app-bar-height)]\n tw-py-[var(--app-bar-header-padding-top,18px)];\n\n &--collapsed {\n @apply tw-items-center tw-justify-between tw-border-0 tw-gap-[16px];\n }\n\n &--mobile {\n @apply tw-h-[var(--app-bar-mobile-height)] tw-px-[var(--app-bar-padding-mobile)];\n }\n\n &__logo {\n @apply tw-w-auto tw-flex tw-items-center tw-h-full tw-relative;\n\n &-container {\n @apply tw-flex tw-flex-row tw-gap-3 tw-items-center;\n }\n\n &-image {\n @apply tw-cursor-pointer tw-max-w-[var(--app-bar-logo-width)] tw-max-h-[var(--app-bar-logo-height)]\n tw-overflow-hidden tw-w-full tw-shrink-0;\n\n &--mobile {\n @apply tw-mx-1 tw-max-w-[var(--app-bar-logo-mobile-width)] tw-max-h-[var(--app-bar-logo-mobile-height)] tw-rounded-full;\n }\n }\n }\n\n &__accent {\n @apply tw-block tw-absolute tw-right-0 tw-top-0\n tw-w-[5px] tw-h-[5px] tw-rounded-full tw-z-[var(--z-local-above)]\n tw-bg-[var(--app-bar-accent-color,var(--danger-500))];\n }\n\n &__accent--logo {\n @apply tw-right-[-7px] tw-top-[-5px];\n }\n\n &__toolbar {\n @apply tw-flex tw-items-center tw-gap-3;\n }\n\n &__actions {\n @apply tw-flex tw-items-center;\n }\n\n &__blade-title {\n @apply tw-text-lg tw-font-bold tw-text-[var(--app-bar-header-blade-title)];\n }\n\n &__notification-bell {\n @apply tw-cursor-pointer tw-relative;\n\n &-wrap {\n @apply tw-relative;\n }\n }\n\n &__menu-button {\n @apply tw-cursor-pointer tw-relative;\n\n &-wrap {\n @apply tw-relative;\n }\n }\n}\n\n.burger-fade-enter-active,\n.burger-fade-leave-active {\n transition:\n opacity 0.15s ease,\n transform 0.15s ease;\n}\n\n.burger-fade-enter-from {\n opacity: 0;\n transform: rotate(90deg);\n}\n\n.burger-fade-leave-to {\n opacity: 0;\n transform: rotate(-90deg);\n}\n</style>\n","import { computed } from \"vue\";\r\nimport type { MaybeRefOrGetter } from \"vue\";\r\nimport { toValue } from \"vue\";\r\nimport { useRoute } from \"vue-router\";\r\nimport type { RouteLocationNormalizedLoaded } from \"vue-router\";\r\n\r\n/**\r\n * Strip the tenant prefix from a route path for comparison with menu URLs.\r\n * Route paths may include a tenant prefix (e.g., \"/583818f7.../products\")\r\n * while menu item URLs don't (e.g., \"/products\").\r\n */\r\nexport function stripTenantPrefix(route: RouteLocationNormalizedLoaded): string {\r\n const firstParam = Object.values(route.params)?.[0];\r\n const tenant = typeof firstParam === \"string\" ? firstParam : \"\";\r\n if (tenant && route.path.startsWith(`/${tenant}/`)) {\r\n return route.path.slice(tenant.length + 1);\r\n }\r\n if (tenant && route.path === `/${tenant}`) {\r\n return \"/\";\r\n }\r\n return route.path;\r\n}\r\n\r\n/**\r\n * Reactive route-based active detection for menu items.\r\n *\r\n * Uses `computed` over `route.path` so it stays reactive when the route changes.\r\n * Supports exact match and prefix match (e.g., `/products` matches `/products/edit/123`).\r\n */\r\nexport function useMenuActiveState(url: MaybeRefOrGetter<string | undefined>) {\r\n const route = useRoute();\r\n\r\n const isActive = computed(() => {\r\n const urlValue = toValue(url);\r\n if (!urlValue) return false;\r\n const path = stripTenantPrefix(route);\r\n return path === urlValue || path.startsWith(urlValue + \"/\");\r\n });\r\n\r\n return { isActive };\r\n}\r\n","<template>\n <VcMenu\n v-if=\"filteredMenuItems.length\"\n :expanded=\"expanded\"\n class=\"vc-app-menu\"\n :class=\"{ 'vc-app-menu--collapsed': !expanded }\"\n >\n <template\n v-for=\"item in filteredMenuItems\"\n :key=\"item.id ?? item.routeId ?? item.url ?? item.title\"\n >\n <!-- Group items (have children) -->\n <VcMenuGroup\n v-if=\"accessibleChildren(item).length\"\n :data-test-id=\"item.routeId\"\n :group-id=\"getGroupId(item)\"\n :icon=\"item.groupIcon || item.icon\"\n :title=\"$t(item.title)\"\n :badge=\"resolvedBadges.get(item.routeId ?? item.groupId ?? '')\"\n >\n <template\n v-for=\"child in accessibleChildren(item)\"\n :key=\"child.routeId || child.url || child.id || child.title\"\n >\n <VcMenuItem\n :data-test-id=\"child.routeId\"\n :icon=\"child.icon\"\n :title=\"$t(child.title)\"\n :badge=\"resolvedBadges.get(child.routeId ?? child.groupId ?? '')\"\n :active=\"isItemActive(child.url)\"\n nested\n @click=\"handleItemClick(child)\"\n />\n </template>\n </VcMenuGroup>\n\n <!-- Standalone items -->\n <VcMenuItem\n v-else\n :data-test-id=\"item.routeId\"\n :icon=\"item.groupIcon || item.icon\"\n :title=\"$t(item.title)\"\n :badge=\"resolvedBadges.get(item.routeId ?? item.groupId ?? '')\"\n :active=\"isItemActive(item.url)\"\n @click=\"handleItemClick(item)\"\n />\n </template>\n </VcMenu>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, isRef, unref, type Ref } from \"vue\";\nimport { useRoute } from \"vue-router\";\nimport { useI18n } from \"vue-i18n\";\nimport { useMenuService, usePermissions } from \"@core/composables\";\nimport type { MenuItem, MenuItemBadgeConfig, MenuItemBadge } from \"@core/types\";\nimport { VcMenu, VcMenuItem, VcMenuGroup } from \"@ui/components/molecules/vc-menu\";\nimport type { VcMenuItemBadge } from \"@ui/components/molecules/vc-menu\";\nimport { stripTenantPrefix } from \"@ui/components/organisms/vc-app/_internal/menu/composables/useMenuActiveState\";\n\nexport interface Props {\n expanded?: boolean;\n searchQuery?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n expanded: true,\n});\n\nconst emit = defineEmits<{\n (event: \"item:click\", item: MenuItem): void;\n}>();\n\nconst route = useRoute();\nconst { t } = useI18n();\nconst { menuItems, menuBadges } = useMenuService();\nconst { hasAccess } = usePermissions();\n\nconst hasAccessToItem = (item: MenuItem): boolean => hasAccess(item.permissions);\n\nconst accessibleChildren = (item: MenuItem): MenuItem[] => {\n return (item.children ?? []).filter((child) => hasAccessToItem(child));\n};\n\nconst visibleMenuItems = computed(() => {\n return menuItems.value.filter((item) => {\n if (!hasAccessToItem(item)) return false;\n if (item.children?.length) return accessibleChildren(item).length > 0;\n return true;\n });\n});\n\nconst filteredMenuItems = computed(() => {\n const query = props.searchQuery?.toLowerCase().trim();\n if (!query) return visibleMenuItems.value;\n\n return visibleMenuItems.value\n .map((item) => {\n const children = accessibleChildren(item);\n\n // Standalone item — match title\n if (!children.length) {\n return t(item.title).toLowerCase().includes(query) ? item : null;\n }\n\n // Group title matches — show all children\n if (t(item.title).toLowerCase().includes(query)) return item;\n\n // Filter matching children only\n const matchedChildren = children.filter((child) => t(child.title).toLowerCase().includes(query));\n\n if (matchedChildren.length) {\n return { ...item, children: matchedChildren };\n }\n\n return null;\n })\n .filter(Boolean) as MenuItem[];\n});\n\nconst getGroupId = (item: MenuItem): string => {\n return item.groupId ?? String(item.id ?? item.routeId ?? item.title);\n};\n\nconst handleItemClick = (item: MenuItem) => {\n emit(\"item:click\", item);\n};\n\nconst isItemActive = (url?: string): boolean => {\n if (!url) return false;\n const path = stripTenantPrefix(route);\n return path === url || path.startsWith(url + \"/\");\n};\n\n/**\n * Resolve a raw MenuItemBadgeConfig (which may contain Ref, ComputedRef, or function)\n * into a simple VcMenuItemBadge with plain values.\n */\nfunction resolveRawBadge(config: MenuItemBadgeConfig): VcMenuItemBadge | undefined {\n let badge: MenuItemBadge;\n if (typeof config === \"object\" && !isRef(config) && \"content\" in config) {\n badge = config as MenuItemBadge;\n } else {\n badge = { content: config as MenuItemBadge[\"content\"] };\n }\n\n let rawContent: string | number | undefined;\n if (typeof badge.content === \"function\") {\n rawContent = badge.content();\n } else if (isRef(badge.content)) {\n rawContent = unref(badge.content as Ref<string | number | undefined>);\n } else {\n rawContent = badge.content;\n }\n\n // Truncate > 99\n let content: string | number | undefined = rawContent;\n if (typeof rawContent === \"number\" && rawContent > 99) {\n content = \"99+\";\n } else if (typeof rawContent === \"string\") {\n const num = parseInt(rawContent, 10);\n if (!isNaN(num) && num > 99) content = \"99+\";\n }\n\n const isDot = badge.isDot ?? false;\n const isVisible = isDot || (content != null && content !== \"\" && content !== 0);\n if (!isVisible) return undefined;\n\n return {\n content,\n variant: badge.variant ?? \"primary\",\n isDot,\n };\n}\n\n/**\n * Reactive map of all resolved badges keyed by routeId/groupId.\n * Reads from both item.badge config and the menuBadges registry.\n * Recomputes when menuItems or menuBadges change.\n */\nconst resolvedBadges = computed(() => {\n const result = new Map<string, VcMenuItemBadge>();\n\n const resolveForItem = (item: MenuItem) => {\n const id = item.routeId ?? item.groupId;\n if (!id) return;\n\n // Priority: direct badge config > registry by routeId > registry by groupId\n let config: MenuItemBadgeConfig | undefined = item.badge;\n if (!config && item.routeId) config = menuBadges.value.get(item.routeId);\n if (!config && item.groupId) config = menuBadges.value.get(item.groupId);\n if (!config) return;\n\n const resolved = resolveRawBadge(config);\n if (resolved) result.set(id, resolved);\n };\n\n for (const item of menuItems.value) {\n resolveForItem(item);\n if (item.children) {\n for (const child of item.children) {\n resolveForItem(child);\n }\n }\n }\n\n return result;\n});\n</script>\n\n<style lang=\"scss\">\n.vc-app-menu {\n @apply tw-pl-3;\n transition: padding var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease);\n\n &--collapsed {\n @apply tw-pl-1 tw-pr-1;\n }\n}\n</style>\n","<template>\n <div class=\"vc-user-info\">\n <div\n v-if=\"avatarUrl\"\n class=\"vc-user-info__avatar\"\n :style=\"imageHandler\"\n ></div>\n <div\n v-else\n class=\"vc-user-info__avatar-fallback\"\n >\n <VcIcon\n icon=\"lucide-circle-user\"\n size=\"l\"\n />\n </div>\n <div class=\"vc-user-info__info\">\n <div class=\"vc-user-info__name\">\n {{ name || (user && \"fullName\" in user && user.fullName) || user?.userName }}\n </div>\n <div class=\"vc-user-info__role\">\n {{\n role\n ? $te(`SHELL.USER.ROLE.${role}`)\n ? $t(`SHELL.USER.ROLE.${role}`)\n : role\n : user?.isAdministrator\n ? $t(\"SHELL.USER.ROLE.ADMINISTRATOR\")\n : \"\"\n }}\n </div>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\nimport { useUserManagement } from \"@core/composables/useUserManagement\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\nexport interface Props {\n avatarUrl?: string;\n name?: string;\n role?: string;\n isExpanded?: boolean;\n}\n\nconst props = defineProps<Props>();\nconst { user } = useUserManagement();\n\nconst imageHandler = computed(() => {\n if (props.avatarUrl) {\n return `background-image: url(${CSS.escape(props.avatarUrl)})`;\n }\n return undefined;\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --user-info-avatar-size: 32px;\n}\n\n.vc-user-info {\n @apply tw-flex tw-items-center tw-gap-2.5 tw-truncate;\n @apply tw-overflow-visible #{!important};\n transition: gap var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease);\n\n &__avatar {\n @apply tw-rounded-lg tw-overflow-hidden tw-bg-cover tw-bg-center tw-shrink-0;\n width: var(--user-info-avatar-size);\n height: var(--user-info-avatar-size);\n background-color: var(--user-dropdown-account-info-role-color);\n }\n\n &__avatar-fallback {\n @apply tw-rounded-lg tw-shrink-0 tw-flex tw-items-center tw-justify-center;\n width: var(--user-info-avatar-size);\n height: var(--user-info-avatar-size);\n background: var(--neutrals-100, #f5f5f5);\n color: var(--neutrals-400, #a3a3a3);\n }\n\n &__info {\n @apply tw-grow tw-basis-0 tw-overflow-hidden tw-flex tw-flex-col tw-items-start;\n transition:\n width var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease),\n flex var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease),\n opacity var(--app-bar-transition-duration, 200ms) var(--app-bar-hover-transition-timing-function, ease);\n }\n\n &__name {\n @apply tw-font-semibold tw-truncate tw-w-full tw-text-left tw-max-w-[250px];\n font-size: 13px;\n color: var(--neutrals-800, #262626);\n }\n\n &__role {\n @apply tw-truncate tw-text-left tw-w-full tw-max-w-[250px];\n font-size: 11px;\n color: var(--neutrals-400, #a3a3a3);\n }\n}\n\n.opacity-enter-active,\n.opacity-leave-active {\n transition: opacity 0.3s ease;\n}\n\n.opacity-enter-from,\n.opacity-leave-to {\n opacity: 0;\n}\n</style>\n","<template>\n <div class=\"vc-settings-menu\">\n <template\n v-for=\"(group, groupIndex) in groupedItems\"\n :key=\"group.name\"\n >\n <div\n v-if=\"groupIndex > 0\"\n class=\"vc-settings-menu__separator\"\n />\n <div class=\"vc-settings-menu__group\">\n <component\n :is=\"item.component\"\n v-for=\"item in group.items\"\n :key=\"item.id\"\n v-bind=\"item.props || {}\"\n />\n </div>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\nimport { useSettingsMenu } from \"@core/composables/useSettingsMenu\";\n\nconst { items } = useSettingsMenu();\n\nconst groupedItems = computed(() => {\n const groups = new Map<string, typeof items.value>();\n\n for (const item of items.value) {\n const groupName = item.group ?? \"general\";\n if (!groups.has(groupName)) {\n groups.set(groupName, []);\n }\n groups.get(groupName)!.push(item);\n }\n\n return Array.from(groups.entries()).map(([name, groupItems]) => ({\n name,\n items: groupItems,\n }));\n});\n</script>\n\n<style lang=\"scss\">\n.vc-settings-menu {\n @apply tw-w-full tw-py-1;\n\n &__separator {\n @apply tw-mx-3 tw-my-1 tw-border-t tw-border-solid tw-border-neutrals-200;\n }\n\n &__group {\n @apply tw-flex tw-flex-col;\n }\n}\n</style>\n","<template>\n <VcSidebar\n :model-value=\"isOpened\"\n position=\"left\"\n :teleport=\"!isDesktop\"\n :title=\"$t('SHELL.ACCOUNT.SETTINGS')\"\n @update:model-value=\"$emit('update:isOpened', $event)\"\n >\n <div\n v-if=\"isOpened\"\n class=\"vc-user-sidebar__menu\"\n @click.stop=\"$emit('update:isOpened', false)\"\n >\n <SettingsMenu />\n </div>\n </VcSidebar>\n</template>\n\n<script lang=\"ts\" setup>\nimport { IMenuItem } from \"@core/types\";\nimport { SettingsMenu } from \"@shell/components/settings-menu\";\nimport { VcSidebar } from \"@ui/components/organisms/vc-sidebar\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\n\ndefineProps<{\n isOpened: boolean;\n}>();\n\ndefineEmits<{\n (e: \"update:isOpened\", value: boolean): void;\n (e: \"item:click\", item: IMenuItem): void;\n}>();\n\nconst { isDesktop } = useResponsive();\n</script>\n\n<style lang=\"scss\">\n.vc-user-sidebar {\n &__menu {\n @apply tw-w-full tw-flex tw-flex-col;\n }\n\n .vc-app--mobile & {\n &__menu {\n @apply tw-static tw-shadow-none #{!important};\n }\n }\n}\n</style>\n","<template>\n <div class=\"vc-user-dropdown-button-container\">\n <button\n ref=\"buttonRef\"\n type=\"button\"\n class=\"vc-user-dropdown-button\"\n :class=\"{\n 'vc-user-dropdown-button--active': isMenuOpened,\n 'vc-user-dropdown-button--auto-width': disabled,\n 'vc-user-dropdown-button--mobile': isMobile,\n 'vc-user-dropdown-button--collapsed': !isPinned && isDesktop,\n }\"\n @click=\"handleClick\"\n >\n <div\n class=\"vc-user-dropdown-button__wrap\"\n :class=\"{\n 'vc-user-dropdown-button__wrap--active': isMenuOpened,\n }\"\n >\n <UserInfo\n class=\"vc-user-dropdown-button__user-info\"\n :avatar-url=\"avatarUrl\"\n :name=\"name\"\n :role=\"role\"\n :is-expanded=\"isExpanded\"\n />\n <div class=\"vc-user-dropdown-button__actions\">\n <div class=\"vc-user-dropdown-button__trigger\"></div>\n </div>\n </div>\n </button>\n\n <!-- Desktop: floating dropdown panel -->\n <VcDropdownPanel\n v-if=\"isDesktop\"\n v-model:show=\"isMenuOpened\"\n :anchor-ref=\"buttonRef\"\n placement=\"right\"\n width=\"260px\"\n max-width=\"300px\"\n >\n <SettingsMenu />\n </VcDropdownPanel>\n\n <!-- Mobile: full sidebar fallback -->\n <UserSidebar\n v-else\n v-model:is-opened=\"isMenuOpened\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, provide } from \"vue\";\nimport { CloseSettingsMenuKey } from \"@framework/injection-keys\";\nimport { default as UserInfo } from \"@shell/components/user-dropdown-button/_internal/user-info.vue\";\nimport { default as UserSidebar } from \"@shell/components/user-dropdown-button/_internal/user-sidebar.vue\";\nimport { SettingsMenu } from \"@shell/components/settings-menu\";\nimport { VcDropdownPanel } from \"@ui/components/molecules/vc-dropdown-panel\";\nimport { useSidebarState } from \"@core/composables/useSidebarState\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\n\nexport interface Props {\n avatarUrl?: string | undefined;\n name?: string | undefined;\n role?: string | undefined;\n disabled?: boolean;\n}\n\ndefineProps<Props>();\n\nconst isMenuOpened = ref(false);\nconst buttonRef = ref<HTMLElement | null>(null);\nconst { isPinned, isExpanded } = useSidebarState();\nconst { isMobile, isDesktop } = useResponsive();\n\nfunction closeMenu() {\n isMenuOpened.value = false;\n}\n\nprovide(CloseSettingsMenuKey, closeMenu);\n\nfunction handleClick() {\n isMenuOpened.value = !isMenuOpened.value;\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --user-dropdown-height: 54px;\n --user-dropdown-button-bg: var(--primary-500);\n --user-dropdown-button-bg-hover: var(--primary-700);\n --user-dropdown-button-bg-logout: var(--danger-500);\n --user-dropdown-button-bg-logout-hover: var(--danger-700);\n --user-dropdown-button-icon-color: var(--additional-50);\n --user-dropdown-account-info-name-color: var(--neutrals-950);\n --user-dropdown-account-info-role-color: var(--secondary-600);\n --user-dropdown-border-color: var(--app-bar-divider-color);\n --user-dropdown-button-color: var(--primary-500);\n --user-dropdown-wrap-bg: var(--neutrals-50);\n --user-dropdown-border-color: var(--neutrals-200);\n --user-dropdown-wrap-padding-left: 18px;\n}\n\n.vc-user-dropdown-button-container {\n @apply tw-flex tw-flex-col;\n}\n\n.vc-user-dropdown-button {\n @apply tw-w-full tw-cursor-pointer tw-relative tw-flex tw-h-[var(--user-dropdown-height)] tw-flex-col tw-select-none tw-overflow-hidden tw-border-solid tw-border-t tw-border-t-[var(--user-dropdown-border-color)] tw-pl-[var(--user-dropdown-wrap-padding-left)];\n transition: padding-left var(--app-bar-transition-duration, 200ms)\n var(--app-bar-hover-transition-timing-function, ease);\n\n &:hover {\n .vc-user-dropdown-button__trigger {\n @apply tw-visible tw-translate-x-0;\n }\n }\n\n .vc-app--mobile & {\n @apply tw-w-full #{!important};\n }\n\n &--mobile {\n }\n\n &--auto-width {\n @apply tw-w-auto;\n }\n\n &__wrap {\n @apply tw-flex tw-justify-between tw-items-center tw-flex-auto tw-bg-[--user-dropdown-wrap-bg] tw-gap-3 tw-min-w-0;\n }\n\n &__user-info {\n @apply tw-min-w-0 tw-flex-1;\n }\n\n &--collapsed {\n @apply tw-pl-0;\n transition: padding-left var(--app-bar-transition-duration, 200ms)\n var(--app-bar-hover-transition-timing-function, ease);\n\n .vc-user-dropdown-button__wrap {\n @apply tw-justify-center;\n }\n\n .vc-user-info {\n @apply tw-w-auto tw-justify-center tw-gap-0 tw-flex-none;\n }\n\n .vc-user-info__info {\n @apply tw-w-0 tw-overflow-hidden tw-opacity-0;\n flex: 0 0 0px;\n }\n\n .vc-user-dropdown-button__actions {\n @apply tw-hidden;\n }\n }\n\n &__actions {\n @apply tw-h-full tw-shrink-0;\n }\n\n &__trigger {\n @apply tw-invisible tw-absolute tw-right-0 tw-top-0 tw-h-full tw-w-1 tw-bg-[--user-dropdown-button-bg] tw-translate-x-full tw-transition-all tw-duration-300 tw-ease-in-out;\n }\n}\n</style>\n","import _UserDropdownButton from \"@shell/components/user-dropdown-button/user-dropdown-button.vue\";\n\nexport const UserDropdownButton = _UserDropdownButton as typeof _UserDropdownButton;\n","<template>\n <div\n class=\"sidebar-content\"\n :class=\"{ 'sidebar-content--no-header': !headerVisible }\"\n >\n <div\n v-if=\"showSearch && expanded\"\n class=\"sidebar-content__search\"\n >\n <VcInput\n v-model=\"searchQuery\"\n :placeholder=\"searchPlaceholder || $t('SHELL.SIDEBAR.SEARCH_PLACEHOLDER', 'Search keyword')\"\n size=\"small\"\n clearable\n :debounce=\"300\"\n />\n </div>\n\n <VcScrollableContainer\n v-if=\"!disableMenu\"\n ref=\"scrollContainer\"\n class=\"sidebar-content__menu\"\n >\n <slot\n name=\"menu\"\n :expanded=\"expanded\"\n :on-item-click=\"handleMenuItemClick\"\n :search-query=\"searchQuery\"\n >\n <VcAppMenu\n :expanded=\"expanded\"\n :search-query=\"searchQuery\"\n @item:click=\"handleMenuItemClick\"\n />\n </slot>\n </VcScrollableContainer>\n\n <div class=\"sidebar-content__footer\">\n <!-- eslint-disable vue/no-duplicate-attributes -- slot name + scoped prop -->\n <slot\n name=\"sidebar-footer\"\n :avatar=\"avatar\"\n :name=\"userName\"\n :role=\"userRole\"\n >\n <!-- eslint-enable vue/no-duplicate-attributes -->\n <UserDropdownButton\n v-if=\"!isEmbedded\"\n :avatar-url=\"avatar\"\n :name=\"userName\"\n :role=\"userRole\"\n />\n </slot>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { inject, ref, onMounted, nextTick, watch } from \"vue\";\nimport VcAppMenu from \"@ui/components/organisms/vc-app/_internal/menu/VcAppMenu.vue\";\nimport { VcScrollableContainer } from \"@ui/components/atoms/vc-scrollable-container\";\nimport { VcInput } from \"@ui/components/molecules/vc-input\";\nimport { UserDropdownButton } from \"@shell/components/user-dropdown-button\";\nimport { EmbeddedModeKey } from \"@framework/injection-keys\";\nimport type { MenuItem } from \"@core/types\";\n\nexport interface Props {\n expanded?: boolean;\n avatar?: string;\n userName?: string;\n userRole?: string;\n disableMenu?: boolean;\n headerVisible?: boolean;\n showSearch?: boolean;\n searchPlaceholder?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n expanded: true,\n disableMenu: false,\n headerVisible: true,\n showSearch: false,\n});\n\nconst emit = defineEmits<{\n (event: \"item:click\", item: MenuItem): void;\n}>();\n\ndefineSlots<{\n menu?: (props: { expanded: boolean; onItemClick: (item: MenuItem) => void; searchQuery: string }) => unknown;\n \"sidebar-footer\"?: (props: { avatar?: string; name?: string; role?: string }) => unknown;\n}>();\n\nconst isEmbedded = inject(EmbeddedModeKey, false);\n\nconst scrollContainer = ref<InstanceType<typeof VcScrollableContainer> | null>(null);\nconst searchQuery = ref(\"\");\n\nonMounted(() => {\n nextTick(() => scrollContainer.value?.updateScrollState());\n});\n\nwatch(\n () => props.expanded,\n (expanded) => {\n if (!expanded) searchQuery.value = \"\";\n },\n);\n\nconst handleMenuItemClick = (item: MenuItem) => {\n searchQuery.value = \"\";\n emit(\"item:click\", item);\n};\n</script>\n\n<style lang=\"scss\">\n.sidebar-content {\n @apply tw-flex tw-flex-col;\n height: calc(100% - var(--app-bar-height));\n\n &__search {\n @apply tw-flex-none tw-px-[18px] tw-py-[11px];\n background-color: var(--secondary-50);\n border-bottom: 1px solid var(--neutrals-200);\n border-top: 1px solid var(--neutrals-200);\n }\n\n &__menu {\n @apply tw-flex-grow tw-min-h-0 tw-pt-[14px];\n\n // Make nested containers transparent — the viewport is the sole scroll viewport\n .vc-menu,\n .vc-app-menu,\n .vc-container {\n @apply tw-h-auto tw-overflow-visible;\n }\n\n .vc-container__inner {\n @apply tw-overflow-visible;\n }\n }\n\n &__footer {\n @apply tw-flex-none tw-mt-auto;\n }\n\n &--no-header {\n height: 100%;\n }\n\n &:before {\n content: \"\";\n @apply tw-absolute tw-left-0 tw-top-[-1px] tw-w-full tw-h-[1px] tw-z-[var(--z-local-above)];\n background-color: var(--app-bar-border);\n }\n}\n</style>\n","<template>\n <div\n class=\"sidebar-collapse-button\"\n @click=\"$emit('click')\"\n >\n <div class=\"sidebar-collapse-button__wrap\">\n <VcIcon\n class=\"sidebar-collapse-button__icon\"\n :icon=\"collapsed ? 'lucide-chevron-right' : 'lucide-chevron-left'\"\n />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\ndefineProps<{\n collapsed?: boolean;\n}>();\n\ndefineEmits<{\n (event: \"click\"): void;\n}>();\n</script>\n\n<style lang=\"scss\">\n.sidebar-collapse-button {\n @apply tw-absolute tw-right-[-13px] tw-top-[50%] tw-translate-y-[-50%]\n tw-flex tw-items-center tw-justify-center tw-cursor-pointer tw-z-[var(--z-local-header)];\n width: var(--app-bar-collapse-button-width);\n height: var(--app-bar-collapse-button-height);\n border-radius: var(--app-bar-collapse-button-border-radius);\n background-color: var(--app-bar-background);\n border: 1px solid var(--app-bar-border);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--app-bar-hover-transition-duration) var(--app-bar-hover-transition-timing-function);\n\n &__wrap {\n @apply tw-flex tw-items-center tw-justify-center;\n }\n\n &__icon {\n color: var(--app-bar-button);\n }\n}\n</style>\n","import { computed, type Ref, toValue, type MaybeRefOrGetter } from \"vue\";\n\n/**\n * Base interface for items that can be controlled through toggling\n */\nexport interface ToggleableItem {\n id: string;\n}\n\n/**\n * Creates a content manager with basic operations\n *\n * @param itemsGetter - function to get the array of items\n * @param activeIdRef - reference for storing the active item ID\n * @returns object with methods and computed properties for managing content\n */\nexport function useToggleableContent<T extends ToggleableItem>(\n itemsGetter: MaybeRefOrGetter<T[] | null | undefined>,\n activeIdRef: Ref<string | null>,\n) {\n // Get the current active item directly from the array of items\n const currentItem = computed(() => {\n const items = toValue(itemsGetter);\n if (!activeIdRef.value || !Array.isArray(items)) {\n return null;\n }\n\n return items.find((item) => item.id === activeIdRef.value) || null;\n });\n\n // Check if any item is visible\n const isAnyItemVisible = computed(() => activeIdRef.value !== null);\n\n // Activate/deactivate item\n const toggleItem = (id: string) => {\n // If already active, hide\n if (activeIdRef.value === id) {\n activeIdRef.value = null;\n } else {\n // Otherwise, show\n activeIdRef.value = id;\n }\n };\n\n const closeItem = () => {\n activeIdRef.value = null;\n };\n\n // Show specific item\n const showItem = (id: string) => {\n activeIdRef.value = id;\n };\n\n // Hide all items\n const hideAllItems = () => {\n activeIdRef.value = null;\n };\n\n return {\n showItem,\n hideAllItems,\n toggleItem,\n currentItem,\n isAnyItemVisible,\n closeItem,\n };\n}\n","import { useAppBarWidget } from \"@core/composables/useAppBarWidget\";\nimport { useToggleableContent } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useToggleableContent\";\nimport { useAppBarState } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarState\";\n\nexport function useAppBarWidgets() {\n const { items } = useAppBarWidget();\n const { activeWidgetId } = useAppBarState();\n\n // Use the common composable to manage content\n const {\n showItem: showWidget,\n hideAllItems: hideAllWidgets,\n toggleItem: toggleWidget,\n currentItem: currentWidget,\n isAnyItemVisible: isAnyWidgetVisible,\n } = useToggleableContent(items, activeWidgetId);\n\n return {\n showWidget,\n hideAllWidgets,\n toggleWidget,\n currentWidget,\n isAnyWidgetVisible,\n };\n}\n","import { computed, ref, type Ref } from \"vue\";\nimport type { AppDescriptor } from \"@core/api/platform\";\nimport type { AppBarWidget } from \"@core/services/app-bar-menu-service\";\nimport { usePermissions } from \"@core/composables/usePermissions\";\n\nexport interface UseAppHubOptions {\n appsList: Ref<AppDescriptor[]>;\n widgets: Ref<AppBarWidget[]>;\n showApplications: Ref<boolean>;\n mobile: Ref<boolean>;\n}\n\nexport function useAppHub(options: UseAppHubOptions) {\n const { hasAccess } = usePermissions();\n const searchQuery = ref<string | null>(\"\");\n\n const normalizedQuery = computed(() => (searchQuery.value ?? \"\").trim().toLowerCase());\n const hasQuery = computed(() => normalizedQuery.value.length > 0);\n\n const accessibleApps = computed(() => options.appsList.value.filter((app) => hasAccess(app.permission)));\n\n const filteredApps = computed(() => {\n if (!options.showApplications.value) {\n return [];\n }\n\n if (!hasQuery.value) {\n return accessibleApps.value;\n }\n\n return accessibleApps.value.filter((app) => {\n const haystack = [app.title, app.description, app.id, app.relativeUrl].filter(Boolean).join(\" \").toLowerCase();\n return haystack.includes(normalizedQuery.value);\n });\n });\n\n const filteredWidgets = computed(() => {\n if (!hasQuery.value) {\n return options.widgets.value;\n }\n\n return options.widgets.value.filter((widget) => {\n const haystack = [getWidgetTitle(widget), widget.id, ...(widget.searchTerms ?? [])].join(\" \").toLowerCase();\n return haystack.includes(normalizedQuery.value);\n });\n });\n\n function getWidgetTitle(widget: AppBarWidget): string {\n return widget.title || humanizeWidgetId(widget.id);\n }\n\n return {\n searchQuery,\n filteredApps,\n filteredWidgets,\n getWidgetTitle,\n };\n}\n\nfunction humanizeWidgetId(id: string): string {\n if (!id) {\n return \"\";\n }\n\n return id\n .replace(/[\\-_]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n","<template>\n <div\n v-if=\"isAnyWidgetVisible && currentWidget?.component\"\n class=\"app-bar-widget-content\"\n :class=\"{ 'app-bar-widget-content--mobile': mobile }\"\n >\n <component\n :is=\"currentWidget?.component\"\n v-bind=\"widgetProps\"\n @close=\"hideAllWidgets\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\nimport { useAppBarWidgets } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarWidgets\";\n\nwithDefaults(\n defineProps<{\n mobile?: boolean;\n }>(),\n {\n mobile: false,\n },\n);\n\nconst { currentWidget, hideAllWidgets, isAnyWidgetVisible } = useAppBarWidgets();\n\nconst widgetProps = computed(() => ({\n ...(currentWidget.value?.props ?? {}),\n onClose: hideAllWidgets,\n}));\n</script>\n\n<style lang=\"scss\">\n.app-bar-widget-content {\n // Scroll bounding is handled by the parent container (menu-sidebar__content-main).\n}\n</style>\n","<template>\n <div\n class=\"app-hub-content\"\n :class=\"{ 'app-hub-content--mobile': mobile }\"\n >\n <div class=\"app-hub-content__search\">\n <VcInput\n v-model=\"searchQuery\"\n clearable\n size=\"small\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_APP.INTERNAL.APP_HUB.SEARCH_PLACEHOLDER')\"\n >\n <template #prepend-inner>\n <VcIcon\n icon=\"lucide-search\"\n size=\"s\"\n />\n </template>\n </VcInput>\n </div>\n\n <div\n class=\"app-hub-content__sections\"\n :class=\"{ 'app-hub-content__sections--single': !showApplications, 'app-hub-content__sections--mobile': mobile }\"\n >\n <section\n v-if=\"showApplications\"\n class=\"app-hub-content__section app-hub-content__section--apps\"\n >\n <header class=\"app-hub-content__section-header\">\n <span class=\"app-hub-content__section-title\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_APP.INTERNAL.APP_HUB.APPLICATIONS\") }}\n </span>\n </header>\n\n <VcScrollableContainer\n ref=\"appsScrollContainerRef\"\n class=\"app-hub-content__scroll\"\n >\n <slot\n name=\"applications\"\n :apps-list=\"filteredApps\"\n :switch-app=\"handleSwitchApp\"\n >\n <div\n v-if=\"filteredApps.length\"\n class=\"app-hub-content__apps-list app-hub-content__apps-list--tiles\"\n >\n <button\n v-for=\"app in visibleApps\"\n :key=\"app.id || app.title\"\n type=\"button\"\n :data-test-id=\"getAppTestId(app)\"\n class=\"app-hub-content__item app-hub-content__item--app app-hub-content__item--app-tile\"\n :class=\"{ 'app-hub-content__item--active': isAppActive(app) }\"\n @click=\"handleSwitchApp(app)\"\n >\n <img\n v-if=\"app.iconUrl\"\n :src=\"normalizeIconUrl(app.iconUrl)\"\n :alt=\"app.title || app.id || 'app icon'\"\n class=\"app-hub-content__item-icon app-hub-content__item-icon--tile\"\n />\n <VcIcon\n v-else\n icon=\"lucide-grid-2x2\"\n size=\"m\"\n class=\"app-hub-content__item-icon app-hub-content__item-icon--fallback app-hub-content__item-icon--tile\"\n />\n\n <div class=\"app-hub-content__item-content app-hub-content__item-content--center\">\n <div\n class=\"app-hub-content__item-title app-hub-content__item-title--app app-hub-content__item-title--center\"\n >\n {{ app.title || app.id }}\n </div>\n </div>\n </button>\n </div>\n <div\n v-else\n class=\"app-hub-content__empty\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_APP.INTERNAL.APP_HUB.NO_APPLICATIONS\") }}\n </div>\n </slot>\n </VcScrollableContainer>\n </section>\n\n <section class=\"app-hub-content__section app-hub-content__section--widgets\">\n <div class=\"app-hub-content__widgets-inner\">\n <!-- Active widget content (inline) -->\n <template v-if=\"!mobile && isAnyWidgetVisible && currentWidget?.component\">\n <header class=\"app-hub-content__section-header app-hub-content__section-header--back\">\n <button\n class=\"app-hub-content__back-button\"\n @click=\"hideAllWidgets\"\n >\n <VcIcon\n icon=\"lucide-arrow-left\"\n size=\"xs\"\n />\n <span class=\"app-hub-content__back-title\">{{ getWidgetTitle(currentWidget) }}</span>\n </button>\n </header>\n <VcScrollableContainer class=\"app-hub-content__widget-inline-body\">\n <AppBarWidgetContent />\n </VcScrollableContainer>\n </template>\n\n <!-- Widget list (default) -->\n <template v-else>\n <header class=\"app-hub-content__section-header\">\n <span class=\"app-hub-content__section-title\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_APP.INTERNAL.APP_HUB.WIDGETS\") }}\n </span>\n </header>\n\n <VcScrollableContainer\n ref=\"widgetsScrollContainerRef\"\n class=\"app-hub-content__scroll\"\n >\n <div\n v-if=\"filteredWidgets.length\"\n class=\"app-hub-content__list\"\n >\n <button\n v-for=\"widget in visibleWidgets\"\n :key=\"widget.id\"\n type=\"button\"\n :data-widget-id=\"widget.id\"\n class=\"app-hub-content__item app-hub-content__item--widget\"\n :class=\"{ 'app-hub-content__item--active': isWidgetActive(widget.id) }\"\n @click=\"handleWidgetClick(widget)\"\n >\n <div class=\"app-hub-content__widget-icon-wrap\">\n <VcIcon\n :icon=\"widget.icon || 'lucide-layout-grid'\"\n size=\"s\"\n class=\"app-hub-content__item-icon app-hub-content__item-icon--fallback\"\n />\n <span\n v-if=\"isBadgeActive(widget)\"\n class=\"app-hub-content__widget-badge\"\n />\n </div>\n\n <div class=\"app-hub-content__item-content\">\n <div class=\"app-hub-content__item-title\">\n {{ getWidgetTitle(widget) }}\n </div>\n </div>\n </button>\n </div>\n\n <div\n v-else\n class=\"app-hub-content__empty\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_APP.INTERNAL.APP_HUB.NO_WIDGETS\") }}\n </div>\n </VcScrollableContainer>\n </template>\n </div>\n </section>\n </div>\n\n <Transition name=\"app-hub-content-flyout\">\n <div\n v-if=\"mobile && isAnyWidgetVisible && currentWidget?.component\"\n class=\"app-hub-content__flyout app-hub-content__flyout--mobile\"\n >\n <div class=\"app-hub-content__flyout-header\">\n <span class=\"app-hub-content__flyout-title\">{{ getWidgetTitle(currentWidget) }}</span>\n <VcButton\n icon=\"lucide-x\"\n text\n @click=\"hideAllWidgets\"\n />\n </div>\n <div class=\"app-hub-content__flyout-body\">\n <AppBarWidgetContent mobile />\n </div>\n </div>\n </Transition>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useSlots, watch } from \"vue\";\nimport type { AppDescriptor } from \"@core/api/platform\";\nimport type { AppBarWidget } from \"@core/services/app-bar-menu-service\";\nimport { useAppBarWidget } from \"@core/composables\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcInput } from \"@ui/components/molecules/vc-input\";\nimport { VcScrollableContainer } from \"@ui/components/atoms/vc-scrollable-container\";\nimport { useAppHub } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppHub\";\nimport { useAppBarWidgets } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarWidgets\";\nimport AppBarWidgetContent from \"@ui/components/organisms/vc-app/_internal/app-bar/components/AppBarWidgetContent.vue\";\n\ninterface Props {\n appsList: AppDescriptor[];\n showApplications?: boolean;\n mobile?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n showApplications: true,\n mobile: false,\n});\n\nconst emit = defineEmits<{\n (e: \"switch-app\", app: AppDescriptor): void;\n}>();\n\ndefineSlots<{\n applications?: (props: { appsList: AppDescriptor[]; switchApp: (app: AppDescriptor) => void }) => unknown;\n}>();\n\nconst slots = useSlots();\nconst hasCustomApplicationsSlot = computed(() => typeof slots.applications === \"function\");\nconst appsScrollContainerRef = ref<InstanceType<typeof VcScrollableContainer> | null>(null);\nconst widgetsScrollContainerRef = ref<InstanceType<typeof VcScrollableContainer> | null>(null);\n\nconst { items } = useAppBarWidget();\nconst { currentWidget, hideAllWidgets, isAnyWidgetVisible, toggleWidget } = useAppBarWidgets();\n\nconst PROGRESSIVE_RENDER_THRESHOLD = 120;\nconst INITIAL_RENDER_BATCH_SIZE = 120;\nconst RENDER_BATCH_SIZE = 80;\nconst LOAD_MORE_TRIGGER_OFFSET = 120;\n\nconst { searchQuery, filteredApps, filteredWidgets, getWidgetTitle } = useAppHub({\n appsList: toRef(props, \"appsList\"),\n widgets: items,\n showApplications: toRef(props, \"showApplications\"),\n mobile: toRef(props, \"mobile\"),\n});\n\nconst appsRenderLimit = ref(INITIAL_RENDER_BATCH_SIZE);\nconst widgetsRenderLimit = ref(INITIAL_RENDER_BATCH_SIZE);\n\nconst shouldProgressiveRenderApps = computed(() => {\n return !hasCustomApplicationsSlot.value && filteredApps.value.length > PROGRESSIVE_RENDER_THRESHOLD;\n});\n\nconst shouldProgressiveRenderWidgets = computed(() => {\n return filteredWidgets.value.length > PROGRESSIVE_RENDER_THRESHOLD;\n});\n\nconst visibleApps = computed(() => {\n if (!shouldProgressiveRenderApps.value) {\n return filteredApps.value;\n }\n\n return filteredApps.value.slice(0, appsRenderLimit.value);\n});\n\nconst visibleWidgets = computed(() => {\n if (!shouldProgressiveRenderWidgets.value) {\n return filteredWidgets.value;\n }\n\n return filteredWidgets.value.slice(0, widgetsRenderLimit.value);\n});\n\nwatch(\n () => items.value.map((item) => item.id),\n () => {\n if (isAnyWidgetVisible.value && !currentWidget.value) {\n hideAllWidgets();\n }\n },\n);\n\nwatch(\n [() => filteredApps.value.length, shouldProgressiveRenderApps],\n ([length, progressive]) => {\n appsRenderLimit.value = progressive ? Math.min(length, INITIAL_RENDER_BATCH_SIZE) : length;\n nextTick(() => refreshScrollState(appsScrollContainerRef.value));\n },\n { immediate: true },\n);\n\nwatch(\n [() => filteredWidgets.value.length, shouldProgressiveRenderWidgets],\n ([length, progressive]) => {\n widgetsRenderLimit.value = progressive ? Math.min(length, INITIAL_RENDER_BATCH_SIZE) : length;\n nextTick(() => refreshScrollState(widgetsScrollContainerRef.value));\n },\n { immediate: true },\n);\n\nwatch(\n () => resolveScrollViewport(appsScrollContainerRef.value),\n (viewport, previousViewport) => {\n previousViewport?.removeEventListener(\"scroll\", handleAppsScroll);\n viewport?.addEventListener(\"scroll\", handleAppsScroll, { passive: true });\n },\n { immediate: true },\n);\n\nwatch(\n () => resolveScrollViewport(widgetsScrollContainerRef.value),\n (viewport, previousViewport) => {\n previousViewport?.removeEventListener(\"scroll\", handleWidgetsScroll);\n viewport?.addEventListener(\"scroll\", handleWidgetsScroll, { passive: true });\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n resolveScrollViewport(appsScrollContainerRef.value)?.removeEventListener(\"scroll\", handleAppsScroll);\n resolveScrollViewport(widgetsScrollContainerRef.value)?.removeEventListener(\"scroll\", handleWidgetsScroll);\n});\n\nfunction normalizeIconUrl(url: string): string {\n if (\n !url ||\n url.startsWith(\"/\") ||\n url.startsWith(\"http://\") ||\n url.startsWith(\"https://\") ||\n url.startsWith(\"data:\")\n ) {\n return url;\n }\n\n return `/${url}`;\n}\n\nfunction isAppActive(app: AppDescriptor): boolean {\n if (typeof window === \"undefined\") {\n return false;\n }\n\n const currentPath = normalizePath(window.location.pathname);\n const appPath = normalizePath(app.relativeUrl ?? \"\");\n\n if (!appPath) {\n return false;\n }\n\n if (appPath === \"/\") {\n return currentPath === \"/\";\n }\n\n return currentPath.startsWith(appPath);\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"\";\n }\n\n const normalized = path.replace(/\\/+$/, \"\");\n return normalized || \"/\";\n}\n\nfunction handleSwitchApp(app: AppDescriptor): void {\n hideAllWidgets();\n emit(\"switch-app\", app);\n}\n\nfunction getAppTestId(app: AppDescriptor): string {\n const rawValue = (app.id || app.title || \"unknown\").toString().trim().toLowerCase();\n const sanitized = rawValue.replace(/[^a-z0-9]+/g, \"-\").replace(/(^-|-$)/g, \"\");\n return `app-hub-app-${sanitized || \"unknown\"}`;\n}\n\nfunction handleAppsScroll(): void {\n if (!shouldProgressiveRenderApps.value) {\n return;\n }\n\n maybeExtendRenderLimit({\n container: appsScrollContainerRef.value,\n totalItems: filteredApps.value.length,\n renderLimit: appsRenderLimit,\n });\n}\n\nfunction handleWidgetsScroll(): void {\n if (!shouldProgressiveRenderWidgets.value) {\n return;\n }\n\n maybeExtendRenderLimit({\n container: widgetsScrollContainerRef.value,\n totalItems: filteredWidgets.value.length,\n renderLimit: widgetsRenderLimit,\n });\n}\n\nfunction handleWidgetClick(widget: AppBarWidget): void {\n if (widget.component) {\n toggleWidget(widget.id);\n }\n\n widget.onClick?.();\n}\n\nfunction maybeExtendRenderLimit(params: {\n container: InstanceType<typeof VcScrollableContainer> | null;\n totalItems: number;\n renderLimit: { value: number };\n}): void {\n const viewport = resolveScrollViewport(params.container);\n if (!viewport || params.renderLimit.value >= params.totalItems) {\n return;\n }\n\n const remainingSpace = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;\n\n if (remainingSpace > LOAD_MORE_TRIGGER_OFFSET) {\n return;\n }\n\n params.renderLimit.value = Math.min(params.renderLimit.value + RENDER_BATCH_SIZE, params.totalItems);\n nextTick(() => refreshScrollState(params.container));\n}\n\nfunction resolveScrollViewport(container: InstanceType<typeof VcScrollableContainer> | null): HTMLElement | null {\n if (!container) {\n return null;\n }\n\n const exposedContainer = container as unknown as {\n viewportRef?: {\n value: HTMLElement | null;\n };\n };\n\n return exposedContainer.viewportRef?.value ?? null;\n}\n\nfunction refreshScrollState(container: InstanceType<typeof VcScrollableContainer> | null): void {\n if (!container) {\n return;\n }\n\n const exposedContainer = container as unknown as {\n updateScrollState?: () => void;\n };\n\n exposedContainer.updateScrollState?.();\n}\n\nfunction isWidgetActive(id: string): boolean {\n return currentWidget.value?.id === id;\n}\n\nfunction isBadgeActive(widget: AppBarWidget): boolean {\n if (widget.badge === undefined) {\n return false;\n }\n\n if (typeof widget.badge === \"function\") {\n return widget.badge();\n }\n\n return !!widget.badge;\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --app-hub-panel-width: 580px;\n --app-hub-search-padding: 12px;\n --app-hub-divider-color: var(--neutrals-200);\n --app-hub-item-bg-hover: var(--secondary-100);\n --app-hub-item-bg-active: var(--secondary-200);\n --app-hub-item-title: var(--neutrals-950);\n --app-hub-item-subtitle: var(--neutrals-500);\n --app-hub-item-icon: var(--neutrals-500);\n --app-hub-item-icon-active: var(--primary-500);\n}\n\n// The parent .vc-dropdown-panel__content is flex:1 + overflow:hidden but NOT\n// a flex container, so percentage/flex heights inside it don't resolve.\n// Make it a flex container so .app-hub-content can use flex:1 + min-height:0\n// to receive the bounded height from floating-ui's maxHeight.\n.vc-dropdown-panel__content:has(> .app-hub-content) {\n display: flex;\n flex-direction: column;\n}\n\n.app-hub-content {\n @apply tw-relative tw-flex tw-flex-col tw-overflow-hidden;\n width: var(--app-hub-panel-width);\n max-width: calc(100vw - 32px);\n // 0 1 auto = content-sized (panel shrinks to fit apps), but can shrink\n // below content when viewport is short (enables scroll via min-height:0).\n flex: 0 1 auto;\n min-height: 0;\n\n &--mobile {\n @apply tw-w-full tw-max-w-full tw-h-auto tw-overflow-visible;\n }\n\n &__search {\n @apply tw-p-[var(--app-hub-search-padding)] tw-border-b tw-border-solid;\n border-color: var(--app-hub-divider-color);\n }\n\n &__sections {\n @apply tw-grid tw-gap-0 tw-min-h-0;\n flex: 0 1 auto;\n grid-template-columns: minmax(0, 1fr) 220px;\n\n &--single {\n grid-template-columns: minmax(0, 1fr);\n }\n\n &--mobile {\n @apply tw-flex tw-flex-col tw-min-h-0 tw-max-h-none;\n\n .app-hub-content__section--apps,\n .app-hub-content__section--widgets {\n min-height: 0;\n }\n\n .app-hub-content__section--apps {\n @apply tw-border-r-0 tw-border-b tw-border-solid;\n border-color: var(--app-hub-divider-color);\n }\n\n // In mobile flex-column layout, widgets-inner must NOT be absolute\n // (absolute is only for the desktop two-column grid where apps drive row height).\n .app-hub-content__widgets-inner {\n @apply tw-relative tw-inset-auto;\n }\n\n .app-hub-content__section--widgets .app-hub-content__scroll {\n max-height: 220px;\n }\n\n .app-hub-content__section--apps .app-hub-content__scroll {\n max-height: 260px;\n }\n }\n }\n\n &__section {\n @apply tw-flex tw-flex-col tw-min-h-0 tw-overflow-hidden;\n\n &--apps {\n @apply tw-border-r tw-border-solid;\n border-color: var(--app-hub-divider-color);\n }\n\n &--widgets {\n @apply tw-bg-[var(--app-bar-background)] tw-relative;\n }\n }\n\n // Absolutely positioned inner wrapper — removes the widgets column\n // from the grid row's intrinsic height calculation so only the apps\n // column drives the panel height. Content scrolls within.\n &__widgets-inner {\n @apply tw-absolute tw-inset-0 tw-flex tw-flex-col tw-overflow-hidden;\n }\n\n &__section-header {\n @apply tw-flex tw-items-center tw-justify-between tw-gap-2 tw-px-3 tw-pt-3 tw-pb-2;\n\n &--back {\n @apply tw-px-2 tw-pt-2 tw-pb-1;\n }\n }\n\n &__section-title {\n @apply tw-text-xs tw-font-semibold tw-uppercase tw-tracking-wide;\n color: var(--app-hub-item-subtitle);\n }\n\n &__scroll {\n @apply tw-flex-1 tw-min-h-0;\n\n .vc-scrollable-container {\n @apply tw-h-full;\n }\n\n .vc-scrollable-container__viewport {\n @apply tw-px-2 tw-pb-2;\n }\n }\n\n &__view-mode {\n @apply tw-shrink-0;\n }\n\n &__apps-list {\n @apply tw-flex tw-flex-col tw-gap-0.5;\n\n &--tiles {\n @apply tw-grid tw-gap-1.5;\n grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));\n }\n }\n\n &__list {\n @apply tw-flex tw-flex-col tw-gap-0.5;\n }\n\n &__item {\n @apply tw-w-full tw-flex tw-items-center tw-gap-1.5 tw-rounded-md tw-px-1.5 tw-py-1.5 tw-text-left tw-transition-colors tw-duration-150;\n\n &:hover {\n background: var(--app-hub-item-bg-hover);\n }\n\n &--active {\n background: var(--app-hub-item-bg-active);\n\n .app-hub-content__item-icon--fallback {\n color: var(--app-hub-item-icon-active);\n }\n }\n\n &--widget {\n @apply tw-py-1.5;\n }\n\n &--app-tile {\n @apply tw-flex-col tw-items-center tw-justify-start tw-gap-1.5 tw-px-1.5 tw-py-2;\n min-height: 82px;\n }\n }\n\n &__item-icon {\n @apply tw-w-4 tw-h-4 tw-shrink-0 tw-rounded;\n\n &--tile {\n @apply tw-w-7 tw-h-7;\n }\n\n &--fallback {\n color: var(--app-hub-item-icon);\n }\n }\n\n &__item-content {\n @apply tw-min-w-0 tw-flex tw-flex-col;\n\n &--center {\n @apply tw-items-center tw-text-center tw-w-full;\n }\n }\n\n &__item-title {\n @apply tw-text-xs tw-leading-4 tw-truncate;\n color: var(--app-hub-item-title);\n\n &--app {\n @apply tw-whitespace-normal tw-break-words;\n overflow: visible;\n text-overflow: clip;\n }\n\n &--center {\n @apply tw-max-w-full tw-text-center;\n }\n }\n\n &__item-subtitle {\n @apply tw-text-[10px] tw-leading-4 tw-whitespace-normal tw-break-words;\n overflow: visible;\n text-overflow: clip;\n color: var(--app-hub-item-subtitle);\n }\n\n &__empty {\n @apply tw-text-sm tw-px-2 tw-py-3;\n color: var(--app-hub-item-subtitle);\n }\n\n &__widget-icon-wrap {\n @apply tw-relative tw-shrink-0 tw-w-5 tw-h-5 tw-flex tw-items-center tw-justify-center;\n }\n\n &__widget-badge {\n @apply tw-absolute -tw-right-[2px] -tw-top-[2px] tw-w-[6px] tw-h-[6px] tw-rounded-full;\n background-color: var(--danger-500);\n }\n\n &__back-button {\n @apply tw-flex tw-items-center tw-gap-1.5 tw-px-1.5 tw-py-1 tw-rounded-md tw-text-xs tw-font-medium tw-cursor-pointer tw-transition-colors tw-duration-150;\n color: var(--app-hub-item-title);\n\n &:hover {\n background: var(--app-hub-item-bg-hover);\n }\n }\n\n &__back-title {\n @apply tw-truncate;\n }\n\n &__widget-inline-body {\n @apply tw-flex tw-flex-col tw-flex-1 tw-min-h-0 tw-overflow-hidden;\n }\n\n &__flyout {\n @apply tw-mx-2 tw-mb-2 tw-w-auto tw-max-h-none tw-flex tw-flex-col tw-rounded-md tw-border tw-border-solid tw-bg-[var(--app-bar-background)] tw-shadow-md;\n border-color: var(--app-hub-divider-color);\n }\n\n &__flyout-header {\n @apply tw-flex tw-items-center tw-justify-between tw-gap-2 tw-px-3 tw-py-2 tw-border-b tw-border-solid;\n border-color: var(--app-hub-divider-color);\n }\n\n &__flyout-title {\n @apply tw-text-sm tw-font-medium tw-truncate;\n color: var(--app-hub-item-title);\n }\n\n &__flyout-body {\n @apply tw-overflow-auto tw-min-h-0;\n }\n}\n\n.app-hub-content-flyout-enter-active,\n.app-hub-content-flyout-leave-active {\n transition:\n opacity 0.16s ease,\n transform 0.16s ease;\n}\n\n.app-hub-content-flyout-enter-from,\n.app-hub-content-flyout-leave-to {\n opacity: 0;\n transform: translateY(-4px);\n}\n</style>\n","<template>\n <VcDropdownPanel\n v-model:show=\"isOpen\"\n :anchor-ref=\"anchorRef\"\n placement=\"right-start\"\n width=\"560px\"\n max-width=\"calc(100vw - 24px)\"\n :max-height=\"9999\"\n :content-scrollable=\"false\"\n >\n <AppHubContent\n :apps-list=\"appsList\"\n :show-applications=\"showApplications\"\n @switch-app=\"handleSwitchApp\"\n >\n <template\n v-if=\"$slots.applications\"\n #applications=\"applicationsScope\"\n >\n <slot\n name=\"applications\"\n v-bind=\"applicationsScope\"\n />\n </template>\n </AppHubContent>\n </VcDropdownPanel>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, watch } from \"vue\";\nimport type { AppDescriptor } from \"@core/api/platform\";\nimport { VcDropdownPanel } from \"@ui/components/molecules/vc-dropdown-panel\";\nimport { useAppBarWidgets } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarWidgets\";\nimport AppHubContent from \"@ui/components/organisms/vc-app/_internal/app-bar/components/AppHubContent.vue\";\n\ninterface Props {\n show: boolean;\n anchorRef?: HTMLElement | null;\n appsList: AppDescriptor[];\n showApplications?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n anchorRef: null,\n showApplications: true,\n});\n\nconst emit = defineEmits<{\n (e: \"update:show\", value: boolean): void;\n (e: \"switch-app\", app: AppDescriptor): void;\n}>();\n\ndefineSlots<{\n applications?: (props: { appsList: AppDescriptor[]; switchApp: (app: AppDescriptor) => void }) => unknown;\n}>();\n\nconst { hideAllWidgets } = useAppBarWidgets();\n\nconst isOpen = computed({\n get: () => props.show,\n set: (value: boolean) => {\n emit(\"update:show\", value);\n },\n});\n\nwatch(\n () => props.show,\n (nextValue) => {\n if (!nextValue) {\n hideAllWidgets();\n }\n },\n);\n\nfunction handleSwitchApp(app: AppDescriptor): void {\n emit(\"switch-app\", app);\n emit(\"update:show\", false);\n}\n</script>\n","<template>\n <div\n class=\"vc-notification-template\"\n @click=\"$emit('click')\"\n >\n <div\n class=\"vc-notification-template__container\"\n :class=\"{\n 'vc-notification-template__container--mobile': isMobile,\n }\"\n >\n <div\n class=\"vc-notification-template__icon-container\"\n :style=\"{ backgroundColor: color ?? 'var(--primary-500)' }\"\n >\n <VcIcon\n :icon=\"icon ?? 'lucide-bell'\"\n size=\"s\"\n />\n </div>\n <div class=\"vc-notification-template__content\">\n <p\n class=\"vc-notification-template__title\"\n :class=\"{ 'vc-notification-template__title--desktop': isDesktop }\"\n >\n {{ title }}\n </p>\n <p class=\"vc-notification-template__time\">\n {{ pushTime }}\n </p>\n <div\n v-if=\"$slots.default\"\n class=\"vc-notification-template__content-body\"\n >\n <slot></slot>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PushNotification } from \"@core/api/platform\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\n\nexport interface Props {\n title: string;\n notification: PushNotification;\n icon?: string;\n color?: string;\n severity?: string;\n}\nexport interface Emits {\n (e: \"click\"): void;\n}\n\nconst props = defineProps<Props>();\nconst _emit = defineEmits<Emits>();\nconst { isMobile, isDesktop } = useResponsive();\n\nconst locale = window.navigator.language;\n\nconst MINUTE = 60;\nconst HOUR = 3600;\nconst DAY = 86400;\n\nconst pushTime = computed(() => {\n const created = props.notification.created;\n if (!created) return \"\";\n\n const date = created instanceof Date ? created : new Date(created);\n if (Number.isNaN(date.getTime())) return \"\";\n const now = Date.now();\n const diffSec = Math.round((now - date.getTime()) / 1000);\n const absDiffSec = Math.abs(diffSec);\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" });\n\n // Recent notifications: relative time\n if (absDiffSec < MINUTE) {\n return rtf.format(-diffSec, \"second\");\n }\n if (absDiffSec < HOUR) {\n return rtf.format(-Math.round(diffSec / MINUTE), \"minute\");\n }\n if (absDiffSec < DAY) {\n return rtf.format(-Math.round(diffSec / HOUR), \"hour\");\n }\n\n // Older notifications: absolute date-time\n return new Intl.DateTimeFormat(locale, {\n dateStyle: \"short\",\n timeStyle: \"short\",\n }).format(date);\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --notification-template-icon-color: var(--additional-50);\n --notification-template-text-color: var(--additional-950);\n --notification-template-time-color: var(--neutrals-500);\n --notification-template-content-body-color: var(--neutrals-700);\n}\n\n.vc-notification-template {\n @apply tw-w-full;\n\n &__container {\n @apply tw-flex tw-flex-row tw-grow tw-basis-0;\n\n &--mobile {\n @apply tw-flex-col-reverse;\n }\n }\n\n &__left {\n @apply tw-flex tw-items-center;\n }\n\n &__icon-container {\n @apply tw-w-[41px] tw-h-[41px] tw-rounded-full tw-text-[color:var(--notification-template-icon-color)]\n tw-mr-4 tw-flex tw-items-center tw-justify-center tw-shrink-0;\n }\n\n &__title {\n @apply tw-text-[color:var(--notification-template-text-color)] tw-text-xs tw-leading-[19px]\n tw-font-medium tw-m-0 tw-text-wrap;\n word-break: break-word;\n }\n\n &__right {\n @apply tw-flex tw-shrink-0;\n\n &--mobile {\n @apply tw-mb-2 tw-justify-end;\n }\n }\n\n &__content {\n @apply tw-flex-1 tw-min-w-0;\n }\n\n &__content-body {\n @apply tw-text-xs tw-text-[color:var(--notification-template-content-body-color)] tw-m-0 tw-text-wrap;\n }\n\n &__time {\n @apply tw-text-xxs tw-text-[color:var(--notification-template-time-color)] tw-m-0 tw-mb-2;\n }\n}\n</style>\n","import _NotificationTemplate from \"@shell/components/notification-template/notification-template.vue\";\n\nexport const NotificationTemplate = _NotificationTemplate as typeof _NotificationTemplate;\n","<template>\n <div\n class=\"vc-notification-item\"\n @click=\"handleClick\"\n >\n <div\n class=\"vc-notification-item__unread-dot\"\n :style=\"{ visibility: notification.isNew ? 'visible' : 'hidden' }\"\n />\n <div class=\"vc-notification-item__content\">\n <component\n :is=\"currentTemplate\"\n v-if=\"currentTemplate\"\n />\n <NotificationTemplate\n v-else\n :title=\"notification.title ?? ''\"\n :notification=\"notification\"\n >\n <VcHint\n v-if=\"notification.description\"\n class=\"tw-mb-1\"\n >\n {{ notification.description }}\n </VcHint>\n </NotificationTemplate>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, provide } from \"vue\";\nimport { PushNotification } from \"@core/api/platform\";\nimport { useNotificationStore, NotificationContextKey } from \"@core/notifications\";\nimport { NotificationTemplate } from \"@shell/components/notification-template\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\n\nexport interface Props {\n notification: PushNotification;\n}\n\nexport interface Emits {\n (event: \"onClick\", notification: PushNotification): void;\n}\n\nconst props = defineProps<Props>();\nconst emit = defineEmits<Emits>();\n\nconst store = useNotificationStore();\n\nconst currentTemplate = computed(() => {\n const type = props.notification.notifyType;\n if (!type) return undefined;\n return store.registry.get(type)?.template;\n});\n\nprovide(\n NotificationContextKey,\n computed(() => props.notification),\n);\n\nconst handleClick = () => {\n emit(\"onClick\", props.notification);\n};\n</script>\n\n<style lang=\"scss\">\n:root {\n --notification-unread-dot-color: var(--primary-500);\n}\n\n.vc-notification-item {\n @apply tw-flex tw-items-start tw-p-3 tw-w-full tw-gap-2 tw-cursor-pointer;\n border-bottom: 1px solid var(--neutrals-100);\n\n &:last-child {\n border-bottom: none;\n }\n\n &__unread-dot {\n @apply tw-w-2 tw-h-2 tw-rounded-full tw-shrink-0 tw-mt-1.5;\n background-color: var(--notification-unread-dot-color);\n }\n\n &__content {\n @apply tw-flex-1 tw-min-w-0;\n }\n}\n</style>\n","<template>\n <div class=\"notification-dropdown\">\n <VcScrollableContainer\n v-if=\"notifications.length\"\n class=\"notification-dropdown__scroll\"\n >\n <div\n v-for=\"item in notifications\"\n :key=\"item.id\"\n >\n <NotificationItem :notification=\"item\" />\n </div>\n </VcScrollableContainer>\n <div\n v-else\n class=\"tw-flex tw-justify-center tw-items-center tw-p-4 tw-text-sm tw-text-[color:var(--neutrals-400)]\"\n >\n {{ t(\"COMPONENTS.NOTIFICATION_DROPDOWN.EMPTY\") }}\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, onBeforeUnmount } from \"vue\";\nimport NotificationItem from \"@shell/components/notification-dropdown/_internal/notification/notification.vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { useNotificationStore } from \"@core/notifications\";\nimport { VcScrollableContainer } from \"@ui/components/atoms/vc-scrollable-container\";\n\nconst store = useNotificationStore();\nconst { t } = useI18n({ useScope: \"global\" });\n\n// Sort with timestamp normalization to handle mixed string/Date created values\nconst notifications = computed(() =>\n [...store.history.value].sort(\n (a, b) => new Date(b.created as unknown as string).getTime() - new Date(a.created as unknown as string).getTime(),\n ),\n);\n\n// Mark all as read when dropdown closes (persists to server)\nonBeforeUnmount(() => {\n if (store.hasUnread.value) {\n store.markAllAsRead();\n }\n});\n</script>\n\n<style lang=\"scss\">\n// Make __content a flex container so the flex-1 chain works all the way down\n.vc-dropdown-panel__content:has(> .notification-dropdown) {\n @apply tw-flex tw-flex-col tw-min-h-0;\n}\n\n.notification-dropdown {\n @apply tw-flex tw-flex-col tw-flex-1 tw-min-h-0 tw-overflow-hidden;\n\n &__scroll {\n @apply tw-flex-1 tw-min-h-0;\n }\n}\n</style>\n","import _NotificationDropdown from \"@shell/components/notification-dropdown/notification-dropdown.vue\";\n\nexport const NotificationDropdown = _NotificationDropdown as typeof _NotificationDropdown;\n","<template>\n <!-- Spacer: pushes main content to the right to account for fixed sidebar -->\n <div\n class=\"desktop-layout__spacer\"\n :class=\"{\n 'desktop-layout__spacer--expanded': sidebar.isPinned.value,\n }\"\n />\n\n <!-- Fixed left sidebar -->\n <nav\n class=\"desktop-layout\"\n :aria-label=\"$t('SHELL.NAVIGATION_ARIA_LABEL')\"\n :class=\"{\n 'desktop-layout--collapsed': !sidebar.isPinned.value,\n }\"\n >\n <div\n class=\"desktop-layout__wrap\"\n :class=\"{\n 'desktop-layout__wrap--collapsed': !sidebar.isPinned.value,\n 'desktop-layout__wrap--expanded': sidebar.isPinned.value,\n }\"\n >\n <!-- Collapse/expand pin button (visible on hover) -->\n <SidebarCollapseButton\n v-show=\"!sidebar.isMenuOpen.value\"\n :collapsed=\"!sidebar.isPinned.value\"\n @click=\"sidebar.togglePin\"\n />\n\n <slot\n name=\"sidebar-header\"\n :logo=\"logo\"\n :expanded=\"sidebar.isExpanded.value\"\n :is-mobile=\"false\"\n >\n <SidebarHeader\n v-if=\"showHeader\"\n :logo=\"logo\"\n :expanded=\"sidebar.isExpanded.value\"\n :show-burger=\"sidebar.isExpanded.value\"\n :is-menu-open=\"sidebar.isMenuOpen.value\"\n :is-notifications-open=\"isNotificationsOpen\"\n class=\"desktop-layout__header\"\n @logo:click=\"$emit('logo:click')\"\n @toggle-menu=\"handleToggleMenu\"\n @toggle-notifications=\"handleToggleNotifications\"\n />\n </slot>\n\n <SidebarContent\n :expanded=\"sidebar.isExpanded.value\"\n :avatar=\"avatar\"\n :user-name=\"userName\"\n :user-role=\"userRole\"\n :disable-menu=\"disableMenu\"\n :header-visible=\"showHeader\"\n :show-search=\"showSearch\"\n :search-placeholder=\"searchPlaceholder\"\n @item:click=\"$emit('item:click', $event)\"\n >\n <template\n v-if=\"$slots.menu\"\n #menu=\"menuScope\"\n >\n <slot\n name=\"menu\"\n v-bind=\"menuScope\"\n />\n </template>\n <template\n v-if=\"$slots['sidebar-footer']\"\n #sidebar-footer=\"footerScope\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"footerScope\"\n />\n </template>\n </SidebarContent>\n </div>\n </nav>\n\n <AppHubPopover\n :show=\"sidebar.isMenuOpen.value\"\n :anchor-ref=\"appHubAnchorRef\"\n :apps-list=\"appsList\"\n :show-applications=\"!disableAppHub\"\n @update:show=\"handleAppHubVisibility\"\n @switch-app=\"handleSwitchApp\"\n >\n <template\n v-if=\"$slots['app-hub'] && !disableAppHub\"\n #applications=\"{ appsList: slotAppsList, switchApp: slotSwitchApp }\"\n >\n <slot\n name=\"app-hub\"\n :apps-list=\"slotAppsList\"\n :switch-app=\"slotSwitchApp\"\n />\n </template>\n </AppHubPopover>\n\n <VcDropdownPanel\n v-model:show=\"isNotificationsOpen\"\n :anchor-ref=\"notificationAnchorRef\"\n placement=\"right-start\"\n width=\"320px\"\n :content-scrollable=\"false\"\n >\n <NotificationDropdown />\n </VcDropdownPanel>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { computed, inject, ref, watch } from \"vue\";\nimport type { AppDescriptor } from \"@core/api/platform\";\nimport type { MenuItem } from \"@core/types\";\nimport { EmbeddedModeKey } from \"@framework/injection-keys\";\nimport { useSidebarState } from \"@core/composables/useSidebarState\";\nimport { useRoute } from \"vue-router\";\nimport SidebarHeader from \"@ui/components/organisms/vc-app/_internal/sidebar/SidebarHeader.vue\";\nimport SidebarContent from \"@ui/components/organisms/vc-app/_internal/sidebar/SidebarContent.vue\";\nimport SidebarCollapseButton from \"@ui/components/organisms/vc-app/_internal/sidebar/SidebarCollapseButton.vue\";\nimport AppHubPopover from \"@ui/components/organisms/vc-app/_internal/app-bar/components/AppHubPopover.vue\";\nimport { NotificationDropdown } from \"@shell/components/notification-dropdown\";\nimport { VcDropdownPanel } from \"@ui/components/molecules/vc-dropdown-panel\";\n\nexport interface Props {\n logo?: string;\n title?: string;\n avatar?: string;\n userName?: string;\n userRole?: string;\n disableMenu?: boolean;\n disableAppHub?: boolean;\n appsList?: AppDescriptor[];\n showSearch?: boolean;\n searchPlaceholder?: string;\n}\n\nwithDefaults(defineProps<Props>(), {\n disableMenu: false,\n disableAppHub: false,\n appsList: () => [],\n showSearch: false,\n});\n\nconst emit = defineEmits<{\n (event: \"logo:click\"): void;\n (event: \"item:click\", item: MenuItem): void;\n (event: \"switch-app\", app: AppDescriptor): void;\n}>();\n\ndefineSlots<{\n \"app-hub\"?: (props: { appsList: AppDescriptor[]; switchApp: (app: AppDescriptor) => void }) => unknown;\n menu?: (props: { expanded: boolean; onItemClick: (item: MenuItem) => void; searchQuery: string }) => unknown;\n \"sidebar-header\"?: (props: { logo?: string; expanded: boolean; isMobile: boolean }) => unknown;\n \"sidebar-footer\"?: (props: { avatar?: string; name?: string; role?: string }) => unknown;\n}>();\n\nconst sidebar = useSidebarState();\nconst isEmbedded = inject(EmbeddedModeKey, false);\nconst route = useRoute();\nconst appHubAnchorRef = ref<HTMLElement | null>(null);\nconst isNotificationsOpen = ref(false);\nconst notificationAnchorRef = ref<HTMLElement | null>(null);\n\nconst showHeader = computed(() => !isEmbedded);\n\nwatch(\n () => route.fullPath,\n () => {\n if (sidebar.isMenuOpen.value) {\n sidebar.closeMenu();\n }\n isNotificationsOpen.value = false;\n },\n);\n\nconst handleToggleMenu = (event: MouseEvent) => {\n if (event.currentTarget instanceof HTMLElement) {\n appHubAnchorRef.value = event.currentTarget;\n }\n\n if (sidebar.isMenuOpen.value) {\n sidebar.closeMenu();\n return;\n }\n\n // Close notifications when opening AppHub\n isNotificationsOpen.value = false;\n\n sidebar.openMenu();\n};\n\nconst handleToggleNotifications = (event: MouseEvent) => {\n if (event.currentTarget instanceof HTMLElement) {\n notificationAnchorRef.value = event.currentTarget;\n }\n\n isNotificationsOpen.value = !isNotificationsOpen.value;\n\n // Close AppHub when opening notifications\n if (isNotificationsOpen.value && sidebar.isMenuOpen.value) {\n sidebar.closeMenu();\n }\n};\n\nconst handleAppHubVisibility = (value: boolean) => {\n if (!value) {\n sidebar.closeMenu();\n return;\n }\n\n if (!appHubAnchorRef.value && typeof document !== \"undefined\") {\n appHubAnchorRef.value = document.querySelector<HTMLElement>(\".sidebar-header__menu-button\");\n }\n\n sidebar.openMenu();\n};\n\nconst handleSwitchApp = (app: AppDescriptor) => {\n sidebar.closeMenu();\n emit(\"switch-app\", app);\n};\n</script>\n\n<style lang=\"scss\">\n:root {\n // Sizes\n --app-bar-height: 70px;\n --app-bar-mobile-height: 58px;\n --app-bar-width: 246px;\n --app-bar-mobile-width: 300px;\n --app-bar-collapsed-width: 76px;\n --app-bar-padding: 18px;\n --app-bar-padding-mobile: 28px;\n --app-bar-shadow: 0 16px 10px 0 rgba(0, 0, 0, 0.14);\n\n // Logo\n --app-bar-logo-width: 125px;\n --app-bar-logo-height: 46px;\n --app-bar-logo-mobile-width: 46px;\n --app-bar-logo-mobile-height: 46px;\n\n // Collapse button\n --app-bar-collapse-button-width: 26px;\n --app-bar-collapse-button-height: 26px;\n --app-bar-collapse-button-border-radius: 3px;\n\n // Colors\n --app-bar-background: var(--neutrals-50);\n --app-bar-border: var(--neutrals-200);\n --app-bar-button: var(--neutrals-500);\n --app-bar-button-hover: var(--neutrals-600);\n --app-bar-product-name: var(--neutrals-600);\n --app-bar-divider: var(--additional-50);\n --app-bar-account-info-role: var(--neutrals-400);\n --app-bar-content-visible-border: var(--primary-500);\n --app-bar-burger: var(--primary-500);\n\n // Transition\n --app-bar-transition-duration: 200ms;\n --app-bar-hover-transition-duration: 250ms;\n --app-bar-hover-leave-duration: 400ms;\n --app-bar-hover-transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);\n}\n\n.desktop-layout {\n @apply tw-relative tw-flex tw-flex-col;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: var(--app-bar-width);\n background-color: var(--app-bar-background);\n z-index: var(--z-layout-sidebar);\n // Persistent right divider between the sidebar and the blade content. Rendered\n // as a box-shadow (not a border) so it sits flush at the right edge, takes no\n // layout space, and follows the animated width on collapse/expand. Kept on the\n // base element so it is visible in both pinned and collapsed states — previously\n // it was only on `--collapsed`, so the divider vanished when the sidebar was\n // pinned open.\n box-shadow: 1px 0 0 0 var(--app-bar-border);\n\n // Show collapse button on hover\n &:hover .sidebar-collapse-button {\n @apply tw-opacity-100;\n pointer-events: auto;\n }\n\n &--collapsed {\n width: var(--app-bar-collapsed-width);\n transition:\n width var(--app-bar-transition-duration) var(--app-bar-hover-transition-timing-function),\n transform var(--app-bar-transition-duration) var(--app-bar-hover-transition-timing-function);\n }\n\n &__spacer {\n width: var(--app-bar-collapsed-width);\n\n &--expanded {\n width: var(--app-bar-width);\n }\n }\n\n &__wrap {\n @apply tw-h-full tw-relative;\n transition-property: width, transform, box-shadow;\n transition-timing-function: var(--app-bar-hover-transition-timing-function);\n transition-duration: var(--app-bar-hover-transition-duration);\n\n &--collapsed {\n width: var(--app-bar-collapsed-width);\n }\n\n &--expanded {\n width: var(--app-bar-width);\n }\n }\n\n &__header {\n transition-property: all, width, transform;\n transition-timing-function: var(--app-bar-hover-transition-timing-function);\n transition-duration: var(--app-bar-hover-transition-duration);\n }\n}\n\n// Overlay / menu transition animations\n.overlay-enter-active,\n.overlay-leave-active,\n.menu-enter-active,\n.menu-leave-active {\n transition:\n opacity var(--app-bar-hover-transition-duration) var(--app-bar-hover-transition-timing-function),\n transform var(--app-bar-hover-transition-duration) var(--app-bar-hover-transition-timing-function);\n}\n\n.overlay-enter-from,\n.menu-enter-from {\n opacity: 0;\n transform: translateY(-10px);\n}\n\n.overlay-leave-to,\n.menu-leave-to {\n opacity: 0;\n transform: translateY(10px);\n}\n</style>\n","import { ComputedRef, ref, computed, Component, MaybeRef, Ref, toValue } from \"vue\";\n\nexport interface AppBarButtonContent {\n id: string;\n /** Accessible name / tooltip for the icon-only action button. */\n title?: string;\n component?: Component;\n props?: Record<string, unknown>;\n icon?: Component | string;\n onClick?: () => void;\n order?: number;\n onClose?: () => void;\n isVisible?: MaybeRef<boolean> | ComputedRef<boolean>;\n badge?: MaybeRef<boolean> | ComputedRef<boolean>;\n}\n\nexport interface IAppBarMobileButtonsService {\n registeredButtons: ComputedRef<AppBarButtonContent[]>;\n register: (button: AppBarButtonContent) => void;\n unregister: (buttonId: string) => void;\n getButton: (buttonId: string) => AppBarButtonContent | undefined;\n getButtons: ComputedRef<AppBarButtonContent[]>;\n}\n\n/**\n * Creates a service for managing mobile AppBar buttons\n * Handles button registration and retrieval for mobile app bar\n */\nexport function createAppBarMobileButtonsService(): IAppBarMobileButtonsService {\n const registeredButtonsState = ref<AppBarButtonContent[]>([]) as Ref<AppBarButtonContent[]>;\n const registeredButtons = computed(() => registeredButtonsState.value);\n\n const register = (button: AppBarButtonContent) => {\n const existingButtonIndex = registeredButtonsState.value.findIndex((b) => b.id === button.id);\n\n if (existingButtonIndex >= 0) {\n registeredButtonsState.value[existingButtonIndex] = button;\n } else {\n registeredButtonsState.value.push(button);\n }\n };\n\n const unregister = (buttonId: string) => {\n registeredButtonsState.value = registeredButtonsState.value.filter((button) => button.id !== buttonId);\n };\n\n const getButton = (buttonId: string) => {\n return registeredButtonsState.value.find((button) => button.id === buttonId);\n };\n\n const getButtons = computed(() =>\n [...registeredButtonsState.value]\n .filter((button) => toValue(button.isVisible) !== false)\n .sort((a, b) => (a.order || 0) - (b.order || 0)),\n );\n\n return {\n registeredButtons,\n register,\n unregister,\n getButton,\n getButtons,\n };\n}\n","import { inject, provide, getCurrentScope, onScopeDispose } from \"vue\";\nimport { AppBarMobileButtonsServiceKey } from \"@framework/injection-keys\";\nimport {\n createAppBarMobileButtonsService,\n IAppBarMobileButtonsService,\n} from \"@core/services/app-bar-mobile-buttons-service\";\nimport { createLogger, InjectionError } from \"@core/utilities\";\n\nexport type UseAppBarMobileButtonsReturn = IAppBarMobileButtonsService;\n\nconst logger = createLogger(\"use-app-bar-mobile-buttons\");\n\nexport function provideAppBarMobileButtonsService(): IAppBarMobileButtonsService {\n const existingService = inject(AppBarMobileButtonsServiceKey, null);\n if (existingService) {\n return existingService;\n }\n\n const service = createAppBarMobileButtonsService();\n provide(AppBarMobileButtonsServiceKey, service);\n\n if (getCurrentScope()) {\n onScopeDispose(() => {\n // Service cleanup on scope disposal\n });\n }\n\n return service;\n}\n\nexport function useAppBarMobileButtons(): UseAppBarMobileButtonsReturn {\n const service = inject(AppBarMobileButtonsServiceKey);\n if (!service) {\n logger.error(\"AppBarMobileButtonsService not found\");\n throw new InjectionError(\"AppBarMobileButtonsService\");\n }\n return service;\n}\n","import { watch } from \"vue\";\nimport { useAppBarMobileButtons } from \"@core/composables/useAppBarMobileButtons\";\nimport { useToggleableContent } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useToggleableContent\";\nimport { useAppBarState } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarState\";\n\nexport function useAppBarMobileActions() {\n const { getButtons } = useAppBarMobileButtons();\n const { activeMobileActionId } = useAppBarState();\n\n // Use the common composable to manage content\n const {\n showItem: showAction,\n hideAllItems: hideAllActions,\n toggleItem: toggleAction,\n currentItem: currentAction,\n isAnyItemVisible: isAnyActionVisible,\n closeItem: closeAction,\n } = useToggleableContent(getButtons, activeMobileActionId);\n\n // Watch for changes in the list of buttons\n watch(\n () => getButtons.value,\n (newButtons) => {\n // If the active button exists\n if (activeMobileActionId.value) {\n // Check if this button still exists in the list\n const buttonStillExists = newButtons.some((button) => button.id === activeMobileActionId.value);\n\n // If the button was removed - close it\n if (!buttonStillExists) {\n const activeButton = currentAction.value;\n if (activeButton?.onClose) {\n activeButton.onClose();\n }\n hideAllActions();\n }\n }\n },\n { deep: true },\n );\n\n return {\n showAction,\n hideAllActions,\n toggleAction,\n currentAction,\n isAnyActionVisible,\n closeAction,\n };\n}\n","<template>\n <div\n v-if=\"isMobile\"\n class=\"app-bar-mobile-actions\"\n >\n <div\n v-for=\"button in getButtons\"\n :key=\"button.id\"\n class=\"app-bar-mobile-actions__button-wrap\"\n >\n <VcButton\n v-if=\"button.isVisible !== undefined ? button.isVisible : true\"\n text\n class=\"app-bar-mobile-actions__button\"\n :class=\"{ 'app-bar-mobile-actions__button--active': button.id === currentAction?.id }\"\n :icon=\"button.icon\"\n icon-size=\"l\"\n :aria-label=\"button.title || button.id\"\n @click=\"handleButtonClick(button)\"\n />\n <span\n v-if=\"isBadgeActive(button)\"\n class=\"app-bar-mobile-actions__badge\"\n />\n </div>\n\n <VcSidebar\n :model-value=\"isAnyActionVisible && !!currentAction?.component\"\n position=\"bottom\"\n size=\"sm\"\n draggable\n drag-handle\n :close-button=\"false\"\n :inset=\"false\"\n @update:model-value=\"!$event && handleClose()\"\n >\n <component\n :is=\"currentAction?.component\"\n v-if=\"currentAction?.component\"\n v-bind=\"currentAction?.props || {}\"\n @close=\"handleClose()\"\n />\n </VcSidebar>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { useAppBarMobileButtons } from \"@core/composables/useAppBarMobileButtons\";\nimport { VcSidebar } from \"@ui/components/organisms/vc-sidebar\";\nimport { useAppBarMobileActions } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarMobileActions\";\nimport { type MaybeRef, toValue, watch } from \"vue\";\nimport type { AppBarButtonContent } from \"@core/services/app-bar-mobile-buttons-service\";\nimport { useRoute } from \"vue-router\";\nexport interface Props {\n isSidebarMode: boolean;\n expanded: MaybeRef<boolean>;\n}\n\nconst props = defineProps<Props>();\n\nconst { isMobile } = useResponsive();\nconst { getButtons } = useAppBarMobileButtons();\nconst { currentAction, toggleAction, hideAllActions, isAnyActionVisible } = useAppBarMobileActions();\nconst route = useRoute();\n\nconst handleButtonClick = (button: AppBarButtonContent) => {\n // If the current button is already active - hide it\n if (currentAction.value?.id === button.id) {\n button.onClose?.();\n hideAllActions();\n return;\n }\n\n // If the previous active button exists - close it\n if (currentAction.value) {\n currentAction.value.onClose?.();\n }\n\n // Enable the new button\n toggleAction(button.id);\n\n // Call onClick for a button without a component\n if (!button.component && button.onClick) {\n button.onClick();\n }\n};\n\nconst handleClose = (value?: AppBarButtonContent | Event) => {\n if (value && typeof value === \"object\" && \"id\" in value) {\n (value as AppBarButtonContent).onClose?.();\n } else {\n currentAction.value?.onClose?.();\n }\n hideAllActions();\n};\n\nfunction isBadgeActive(button: AppBarButtonContent): boolean {\n if (button.badge === undefined) return false;\n return !!toValue(button.badge);\n}\n\n// Hide actions on route change or sidebar mode toggle\nwatch([() => route.fullPath, () => props.isSidebarMode], () => {\n hideAllActions();\n});\n</script>\n\n<style lang=\"scss\">\n.app-bar-mobile-actions {\n @apply tw-relative tw-flex tw-flex-row tw-gap-[30px];\n\n &__button-wrap {\n @apply tw-relative;\n }\n\n &__button {\n @apply tw-cursor-pointer tw-text-[var(--app-bar-header-actions-button-color)] #{!important};\n\n &--active {\n @apply tw-text-[var(--app-bar-header-actions-button-active-color)] #{!important};\n }\n }\n\n &__badge {\n @apply tw-absolute tw-right-0 tw-top-0 tw-w-[5px] tw-h-[5px] tw-rounded-full tw-z-[var(--z-local-above)] tw-pointer-events-none;\n background-color: var(--app-bar-accent-color, var(--danger-500));\n }\n}\n</style>\n","<template>\n <component\n :is=\"wrapperComponent\"\n v-bind=\"wrapperProps\"\n >\n <div\n class=\"menu-sidebar__wrapper\"\n :class=\"{\n 'menu-sidebar__wrapper--desktop': isDesktop,\n 'menu-sidebar__wrapper--expanded': isDesktop && expanded,\n }\"\n >\n <div\n v-if=\"showHeader\"\n class=\"menu-sidebar__header\"\n :class=\"{\n 'menu-sidebar__header--mobile': isMobile,\n }\"\n >\n <div class=\"menu-sidebar__widgets\">\n <slot name=\"widgets\" />\n </div>\n <div class=\"menu-sidebar__spacer\" />\n <div\n v-if=\"isDesktop\"\n class=\"menu-sidebar__close-button\"\n >\n <VcButton\n icon-class=\"menu-sidebar__close-button-icon\"\n icon=\"lucide-x\"\n text\n @click.stop=\"$emit('update:is-opened', false)\"\n />\n </div>\n </div>\n <div\n class=\"menu-sidebar__content\"\n :class=\"{ 'menu-sidebar__content--without-header': !showHeader }\"\n >\n <div\n v-if=\"$slots['widgets-active-content']\"\n class=\"menu-sidebar__content-main\"\n >\n <slot name=\"widgets-active-content\" />\n </div>\n\n <template v-if=\"isMobile\">\n <div class=\"menu-sidebar__navmenu-container\">\n <slot name=\"navmenu\" />\n </div>\n\n <div class=\"menu-sidebar__user\">\n <slot name=\"user-dropdown\" />\n </div>\n </template>\n <template v-else>\n <div class=\"menu-sidebar__app-hub-wrapper\">\n <slot name=\"app-hub\" />\n </div>\n </template>\n </div>\n </div>\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, inject, useSlots, type MaybeRef } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { EmbeddedModeKey } from \"@framework/injection-keys\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { VcSidebar } from \"@ui/components/organisms/vc-sidebar\";\n\nconst props = defineProps<{\n isOpened: boolean;\n expanded: MaybeRef<boolean>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"update:is-opened\", value: boolean): void;\n}>();\n\ndefineSlots<{\n navmenu: () => unknown;\n \"user-dropdown\": () => unknown;\n \"app-hub\": () => unknown;\n \"widgets-active-content\": () => unknown;\n widgets: () => unknown;\n}>();\n\nconst isEmbedded = inject(EmbeddedModeKey, false);\nconst { isMobile, isDesktop } = useResponsive();\nconst slots = useSlots();\n\nconst showHeader = computed(() => !isEmbedded && (isDesktop.value || Boolean(slots.widgets)));\n\nconst wrapperComponent = computed(() => (isMobile.value ? VcSidebar : \"div\"));\n\nconst wrapperProps = computed<Record<string, unknown>>(() => {\n if (!isMobile.value) {\n return {};\n }\n\n return {\n modelValue: props.isOpened,\n position: \"left\",\n closeButton: false,\n \"onUpdate:modelValue\": (value: boolean) => {\n if (!value) {\n emit(\"update:is-opened\", false);\n }\n },\n };\n});\n</script>\n\n<style lang=\"scss\">\n.menu-sidebar {\n &__wrapper {\n @apply tw-absolute tw-top-0 tw-left-0 tw-w-full tw-bottom-0 tw-z-[var(--z-local-sticky)] tw-flex tw-flex-col;\n\n &--desktop {\n @apply tw-w-[var(--app-bar-width)] tw-z-[var(--z-local-header)];\n }\n\n &--expanded {\n @apply tw-absolute tw-top-0 tw-left-0;\n }\n }\n\n &__content {\n @apply tw-flex tw-flex-col tw-bg-[var(--app-bar-background)] tw-flex-1 tw-relative tw-overflow-x-hidden tw-min-h-0;\n height: calc(100dvh - var(--app-bar-height));\n\n &--without-header {\n height: 100dvh;\n }\n\n &:before {\n content: \"\";\n @apply tw-absolute tw-left-0 tw-top-[-1px] tw-w-full tw-h-[1px] tw-bg-[color:var(--app-bar-border)] tw-z-[var(--z-local-above)] #{!important};\n }\n }\n\n &__header {\n @apply tw-flex;\n background-color: var(--app-bar-background);\n height: var(--app-bar-height);\n\n &--mobile {\n height: var(--app-bar-mobile-height);\n }\n }\n\n &__navmenu-container {\n @apply tw-flex-auto tw-min-h-0;\n }\n\n &__user {\n @apply tw-mt-auto;\n }\n\n &__content-main {\n @apply tw-relative tw-flex-shrink-0 tw-overflow-y-auto;\n max-height: 40vh;\n\n &:not(:empty) {\n @apply tw-visible tw-border-b-[2px] tw-border-[color:var(--app-bar-border)] tw-z-[var(--z-local-above)];\n\n &:before {\n content: \"\";\n @apply tw-absolute tw-left-0 tw-top-[-2px] tw-w-full tw-h-[2px] tw-bg-[color:var(--app-bar-content-visible-border)] tw-z-[var(--z-local-above)] #{!important};\n }\n }\n }\n\n &__app-hub-wrapper {\n @apply tw-flex-1 tw-overflow-y-auto tw-min-h-0;\n }\n\n &__spacer {\n @apply tw-grow tw-basis-0;\n }\n\n &__close-button {\n @apply tw-px-4 tw-flex tw-items-center tw-justify-center;\n\n &-icon {\n @apply tw-text-[color:var(--app-bar-button)];\n }\n }\n\n &__widgets {\n @apply tw-flex tw-flex-row tw-items-center tw-justify-between tw-overflow-auto;\n }\n}\n</style>\n","<template>\n <!-- Top bar -->\n <div\n v-if=\"showHeader\"\n class=\"mobile-layout\"\n >\n <slot\n name=\"sidebar-header\"\n :logo=\"logo\"\n :expanded=\"false\"\n :is-mobile=\"true\"\n >\n <SidebarHeader\n :logo=\"logo\"\n :expanded=\"false\"\n :is-mobile=\"true\"\n :mobile-title=\"viewTitle\"\n :show-mobile-title=\"blades.length === 1\"\n class=\"mobile-layout__header\"\n @logo:click=\"sidebar.openMenu\"\n >\n <template #actions>\n <AppBarMobileActions\n :is-sidebar-mode=\"sidebar.isMenuOpen.value\"\n :expanded=\"false\"\n />\n </template>\n </SidebarHeader>\n </slot>\n </div>\n\n <!-- Slide-out sidebar overlay (no v-if — VcSidebar manages visibility internally via Transition) -->\n <MenuSidebar\n :is-opened=\"sidebar.isMenuOpen.value\"\n :expanded=\"true\"\n @update:is-opened=\"!$event && sidebar.closeMenu()\"\n >\n <template #navmenu>\n <div\n class=\"mobile-layout__navmenu\"\n :class=\"{ 'mobile-layout__navmenu--tabs': showTabs }\"\n >\n <template v-if=\"showTabs\">\n <div\n class=\"mobile-layout__tabs\"\n role=\"tablist\"\n >\n <button\n type=\"button\"\n class=\"mobile-layout__tab\"\n :class=\"{ 'mobile-layout__tab--active': activeIndex === MENU_TAB_INDEX }\"\n role=\"tab\"\n :aria-selected=\"activeIndex === MENU_TAB_INDEX\"\n aria-controls=\"mobile-layout-panel-menu\"\n @click=\"setActiveIndex(MENU_TAB_INDEX)\"\n >\n <span class=\"mobile-layout__tab-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_APP.INTERNAL.MOBILE_LAYOUT.TAB_MENU\") }}\n </span>\n </button>\n\n <button\n type=\"button\"\n class=\"mobile-layout__tab\"\n :class=\"{ 'mobile-layout__tab--active': activeIndex === HUB_TAB_INDEX }\"\n role=\"tab\"\n :aria-selected=\"activeIndex === HUB_TAB_INDEX\"\n aria-controls=\"mobile-layout-panel-hub\"\n @click=\"setActiveIndex(HUB_TAB_INDEX)\"\n >\n <span class=\"mobile-layout__tab-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_APP.INTERNAL.MOBILE_LAYOUT.TAB_HUB\") }}\n <span\n v-if=\"hasWidgetBadge\"\n class=\"mobile-layout__tab-badge\"\n />\n </span>\n </button>\n\n <span\n class=\"mobile-layout__tab-indicator\"\n :style=\"indicatorStyle\"\n />\n </div>\n\n <div\n ref=\"sliderViewportRef\"\n class=\"mobile-layout__slider-viewport\"\n @touchstart.passive=\"onTouchStart\"\n @touchmove=\"onTouchMove\"\n @touchend.passive=\"onTouchEnd\"\n @touchcancel.passive=\"onTouchEnd\"\n >\n <div\n class=\"mobile-layout__slider\"\n :style=\"sliderStyle\"\n >\n <div\n id=\"mobile-layout-panel-menu\"\n role=\"tabpanel\"\n class=\"mobile-layout__panel mobile-layout__panel--menu\"\n >\n <div\n v-if=\"showSearch\"\n class=\"mobile-layout__search\"\n >\n <VcInput\n v-model=\"searchQuery\"\n :placeholder=\"props.searchPlaceholder || $t('SHELL.SIDEBAR.SEARCH_PLACEHOLDER', 'Search keyword')\"\n size=\"small\"\n clearable\n :debounce=\"300\"\n />\n </div>\n <VcScrollableContainer class=\"mobile-layout__menu-scroll\">\n <slot\n name=\"menu\"\n :expanded=\"true\"\n :on-item-click=\"handleMenuItemClick\"\n :search-query=\"searchQuery\"\n >\n <VcAppMenu\n :expanded=\"true\"\n :search-query=\"searchQuery\"\n @item:click=\"handleMenuItemClick\"\n />\n </slot>\n </VcScrollableContainer>\n </div>\n\n <div\n id=\"mobile-layout-panel-hub\"\n role=\"tabpanel\"\n class=\"mobile-layout__panel mobile-layout__panel--hub\"\n >\n <AppHubContent\n :apps-list=\"props.appsList\"\n :show-applications=\"!props.disableAppHub\"\n mobile\n @switch-app=\"handleSwitchApp\"\n >\n <template\n v-if=\"$slots['app-hub'] && !props.disableAppHub\"\n #applications=\"{ appsList: slotAppsList, switchApp: slotSwitchApp }\"\n >\n <slot\n name=\"app-hub\"\n :apps-list=\"slotAppsList\"\n :switch-app=\"slotSwitchApp\"\n />\n </template>\n </AppHubContent>\n </div>\n </div>\n </div>\n </template>\n\n <div\n v-else-if=\"props.disableMenu\"\n class=\"mobile-layout__panel mobile-layout__panel--single mobile-layout__panel--hub\"\n >\n <AppHubContent\n :apps-list=\"props.appsList\"\n :show-applications=\"!props.disableAppHub\"\n mobile\n @switch-app=\"handleSwitchApp\"\n >\n <template\n v-if=\"$slots['app-hub'] && !props.disableAppHub\"\n #applications=\"{ appsList: slotAppsList, switchApp: slotSwitchApp }\"\n >\n <slot\n name=\"app-hub\"\n :apps-list=\"slotAppsList\"\n :switch-app=\"slotSwitchApp\"\n />\n </template>\n </AppHubContent>\n </div>\n\n <div\n v-else\n class=\"mobile-layout__panel mobile-layout__panel--single mobile-layout__panel--menu\"\n >\n <div\n v-if=\"showSearch\"\n class=\"mobile-layout__search\"\n >\n <VcInput\n v-model=\"searchQuery\"\n :placeholder=\"props.searchPlaceholder || $t('SHELL.SIDEBAR.SEARCH_PLACEHOLDER', 'Search keyword')\"\n size=\"small\"\n clearable\n :debounce=\"300\"\n />\n </div>\n <VcScrollableContainer class=\"mobile-layout__menu-scroll\">\n <slot\n name=\"menu\"\n :expanded=\"true\"\n :on-item-click=\"handleMenuItemClick\"\n :search-query=\"searchQuery\"\n >\n <VcAppMenu\n :expanded=\"true\"\n :search-query=\"searchQuery\"\n @item:click=\"handleMenuItemClick\"\n />\n </slot>\n </VcScrollableContainer>\n </div>\n </div>\n </template>\n <template #user-dropdown>\n <!-- eslint-disable vue/no-duplicate-attributes -- slot name + scoped prop -->\n <slot\n name=\"sidebar-footer\"\n :avatar=\"avatar\"\n :name=\"userName\"\n :role=\"userRole\"\n >\n <!-- eslint-enable vue/no-duplicate-attributes -->\n <UserDropdownButton\n v-if=\"!isEmbedded\"\n :avatar-url=\"avatar\"\n :name=\"userName\"\n :role=\"userRole\"\n />\n </slot>\n </template>\n </MenuSidebar>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { computed, inject, ref, watch } from \"vue\";\nimport type { AppDescriptor } from \"@core/api/platform\";\nimport type { MenuItem } from \"@core/types\";\nimport { EmbeddedModeKey } from \"@framework/injection-keys\";\nimport { useBladeStack } from \"@core/blade-navigation\";\nimport { UserDropdownButton } from \"@shell/components/user-dropdown-button\";\nimport { useSidebarState } from \"@core/composables/useSidebarState\";\nimport { useAppBarWidget } from \"@core/composables\";\nimport SidebarHeader from \"@ui/components/organisms/vc-app/_internal/sidebar/SidebarHeader.vue\";\nimport AppBarMobileActions from \"@ui/components/organisms/vc-app/_internal/app-bar/components/AppBarMobileActions.vue\";\nimport MenuSidebar from \"@ui/components/organisms/vc-app/_internal/app-bar/components/MenuSidebar.vue\";\nimport AppHubContent from \"@ui/components/organisms/vc-app/_internal/app-bar/components/AppHubContent.vue\";\nimport VcAppMenu from \"@ui/components/organisms/vc-app/_internal/menu/VcAppMenu.vue\";\nimport { VcScrollableContainer } from \"@ui/components/atoms/vc-scrollable-container\";\nimport { VcInput } from \"@ui/components/molecules/vc-input\";\n\nexport interface Props {\n logo?: string;\n title?: string;\n avatar?: string;\n userName?: string;\n userRole?: string;\n disableMenu?: boolean;\n disableAppHub?: boolean;\n appsList?: AppDescriptor[];\n showSearch?: boolean;\n searchPlaceholder?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disableMenu: false,\n disableAppHub: false,\n appsList: () => [],\n showSearch: false,\n});\n\nconst emit = defineEmits<{\n (event: \"item:click\", item: MenuItem): void;\n (event: \"switch-app\", app: AppDescriptor): void;\n}>();\n\ndefineSlots<{\n \"app-hub\"?: (props: { appsList: AppDescriptor[]; switchApp: (app: AppDescriptor) => void }) => unknown;\n menu?: (props: { expanded: boolean; onItemClick: (item: MenuItem) => void; searchQuery: string }) => unknown;\n \"sidebar-header\"?: (props: { logo?: string; expanded: boolean; isMobile: boolean }) => unknown;\n \"sidebar-footer\"?: (props: { avatar?: string; name?: string; role?: string }) => unknown;\n}>();\n\nconst searchQuery = ref(\"\");\n\nconst sidebar = useSidebarState();\nconst isEmbedded = inject(EmbeddedModeKey, false);\nconst { blades, activeBlade } = useBladeStack();\nconst { items: widgetItems } = useAppBarWidget();\n\nconst MENU_TAB_INDEX = 0;\nconst HUB_TAB_INDEX = 1;\nconst GESTURE_LOCK_THRESHOLD = 8;\nconst SWIPE_DISTANCE_RATIO = 0.3;\nconst SWIPE_VELOCITY_THRESHOLD = 0.3;\nconst MAX_DRAG_RATIO = 1;\nconst BOUNDARY_RESISTANCE_RATIO = 0.2;\nconst SLIDER_TRANSITION = \"transform 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94)\";\n\nconst hasWidgetBadge = computed(() =>\n widgetItems.value.some((widget) => {\n if (widget.badge === undefined) return false;\n if (typeof widget.badge === \"function\") return widget.badge();\n return !!widget.badge;\n }),\n);\n\nconst showHubTab = computed(() => widgetItems.value.length > 0 || (!props.disableAppHub && props.appsList.length > 0));\n\nconst showTabs = computed(() => showHubTab.value && !props.disableMenu);\n\nconst activeIndex = ref(MENU_TAB_INDEX);\nconst isDragging = ref(false);\nconst dragOffsetX = ref(0);\nconst sliderViewportRef = ref<HTMLElement | null>(null);\nconst gestureState = ref<\"idle\" | \"pending\" | \"horizontal\" | \"vertical\">(\"idle\");\n\nlet touchStartX = 0;\nlet touchStartY = 0;\nlet lastTouchX = 0;\nlet touchStartTime = 0;\n\nconst sliderStyle = computed(() => {\n const baseTranslate = activeIndex.value * -50;\n const viewportWidth = sliderViewportRef.value?.clientWidth ?? 0;\n\n if (isDragging.value && viewportWidth > 0) {\n const dragTranslate = (dragOffsetX.value / viewportWidth) * 50;\n return {\n transform: `translateX(${baseTranslate + dragTranslate}%)`,\n transition: \"none\",\n };\n }\n\n return {\n transform: `translateX(${baseTranslate}%)`,\n transition: SLIDER_TRANSITION,\n };\n});\n\nconst indicatorStyle = computed(() => {\n const viewportWidth = sliderViewportRef.value?.clientWidth ?? 0;\n const dragProgress = isDragging.value && viewportWidth > 0 ? -dragOffsetX.value / viewportWidth : 0;\n const progress = Math.max(0, Math.min(1, activeIndex.value + dragProgress));\n\n return {\n transform: `translateX(${progress * 100}%)`,\n transition: isDragging.value ? \"none\" : SLIDER_TRANSITION,\n };\n});\n\nfunction setActiveIndex(nextIndex: number) {\n activeIndex.value = Math.max(MENU_TAB_INDEX, Math.min(HUB_TAB_INDEX, nextIndex));\n resetDragState();\n}\n\nfunction resetDragState() {\n dragOffsetX.value = 0;\n isDragging.value = false;\n gestureState.value = \"idle\";\n}\n\nfunction getRubberBandOffset(offset: number, dimension: number) {\n const absoluteOffset = Math.abs(offset);\n if (!absoluteOffset || !dimension) {\n return 0;\n }\n\n const resistedOffset = (absoluteOffset * dimension) / (absoluteOffset + dimension);\n return Math.sign(offset) * resistedOffset;\n}\n\nfunction getDragOffset(offset: number) {\n const viewportWidth = sliderViewportRef.value?.clientWidth ?? 0;\n if (!viewportWidth) {\n return offset;\n }\n\n const isLeadingBoundary = activeIndex.value === MENU_TAB_INDEX && offset > 0;\n const isTrailingBoundary = activeIndex.value === HUB_TAB_INDEX && offset < 0;\n\n if (isLeadingBoundary || isTrailingBoundary) {\n return getRubberBandOffset(offset, viewportWidth * BOUNDARY_RESISTANCE_RATIO);\n }\n\n const maxDragDistance = viewportWidth * MAX_DRAG_RATIO;\n return Math.max(-maxDragDistance, Math.min(maxDragDistance, offset));\n}\n\nfunction onTouchStart(event: TouchEvent) {\n if (!showTabs.value || event.touches.length === 0) {\n return;\n }\n\n const touch = event.touches[0];\n touchStartX = touch.clientX;\n touchStartY = touch.clientY;\n lastTouchX = touch.clientX;\n touchStartTime = Date.now();\n dragOffsetX.value = 0;\n isDragging.value = false;\n gestureState.value = \"pending\";\n}\n\nfunction onTouchMove(event: TouchEvent) {\n if (!showTabs.value || event.touches.length === 0 || gestureState.value === \"idle\") {\n return;\n }\n\n const touch = event.touches[0];\n const deltaX = touch.clientX - touchStartX;\n const deltaY = touch.clientY - touchStartY;\n const absDeltaX = Math.abs(deltaX);\n const absDeltaY = Math.abs(deltaY);\n\n if (gestureState.value === \"pending\") {\n if (absDeltaX < GESTURE_LOCK_THRESHOLD && absDeltaY < GESTURE_LOCK_THRESHOLD) {\n return;\n }\n\n if (absDeltaY > absDeltaX) {\n gestureState.value = \"vertical\";\n return;\n }\n\n gestureState.value = \"horizontal\";\n isDragging.value = true;\n }\n\n if (gestureState.value !== \"horizontal\") {\n return;\n }\n\n if (event.cancelable) {\n event.preventDefault();\n }\n\n lastTouchX = touch.clientX;\n dragOffsetX.value = getDragOffset(deltaX);\n}\n\nfunction onTouchEnd(event: TouchEvent) {\n if (!showTabs.value) {\n resetDragState();\n return;\n }\n\n const touch = event.changedTouches[0];\n\n if (gestureState.value !== \"horizontal\") {\n resetDragState();\n return;\n }\n\n const endX = touch?.clientX ?? lastTouchX;\n const deltaX = endX - touchStartX;\n const duration = Math.max(Date.now() - touchStartTime, 1);\n const velocity = Math.abs(deltaX) / duration;\n const viewportWidth = sliderViewportRef.value?.clientWidth ?? 0;\n const distanceThreshold = viewportWidth * SWIPE_DISTANCE_RATIO;\n const shouldSwitch = velocity > SWIPE_VELOCITY_THRESHOLD || Math.abs(deltaX) > distanceThreshold;\n\n if (shouldSwitch) {\n if (deltaX < 0) {\n setActiveIndex(activeIndex.value + 1);\n return;\n }\n\n if (deltaX > 0) {\n setActiveIndex(activeIndex.value - 1);\n return;\n }\n }\n\n resetDragState();\n}\n\nwatch(\n () => sidebar.isMenuOpen.value,\n (isOpen) => {\n if (!isOpen) {\n setActiveIndex(MENU_TAB_INDEX);\n searchQuery.value = \"\";\n }\n },\n);\n\nwatch(showHubTab, (isVisible) => {\n if (!isVisible) {\n setActiveIndex(MENU_TAB_INDEX);\n }\n});\n\nwatch(showTabs, (isVisible) => {\n if (!isVisible) {\n setActiveIndex(MENU_TAB_INDEX);\n }\n});\n\nconst showHeader = computed(() => blades.value.length <= 1);\n\nconst viewTitle = computed(() => {\n const currentTitle = activeBlade.value?.title;\n const lastBladeTitle = blades.value[blades.value.length - 1]?.title;\n return currentTitle ?? lastBladeTitle ?? \"\";\n});\n\nwatch(showHeader, (nextValue) => {\n if (!nextValue && sidebar.isMenuOpen.value) {\n sidebar.closeMenu();\n }\n});\n\nconst handleMenuItemClick = (item: MenuItem) => {\n searchQuery.value = \"\";\n sidebar.closeMenu();\n emit(\"item:click\", item);\n};\n\nconst handleSwitchApp = (app: AppDescriptor) => {\n sidebar.closeMenu();\n emit(\"switch-app\", app);\n};\n</script>\n\n<style lang=\"scss\">\n.mobile-layout {\n @apply tw-w-full tw-shrink-0;\n\n &__header {\n @apply tw-h-[var(--app-bar-mobile-height)] tw-px-[var(--app-bar-padding-mobile,28px)];\n background-color: var(--app-bar-background);\n }\n\n &__navmenu {\n @apply tw-flex tw-flex-col tw-h-full tw-min-h-0;\n }\n\n &__tabs {\n @apply tw-relative tw-flex tw-shrink-0;\n border-bottom: 1px solid var(--app-bar-border);\n }\n\n &__tab {\n @apply tw-flex-1 tw-py-3 tw-text-center tw-text-xs tw-font-semibold tw-cursor-pointer tw-relative tw-border-0 tw-bg-transparent tw-z-[var(--z-local-above)];\n color: var(--app-bar-button);\n transition: color 0.15s ease;\n\n &:hover {\n color: var(--app-bar-button-hover);\n }\n\n &--active {\n color: var(--app-bar-burger);\n }\n }\n\n &__tab-label {\n @apply tw-inline-flex tw-items-center tw-justify-center tw-gap-1;\n }\n\n &__tab-badge {\n @apply tw-inline-block tw-w-1.5 tw-h-1.5 tw-rounded-full;\n background-color: var(--danger-500, #ef4444);\n }\n\n &__tab-indicator {\n @apply tw-absolute tw-bottom-0 tw-left-0 tw-h-0.5 tw-w-1/2 tw-pointer-events-none;\n background-color: var(--app-bar-burger);\n }\n\n &__slider-viewport {\n @apply tw-flex-1 tw-min-h-0 tw-overflow-hidden;\n }\n\n &__slider {\n @apply tw-flex tw-h-full;\n width: 200%;\n will-change: transform;\n }\n\n &__menu-scroll {\n @apply tw-h-full tw-min-h-0;\n\n .vc-scrollable-container__viewport {\n @apply tw-pt-2;\n padding-left: var(--app-bar-padding);\n padding-right: var(--app-bar-padding);\n }\n\n // Make nested containers transparent — VcScrollableContainer is the sole scroll owner\n .vc-app-menu,\n .vc-container {\n @apply tw-h-auto tw-overflow-visible;\n }\n\n .vc-container__inner {\n @apply tw-overflow-visible;\n }\n }\n\n &__search {\n @apply tw-flex-none tw-px-[18px] tw-py-[11px];\n background-color: var(--secondary-50);\n border-bottom: 1px solid var(--neutrals-200);\n }\n\n &__panel {\n @apply tw-h-full tw-min-h-0 tw-min-w-0;\n width: 50%;\n\n &--single {\n @apply tw-w-full;\n }\n\n &--hub {\n @apply tw-py-2;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n overscroll-behavior: contain;\n scrollbar-width: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n }\n }\n}\n</style>\n","import { watch } from \"vue\";\nimport { useLocalStorage } from \"@vueuse/core\";\nimport { useLanguages } from \"@core/composables/useLanguages\";\n\nconst PLATFORM_LOCALE_STORAGE_KEY = \"NG_TRANSLATE_LANG_KEY\";\n\n/**\n * One-way reactive bridge from the VirtoCommerce platform's locale key\n * (`NG_TRANSLATE_LANG_KEY`) to the shell's language service.\n *\n * Intended for embedded mode only. Call from `useShellBootstrap` when\n * `options.isEmbedded === true`.\n *\n * Behaviour:\n * - Applies the current platform value on setup (if non-empty).\n * - Watches the key and applies subsequent changes (including cross-tab\n * `storage` events, handled by VueUse).\n * - Skips empty values so platform clearing the key does not blank the shell.\n * - Skips values equal to `currentLocale` to avoid redundant\n * vee-validate reconfiguration.\n */\nexport function usePlatformLocaleSync(): void {\n const { setLocale, currentLocale } = useLanguages();\n const platformLocale = useLocalStorage(PLATFORM_LOCALE_STORAGE_KEY, \"\");\n\n const apply = (value: string) => {\n if (!value) return;\n if (value === currentLocale.value) return;\n setLocale(value);\n };\n\n apply(platformLocale.value);\n watch(platformLocale, apply);\n}\n","<template>\n <div\n class=\"vc-menu-item\"\n :class=\"{\n 'vc-menu-item--active': hasSubmenu ? isSubmenuOpen : isActive,\n 'vc-menu-item--clickable': !disabled,\n 'vc-menu-item--invisible': !isVisible,\n }\"\n >\n <!-- Trigger -->\n <div\n ref=\"triggerRef\"\n class=\"vc-menu-item__trigger\"\n @click.stop=\"handleTriggerClick\"\n >\n <slot name=\"trigger\">\n <div class=\"vc-menu-item__content\">\n <slot name=\"icon\">\n <VcIcon\n v-if=\"icon\"\n :icon=\"icon\"\n :custom-size=\"16\"\n class=\"vc-menu-item__icon\"\n />\n <VcImage\n v-else-if=\"image\"\n :src=\"image\"\n class=\"vc-menu-item__image\"\n :empty-icon=\"emptyIcon\"\n />\n </slot>\n\n <slot name=\"title\">\n <p class=\"vc-menu-item__title\">{{ title }}</p>\n </slot>\n\n <slot name=\"additional\">\n <span\n v-if=\"value\"\n class=\"vc-menu-item__value\"\n >{{ value }}</span\n >\n </slot>\n\n <VcIcon\n v-if=\"showChevron || hasSubmenu\"\n icon=\"lucide-chevron-right\"\n size=\"xs\"\n class=\"vc-menu-item__chevron\"\n :class=\"{ 'vc-menu-item__chevron--rotated': isMobile && isSubmenuOpen }\"\n />\n </div>\n </slot>\n </div>\n\n <!-- Submenu: mobile inline expand -->\n <div\n v-if=\"hasSubmenu && isMobile\"\n class=\"vc-menu-item__submenu-wrapper\"\n :style=\"wrapperStyle\"\n >\n <div\n ref=\"contentRef\"\n class=\"vc-menu-item__submenu-content\"\n >\n <slot name=\"submenu\" />\n </div>\n </div>\n\n <!-- Submenu: desktop dropdown panel -->\n <VcDropdownPanel\n v-if=\"hasSubmenu && !isMobile\"\n v-model:show=\"isSubmenuOpen\"\n :anchor-ref=\"triggerRef\"\n placement=\"right-start\"\n width=\"180px\"\n max-width=\"260px\"\n >\n <div class=\"tw-p-1\">\n <slot name=\"submenu\" />\n </div>\n </VcDropdownPanel>\n\n <!-- Content (legacy slot) -->\n <slot name=\"content\" />\n </div>\n</template>\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { Component, useSlots, computed, watch, ref } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcImage } from \"@ui/components/atoms/vc-image\";\nimport { VcDropdownPanel } from \"@ui/components/molecules/vc-dropdown-panel\";\nimport { useCollapsible } from \"@ui/composables\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\n\ninterface Props {\n title?: string;\n icon?: string | Component;\n image?: string;\n emptyIcon?: string;\n isActive?: boolean;\n disabled?: boolean;\n isVisible?: boolean;\n triggerAction?: \"click\" | \"hover\" | \"none\";\n value?: string;\n showChevron?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n isVisible: true,\n triggerAction: \"click\",\n});\n\ndefineSlots<{\n trigger: (props: any) => any;\n icon: (props: any) => any;\n title: (props: any) => any;\n additional: (props: any) => any;\n content: (props: any) => any;\n submenu: (props: any) => any;\n}>();\n\nconst emit = defineEmits<{\n (e: \"trigger:click\"): void;\n (e: \"trigger:hover\"): void;\n}>();\n\nconst slots = useSlots();\nconst { isMobile } = useResponsive();\n\nconst hasSubmenu = computed(() => !!slots.submenu);\nconst isSubmenuOpen = ref(false);\n\n// Collapsible for mobile inline expand\nconst { contentRef, wrapperStyle, isExpanded } = useCollapsible();\n\n// Keep collapsible in sync with submenu open state\nwatch(isSubmenuOpen, (open) => {\n if (isExpanded.value !== open) {\n isExpanded.value = open;\n }\n});\n\n// Close submenu when switching between mobile/desktop\nwatch(isMobile, () => {\n isSubmenuOpen.value = false;\n});\n\nconst triggerRef = ref<HTMLElement | null>(null);\n\nconst handleTriggerClick = () => {\n if (props.disabled || props.triggerAction === \"none\") return;\n\n if (hasSubmenu.value) {\n isSubmenuOpen.value = !isSubmenuOpen.value;\n }\n\n emit(\"trigger:click\");\n};\n\ndefineExpose({ triggerRef });\n</script>\n\n<style lang=\"scss\">\n:root {\n --menu-item-text-color: var(--additional-950);\n --menu-item-border-color: var(--neutrals-200);\n --menu-item-bg: transparent;\n --menu-item-bg-hover: var(--neutrals-100);\n --menu-item-icon-color: var(--secondary-700);\n --menu-item-bg-active: var(--neutrals-100);\n --menu-item-value-color: var(--neutrals-500);\n --menu-item-chevron-color: var(--neutrals-400);\n}\n\n.vc-menu-item {\n @apply tw-flex tw-flex-col;\n\n &__trigger {\n @apply tw-mx-1 tw-px-2 tw-py-[7px] tw-rounded-md tw-text-sm tw-text-[color:var(--menu-item-text-color)]\n tw-bg-[color:var(--menu-item-bg)] tw-flex tw-flex-row tw-items-center\n tw-transition-colors tw-duration-150;\n }\n\n &--clickable {\n @apply tw-cursor-pointer;\n\n .vc-menu-item__trigger:hover {\n @apply tw-bg-[color:var(--menu-item-bg-hover)];\n }\n }\n\n &--invisible {\n @apply tw-hidden;\n }\n\n &__content {\n @apply tw-flex tw-items-center tw-w-full tw-gap-2;\n }\n\n &__icon {\n @apply tw-shrink-0 tw-text-[color:var(--menu-item-icon-color)];\n }\n\n &__image {\n @apply tw-w-4 tw-h-4 tw-shrink-0 tw-object-contain;\n }\n\n &__title {\n @apply tw-flex-grow tw-truncate;\n }\n\n &__value {\n @apply tw-text-[color:var(--menu-item-value-color)] tw-text-xs tw-shrink-0 tw-ml-auto;\n }\n\n &__chevron {\n @apply tw-text-[color:var(--menu-item-chevron-color)] tw-text-[10px] tw-shrink-0 tw-ml-1\n tw-transition-transform tw-duration-200;\n\n &--rotated {\n @apply tw-rotate-90;\n }\n }\n\n &__submenu-wrapper {\n @apply tw-overflow-hidden tw-transition-all tw-duration-200 tw-ease-in-out;\n }\n\n &__submenu-content {\n @apply tw-py-1 tw-pl-6 tw-pr-1;\n }\n}\n</style>\n","<template>\n <SettingsMenuItem\n icon=\"lucide-languages\"\n :title=\"$t('COMPONENTS.LANGUAGE_SELECTOR.TITLE')\"\n :value=\"currentLanguageName\"\n >\n <template #submenu>\n <VcDropdownItem\n v-for=\"lang in languageItems\"\n :key=\"lang.lang\"\n :title=\"lang.title\"\n :active=\"lang.lang === currentLocale\"\n @click=\"handleLanguageSelect(lang)\"\n />\n </template>\n </SettingsMenuItem>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useI18n } from \"vue-i18n\";\nimport { useLanguages } from \"@core/composables\";\nimport { computed } from \"vue\";\nimport { SettingsMenuItem } from \"@shell/components/settings-menu-item\";\nimport VcDropdownItem from \"@ui/components/molecules/vc-dropdown/_internal/VcDropdownItem.vue\";\n\ninterface ILanguage {\n lang: string;\n title: string;\n clickHandler: (lang: string) => void;\n}\n\nconst { availableLocales, getLocaleMessage } = useI18n({ useScope: \"global\" });\nconst { setLocale, currentLocale } = useLanguages();\n\nconst languageItems: ILanguage[] = availableLocales\n .map((locale: string) => ({\n lang: locale,\n title: (getLocaleMessage(locale) as { language_name: string }).language_name,\n async clickHandler(lang: string) {\n await setLocale(lang);\n },\n }))\n .filter((item) => item.title);\n\nconst currentLanguageName = computed(() => {\n const current = languageItems.find((l) => l.lang === currentLocale.value);\n return current?.title;\n});\n\nconst handleLanguageSelect = (lang: ILanguage) => {\n if (Object.prototype.hasOwnProperty.call(lang, \"clickHandler\")) {\n lang.clickHandler(lang.lang);\n }\n};\n</script>\n","import _LanguageSelector from \"@shell/components/language-selector/language-selector.vue\";\n\nexport const LanguageSelector = _LanguageSelector as typeof _LanguageSelector;\n","<template>\n <SettingsMenuItem\n icon=\"lucide-palette\"\n :title=\"$t('COMPONENTS.THEME_SELECTOR.THEME_SELECTOR')\"\n :value=\"currentLocalizedName\"\n >\n <template #submenu>\n <VcDropdownItem\n v-for=\"theme in themes\"\n :key=\"theme.key\"\n :title=\"theme.name\"\n :active=\"theme.key === currentThemeKey\"\n @click=\"handleThemeSelect(theme)\"\n />\n </template>\n </SettingsMenuItem>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useTheme } from \"@core/composables/useTheme\";\nimport { notification } from \"@core/notifications/notification\";\nimport { SettingsMenuItem } from \"@shell/components/settings-menu-item\";\nimport VcDropdownItem from \"@ui/components/molecules/vc-dropdown/_internal/VcDropdownItem.vue\";\n\nconst { currentThemeKey, currentLocalizedName, themes, setTheme } = useTheme();\n\nconst handleThemeSelect = (theme: { key: string; name: string }) => {\n setTheme(theme.key);\n\n if (currentLocalizedName.value) {\n notification(currentLocalizedName.value);\n }\n};\n</script>\n","<template>\n <VcPopup\n :title=\"t('COMPONENTS.CHANGE_PASSWORD.TITLE')\"\n is-mobile-fullscreen\n @close=\"cancelChange\"\n >\n <template #content>\n <!-- <div class=\"change-password tw-p-3 tw-overflow-scroll\"> -->\n <VcForm class=\"tw-flex tw-flex-col tw-flex-auto\">\n <div\n v-if=\"forced\"\n class=\"tw-mb-4\"\n >\n <VcStatus\n extend\n :outline=\"false\"\n variant=\"info-dark\"\n >\n <div class=\"tw-flex tw-flex-row tw-items-center tw-text-[color:var(--change-password-text-color)]\">\n <VcIcon\n icon=\"lucide-lightbulb\"\n size=\"l\"\n class=\"tw-mr-3\"\n />\n <div>\n <p>{{ t(\"COMPONENTS.CHANGE_PASSWORD.FORCED.LABEL\") }}</p>\n </div>\n </div>\n </VcStatus>\n </div>\n\n <Field\n v-slot=\"{ field, errorMessage, errors }\"\n :label=\"t('COMPONENTS.CHANGE_PASSWORD.CURRENT_PASSWORD.LABEL')\"\n name=\"current\"\n rules=\"required|min:6\"\n :model-value=\"form.currentPassword\"\n >\n <VcInput\n v-bind=\"field\"\n ref=\"passwordField\"\n v-model=\"form.currentPassword\"\n class=\"tw-mb-4 tw-mt-1 tw-shrink-0\"\n :label=\"t('COMPONENTS.CHANGE_PASSWORD.CURRENT_PASSWORD.LABEL')\"\n :placeholder=\"t('COMPONENTS.CHANGE_PASSWORD.CURRENT_PASSWORD.PLACEHOLDER')\"\n type=\"password\"\n required\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n @update:model-value=\"validate\"\n ></VcInput>\n </Field>\n <Field\n v-slot=\"{ field, errorMessage, errors }\"\n :label=\"t('COMPONENTS.CHANGE_PASSWORD.NEW_PASSWORD.LABEL')\"\n name=\"new_pass\"\n rules=\"required|min:6\"\n :model-value=\"form.password\"\n >\n <VcInput\n v-bind=\"field\"\n ref=\"newPasswordField\"\n v-model=\"form.password\"\n class=\"tw-mb-4 tw-mt-1 tw-shrink-0\"\n :label=\"t('COMPONENTS.CHANGE_PASSWORD.NEW_PASSWORD.LABEL')\"\n :placeholder=\"t('COMPONENTS.CHANGE_PASSWORD.NEW_PASSWORD.PLACEHOLDER')\"\n type=\"password\"\n required\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n @update:model-value=\"validate\"\n ></VcInput>\n </Field>\n <Field\n v-slot=\"{ field, errorMessage, errors }\"\n :label=\"t('COMPONENTS.CHANGE_PASSWORD.CONFIRM_PASSWORD.LABEL')\"\n name=\"confirm_pass\"\n rules=\"required|min:6\"\n :model-value=\"form.confirmPassword\"\n >\n <VcInput\n v-bind=\"field\"\n ref=\"confirmPasswordField\"\n v-model=\"form.confirmPassword\"\n class=\"tw-mb-4 tw-shrink-0\"\n :label=\"t('COMPONENTS.CHANGE_PASSWORD.CONFIRM_PASSWORD.LABEL')\"\n :placeholder=\"t('COMPONENTS.CHANGE_PASSWORD.CONFIRM_PASSWORD.PLACEHOLDER')\"\n type=\"password\"\n required\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n @update:model-value=\"validate\"\n ></VcInput>\n </Field>\n </VcForm>\n </template>\n <template #footer>\n <div class=\"tw-flex tw-flex-col tw-flex-auto\">\n <div class=\"tw-flex tw-justify-between tw-flex-auto\">\n <!-- <span\n v-if=\"$isDesktop.value\"\n class=\"tw-grow tw-basis-0\"\n ></span> -->\n <VcButton\n variant=\"secondary\"\n class=\"tw-mr-3\"\n @click=\"cancelChange\"\n >\n {{ t(\"COMPONENTS.CHANGE_PASSWORD.CANCEL\") }}\n </VcButton>\n <VcButton\n :disabled=\"loading || !form.isValid || isDisabled\"\n @click=\"changePassword\"\n >\n {{ t(\"COMPONENTS.CHANGE_PASSWORD.SAVE\") }}\n </VcButton>\n </div>\n <VcHint\n v-for=\"(err, i) in form.errors\"\n :key=\"i\"\n class=\"tw-mt-3 !tw-text-[color:var(--change-password-error-color)]\"\n >\n <!-- TODO: stylizing-->\n {{\n (err as IdentityError).code ? t(`COMPONENTS.CHANGE_PASSWORD.ERRORS.${(err as IdentityError).code}`) : err\n }}\n </VcHint>\n </div>\n </template>\n\n <!-- </div> -->\n </VcPopup>\n</template>\n\n<script lang=\"ts\" setup>\nimport { nextTick, reactive, computed } from \"vue\";\nimport { useIsFormValid, Field, useIsFormDirty, useForm } from \"vee-validate\";\nimport { VcInput } from \"@ui/components/molecules/vc-input\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { VcPopup } from \"@ui/components/organisms/vc-popup\";\nimport { VcForm } from \"@ui/components/molecules/vc-form\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcStatus } from \"@ui/components/atoms/vc-status\";\nimport { IdentityError } from \"@core/api/platform\";\nimport { useUserManagement } from \"@core/composables/useUserManagement\";\nimport { useI18n } from \"vue-i18n\";\nimport { useRouter } from \"vue-router\";\n\ninterface IChangePassForm {\n isValid: boolean;\n errors: IdentityError[] | string[];\n currentPassword: string;\n password: string;\n confirmPassword: string;\n}\n\nexport interface Props {\n forced?: boolean;\n login?: string;\n}\n\nconst props = defineProps<Props>();\n\ninterface Emits {\n (event: \"close\"): void;\n}\n\nconst emit = defineEmits<Emits>();\nconst { t } = useI18n({ useScope: \"global\" });\nconst { changeUserPassword, loading, validatePassword, signOut } = useUserManagement();\nuseForm({ validateOnMount: false });\nconst isValid = useIsFormValid();\nconst isDirty = useIsFormDirty();\nconst router = useRouter();\n\nconst form = reactive<IChangePassForm>({\n isValid: false,\n errors: [],\n currentPassword: \"\",\n password: \"\",\n confirmPassword: \"\",\n});\n\nconst isDisabled = computed(() => {\n return !isDirty.value || !isValid.value;\n});\n\nasync function cancelChange() {\n if (props.forced) {\n await signOut();\n await router.push(\"/login\");\n } else {\n emit(\"close\");\n }\n}\n\nasync function changePassword() {\n const result = await changeUserPassword(form.currentPassword, form.password);\n if (result?.succeeded) {\n if (props.forced) {\n await router.push(\"/\");\n } else {\n emit(\"close\");\n }\n } else if (result?.errors) {\n form.errors = result?.errors;\n form.isValid = form.errors.length == 0;\n }\n}\n\nfunction validate() {\n nextTick(async () => {\n if (form.password || form.confirmPassword) {\n form.errors = (await validatePassword(form.password)).errors ?? [];\n if (form.confirmPassword !== form.password) {\n (form.errors as IdentityError[]).push({ code: \"Repeat-password\" });\n }\n if (form.confirmPassword === form.currentPassword && form.password === form.currentPassword) {\n (form.errors as IdentityError[]).push({ code: \"Equal-passwords\" });\n }\n form.isValid = form.errors.length == 0;\n }\n });\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --change-password-error-color: var(--danger-500);\n --change-password-text-color: var(--additional-950);\n}\n</style>\n","import _ChangePassword from \"@shell/components/change-password/change-password.vue\";\n\nexport const ChangePassword = _ChangePassword as typeof _ChangePassword;\n","<template>\n <SettingsMenuItem\n icon=\"lucide-key\"\n :title=\"$t('SHELL.ACCOUNT.CHANGE_PASSWORD')\"\n @trigger:click=\"handleClick\"\n />\n</template>\n\n<script lang=\"ts\" setup>\nimport { inject } from \"vue\";\nimport { CloseSettingsMenuKey } from \"@framework/injection-keys\";\nimport { SettingsMenuItem } from \"@shell/components/settings-menu-item\";\nimport { usePopup } from \"@core/composables/usePopup\";\nimport { ChangePassword } from \"@shell/components/change-password\";\n\nconst { open } = usePopup({ component: ChangePassword });\nconst closeSettingsMenu = inject(CloseSettingsMenuKey, undefined);\n\nconst handleClick = () => {\n closeSettingsMenu?.();\n open();\n};\n</script>\n","<template>\n <SettingsMenuItem\n icon=\"lucide-log-out\"\n :title=\"$t('SHELL.ACCOUNT.LOGOUT')\"\n @trigger:click=\"handleLogout\"\n />\n</template>\n\n<script lang=\"ts\" setup>\nimport { inject } from \"vue\";\nimport { CloseSettingsMenuKey } from \"@framework/injection-keys\";\nimport { SettingsMenuItem } from \"@shell/components/settings-menu-item\";\nimport { useUserManagement } from \"@core/composables/useUserManagement\";\nimport { useRouter } from \"vue-router\";\nimport { useBladeStack } from \"@core/blade-navigation\";\n\nconst { signOut } = useUserManagement();\nconst router = useRouter();\nconst { blades, closeBlade } = useBladeStack();\nconst closeSettingsMenu = inject(CloseSettingsMenuKey, undefined);\n\nconst handleLogout = async () => {\n closeSettingsMenu?.();\n while (blades.value.length > 1) {\n const activeChild = blades.value[blades.value.length - 1];\n const isPrevented = await closeBlade(activeChild.id);\n if (isPrevented) {\n return;\n }\n }\n\n await signOut();\n router.push({ name: \"Login\" });\n};\n</script>\n","import { provide, inject } from \"vue\";\nimport { provideAppBarMobileButtonsService } from \"@core/composables/useAppBarMobileButtons\";\nimport { provideDashboardService } from \"@core/composables/useDashboard\";\nimport { usePlatformLocaleSync } from \"@core/composables/usePlatformLocaleSync\";\nimport {\n SettingsMenuServiceKey,\n EmbeddedModeKey,\n DynamicModulesKey,\n ShellIndicatorsKey,\n InternalRoutesKey,\n type DynamicModuleRegistry,\n} from \"@framework/injection-keys\";\nimport { useNotificationStore } from \"@core/notifications\";\nimport { NotificationDropdown } from \"@shell/components/notification-dropdown\";\nimport { LanguageSelector } from \"@shell/components/language-selector\";\nimport { ThemeSelector } from \"@shell/components/theme-selector\";\nimport { ChangePasswordButton } from \"@shell/components/change-password-button\";\nimport { LogoutButton } from \"@shell/components/logout-button\";\nimport { provideAiAgentService } from \"@core/plugins/ai-agent\";\nimport type { IAiAgentConfig } from \"@core/plugins/ai-agent\";\nimport type { BladeRoutesRecord } from \"@core/blade-navigation/types\";\nimport type { AppBarButtonContent } from \"@core/services/app-bar-mobile-buttons-service\";\nimport type { RegisterSettingsMenuItemOptions } from \"@core/services/settings-menu-service\";\n\nexport interface ShellBootstrapOptions {\n isEmbedded: boolean;\n internalRoutes?: BladeRoutesRecord[];\n dynamicModules?: DynamicModuleRegistry;\n aiAgentConfig?: IAiAgentConfig;\n aiAgentAddGlobalToolbarButton?: boolean;\n}\n\nexport function useShellBootstrap(options: ShellBootstrapOptions) {\n // 1a. App-level services (created by framework plugin install)\n const settingsMenuService = inject(SettingsMenuServiceKey)!;\n\n // 1b. Component-scoped services (created here for VcApp descendants)\n const mobileButtons = provideAppBarMobileButtonsService();\n provideDashboardService();\n\n // 2. Provide injection keys\n provide(EmbeddedModeKey, options.isEmbedded);\n if (options.isEmbedded) {\n usePlatformLocaleSync();\n }\n if (options.internalRoutes) {\n provide(InternalRoutesKey, options.internalRoutes);\n }\n if (options.dynamicModules !== undefined) {\n provide(DynamicModulesKey, options.dynamicModules);\n }\n\n // 3. AI agent (conditional)\n if (options.aiAgentConfig?.url) {\n provideAiAgentService({\n config: options.aiAgentConfig,\n addGlobalToolbarButton: options.aiAgentAddGlobalToolbarButton ?? true,\n isEmbedded: options.isEmbedded,\n });\n }\n\n // 4. Register default shell UI\n useShellDefaults({\n isEmbedded: options.isEmbedded,\n registerMobileButton: mobileButtons.register,\n registerSettingsMenuItem: settingsMenuService.register,\n });\n}\n\n// ── Internal: default UI element registration ─────────────────────\ninterface ShellDefaultsContext {\n isEmbedded: boolean;\n registerMobileButton: (button: AppBarButtonContent) => void;\n registerSettingsMenuItem: (options: RegisterSettingsMenuItemOptions) => string;\n}\n\nfunction useShellDefaults(ctx: ShellDefaultsContext) {\n const notificationStore = useNotificationStore();\n\n if (!ctx.isEmbedded) {\n ctx.registerMobileButton({\n id: \"notifications\",\n component: NotificationDropdown,\n icon: \"lucide-bell\",\n order: 10,\n isVisible: true,\n badge: notificationStore.hasUnread,\n });\n }\n\n // Settings menu items\n ctx.registerSettingsMenuItem({ id: \"theme-selector\", component: ThemeSelector, group: \"preferences\", order: 10 });\n ctx.registerSettingsMenuItem({\n id: \"language-selector\",\n component: LanguageSelector,\n group: \"preferences\",\n order: 20,\n });\n ctx.registerSettingsMenuItem({ id: \"change-password\", component: ChangePasswordButton, group: \"account\", order: 30 });\n ctx.registerSettingsMenuItem({ id: \"logout\", component: LogoutButton, group: \"account\", order: 100 });\n\n // Shell indicator state for SidebarHeader\n provide(ShellIndicatorsKey, notificationStore.hasUnread);\n}\n","import { useRoute, useRouter } from \"vue-router\";\r\nimport { useBlade } from \"@core/composables/useBlade\";\r\nimport { navigateToMainRoute } from \"@core/blade-navigation/utils/navigateToMainRoute\";\r\nimport { createLogger } from \"@core/utilities\";\r\nimport type { MenuItem } from \"@core/types\";\r\n\r\nconst logger = createLogger(\"useShellNavigation\");\r\n\r\n/**\r\n * Encapsulates menu click handling and blade navigation logic.\r\n * Extracted from vc-app.vue for separation of concerns.\r\n */\r\nexport function useShellNavigation() {\r\n const router = useRouter();\r\n const route = useRoute();\r\n const { openBlade } = useBlade();\r\n const routes = router.getRoutes();\r\n\r\n const handleMenuItemClick = (item: MenuItem) => {\r\n logger.debug(\"handleMenuItemClick() called\");\r\n\r\n if (item.routeId) {\r\n openBlade({ name: item.routeId, isWorkspace: true });\r\n } else if (!item.routeId && item.url) {\r\n const itemUrl = item.url;\r\n // Match by exact path OR by comparing static (non-param) segments against item.url\r\n // Handles tenant-prefixed routes like \"/:sellerId/products\" matching item.url \"/products\"\r\n const menuRoute = routes.find((r) => {\r\n if (r.path === itemUrl) return true;\r\n const staticSegments = r.path\r\n .split(\"/\")\r\n .filter(Boolean)\r\n .filter((s) => !s.startsWith(\":\"));\r\n const itemSegment = itemUrl.replace(/^\\//, \"\");\r\n return staticSegments.includes(itemSegment);\r\n });\r\n if (typeof menuRoute === \"undefined\") {\r\n openRoot();\r\n } else {\r\n router.push({ name: menuRoute?.name, params: route.params });\r\n }\r\n }\r\n };\r\n\r\n const openRoot = async () => {\r\n // Navigate to main route — workspace cleanup is handled by BladeStack\r\n navigateToMainRoute(router, route.params as Record<string, string>);\r\n };\r\n\r\n return { handleMenuItemClick, openRoot };\r\n}\r\n","import { computed, Ref, ref } from \"vue\";\nimport { AppDescriptor, AppsClient } from \"@core/api/platform\";\nimport { usePermissions } from \"@core/composables/usePermissions\";\nimport { notification } from \"@core/notifications/notification\";\nimport { i18n } from \"@core/plugins\";\nimport { createLogger } from \"@core/utilities\";\n\nconst logger = createLogger(\"use-app-hub\");\n\ninterface IUseAppHub {\n readonly appsList: Ref<AppDescriptor[]>;\n getApps: () => Promise<void>;\n switchApp: (app: AppDescriptor) => void;\n}\n\nexport function useAppHub(): IUseAppHub {\n const { hasAccess } = usePermissions();\n const appsList = ref<AppDescriptor[]>([]);\n\n async function getApiClient(): Promise<AppsClient> {\n const client = new AppsClient();\n return client;\n }\n\n async function getApps() {\n const client = await getApiClient();\n\n try {\n appsList.value = await client.getApps();\n } catch (e) {\n logger.error(\"Failed to get apps:\", e);\n throw e;\n }\n }\n\n function switchApp(app: AppDescriptor) {\n if (hasAccess(app.permission)) {\n if (app.relativeUrl) {\n window.location.href = window.location.origin + app.relativeUrl;\n }\n } else {\n notification.error(i18n.global.t(\"PERMISSION_MESSAGES.ACCESS_RESTRICTED\"), {\n timeout: 3000,\n });\n }\n }\n\n return {\n appsList: computed(() => appsList.value),\n getApps,\n switchApp,\n };\n}\n","import { ref, watch, onUnmounted } from \"vue\";\nimport { useNotificationStore } from \"@core/notifications\";\nimport { useUserManagement } from \"@core/composables/useUserManagement\";\nimport { useAppHub } from \"@shell/components/app-hub/composables/useAppHub\";\n\n/**\n * Manages app readiness and authentication lifecycle.\n * Extracted from vc-app.vue for separation of concerns.\n */\nexport function useShellLifecycle(props: { isReady: boolean }) {\n const isAppReady = ref(false);\n const isBootstrapped = ref(false);\n const { isAuthenticated } = useUserManagement();\n const { loadHistory } = useNotificationStore();\n const { appsList, switchApp, getApps } = useAppHub();\n\n // Show the shell as soon as isReady is true (don't block on auth).\n // Auth only gates one-time bootstrap (loading notifications, app list).\n watch(\n [() => props.isReady, isAuthenticated],\n async ([isReady, isAuth]) => {\n isAppReady.value = isReady;\n\n if (!isBootstrapped.value && isReady && isAuth) {\n isBootstrapped.value = true;\n await loadHistory();\n await getApps();\n }\n },\n { immediate: true },\n );\n\n onUnmounted(() => {\n isAppReady.value = false;\n isBootstrapped.value = false;\n });\n\n return { isAppReady, isAuthenticated, appsList, switchApp };\n}\n","<template>\n <VcLoading\n v-if=\"!isAppReady\"\n active\n class=\"vc-app__loader\"\n />\n <div\n v-else\n ref=\"appRootRef\"\n class=\"vc-app\"\n :class=\"{\n 'vc-app--mobile': isMobile,\n }\"\n >\n <VcEnvironmentBanner\n v-if=\"!isEnvironmentIgnored && environmentName\"\n :name=\"environmentName\"\n :color=\"environmentColor\"\n />\n <div class=\"vc-app__main-content\">\n <!-- Layout: desktop sidebar or mobile top bar -->\n <slot\n name=\"layout\"\n :is-mobile=\"isMobile\"\n :sidebar=\"sidebar\"\n :apps-list=\"appsList\"\n :switch-app=\"switchApp\"\n :open-root=\"openRoot\"\n :handle-menu-item-click=\"handleMenuItemClick\"\n >\n <component\n :is=\"isDesktop ? DesktopLayout : MobileLayout\"\n :logo=\"logo\"\n :avatar=\"avatar\"\n :user-name=\"name\"\n :user-role=\"role\"\n :title=\"title\"\n :disable-menu=\"disableMenu\"\n :disable-app-hub=\"disableAppHub\"\n :apps-list=\"appsList\"\n :show-search=\"showSearch\"\n :search-placeholder=\"searchPlaceholder\"\n @logo:click=\"openRoot\"\n @item:click=\"handleMenuItemClick\"\n @switch-app=\"switchApp\"\n >\n <template\n v-if=\"$slots['app-hub'] && !disableAppHub\"\n #app-hub=\"{ appsList: slotAppsList, switchApp: slotSwitchApp }\"\n >\n <slot\n name=\"app-hub\"\n :apps-list=\"slotAppsList\"\n :switch-app=\"slotSwitchApp\"\n />\n </template>\n <template\n v-if=\"$slots.menu\"\n #menu=\"menuScope\"\n >\n <slot\n name=\"menu\"\n v-bind=\"menuScope\"\n />\n </template>\n <template\n v-if=\"$slots['sidebar-header']\"\n #sidebar-header=\"headerScope\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"headerScope\"\n />\n </template>\n <template\n v-if=\"$slots['sidebar-footer']\"\n #sidebar-footer=\"footerScope\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"footerScope\"\n />\n </template>\n </component>\n </slot>\n\n <!-- Blade navigation / workspace -->\n <slot\n name=\"workspace\"\n :is-authenticated=\"isAuthenticated\"\n >\n <main\n v-if=\"isAuthenticated\"\n class=\"vc-app__workspace\"\n >\n <VcBladeNavigation v-if=\"hasBladeNavigation\" />\n <!-- AI Agent Panel (shown when plugin is installed) -->\n <VcAiAgentPanel v-if=\"aiAgentConfig?.url\" />\n </main>\n </slot>\n\n <!-- Popup container -->\n <VcPopupContainer />\n </div>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport { inject, provide, ref, watch } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport DesktopLayout from \"@ui/components/organisms/vc-app/_internal/layouts/DesktopLayout.vue\";\nimport MobileLayout from \"@ui/components/organisms/vc-app/_internal/layouts/MobileLayout.vue\";\nimport { VcPopupContainer } from \"@shell/_internal/popup\";\nimport { VcLoading } from \"@ui/components/atoms/vc-loading\";\nimport { VcBladeNavigation } from \"@shell/_internal/blade-navigation/components\";\nimport type { AppDescriptor } from \"@core/api/platform\";\nimport type { MenuItem } from \"@core/types\";\nimport type { SidebarStateReturn } from \"@core/composables/useSidebarState\";\nimport { VcAiAgentPanel } from \"@core/plugins/ai-agent\";\nimport type { IAiAgentConfig } from \"@core/plugins/ai-agent\";\nimport { notification } from \"@core/notifications/notification\";\nimport { useRoute } from \"vue-router\";\nimport { AppRootElementKey, DynamicModulesKey, BladeRoutesKey, ModulesLoadErrorKey } from \"@framework/injection-keys\";\nimport { createLogger } from \"@core/utilities\";\nimport { provideSidebarState } from \"@core/composables/useSidebarState\";\nimport { provideAppBarState } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarState\";\nimport { useShellBootstrap } from \"@ui/components/organisms/vc-app/composables/useShellBootstrap\";\nimport { useShellNavigation } from \"@ui/components/organisms/vc-app/composables/useShellNavigation\";\nimport { useShellLifecycle } from \"@ui/components/organisms/vc-app/composables/useShellLifecycle\";\nimport { BladeMessagingKey, BladeStackKey } from \"@core/blade-navigation/types\";\nimport { VcEnvironmentBanner } from \"@ui/components/atoms/vc-environment-banner\";\nimport { useEnvironmentName } from \"@core/composables/useEnvironmentName\";\n\nexport interface Props {\n isReady: boolean;\n logo?: string;\n version?: string;\n title?: string;\n avatar?: string;\n name?: string;\n disableMenu?: boolean;\n disableAppHub?: boolean;\n role?: string;\n showSearch?: boolean;\n searchPlaceholder?: string;\n}\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ndefineSlots<{\n \"app-hub\"?: (props: { appsList: AppDescriptor[]; switchApp: (app: AppDescriptor) => void }) => unknown;\n layout?: (props: {\n isMobile: boolean;\n sidebar: SidebarStateReturn;\n appsList: AppDescriptor[];\n switchApp: (app: AppDescriptor) => void;\n openRoot: () => void;\n handleMenuItemClick: (item: MenuItem) => void;\n }) => unknown;\n menu?: (props: { expanded: boolean; onItemClick: (item: MenuItem) => void; searchQuery: string }) => unknown;\n \"sidebar-header\"?: (props: { logo?: string; expanded: boolean; isMobile: boolean }) => unknown;\n \"sidebar-footer\"?: (props: { avatar?: string; name?: string; role?: string }) => unknown;\n workspace?: (props: { isAuthenticated: boolean }) => unknown;\n}>();\n\nconst props = defineProps<Props>();\n\nconst { isMobile, isDesktop } = useResponsive();\n\nconst hasBladeNavigation = Boolean(inject(BladeStackKey, null) && inject(BladeMessagingKey, null));\n\nconst logger = createLogger(\"vc-app\");\nlogger.debug(\"Init vc-app\");\n\nconst route = useRoute();\nconst isEmbedded = route.query.EmbeddedMode === \"true\";\n\n// App root element ref (for scoped Teleport targets)\nconst appRootRef = ref<HTMLElement>();\nprovide(AppRootElementKey, appRootRef);\n\n// Sidebar state (provide to all children)\nconst sidebar = provideSidebarState();\nprovideAppBarState();\n\n// Lifecycle: isReady/isAuthenticated watchers\nconst { isAppReady, isAuthenticated, appsList, switchApp } = useShellLifecycle(props);\n\n// Navigation: menu click handling + blade resolution\nconst { handleMenuItemClick, openRoot } = useShellNavigation();\n\n// Injected config from parent\nconst internalRoutes = inject(BladeRoutesKey)!;\nconst dynamicModules = inject(DynamicModulesKey, undefined);\nconst aiAgentConfig = inject<IAiAgentConfig | undefined>(\"aiAgentConfig\", undefined);\nconst aiAgentAddGlobalToolbarButton = inject<boolean>(\"aiAgentAddGlobalToolbarButton\", true);\n\n// Module load error state for notification toast\n// Default ref(false) = backward-compatible: no dynamic modules means no error\nconst modulesLoadError = inject(ModulesLoadErrorKey, ref(false));\n\n// Bootstrap: provide services + register default shell UI\nuseShellBootstrap({\n isEmbedded,\n internalRoutes,\n dynamicModules,\n aiAgentConfig,\n aiAgentAddGlobalToolbarButton,\n});\n\n// Progressive loading: show error as notification toast instead of blocking overlay\nwatch(modulesLoadError, (hasError) => {\n if (hasError) {\n notification.error(\n \"Unable to load application modules. Please check your connection and try refreshing the page.\",\n { timeout: 10000 },\n );\n }\n});\n\n// Environment indicator (derived client-side from the hostname)\nconst { environmentName, isIgnored: isEnvironmentIgnored, color: environmentColor } = useEnvironmentName();\n</script>\n\n<style lang=\"scss\">\n:root {\n --app-background: var(--secondary-200);\n // Shared transition timing for synchronized animations\n --app-panel-transition-duration: 0.3s;\n --app-panel-transition-timing: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.vc-app {\n @apply tw-flex tw-flex-col tw-w-full tw-h-full tw-box-border tw-m-0 tw-overflow-hidden tw-text-base;\n background: var(--app-background);\n\n &__loader {\n background: var(--app-background);\n }\n\n &__app-bar {\n @apply tw-shrink-0;\n }\n\n &__app-menu {\n @apply tw-shrink-0;\n }\n\n &__main-content {\n @apply tw-overflow-hidden tw-flex tw-grow tw-basis-0;\n }\n\n &__workspace {\n @apply tw-w-full tw-overflow-hidden tw-flex tw-grow tw-basis-0 tw-relative;\n\n .vc-app--mobile & {\n @apply tw-p-0;\n }\n }\n\n &__user-dropdown-button {\n @apply tw-p-0 tw-mb-2 tw-w-full tw-h-auto;\n }\n\n &--mobile {\n .vc-app__main-content {\n @apply tw-flex-col;\n }\n }\n}\n</style>\n","import { computed, unref, isRef, toValue, type ComputedRef, type MaybeRefOrGetter, type Ref } from \"vue\";\r\nimport type { MenuItemBadgeConfig, MenuItemBadge } from \"@core/types\";\r\nimport { useMenuService } from \"@core/composables/useMenuService\";\r\n\r\nexport interface ResolvedBadge {\r\n content: string | number | undefined;\r\n variant: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"info\" | \"secondary\";\r\n isDot: boolean;\r\n isVisible: boolean;\r\n}\r\n\r\n/**\r\n * Composable to resolve badge configuration for menu items.\r\n * Supports direct badge config, routeId lookup, or groupId lookup.\r\n *\r\n * @param badgeConfig - Direct badge configuration (takes priority). Accepts a reactive getter.\r\n * @param routeId - Route ID to lookup badge from registry. Accepts a reactive getter.\r\n * @param groupId - Group ID to lookup badge from registry. Accepts a reactive getter.\r\n */\r\nexport function useBadge(\r\n badgeConfig: MaybeRefOrGetter<MenuItemBadgeConfig | undefined>,\r\n routeId?: MaybeRefOrGetter<string | undefined>,\r\n groupId?: MaybeRefOrGetter<string | undefined>,\r\n): ComputedRef<ResolvedBadge> {\r\n const { menuBadges } = useMenuService();\r\n\r\n return computed(() => {\r\n // Priority: direct badge config > badge from registry by routeId > badge from registry by groupId\r\n let config: MenuItemBadgeConfig | undefined = toValue(badgeConfig);\r\n const resolvedRouteId = toValue(routeId);\r\n const resolvedGroupId = toValue(groupId);\r\n if (!config && resolvedRouteId) {\r\n config = menuBadges.value.get(resolvedRouteId);\r\n }\r\n if (!config && resolvedGroupId) {\r\n config = menuBadges.value.get(resolvedGroupId);\r\n }\r\n\r\n if (!config) {\r\n return { content: undefined, variant: \"primary\", isDot: false, isVisible: false };\r\n }\r\n\r\n // Normalize shorthand to full config object\r\n let badge: MenuItemBadge;\r\n if (typeof config === \"object\" && !isRef(config) && \"content\" in config) {\r\n badge = config as MenuItemBadge;\r\n } else {\r\n badge = { content: config as MenuItemBadge[\"content\"] };\r\n }\r\n\r\n // Resolve reactive content\r\n let rawContent: string | number | undefined = undefined;\r\n if (typeof badge.content === \"function\") {\r\n rawContent = badge.content();\r\n } else if (isRef(badge.content)) {\r\n rawContent = unref(badge.content as Ref<string | number | undefined>);\r\n } else {\r\n rawContent = badge.content;\r\n }\r\n\r\n // Truncate values > 99\r\n let displayContent: string | number | undefined = rawContent;\r\n if (typeof rawContent === \"number\" && rawContent > 99) {\r\n displayContent = \"99+\";\r\n } else if (typeof rawContent === \"string\") {\r\n const numValue = parseInt(rawContent, 10);\r\n if (!isNaN(numValue) && numValue > 99) {\r\n displayContent = \"99+\";\r\n }\r\n }\r\n\r\n const isDot = badge.isDot ?? false;\r\n const isVisible = isDot || (displayContent != null && displayContent !== \"\" && displayContent !== 0);\r\n\r\n return {\r\n content: displayContent,\r\n variant: badge.variant ?? \"primary\",\r\n isDot,\r\n isVisible,\r\n };\r\n });\r\n}\r\n","<template>\n <Teleport\n v-if=\"appRootEl\"\n :to=\"appRootEl\"\n >\n <div\n class=\"app-bar-overlay\"\n :class=\"{\n 'app-bar-overlay--mobile': isMobile,\n 'app-bar-overlay--desktop': isDesktop,\n 'app-bar-overlay--sidebar': isSidebarMode,\n 'app-bar-overlay--standalone-mobile': isMobile && !isSidebarMode,\n 'app-bar-overlay--collapsed': !expanded && !isMobile,\n }\"\n >\n <div class=\"app-bar-overlay__content app-bar-overlay__dropdowns\">\n <slot />\n </div>\n </div>\n </Teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { inject, type MaybeRef } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { AppRootElementKey } from \"@framework/injection-keys\";\n\ndefineProps<{\n isSidebarMode: boolean;\n expanded: MaybeRef<boolean>;\n}>();\n\nconst { isMobile, isDesktop } = useResponsive();\nconst appRootEl = inject(AppRootElementKey, undefined);\n</script>\n\n<style lang=\"scss\">\n.app-bar-overlay {\n @apply tw-w-auto tw-h-full tw-absolute tw-top-0 tw-right-0 tw-z-[var(--z-local-header)]\n tw-bg-[color:var(--app-bar-background)];\n\n &--standalone-mobile {\n @apply tw-w-full #{!important};\n }\n\n &--sidebar {\n @apply tw-w-[var(--app-bar-width)];\n }\n\n &--mobile {\n @apply tw-fixed tw-top-[var(--app-bar-mobile-height)] tw-left-0 tw-bottom-0 tw-flex-1 tw-w-[var(--app-bar-mobile-width)] tw-z-[var(--z-critical-notification)];\n\n .app-bar-overlay__content {\n @apply tw-flex tw-flex-col;\n height: calc(100% - var(--app-bar-mobile-height));\n }\n }\n\n &--collapsed {\n @apply tw-z-[var(--z-local-header)];\n }\n\n &--desktop {\n @apply tw-fixed tw-top-[var(--app-bar-height)] tw-left-0 tw-bottom-0 tw-flex-1 tw-w-[var(--app-bar-width)];\n\n .app-bar-overlay__content {\n @apply tw-flex tw-flex-col;\n height: calc(100% - var(--app-bar-height));\n }\n }\n\n &__content {\n @apply tw-relative;\n\n &:before {\n content: \"\";\n @apply tw-absolute tw-left-0 tw-top-[-1px] tw-w-full tw-h-[1px]\n tw-bg-[color:var(--app-bar-border)] tw-z-[var(--z-local-above)];\n }\n }\n\n &__dropdowns {\n @apply tw-h-auto tw-relative;\n\n &:not(:empty) {\n @apply tw-visible tw-border-b-[2px] tw-border-[color:var(--app-bar-border)] tw-z-[var(--z-local-above)];\n\n &:before {\n content: \"\";\n @apply tw-absolute tw-left-0 tw-top-[-2px] tw-w-full tw-h-[2px]\n tw-bg-[color:var(--app-bar-content-visible-border)] tw-z-[var(--z-local-above)] #{!important};\n }\n }\n }\n}\n</style>\n","<template>\n <div\n class=\"app-bar-button\"\n :class=\"{ 'app-bar-button--mobile': isMobile }\"\n >\n <VcTooltip\n placement=\"bottom\"\n :offset=\"{ crossAxis: 0, mainAxis: -10 }\"\n :delay=\"1000\"\n class=\"tw-w-full\"\n >\n <template\n v-if=\"!isActive && !!title\"\n #tooltip\n >{{ title }}</template\n >\n <button\n class=\"app-bar-button__button\"\n @click.stop=\"toggleContent\"\n >\n <div :class=\"['app-bar-button__button-container']\">\n <slot\n name=\"trigger\"\n :is-active=\"isActive\"\n :toggle=\"toggleContent\"\n >\n <div class=\"app-bar-button__button-wrap\">\n <VcIcon\n :icon=\"icon\"\n size=\"xl\"\n :class=\"['app-bar-button__icon', { 'app-bar-button__icon--active': isActive }]\"\n ></VcIcon>\n </div>\n </slot>\n </div>\n </button>\n </VcTooltip>\n </div>\n</template>\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup>\nimport { computed, type Component } from \"vue\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { useAppBarWidgets } from \"@ui/components/organisms/vc-app/_internal/app-bar/composables/useAppBarWidgets\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcTooltip } from \"@ui/components/atoms/vc-tooltip\";\n\nexport interface Props {\n title?: string;\n icon?: string | Component;\n beforeOpen?: () => boolean;\n widgetId?: string;\n}\n\nexport interface Emits {\n (event: \"toggle\", state: boolean): void;\n}\n\nconst props = defineProps<Props>();\nconst emit = defineEmits<Emits>();\n\ndefineSlots<{\n content: (props: { opened: boolean; toggle: () => void }) => any;\n trigger: (props: { isActive: boolean; toggle: () => void }) => any;\n}>();\n\nconst { isMobile } = useResponsive();\nconst { toggleWidget, currentWidget } = useAppBarWidgets();\n// Check if the current widget is active\nconst isActive = computed(() => (props.widgetId ? currentWidget.value?.id === props.widgetId : false));\n\nfunction toggleContent() {\n if (props.beforeOpen && typeof props.beforeOpen === \"function\" && props.beforeOpen() === false) {\n return;\n }\n\n if (props.widgetId) {\n const nextState = !isActive.value;\n toggleWidget(props.widgetId);\n emit(\"toggle\", nextState);\n }\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --app-bar-button-width: 52px;\n --app-bar-button-shadow-color: var(--additional-950);\n --app-bar-button-shadow:\n 0 -6px 6px var(--additional-50), 1px 1px 22px rgb(from var(--app-bar-button-shadow-color) r g b / 7%);\n --app-bar-button-height: var(--app-bar-height);\n --app-bar-button-bg-color: var(--additional-50);\n --app-bar-button-dropdown-bg-color: var(--additional-50);\n --app-bar-button-dropdown-button-width: var(--app-bar-button-width);\n --app-bar-button-border-color: var(--accent-500);\n --app-bar-button-dropdown-button-border: var(--app-bar-button-border-color);\n\n --app-bar-button-dropdown-button-background-color: var(--app-bar-button-background-color);\n\n --app-bar-button-dropdown-button-background-color-hover: var(--app-bar-button-background-color-hover);\n --app-bar-button-mobile-bg-color: var(--neutral-500);\n\n --app-bar-button-dropdown-button-text-color: var(--neutrals-500);\n --app-bar-button-dropdown-button-active-text-color: var(--primary-500);\n --app-bar-button-border-width: 2px;\n}\n\n.app-bar-button {\n @apply tw-relative tw-flex tw-h-[var(--app-bar-height)];\n\n &--mobile {\n @apply tw-h-[var(--app-bar-mobile-height)];\n }\n\n &::after {\n content: \"\";\n @apply tw-absolute tw-left-0 tw-bottom-0 tw-w-full\n tw-border-b-[2px]\n tw-border-[color:var(--app-bar-button-border-color)]\n tw-opacity-0 tw-transition-opacity tw-duration-200 tw-z-[var(--z-local-above)];\n }\n\n &:hover::after {\n @apply tw-opacity-100;\n }\n\n &__button {\n @apply tw-flex tw-text-left tw-w-full tw-box-border tw-relative tw-w-[var(--app-bar-button-width)];\n }\n\n &__button-container {\n @apply tw-w-full tw-relative tw-h-full tw-flex tw-items-center tw-justify-center\n tw-cursor-pointer\n tw-text-[color:var(--app-bar-button-dropdown-button-text-color)] tw-bg-[color:var(--app-bar-button-dropdown-button-background-color)]\n tw-transition-colors tw-duration-200 tw-box-border;\n }\n\n &__button-wrap {\n @apply tw-w-[var(--app-bar-button-dropdown-button-width)] tw-flex tw-justify-center;\n }\n\n &__icon {\n @apply tw-text-[color:var(--app-bar-button-dropdown-button-text-color)] tw-transition-colors tw-duration-300 tw-ease-in-out;\n\n &--active {\n @apply tw-text-[color:var(--app-bar-button-dropdown-button-active-text-color)];\n }\n }\n\n &__dropdown {\n @apply tw-min-w-[100%];\n }\n\n &__menu-dropdowns {\n //@apply tw-w-full tw-h-full tw-border-t-[2px] tw-border-[color:var(--app-bar-button-border-color)] tw-border-solid tw-border-b-[2px] tw-border-b-[color:var(--app-bar-button-border-color)];\n }\n}\n</style>\n","<template>\n <div class=\"vc-app-toolbar-menu\">\n <div\n v-for=\"item in items\"\n :key=\"item.id\"\n class=\"vc-app-toolbar-menu__item\"\n >\n <AppBarWidgetItem\n v-if=\"item.component\"\n :widget-id=\"item.id\"\n @toggle=\"item.onClick && item.onClick()\"\n >\n <template #trigger=\"{ isActive }\">\n <div class=\"vc-app-toolbar-menu__button\">\n <div\n class=\"vc-app-toolbar-menu__button-icon\"\n :class=\"{\n 'vc-app-toolbar-menu__button-icon--active': isActive,\n }\"\n >\n <VcIcon\n v-if=\"item.icon\"\n :icon=\"item.icon\"\n size=\"l\"\n />\n <div\n v-if=\"isBadgeActive(item)\"\n class=\"vc-app-toolbar-menu__accent\"\n ></div>\n </div>\n </div>\n </template>\n </AppBarWidgetItem>\n\n <AppBarWidgetItem\n v-else-if=\"item.onClick\"\n :widget-id=\"item.id\"\n @toggle=\"item.onClick\"\n >\n <template #trigger=\"{ isActive }\">\n <div\n class=\"vc-app-toolbar-menu__button-icon\"\n :class=\"{\n 'vc-app-toolbar-menu__button-icon--active': isActive,\n }\"\n >\n <VcIcon\n v-if=\"item.icon\"\n :icon=\"item.icon\"\n size=\"l\"\n />\n <div\n v-if=\"isBadgeActive(item)\"\n class=\"vc-app-toolbar-menu__accent\"\n ></div>\n </div>\n </template>\n </AppBarWidgetItem>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport AppBarWidgetItem from \"@ui/components/organisms/vc-app/_internal/app-bar/components/AppBarWidgetItem.vue\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { useAppBarWidget } from \"@core/composables\";\nimport type { AppBarWidget } from \"@core/services/app-bar-menu-service\";\n\nconst { items } = useAppBarWidget();\n\nfunction isBadgeActive(item: AppBarWidget): boolean {\n if (item.badge === undefined) {\n return false;\n }\n\n if (typeof item.badge === \"function\") {\n return item.badge();\n }\n\n return !!item.badge;\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --app-toolbar-menu-accent-color: var(--danger-500);\n --app-toolbar-menu-icon-color: var(--neutrals-500);\n --app-toolbar-menu-icon-color-active: var(--primary-500);\n}\n\n.vc-app-toolbar-menu {\n @apply tw-flex tw-items-center;\n\n &__accent {\n @apply tw-block tw-absolute -tw-right-[4px] tw-top-[0px] tw-w-[5px] tw-h-[5px] tw-bg-[--app-toolbar-menu-accent-color] tw-rounded-full tw-z-[var(--z-local-above)];\n }\n\n &__button {\n @apply tw-flex tw-items-center tw-justify-center tw-relative tw-cursor-pointer;\n }\n\n &__button-icon {\n @apply tw-relative tw-text-[color:var(--app-toolbar-menu-icon-color)];\n\n &--active {\n @apply tw-text-[color:var(--app-toolbar-menu-icon-color-active)];\n }\n }\n}\n</style>\n","<template>\r\n <main\r\n class=\"vc-auth-layout\"\r\n :style=\"containerStyle\"\r\n >\r\n <div class=\"vc-auth-layout__logo-wrapper\">\r\n <img\r\n v-if=\"logo\"\r\n :src=\"logo\"\r\n :alt=\"logoAlt\"\r\n class=\"vc-auth-layout__logo\"\r\n :class=\"{ 'vc-auth-layout__logo--loaded': logoLoaded }\"\r\n @load=\"logoLoaded = true\"\r\n />\r\n </div>\r\n\r\n <div class=\"vc-auth-layout__card\">\r\n <div\r\n v-if=\"title || subtitle\"\r\n class=\"vc-auth-layout__header\"\r\n >\r\n <h2\r\n v-if=\"title\"\r\n class=\"vc-auth-layout__title\"\r\n >\r\n {{ title }}\r\n </h2>\r\n <p\r\n v-if=\"subtitle\"\r\n class=\"vc-auth-layout__subtitle\"\r\n >\r\n {{ subtitle }}\r\n </p>\r\n </div>\r\n\r\n <div class=\"vc-auth-layout__content\">\r\n <slot></slot>\r\n </div>\r\n </div>\r\n\r\n <div\r\n v-if=\"$slots.footer\"\r\n class=\"vc-auth-layout__footer\"\r\n >\r\n <slot name=\"footer\"></slot>\r\n </div>\r\n\r\n <div\r\n v-if=\"version\"\r\n class=\"vc-auth-layout__version\"\r\n >\r\n {{ version }}\r\n </div>\r\n </main>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { computed, ref, watch } from \"vue\";\r\nimport { useRouter } from \"vue-router\";\r\n\r\nexport interface Props {\r\n /** Path to logo image */\r\n logo?: string;\r\n /** Background image URL (legacy support). If provided, renders full-screen background-image */\r\n background?: string;\r\n /** Card heading */\r\n title?: string;\r\n /** Card subheading */\r\n subtitle?: string;\r\n /** Page background color override */\r\n bgColor?: string;\r\n /** Accessible alt text for logo image */\r\n logoAlt?: string;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n logoAlt: \"Logo\",\r\n});\r\n\r\ndefineSlots<{\r\n /** Form content (fields, buttons, SSO, errors) */\r\n default: () => unknown;\r\n /** Below card (terms of service, privacy links) */\r\n footer: () => unknown;\r\n}>();\r\n\r\nconst router = useRouter();\r\nconst version = router.currentRoute.value.meta?.appVersion;\r\n\r\nconst logoLoaded = ref(false);\r\nconst bgLoaded = ref(false);\r\n\r\n// Preload background image to avoid pop-in\r\nwatch(\r\n () => props.background,\r\n (url) => {\r\n bgLoaded.value = false;\r\n if (!url) return;\r\n const img = new Image();\r\n img.onload = () => {\r\n bgLoaded.value = true;\r\n };\r\n img.src = url;\r\n },\r\n { immediate: true },\r\n);\r\n\r\nconst containerStyle = computed(() => {\r\n if (props.background) {\r\n return {\r\n background: bgLoaded.value ? `url(${props.background}) center / cover no-repeat` : undefined,\r\n backgroundColor: props.bgColor || undefined,\r\n };\r\n }\r\n if (props.bgColor) {\r\n return { backgroundColor: props.bgColor };\r\n }\r\n return undefined;\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n:root {\r\n --auth-layout-bg: var(--neutrals-100);\r\n --auth-layout-card-bg: var(--additional-50);\r\n --auth-layout-card-border: var(--neutrals-200);\r\n --auth-layout-card-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\r\n --auth-layout-card-radius: 12px;\r\n --auth-layout-card-max-width: 420px;\r\n --auth-layout-title-color: var(--neutrals-900);\r\n --auth-layout-subtitle-color: var(--neutrals-400);\r\n --auth-layout-version-color: var(--neutrals-400);\r\n}\r\n\r\n.vc-auth-layout {\r\n @apply tw-w-full tw-h-full tw-min-h-screen tw-box-border\r\n tw-flex tw-flex-col tw-items-center tw-justify-center\r\n tw-bg-[var(--auth-layout-bg)]\r\n tw-px-4 tw-py-8;\r\n transition: background 0.3s ease;\r\n\r\n &__logo-wrapper {\r\n @apply tw-mb-8 tw-flex tw-items-center tw-justify-center;\r\n min-height: 48px; // Reserve space for logo to prevent layout shift\r\n }\r\n\r\n &__logo {\r\n @apply tw-h-12 tw-max-w-[280px] tw-object-contain;\r\n opacity: 0;\r\n transition: opacity 0.3s ease;\r\n\r\n &--loaded {\r\n opacity: 1;\r\n }\r\n }\r\n\r\n &__card {\r\n @apply tw-w-full tw-bg-[var(--auth-layout-card-bg)]\r\n tw-border tw-border-solid tw-border-[var(--auth-layout-card-border)]\r\n tw-rounded-[var(--auth-layout-card-radius)]\r\n tw-overflow-y-auto;\r\n max-width: var(--auth-layout-card-max-width);\r\n box-shadow: var(--auth-layout-card-shadow);\r\n }\r\n\r\n &__header {\r\n @apply tw-pt-8 tw-px-8 tw-text-center;\r\n }\r\n\r\n &__title {\r\n @apply tw-text-2xl tw-font-semibold tw-text-[var(--auth-layout-title-color)]\r\n tw-m-0 tw-leading-tight;\r\n }\r\n\r\n &__subtitle {\r\n @apply tw-text-sm tw-text-[var(--auth-layout-subtitle-color)]\r\n tw-mt-2 tw-mb-0;\r\n }\r\n\r\n &__content {\r\n @apply tw-px-8 tw-pt-6 tw-pb-8;\r\n }\r\n\r\n &__footer {\r\n @apply tw-mt-6 tw-text-center tw-text-xs tw-text-[var(--auth-layout-subtitle-color)];\r\n max-width: var(--auth-layout-card-max-width);\r\n }\r\n\r\n &__version {\r\n @apply tw-mt-4 tw-text-xs tw-text-[var(--auth-layout-version-color)];\r\n }\r\n}\r\n</style>\r\n","<template>\n <Field\n v-slot=\"{ errorMessage, errors }\"\n :key=\"computedProperty.key\"\n :label=\"computedProperty.displayName\"\n :name=\"computedProperty.name\"\n :model-value=\"value\"\n :rules=\"computedProperty.rules\"\n >\n <template\n v-if=\"computedProperty.valueType !== 'Color' && computedProperty.dictionary && !computedProperty.multivalue\"\n >\n <VcSelect\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"computedProperty.placeholder\"\n :options=\"items\"\n :option-value=\"computedProperty.optionValue\"\n :option-label=\"computedProperty.optionLabel\"\n :disabled=\"disabled\"\n searchable\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :loading=\"loading\"\n @search=\"onSearch\"\n @close=\"onClose\"\n ></VcSelect>\n </template>\n <template\n v-else-if=\"\n computedProperty.valueType === 'ShortText' && computedProperty.multivalue && !computedProperty.dictionary\n \"\n >\n <VcMultivalue\n v-bind=\"$attrs\"\n v-model=\"value\"\n :name=\"computedProperty.name\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.ADD')\"\n :disabled=\"disabled\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n ></VcMultivalue>\n </template>\n <template\n v-else-if=\"\n computedProperty.valueType === 'ShortText' && computedProperty.multivalue && computedProperty.dictionary\n \"\n >\n <VcMultivalue\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.ADD')\"\n :disabled=\"disabled\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :options=\"items\"\n :option-label=\"multilanguage ? 'value' : 'alias'\"\n :option-value=\"multilanguage ? 'value' : 'alias'\"\n :multivalue=\"computedProperty.multivalue\"\n :loading=\"loading\"\n @search=\"onSearch\"\n @close=\"onClose\"\n ></VcMultivalue>\n </template>\n <template v-else-if=\"computedProperty.valueType === 'ShortText'\">\n <VcInput\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n clearable\n :required=\"computedProperty.required\"\n :placeholder=\"computedProperty.displayName || $t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.ADD')\"\n :disabled=\"disabled\"\n :current-language=\"currentLanguage\"\n :loading=\"loading\"\n ></VcInput>\n </template>\n <template v-else-if=\"computedProperty.valueType === 'Number' && computedProperty.multivalue\">\n <VcMultivalue\n v-bind=\"$attrs\"\n v-model=\"value\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.ADD')\"\n :disabled=\"disabled\"\n type=\"number\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n option-label=\"value\"\n option-value=\"value\"\n :options=\"items\"\n ></VcMultivalue>\n </template>\n <template v-else-if=\"computedProperty.valueType === 'Integer' && computedProperty.multivalue\">\n <VcMultivalue\n v-bind=\"$attrs\"\n v-model=\"value\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.ADD')\"\n :disabled=\"disabled\"\n type=\"integer\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n option-label=\"value\"\n option-value=\"value\"\n :options=\"items\"\n ></VcMultivalue>\n </template>\n <template v-else-if=\"computedProperty.valueType === 'Number'\">\n <VcInput\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n clearable\n type=\"number\"\n :required=\"computedProperty.required\"\n :placeholder=\"computedProperty.placeholder\"\n :disabled=\"disabled\"\n :loading=\"loading\"\n ></VcInput>\n </template>\n <template v-else-if=\"computedProperty.valueType === 'Integer'\">\n <VcInput\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n clearable\n type=\"integer\"\n step=\"1\"\n :required=\"computedProperty.required\"\n :placeholder=\"computedProperty.placeholder\"\n :disabled=\"disabled\"\n :loading=\"loading\"\n ></VcInput>\n </template>\n <template v-else-if=\"computedProperty.valueType === 'DateTime'\">\n <VcInput\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n type=\"datetime-local\"\n :required=\"computedProperty.required\"\n :placeholder=\"computedProperty.placeholder\"\n :disabled=\"disabled\"\n :loading=\"loading\"\n clearable\n ></VcInput\n ></template>\n <template v-else-if=\"computedProperty.valueType === 'LongText'\">\n <VcTextarea\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"computedProperty.placeholder\"\n :disabled=\"disabled\"\n :current-language=\"currentLanguage\"\n ></VcTextarea\n ></template>\n <template v-else-if=\"computedProperty.valueType === 'Boolean'\">\n <VcSwitch\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error-message=\"errorMessage\"\n :required=\"computedProperty.required\"\n :disabled=\"disabled\"\n :name=\"computedProperty.name\"\n :label=\"computedProperty.displayName\"\n >\n </VcSwitch>\n </template>\n <template v-else-if=\"computedProperty.valueType === 'Measure'\">\n <VcInputDropdown\n v-bind=\"$attrs\"\n v-model=\"value\"\n v-model:option=\"measureUnit\"\n :options=\"measurementOptions\"\n :loading=\"measurementLoading\"\n option-label=\"displayName\"\n option-value=\"id\"\n input-type=\"number\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :label=\"computedProperty.displayName\"\n :placeholder=\"computedProperty.placeholder\"\n :required=\"computedProperty.required\"\n :disabled=\"disabled\"\n @update:option=\"onUpdateUnit\"\n >\n <template #button=\"scope\">\n <button\n class=\"vc-input-dropdown__toggle-button\"\n tabindex=\"0\"\n @click.stop.prevent=\"scope.toggleHandler\"\n @keydown.enter.stop.prevent=\"scope.toggleHandler\"\n @keydown.space.stop.prevent=\"scope.toggleHandler\"\n >\n {{ measurementSymbol }}\n </button>\n </template>\n </VcInputDropdown>\n </template>\n <template\n v-else-if=\"computedProperty.valueType === 'Color' && computedProperty.multivalue && !computedProperty.dictionary\"\n >\n <VcMultivalue\n v-bind=\"$attrs\"\n v-model=\"value\"\n type=\"color\"\n :name=\"computedProperty.name\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.VALUE_TYPE.COLOR.NAME')\"\n :disabled=\"disabled\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n option-label=\"value\"\n option-value=\"value\"\n ></VcMultivalue>\n </template>\n <template\n v-else-if=\"computedProperty.valueType === 'Color' && computedProperty.multivalue && computedProperty.dictionary\"\n >\n <VcMultivalue\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.ADD')\"\n :disabled=\"disabled\"\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :options=\"items\"\n :option-label=\"multilanguage ? 'value' : 'alias'\"\n :option-value=\"multilanguage ? 'value' : 'alias'\"\n :multivalue=\"computedProperty.multivalue\"\n :loading=\"loading\"\n @search=\"onSearch\"\n @close=\"onClose\"\n >\n <template #selected-item=\"scope\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <div\n class=\"tw-w-5 tw-h-5 tw-rounded tw-border tw-border-solid tw-border-neutrals-300\"\n :style=\"{ backgroundColor: scope.item.colorCode }\"\n ></div>\n <span>{{ scope.item.value }}</span>\n </div>\n </template>\n <template #option=\"scope\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <div\n class=\"tw-w-5 tw-h-5 tw-rounded tw-border tw-border-solid tw-border-neutrals-300\"\n :style=\"{ backgroundColor: scope.item.colorCode }\"\n ></div>\n <span>{{ scope.item.value }}</span>\n </div>\n </template>\n </VcMultivalue>\n </template>\n <template\n v-else-if=\"computedProperty.valueType === 'Color' && !computedProperty.multivalue && !computedProperty.dictionary\"\n >\n <VcInput\n v-bind=\"$attrs\"\n v-model=\"value\"\n type=\"color\"\n :label=\"computedProperty.displayName\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :placeholder=\"$t('COMPONENTS.ORGANISMS.VC_DYNAMIC_PROPERTY.VALUE_TYPE.COLOR.NAME')\"\n ></VcInput>\n </template>\n <template\n v-else-if=\"computedProperty.valueType === 'Color' && computedProperty.dictionary && !computedProperty.multivalue\"\n >\n <VcSelect\n v-bind=\"$attrs\"\n v-model=\"value\"\n :error=\"!!errors.length\"\n :error-message=\"errorMessage\"\n :label=\"computedProperty.displayName\"\n :required=\"computedProperty.required\"\n :placeholder=\"computedProperty.placeholder\"\n :options=\"items\"\n :option-value=\"computedProperty.optionValue\"\n :option-label=\"computedProperty.optionLabel\"\n :disabled=\"disabled\"\n searchable\n :multilanguage=\"multilanguage\"\n :current-language=\"currentLanguage\"\n :loading=\"loading\"\n @search=\"onSearch\"\n @close=\"onClose\"\n >\n <template #selected-item=\"scope\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <div\n class=\"tw-w-5 tw-h-5 tw-rounded tw-border tw-border-solid tw-border-neutrals-300\"\n :style=\"{ backgroundColor: scope.opt.colorCode }\"\n ></div>\n <span>{{ scope.opt.value }}</span>\n </div>\n </template>\n <template #option=\"scope\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <div\n class=\"tw-w-5 tw-h-5 tw-rounded tw-border tw-border-solid tw-border-neutrals-300\"\n :style=\"{ backgroundColor: scope.opt.colorCode }\"\n ></div>\n <span>{{ scope.opt.value }}</span>\n </div>\n </template>\n </VcSelect>\n </template>\n </Field>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup generic=\"T extends { [x: string]: any; id?: string }\">\nimport { ref, onMounted, computed, Ref, watch } from \"vue\";\nimport { Field } from \"vee-validate\";\nimport { useI18n } from \"vue-i18n\";\nimport { VcSelect } from \"@ui/components/molecules/vc-select\";\nimport { VcInput } from \"@ui/components/molecules/vc-input\";\nimport { VcTextarea } from \"@ui/components/molecules/vc-textarea\";\nimport { VcSwitch } from \"@ui/components/molecules/vc-switch\";\nimport { VcMultivalue } from \"@ui/components/molecules/vc-multivalue\";\nimport { VcInputDropdown } from \"@ui/components/molecules/vc-input-dropdown\";\nimport { cloneDeep } from \"lodash-es\";\nimport { convertColorNameToHex } from \"@core/utilities\";\n\ntype IValidationRules = {\n required?: boolean;\n min?: number;\n max?: number;\n regex?: RegExp;\n};\n\nconst props = withDefaults(\n defineProps<{\n property: T;\n modelValue: any;\n optionsGetter: (\n propertyId: string,\n keyword?: string,\n locale?: string,\n ) => Promise<any[] | undefined> | any[] | undefined;\n measurementsGetter?: (measureId: string, locale?: string) => Promise<any[] | undefined> | any[] | undefined;\n required: boolean;\n multivalue?: boolean;\n multilanguage?: boolean;\n currentLanguage?: string;\n valueType: string;\n dictionary?: boolean;\n name: string;\n optionsValue?: string;\n optionsLabel?: string;\n displayNames?: {\n name?: string;\n languageCode?: string;\n }[];\n rules?: {\n min?: number;\n max?: number;\n regex?: string;\n };\n disabled?: boolean;\n placeholder?: string;\n }>(),\n {\n optionsValue: \"id\",\n optionsLabel: \"value\",\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n \"update:model-value\": [\n data: {\n readonly value: any;\n readonly dictionary?: any[];\n readonly locale?: string;\n readonly unitOfMeasureId?: string;\n readonly colorCode?: string;\n },\n ];\n}>();\n\nconst { te, t } = useI18n({ useScope: \"global\" });\n\nconst items: Ref<any[]> = ref([]);\nconst loading = ref(false);\nconst initialOptions = ref<any[]>([]);\nconst internalProperty = ref(props.property) as Ref<typeof props.property>;\nconst internalModel = ref(props.modelValue) as Ref<typeof props.modelValue>;\nconst measurementOptions = ref<any[]>([]);\nconst measurementLoading = ref(false);\nconst measureUnit = ref<Record<string, any>>();\n\nwatch(\n () => props.property,\n (newVal) => {\n internalProperty.value = cloneDeep(newVal);\n },\n {\n deep: true,\n immediate: true,\n },\n);\n\nwatch(\n () => props.modelValue,\n (newVal) => {\n internalModel.value = cloneDeep(newVal);\n },\n {\n deep: true,\n immediate: true,\n },\n);\n\nconst measurementSymbol = computed(() => {\n const option = measurementOptions.value.find((x) => x.id === measureUnit.value);\n const displaySymbol = option?.displaySymbol;\n const localizedSymbol = option?.localizedSymbol.values[props.currentLanguage as string];\n return localizedSymbol ? localizedSymbol : displaySymbol;\n});\n\nconst computedProperty = computed(() => {\n const rules: IValidationRules = {};\n if (props.required) {\n rules[\"required\"] = true;\n }\n if (props.rules?.min) {\n rules[\"min\"] = Number(props.rules.min);\n }\n if (props.rules?.max) {\n rules[\"max\"] = Number(props.rules.max);\n }\n if (props.rules?.regex) {\n rules[\"regex\"] = new RegExp(props.rules.regex);\n }\n\n const propertyDisplayName =\n props.displayNames?.find((displayName) => displayName.languageCode?.startsWith(props.currentLanguage as string))\n ?.name || props.name;\n const propertyDisplayNameLocalized =\n propertyDisplayName && te(propertyDisplayName.toUpperCase())\n ? t(propertyDisplayName.toUpperCase())\n : propertyDisplayName;\n\n const optionLabelField = props.multilanguage ? \"value\" : \"alias\";\n\n return {\n rules,\n valueType: props.valueType,\n dictionary: props.dictionary || false,\n multivalue: props.multivalue || false,\n name: props.multilanguage ? props.name + \"_\" + props.currentLanguage : props.name,\n key: props.multilanguage ? internalProperty.value.id + \"_\" + props.currentLanguage : internalProperty.value.id,\n displayName: propertyDisplayNameLocalized,\n optionValue: props.optionsValue,\n optionLabel: optionLabelField,\n required: props.required,\n placeholder: props.placeholder || propertyDisplayNameLocalized,\n };\n});\n\nconst value = computed({\n get() {\n // For multivalue, extract array from PropertyValue.value if needed\n if (computedProperty.value.multivalue) {\n // If internalModel.value is already an array, return it\n if (Array.isArray(internalModel.value)) {\n return internalModel.value;\n }\n // If it has a value property that's an array, extract it\n if (internalModel.value?.value && Array.isArray(internalModel.value.value)) {\n return internalModel.value.value;\n }\n // Return empty array as fallback\n return [];\n }\n // For boolean and other types, extract value from PropertyValue object if needed\n if (internalModel.value && typeof internalModel.value === \"object\" && \"value\" in internalModel.value) {\n return internalModel.value.value;\n }\n return internalModel.value;\n },\n set(newValue) {\n // For multivalue (array), pass it directly\n if (computedProperty.value.multivalue && Array.isArray(newValue)) {\n emit(\"update:model-value\", {\n value: newValue,\n dictionary: items.value,\n locale: props.currentLanguage,\n });\n return;\n }\n\n // For color type without dictionary (single value), extract colorCode\n let colorCode: string | undefined;\n if (computedProperty.value.valueType === \"Color\" && !computedProperty.value.dictionary) {\n if (typeof newValue === \"string\") {\n // If it's already a hex color, use it directly\n if (newValue.startsWith(\"#\")) {\n colorCode = newValue;\n } else {\n // Try to convert color name to hex\n const hexColor = convertColorNameToHex(newValue);\n if (hexColor) {\n colorCode = hexColor;\n }\n }\n }\n }\n\n emit(\"update:model-value\", {\n value: newValue,\n dictionary: items.value,\n locale: props.currentLanguage,\n colorCode,\n });\n },\n});\n\nonMounted(async () => {\n await getOptions();\n await getMeasurements();\n initialOptions.value = items.value;\n});\n\nfunction onUpdateUnit(newUnitOfMeasureId: any) {\n measureUnit.value = newUnitOfMeasureId;\n emit(\"update:model-value\", {\n value: value.value,\n unitOfMeasureId: newUnitOfMeasureId,\n dictionary: items.value,\n locale: props.currentLanguage,\n });\n}\n\nasync function getOptions(keyword: string | undefined = undefined) {\n if (props.optionsGetter && internalProperty.value.dictionary && internalProperty.value.id) {\n try {\n loading.value = true;\n const res = await props.optionsGetter(internalProperty.value.id, keyword, props.currentLanguage);\n\n if (res) {\n items.value = res;\n }\n } finally {\n loading.value = false;\n }\n }\n}\n\nasync function getMeasurements() {\n if (props.measurementsGetter && internalProperty.value.valueType === \"Measure\" && internalProperty.value.measureId) {\n try {\n measurementLoading.value = true;\n const measurements = await props.measurementsGetter(\n internalProperty.value.measureId,\n props.currentLanguage ?? \"en-US\",\n );\n if (measurements) {\n measurementOptions.value = measurements;\n\n const firstVal = internalProperty.value.values?.[0];\n if (firstVal?.unitOfMeasureId) {\n measureUnit.value = firstVal.unitOfMeasureId;\n } else {\n const defaultValue = measurementOptions.value.find((x) => x.isDefault)?.id ?? measurementOptions.value[0]?.id;\n measureUnit.value = defaultValue;\n }\n }\n } finally {\n measurementLoading.value = false;\n }\n }\n}\n\nasync function onSearch(keyword: string) {\n getOptions(keyword);\n}\n\nasync function onClose() {\n if (initialOptions.value.length) {\n items.value = initialOptions.value;\n }\n}\n</script>\n","<template>\n <VcImageTile\n :src=\"image.url\"\n :alt=\"image.altText || image.name || ''\"\n :name=\"image.name\"\n :image-fit=\"imageFit\"\n :thumbnail-size=\"thumbnailSize\"\n :actions=\"resolvedActions\"\n class=\"vc-gallery-item\"\n :class=\"{\n 'vc-gallery-item--readonly': readonly,\n 'vc-gallery-item--mobile': isMobile,\n }\"\n @preview=\"$emit('preview', image)\"\n @edit=\"$emit('edit', image)\"\n @remove=\"$emit('remove', image)\"\n >\n <template #overlay>\n <div\n v-if=\"!readonly && !disableDrag\"\n class=\"vc-gallery-item__drag-handle\"\n :class=\"{ 'vc-gallery-item__drag-handle--mobile': isMobile }\"\n >\n <VcIcon\n icon=\"lucide-grip-vertical\"\n size=\"s\"\n />\n </div>\n </template>\n </VcImageTile>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport { VcImageTile } from \"@ui/components/molecules/vc-image-tile\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport type { ThumbnailSize } from \"@core/utilities/thumbnail\";\n\nexport interface Props {\n image?: AssetLike;\n readonly?: boolean;\n actions?: {\n preview?: boolean;\n edit?: boolean;\n remove?: boolean;\n };\n disableDrag?: boolean;\n imageFit?: \"contain\" | \"cover\";\n thumbnailSize?: ThumbnailSize;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n image: () => ({}) as AssetLike,\n readonly: false,\n disableDrag: false,\n imageFit: \"contain\",\n});\n\nconst { isMobile } = useResponsive();\n\ndefineEmits<{\n (e: \"preview\", image: AssetLike): void;\n (e: \"edit\", image: AssetLike): void;\n (e: \"remove\", image: AssetLike): void;\n}>();\n\nconst resolvedActions = computed(() => ({\n preview: props.actions?.preview !== false,\n edit: !props.readonly && props.actions?.edit !== false,\n remove: !props.readonly && props.actions?.remove !== false,\n}));\n</script>\n\n<style lang=\"scss\">\n.vc-gallery-item {\n &__drag-handle {\n @apply tw-cursor-move tw-p-0.5 tw-rounded tw-shrink-0;\n color: var(--secondary-400);\n }\n}\n</style>\n","<template>\n <div class=\"vc-gallery-filmstrip\">\n <Swiper\n :modules=\"swiperModules\"\n :slides-per-view=\"'auto'\"\n :space-between=\"gap\"\n :navigation=\"false\"\n :mousewheel=\"{ forceToAxis: true }\"\n :free-mode=\"{ enabled: true, sticky: false }\"\n :grid=\"{ rows: 1, fill: 'row' }\"\n :slides-per-group=\"1\"\n class=\"vc-gallery-filmstrip__swiper\"\n :class=\"{ 'vc-gallery-filmstrip__swiper--expanded': expanded }\"\n @swiper=\"onSwiperInit\"\n @resize=\"onSwiperResize\"\n @slides-updated=\"onSlidesUpdated\"\n >\n <SwiperSlide\n v-for=\"(image, i) in images\"\n :key=\"`img_${image.id || i}`\"\n class=\"vc-gallery-filmstrip__slide\"\n >\n <div class=\"vc-gallery__item\">\n <slot\n name=\"item\"\n :image=\"image\"\n :index=\"i\"\n />\n </div>\n </SwiperSlide>\n </Swiper>\n\n <!-- Navigation arrows (hidden in expanded mode) -->\n <button\n v-show=\"hasOverflow && !loading && !expanded\"\n ref=\"prevRef\"\n type=\"button\"\n :aria-label=\"t('COMPONENTS.ORGANISMS.VC_GALLERY.INTERNAL.VC_GALLERY_FILMSTRIP.PREVIOUS')\"\n class=\"vc-gallery-filmstrip__nav vc-gallery-filmstrip__nav--prev\"\n >\n <VcIcon\n icon=\"lucide-chevron-left\"\n size=\"xs\"\n />\n </button>\n <button\n v-show=\"hasOverflow && !loading && !expanded\"\n ref=\"nextRef\"\n type=\"button\"\n :aria-label=\"t('COMPONENTS.ORGANISMS.VC_GALLERY.INTERNAL.VC_GALLERY_FILMSTRIP.NEXT')\"\n class=\"vc-gallery-filmstrip__nav vc-gallery-filmstrip__nav--next\"\n >\n <VcIcon\n icon=\"lucide-chevron-right\"\n size=\"xs\"\n />\n </button>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, watch, toRef, nextTick } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { Swiper, SwiperSlide } from \"swiper/vue\";\nimport { Navigation, Mousewheel, FreeMode, Grid } from \"swiper/modules\";\nimport type { Swiper as SwiperType } from \"swiper\";\nimport \"swiper/css\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\n\nconst { t } = useI18n({ useScope: \"global\" });\n\nexport interface Props {\n images: AssetLike[];\n gap?: number;\n hasOverflow: boolean;\n loading?: boolean;\n /** When true, shows all images in a wrapped grid instead of horizontal filmstrip */\n expanded?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n gap: 8,\n loading: false,\n expanded: false,\n});\n\nconst emit = defineEmits<{\n (e: \"swiper-init\", swiper: SwiperType): void;\n (e: \"swiper-resize\", swiper: SwiperType): void;\n (e: \"slides-updated\", swiper: SwiperType): void;\n (e: \"sortable-container\", el: HTMLElement | undefined): void;\n}>();\n\nconst swiperModules = [Navigation, Mousewheel, FreeMode, Grid];\n\nconst prevRef = ref<HTMLButtonElement>();\nconst nextRef = ref<HTMLButtonElement>();\nconst swiperInstance = ref<SwiperType>();\n\nfunction onSwiperInit(swiper: SwiperType) {\n swiperInstance.value = swiper;\n\n // Bind navigation to scoped refs (not global selectors)\n if (prevRef.value && nextRef.value) {\n swiper.params.navigation = {\n ...(swiper.params.navigation as object),\n prevEl: prevRef.value,\n nextEl: nextRef.value,\n };\n swiper.navigation.init();\n swiper.navigation.update();\n }\n\n emit(\"swiper-init\", swiper);\n emit(\"sortable-container\", swiper.wrapperEl);\n}\n\nfunction onSwiperResize(swiper: SwiperType) {\n emit(\"swiper-resize\", swiper);\n}\n\nfunction onSlidesUpdated(swiper: SwiperType) {\n emit(\"slides-updated\", swiper);\n}\n\n// Toggle Swiper interaction when expanding/collapsing.\n// In expanded mode, CSS --expanded class handles the visual grid layout\n// (flex-wrap + override of Swiper inline styles). Here we only control\n// Swiper's interaction layer: disable touch/mousewheel so it doesn't scroll.\nwatch(\n () => props.expanded,\n (isExpanded) => {\n const swiper = swiperInstance.value;\n if (!swiper) return;\n\n swiper.allowTouchMove = !isExpanded;\n\n if (isExpanded) {\n swiper.mousewheel?.disable();\n } else {\n swiper.mousewheel?.enable();\n swiper.slideTo(0, 0);\n }\n\n nextTick(() => swiper.update());\n },\n);\n\n// Disable/enable swiper during loading\nwatch(toRef(props, \"loading\"), (isLoading) => {\n if (!swiperInstance.value) return;\n if (isLoading) {\n swiperInstance.value.disable();\n } else {\n swiperInstance.value.enable();\n }\n});\n\n// Scroll to end when new images are added (only in filmstrip mode)\nlet prevImageCount = props.images.length;\nwatch(\n () => props.images.length,\n (newCount) => {\n if (newCount > prevImageCount && swiperInstance.value && !props.expanded) {\n nextTick(() => {\n swiperInstance.value?.slideTo(newCount - 1, 300);\n });\n }\n prevImageCount = newCount;\n },\n);\n</script>\n\n<style lang=\"scss\">\n.vc-gallery-filmstrip {\n @apply tw-relative;\n\n &__swiper {\n @apply tw-overflow-hidden;\n\n // Expanded mode: override Swiper's inline layout to show all images\n // in a wrapped grid. Swiper stays in DOM (no remount = no image flicker)\n // but CSS takes over visual positioning.\n &--expanded {\n @apply tw-overflow-visible;\n\n .swiper-wrapper {\n flex-wrap: wrap;\n gap: var(--gallery-gap);\n width: 100% !important;\n height: auto !important;\n transform: none !important;\n }\n\n .swiper-slide {\n margin-right: 0 !important;\n margin-top: 0 !important;\n }\n }\n }\n\n &__slide {\n width: var(--gallery-tile-min, 160px) !important;\n @apply tw-aspect-square;\n }\n\n // ── Navigation arrows ──\n &__nav {\n @apply tw-absolute tw-top-1/2 -tw-translate-y-1/2 tw-z-[var(--z-local-above)]\n tw-flex tw-items-center tw-justify-center\n tw-w-6 tw-h-6 tw-rounded-full tw-border tw-border-solid tw-cursor-pointer\n tw-transition-all tw-duration-150 tw-p-0;\n background: rgba(255, 255, 255, 0.92);\n border-color: var(--secondary-200);\n color: var(--secondary-700);\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);\n\n &:hover {\n @apply tw-bg-white;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n &--prev {\n @apply tw-left-0 -tw-translate-x-1/2;\n }\n\n &--next {\n @apply tw-right-0 tw-translate-x-1/2;\n }\n\n &.swiper-button-disabled {\n @apply tw-opacity-0 tw-pointer-events-none;\n }\n }\n}\n</style>\n","<template>\n <VcPopup\n v-if=\"currentImage\"\n is-mobile-fullscreen\n is-fullscreen\n modal-width=\"vc-gallery-preview__modal\"\n @close=\"$emit('close')\"\n >\n <template #header>\n <div class=\"vc-gallery-preview__header\">\n <VcIcon\n icon=\"lucide-image\"\n size=\"m\"\n class=\"vc-gallery-preview__header-icon\"\n />\n <span\n class=\"vc-gallery-preview__filename\"\n :title=\"currentImage.name\"\n >\n {{ currentImage.name }}\n </span>\n <button\n type=\"button\"\n class=\"vc-gallery-preview__action-btn\"\n :title=\"t('COMPONENTS.ORGANISMS.VC_GALLERY.INTERNAL.VC_GALLERY_PREVIEW.COPY_IMAGE_LINK')\"\n @click=\"onCopyLink\"\n >\n <VcIcon\n :icon=\"copied ? 'lucide-check' : 'lucide-link'\"\n size=\"s\"\n />\n </button>\n </div>\n </template>\n\n <template #content>\n <div class=\"vc-gallery-preview__body\">\n <!-- Main image swiper -->\n <div class=\"vc-gallery-preview__stage\">\n <Swiper\n :modules=\"mainModules\"\n :initial-slide=\"localIndex\"\n :space-between=\"0\"\n :keyboard=\"{ enabled: true }\"\n :simulate-touch=\"true\"\n :grab-cursor=\"true\"\n class=\"vc-gallery-preview__main-swiper\"\n @swiper=\"onMainSwiperInit\"\n @slide-change=\"onMainSlideChange\"\n >\n <SwiperSlide\n v-for=\"(image, i) in images\"\n :key=\"i\"\n class=\"vc-gallery-preview__slide\"\n >\n <img\n :src=\"image.url\"\n :alt=\"image.altText || image.name || ''\"\n loading=\"lazy\"\n class=\"vc-gallery-preview__image\"\n />\n </SwiperSlide>\n </Swiper>\n\n <!-- Nav buttons (desktop only) -->\n <template v-if=\"!isMobile\">\n <button\n v-if=\"localIndex > 0\"\n type=\"button\"\n class=\"vc-gallery-preview__nav vc-gallery-preview__nav--prev\"\n @click=\"slidePrev\"\n >\n <VcIcon\n icon=\"lucide-chevron-left\"\n size=\"l\"\n />\n </button>\n <button\n v-if=\"localIndex < images.length - 1\"\n type=\"button\"\n class=\"vc-gallery-preview__nav vc-gallery-preview__nav--next\"\n @click=\"slideNext\"\n >\n <VcIcon\n icon=\"lucide-chevron-right\"\n size=\"l\"\n />\n </button>\n </template>\n </div>\n\n <!-- Thumbnail swiper -->\n <div\n v-if=\"images.length > 1\"\n class=\"vc-gallery-preview__filmstrip\"\n >\n <Swiper\n :modules=\"thumbModules\"\n :slides-per-view=\"'auto'\"\n :space-between=\"6\"\n :center-insufficient-slides=\"true\"\n :slide-to-clicked-slide=\"true\"\n :free-mode=\"{ enabled: true, sticky: false }\"\n class=\"vc-gallery-preview__thumb-swiper\"\n @swiper=\"onThumbSwiperInit\"\n >\n <SwiperSlide\n v-for=\"(item, i) in images\"\n :key=\"i\"\n class=\"vc-gallery-preview__thumb-slide\"\n >\n <button\n type=\"button\"\n class=\"vc-gallery-preview__thumb\"\n :class=\"{ 'vc-gallery-preview__thumb--active': i === localIndex }\"\n @click=\"slideTo(i)\"\n >\n <img\n :src=\"getThumbnailUrl(item.url, '64x64') ?? item.url\"\n :alt=\"item.name || ''\"\n loading=\"lazy\"\n class=\"vc-gallery-preview__thumb-img\"\n @error=\"onThumbImageError($event, item.url)\"\n />\n </button>\n </SwiperSlide>\n </Swiper>\n <span class=\"vc-gallery-preview__counter\"> {{ localIndex + 1 }} / {{ images.length }} </span>\n </div>\n </div>\n </template>\n </VcPopup>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport { Swiper, SwiperSlide } from \"swiper/vue\";\nimport { Keyboard, FreeMode } from \"swiper/modules\";\nimport type { Swiper as SwiperType } from \"swiper\";\nimport \"swiper/css\";\nimport { VcPopup } from \"@ui/components/organisms/vc-popup\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\nimport { useI18n } from \"vue-i18n\";\nimport { useScrollLock } from \"@vueuse/core\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { getThumbnailUrl } from \"@core/utilities/thumbnail\";\n\nexport interface Props {\n images?: AssetLike[];\n index?: number;\n}\n\nexport interface Emits {\n (event: \"close\"): void;\n}\n\nconst emit = defineEmits<Emits>();\n\nconst props = withDefaults(defineProps<Props>(), {\n images: () => [],\n index: 0,\n});\nconst { t } = useI18n({ useScope: \"global\" });\nconst { isMobile } = useResponsive();\nconst localIndex = ref(props.index);\nconst copied = ref(false);\n\nconst mainModules = [Keyboard];\nconst thumbModules = [FreeMode];\n\nconst mainSwiper = ref<SwiperType>();\nconst thumbSwiper = ref<SwiperType>();\n\nconst currentImage = computed(() => props.images[localIndex.value]);\n\nwatch(\n () => props.index,\n (nextIndex) => {\n localIndex.value = nextIndex;\n mainSwiper.value?.slideTo(nextIndex);\n },\n);\n\nfunction onMainSwiperInit(swiper: SwiperType) {\n mainSwiper.value = swiper;\n}\n\nfunction onThumbSwiperInit(swiper: SwiperType) {\n thumbSwiper.value = swiper;\n}\n\nfunction onMainSlideChange(swiper: SwiperType) {\n localIndex.value = swiper.activeIndex;\n // Sync thumbnail swiper to keep active thumb visible\n thumbSwiper.value?.slideTo(swiper.activeIndex);\n}\n\nfunction slideTo(index: number) {\n mainSwiper.value?.slideTo(index);\n}\n\nfunction slidePrev() {\n mainSwiper.value?.slidePrev();\n}\n\nfunction slideNext() {\n mainSwiper.value?.slideNext();\n}\n\nfunction onThumbImageError(event: Event, fallbackUrl?: string) {\n if (!fallbackUrl) return;\n const target = event.target;\n if (target instanceof HTMLImageElement) {\n target.src = fallbackUrl;\n }\n}\n\nasync function onCopyLink() {\n const link = currentImage.value?.url ?? \"\";\n const fullLink = link.charAt(0) === \"/\" ? `${location.origin}${link}` : link;\n\n try {\n await navigator.clipboard.writeText(fullLink);\n copied.value = true;\n setTimeout(() => {\n copied.value = false;\n }, 1500);\n } catch {\n // Clipboard API unavailable (HTTP context) — silent fail\n }\n}\n\nfunction handleKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n event.preventDefault();\n emit(\"close\");\n }\n}\n\nconst scrollLock = useScrollLock(document.body);\n\nonMounted(() => {\n window.addEventListener(\"keydown\", handleKeyDown);\n scrollLock.value = true;\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n scrollLock.value = false;\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --gp-stage-bg: var(--neutrals-50);\n --gp-nav-size: 44px;\n --gp-nav-bg: rgba(255, 255, 255, 0.92);\n --gp-nav-color: var(--secondary-700);\n --gp-nav-shadow: 0 1px 6px rgb(0 0 0 / 0.08), 0 0 0 1px rgb(0 0 0 / 0.04);\n --gp-thumb-ring: var(--primary-400);\n --gp-thumb-size: 56px;\n --gp-border: var(--secondary-200);\n --gp-counter-color: var(--secondary-500);\n --gp-header-icon: var(--secondary-400);\n --gp-action-btn-bg: var(--neutrals-100);\n --gp-action-btn-hover: var(--neutrals-200);\n --gp-action-btn-color: var(--secondary-600);\n --gp-copied-color: var(--success-500);\n}\n\n/* ---------- Header ---------- */\n.vc-gallery-preview {\n &__header {\n @apply tw-flex tw-items-center tw-gap-2 tw-min-w-0 tw-mr-2;\n }\n\n &__header-icon {\n @apply tw-shrink-0;\n color: var(--gp-header-icon);\n }\n\n &__filename {\n @apply tw-font-medium tw-truncate tw-min-w-0;\n }\n\n &__action-btn {\n @apply tw-shrink-0 tw-flex tw-items-center tw-justify-center\n tw-w-7 tw-h-7 tw-rounded tw-border-0 tw-cursor-pointer\n tw-transition-colors tw-duration-150;\n background: var(--gp-action-btn-bg);\n color: var(--gp-action-btn-color);\n\n &:hover {\n background: var(--gp-action-btn-hover);\n }\n }\n\n &__action-btn .vc-icon--lucide-check {\n color: var(--gp-copied-color);\n }\n\n /* ---------- Body ---------- */\n &__body {\n @apply tw-flex tw-flex-col tw-h-full tw-min-h-0;\n min-width: 0;\n overflow: hidden;\n }\n\n /* ---------- Image stage ---------- */\n &__stage {\n @apply tw-relative tw-flex tw-items-center tw-justify-center\n tw-flex-1 tw-min-h-0 tw-overflow-hidden;\n background: var(--gp-stage-bg);\n border-top: 1px solid var(--gp-border);\n }\n\n &__main-swiper {\n @apply tw-w-full tw-h-full;\n position: absolute;\n inset: 0;\n }\n\n &__slide {\n @apply tw-flex tw-items-center tw-justify-center tw-h-full;\n }\n\n &__image {\n @apply tw-max-w-full tw-max-h-full tw-object-contain tw-select-none tw-p-4;\n\n @media (min-width: 768px) {\n @apply tw-p-8;\n }\n }\n\n /* ---------- Nav buttons (desktop) ---------- */\n &__nav {\n @apply tw-absolute tw-top-1/2 -tw-translate-y-1/2\n tw-flex tw-items-center tw-justify-center\n tw-rounded-full tw-cursor-pointer tw-border-0\n tw-opacity-0 tw-transition-all tw-duration-200;\n width: var(--gp-nav-size);\n height: var(--gp-nav-size);\n background: var(--gp-nav-bg);\n color: var(--gp-nav-color);\n box-shadow: var(--gp-nav-shadow);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n z-index: var(--z-local-above);\n\n &--prev {\n @apply tw-left-4;\n }\n\n &--next {\n @apply tw-right-4;\n }\n\n &:hover {\n @apply tw-opacity-100 tw-scale-105;\n }\n\n &:active {\n @apply tw-scale-95;\n }\n }\n\n &__stage:hover &__nav {\n @apply tw-opacity-100;\n }\n\n /* ---------- Filmstrip (thumbnails) ---------- */\n &__filmstrip {\n @apply tw-flex tw-items-center tw-gap-3 tw-px-4 tw-py-3 tw-shrink-0;\n background: var(--popup-bg, #fff);\n border-top: 1px solid var(--gp-border);\n }\n\n &__thumb-swiper {\n @apply tw-flex-1 tw-min-w-0 tw-overflow-hidden;\n }\n\n &__thumb-slide {\n width: var(--gp-thumb-size) !important;\n }\n\n &__thumb {\n @apply tw-shrink-0 tw-rounded-md tw-overflow-hidden\n tw-cursor-pointer tw-border-2 tw-border-solid\n tw-p-0 tw-bg-transparent\n tw-opacity-60 tw-transition-all tw-duration-200;\n width: var(--gp-thumb-size);\n height: var(--gp-thumb-size);\n border-color: var(--gp-border);\n display: block;\n\n &:hover {\n @apply tw-opacity-90;\n }\n\n &--active {\n @apply tw-opacity-100;\n border-color: var(--gp-thumb-ring);\n }\n }\n\n &__thumb-img {\n @apply tw-w-full tw-h-full tw-object-cover;\n }\n\n &__counter {\n @apply tw-text-xs tw-shrink-0 tw-tabular-nums tw-font-medium;\n color: var(--gp-counter-color);\n }\n}\n</style>\n","import { computed, ref, Ref, toValue } from \"vue\";\nimport { usePopup } from \"@core/composables/usePopup\";\nimport VcGalleryPreview from \"../_internal/vc-gallery-preview/vc-gallery-preview.vue\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\n\nexport function useGalleryPreview(images: Ref<AssetLike[]>) {\n const previewIndex = ref(0);\n\n const { open } = usePopup(\n computed(() => ({\n component: VcGalleryPreview,\n props: {\n images: toValue(images),\n index: previewIndex.value,\n },\n })) as any,\n );\n\n function openPreview(index: number) {\n previewIndex.value = index;\n open();\n }\n\n return { openPreview };\n}\n","<template>\n <div class=\"vc-image-upload\">\n <!-- Has image: tile with tray -->\n <VcImageTile\n v-if=\"image?.url\"\n :src=\"image.url\"\n :alt=\"image.altText || image.name || ''\"\n :name=\"image.name\"\n image-fit=\"contain\"\n :actions=\"resolvedActions\"\n @preview=\"onPreviewClick\"\n @remove=\"emit('remove', image!)\"\n />\n\n <!-- No image: show upload zone -->\n <VcFileUpload\n v-else-if=\"!disabled\"\n :icon=\"icon\"\n :multiple=\"false\"\n :rules=\"rules\"\n :name=\"name\"\n :loading=\"loading\"\n :accept=\"accept\"\n :custom-text=\"placeholderText\"\n @upload=\"(files: FileList) => emit('upload', files)\"\n />\n\n <!-- Disabled + no image -->\n <div\n v-else\n class=\"vc-image-upload__empty\"\n >\n <VcHint>{{ t(\"COMPONENTS.ORGANISMS.VC_GALLERY.GALLERY_IS_EMPTY\") }}</VcHint>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed } from \"vue\";\nimport type { IValidationRules } from \"@core/types\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\nimport { VcFileUpload } from \"@ui/components/molecules/vc-file-upload\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcImageTile } from \"@ui/components/molecules/vc-image-tile\";\nimport { useI18n } from \"vue-i18n\";\nimport { useGalleryPreview } from \"@ui/components/organisms/vc-gallery/composables/useGalleryPreview\";\n\nexport interface Props {\n image?: AssetLike;\n disabled?: boolean;\n loading?: boolean;\n accept?: string;\n rules?: keyof IValidationRules | IValidationRules;\n name?: string;\n icon?: string;\n placeholder?: { text: string; link: string };\n previewable?: boolean;\n removable?: boolean;\n}\n\nexport interface Emits {\n (event: \"upload\", files: FileList): void;\n (event: \"remove\", image: AssetLike): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n accept: \".jpg,.png,.jpeg,.webp,.heic,.svg\",\n name: \"Image\",\n icon: \"lucide-cloud-upload\",\n previewable: true,\n removable: true,\n});\n\nconst emit = defineEmits<Emits>();\nconst { t } = useI18n({ useScope: \"global\" });\n\nconst imagesArray = computed(() => (props.image ? [props.image] : []));\nconst preview = useGalleryPreview(imagesArray);\n\nconst resolvedActions = computed(() => ({\n preview: props.previewable,\n remove: props.removable && !props.disabled,\n}));\n\nconst placeholderText = computed(() =>\n props.placeholder ? { dragHere: props.placeholder.text, browse: props.placeholder.link } : undefined,\n);\n\nfunction onPreviewClick() {\n if (props.previewable && props.image) {\n preview.openPreview(0);\n }\n}\n</script>\n\n<style lang=\"scss\">\n.vc-image-upload {\n max-width: 200px;\n\n &__empty {\n @apply tw-flex tw-justify-center tw-p-5 tw-items-center;\n }\n}\n</style>\n","import { computed, ref, Ref, toValue, watch, nextTick, onBeforeUnmount } from \"vue\";\nimport Sortable from \"sortablejs\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\n\ninterface UseGalleryReorderOptions {\n disabled: Ref<boolean>;\n onSort: (sorted: AssetLike[]) => void;\n onReorderStart?: () => void;\n onReorderEnd?: () => void;\n /** Called during drag with edge proximity: -1 = near left, 1 = near right, 0 = center */\n onDragEdge?: (direction: -1 | 0 | 1) => void;\n}\n\nexport function useGalleryReorder(images: Ref<AssetLike[]>, options: UseGalleryReorderOptions) {\n const galleryRef = ref<HTMLElement>();\n const isDragging = ref(false);\n const draggedId = ref<string>();\n\n const disableDrag = computed(() => toValue(options.disabled) || toValue(images).length <= 1);\n\n let sortableInstance: Sortable | null = null;\n let edgeInterval: ReturnType<typeof setInterval> | null = null;\n let mouseX = 0;\n\n function onPointerMove(e: PointerEvent | MouseEvent) {\n mouseX = e.clientX;\n }\n\n function startEdgeDetection() {\n document.addEventListener(\"pointermove\", onPointerMove, true);\n const EDGE_THRESHOLD = 80; // px from visible edge\n const SCROLL_INTERVAL = 250; // ms between ticks\n\n edgeInterval = setInterval(() => {\n const container = galleryRef.value;\n if (!container || !options.onDragEdge) return;\n\n // Use the visible parent (swiper container or gallery dropzone), not swiper-wrapper\n const visibleParent =\n container.closest(\".vc-gallery-filmstrip\") || container.closest(\".vc-gallery__dropzone\") || container;\n const rect = visibleParent.getBoundingClientRect();\n\n if (mouseX < rect.left + EDGE_THRESHOLD) {\n options.onDragEdge(-1);\n } else if (mouseX > rect.right - EDGE_THRESHOLD) {\n options.onDragEdge(1);\n }\n }, SCROLL_INTERVAL);\n }\n\n function stopEdgeDetection() {\n document.removeEventListener(\"pointermove\", onPointerMove, true);\n if (edgeInterval) {\n clearInterval(edgeInterval);\n edgeInterval = null;\n }\n }\n\n function createSortable(el: HTMLElement) {\n destroySortable();\n sortableInstance = Sortable.create(el, {\n handle: \".vc-gallery-item__drag-handle\",\n animation: 250,\n ghostClass: \"vc-gallery__item--ghost\",\n dragClass: \"vc-gallery__item--dragging\",\n forceFallback: true,\n fallbackTolerance: 3,\n disabled: disableDrag.value,\n onStart: (evt) => {\n isDragging.value = true;\n const item = images.value[evt.oldIndex!];\n draggedId.value = item?.id;\n options.onReorderStart?.();\n startEdgeDetection();\n },\n onEnd: (evt) => {\n stopEdgeDetection();\n isDragging.value = false;\n draggedId.value = undefined;\n\n if (evt.oldIndex != null && evt.newIndex != null && evt.oldIndex !== evt.newIndex) {\n const arr = [...images.value];\n const [moved] = arr.splice(evt.oldIndex, 1);\n arr.splice(evt.newIndex, 0, moved);\n images.value = arr;\n\n nextTick(() => {\n const sorted = images.value.map((img, index) => ({\n ...img,\n sortOrder: index,\n }));\n options.onSort(sorted);\n });\n }\n\n // Always call onReorderEnd — even on no-op drop — to restore Swiper state\n options.onReorderEnd?.();\n },\n });\n }\n\n function destroySortable() {\n if (sortableInstance) {\n sortableInstance.destroy();\n sortableInstance = null;\n }\n }\n\n // Create/destroy sortable when element appears/disappears (v-if toggle)\n watch(galleryRef, (el) => {\n if (el) {\n createSortable(el);\n } else {\n destroySortable();\n }\n });\n\n // Update disabled state\n watch(disableDrag, (val) => {\n if (sortableInstance) {\n sortableInstance.option(\"disabled\", val);\n }\n });\n\n onBeforeUnmount(() => {\n stopEdgeDetection();\n destroySortable();\n });\n\n return {\n galleryRef,\n disableDrag,\n isDragging,\n draggedId,\n };\n}\n","import { Ref, toValue } from \"vue\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\n\ninterface UseGalleryUploadOptions {\n onUpload: (files: FileList, startingSortOrder?: number) => void;\n}\n\nconst IMAGE_EXT_RE = /\\.(apng|avif|bmp|gif|heic|heif|ico|jfif|jpe?g|pjp(eg)?|png|svg|tiff?|webp)$/i;\n\nfunction isImageFile(file: File): boolean {\n if (file.type) return file.type.startsWith(\"image/\");\n return IMAGE_EXT_RE.test(file.name);\n}\n\nexport function useGalleryUpload(images: Ref<AssetLike[]>, options: UseGalleryUploadOptions) {\n function onUpload(files: FileList) {\n if (!files || !files.length) return;\n\n const imageFiles = Array.from(files).filter(isImageFile);\n if (!imageFiles.length) return;\n\n const currentImages = toValue(images);\n const existingNames = currentImages.map((img) => img.name);\n const uploadedFiles: File[] = [];\n\n imageFiles.forEach((file) => {\n let fileName = file.name;\n\n if (existingNames.includes(fileName)) {\n const dotIndex = fileName.lastIndexOf(\".\");\n const baseName = dotIndex > 0 ? fileName.slice(0, dotIndex) : fileName;\n const ext = dotIndex > 0 ? fileName.slice(dotIndex) : \"\";\n let index = 1;\n\n while (existingNames.includes(fileName)) {\n fileName = `${baseName}_${index}${ext}`;\n index++;\n }\n }\n\n uploadedFiles.push(new File([file], fileName, { type: file.type }));\n existingNames.push(fileName);\n });\n\n const dt = new DataTransfer();\n uploadedFiles.forEach((f) => dt.items.add(f));\n\n const lastSortOrder = currentImages[currentImages.length - 1]?.sortOrder;\n options.onUpload(dt.files, lastSortOrder);\n }\n\n return { onUpload };\n}\n","import { ref, Ref, watch, nextTick } from \"vue\";\nimport type { Swiper as SwiperType } from \"swiper\";\n\ninterface UseGalleryFilmstripOptions {\n imageCount: Ref<number>;\n}\n\nexport function useGalleryFilmstrip(options: UseGalleryFilmstripOptions) {\n const isExpanded = ref(false);\n const hasOverflow = ref(true); // Optimistic: render filmstrip first, Swiper init will correct\n const swiperRef = ref<SwiperType>();\n\n function toggleExpand() {\n isExpanded.value = !isExpanded.value;\n }\n\n function checkOverflow(swiper: SwiperType) {\n hasOverflow.value = !(swiper.isBeginning && swiper.isEnd);\n }\n\n function onSwiperInit(swiper: SwiperType) {\n swiperRef.value = swiper;\n checkOverflow(swiper);\n }\n\n function onSwiperResize(swiper: SwiperType) {\n checkOverflow(swiper);\n }\n\n // Re-check overflow when image count changes (add/remove)\n watch(options.imageCount, () => {\n if (swiperRef.value) {\n // Swiper exists — update and re-check\n nextTick(() => {\n swiperRef.value!.update();\n checkOverflow(swiperRef.value!);\n });\n } else {\n // Swiper doesn't exist (grid is showing) — reset to optimistic\n // so filmstrip renders again and Swiper can re-evaluate\n hasOverflow.value = true;\n }\n });\n\n return {\n isExpanded,\n hasOverflow,\n swiperRef,\n toggleExpand,\n checkOverflow,\n onSwiperInit,\n onSwiperResize,\n };\n}\n","<template>\n <!-- Skeleton mode: blade is loading -->\n <div\n v-if=\"bladeLoading\"\n class=\"vc-gallery vc-gallery--skeleton\"\n >\n <VcSkeleton\n v-if=\"label\"\n variant=\"block\"\n :width=\"60 + (label?.length || 0) * 4\"\n :height=\"11\"\n />\n <div class=\"vc-gallery__skeleton-filmstrip\">\n <VcSkeleton\n v-for=\"i in 4\"\n :key=\"i\"\n variant=\"block\"\n class=\"vc-gallery__skeleton-tile\"\n />\n </div>\n </div>\n\n <!-- Legacy shim: variant=\"file-upload\" delegates to VcImageUpload -->\n <VcImageUpload\n v-else-if=\"isLegacySingleImageMode\"\n :image=\"images?.[0]\"\n :disabled=\"disabled\"\n :loading=\"loading\"\n :rules=\"rules\"\n :name=\"name\"\n :icon=\"uploadIcon\"\n :accept=\"accept\"\n :placeholder=\"legacyPlaceholder\"\n :removable=\"itemActions?.remove !== false\"\n :previewable=\"itemActions?.preview !== false\"\n @upload=\"(files: FileList) => emit('upload', files)\"\n @remove=\"(img: AssetLike) => emit('remove', img)\"\n />\n\n <!-- Normal gallery mode -->\n <div\n v-else\n class=\"vc-gallery\"\n :class=\"{\n 'vc-gallery--drag-over': isDragOver,\n 'vc-gallery--reordering': reorder.isDragging.value,\n 'vc-gallery--mobile': isMobile,\n [`vc-gallery--${size}`]: true,\n }\"\n :style=\"{ '--gallery-gap': `${gap}px` }\"\n @dragenter.prevent=\"onGlobalDragEnter\"\n @dragleave.prevent=\"onGlobalDragLeave\"\n @dragover.prevent\n @drop.prevent=\"onGlobalDrop\"\n >\n <!-- Header row: label always visible, upload button after first image -->\n <div\n v-if=\"label || (hasImages && !disabled)\"\n class=\"vc-gallery__header\"\n >\n <VcLabel\n v-if=\"label\"\n class=\"vc-gallery__label\"\n :required=\"required\"\n >\n {{ label }}\n </VcLabel>\n <div\n v-if=\"!disabled && hasImages\"\n class=\"vc-gallery__header-actions\"\n >\n <button\n type=\"button\"\n class=\"vc-gallery__upload-btn\"\n :disabled=\"loading\"\n @click=\"onHeaderUploadClick\"\n >\n <VcIcon\n icon=\"lucide-cloud-upload\"\n size=\"xs\"\n />\n {{ t(\"COMPONENTS.ORGANISMS.VC_GALLERY.UPLOAD\") }}\n </button>\n <span\n v-if=\"!isMobile\"\n class=\"vc-gallery__dnd-hint\"\n >{{ t(\"COMPONENTS.ORGANISMS.VC_GALLERY.OR_DROP_HERE\") }}</span\n >\n <input\n ref=\"fileInputRef\"\n type=\"file\"\n :multiple=\"multiple\"\n :accept=\"accept\"\n hidden\n @change=\"onFileInputChange\"\n />\n </div>\n </div>\n\n <!-- Dropzone wrapper (only when images exist) -->\n <div\n v-if=\"hasImages\"\n class=\"vc-gallery__dropzone\"\n :class=\"{\n 'vc-gallery__dropzone--loading': loading,\n 'vc-gallery__dropzone--mobile': isMobile,\n }\"\n >\n <!-- Filmstrip / Expanded grid (single Swiper instance, no DOM remount) -->\n <VcGalleryFilmstrip\n v-if=\"layout === 'filmstrip'\"\n :images=\"localImages\"\n :gap=\"gap\"\n :has-overflow=\"filmstrip.hasOverflow.value\"\n :loading=\"loading\"\n :expanded=\"filmstrip.isExpanded.value\"\n @swiper-init=\"filmstrip.onSwiperInit\"\n @swiper-resize=\"filmstrip.onSwiperResize\"\n @slides-updated=\"filmstrip.checkOverflow\"\n @sortable-container=\"\n (el) => {\n reorder.galleryRef.value = el;\n }\n \"\n >\n <template #item=\"{ image, index }\">\n <slot\n name=\"item\"\n :image=\"image\"\n :index=\"index\"\n :actions=\"{\n preview: () => preview.openPreview(index),\n edit: () => emit('edit', image),\n remove: () => emit('remove', image),\n }\"\n >\n <VcGalleryItem\n :image=\"image\"\n :readonly=\"disabled\"\n :actions=\"itemActions\"\n :disable-drag=\"isMobile || reorder.disableDrag.value\"\n :image-fit=\"imagefit\"\n :thumbnail-size=\"resolvedThumbnailSize\"\n @preview=\"preview.openPreview(index)\"\n @edit=\"emit('edit', $event)\"\n @remove=\"emit('remove', $event)\"\n />\n </slot>\n </template>\n </VcGalleryFilmstrip>\n\n <!-- Grid mode (layout=\"grid\", no filmstrip) -->\n <div\n v-else-if=\"layout === 'grid'\"\n :ref=\"\n (el) => {\n if (el) reorder.galleryRef.value = el as HTMLElement;\n }\n \"\n class=\"vc-gallery__grid\"\n >\n <div\n v-for=\"(image, i) in localImages\"\n :key=\"`img_${image.id || i}`\"\n class=\"vc-gallery__item\"\n >\n <slot\n name=\"item\"\n :image=\"image\"\n :index=\"i\"\n :actions=\"{\n preview: () => preview.openPreview(i),\n edit: () => emit('edit', image),\n remove: () => emit('remove', image),\n }\"\n >\n <VcGalleryItem\n :image=\"image\"\n :readonly=\"disabled\"\n :actions=\"itemActions\"\n :disable-drag=\"reorder.disableDrag.value\"\n :image-fit=\"imagefit\"\n :thumbnail-size=\"resolvedThumbnailSize\"\n @preview=\"preview.openPreview(i)\"\n @edit=\"emit('edit', $event)\"\n @remove=\"emit('remove', $event)\"\n />\n </slot>\n </div>\n </div>\n\n <!-- Loading overlay (inside dropzone so nav arrows stay visible) -->\n <!-- Expand toggle (inside dropzone) -->\n <button\n v-if=\"layout === 'filmstrip' && filmstrip.hasOverflow.value\"\n type=\"button\"\n class=\"vc-gallery__expand-toggle\"\n :class=\"{ 'vc-gallery__expand-toggle--open': filmstrip.isExpanded.value }\"\n @click=\"filmstrip.toggleExpand()\"\n >\n <template v-if=\"filmstrip.isExpanded.value\">\n {{ t(\"COMPONENTS.ORGANISMS.VC_GALLERY.COLLAPSE\") }}\n </template>\n <template v-else>\n {{ t(\"COMPONENTS.ORGANISMS.VC_GALLERY.SHOW_ALL\", { count: localImages.length }) }}\n </template>\n <VcIcon\n icon=\"lucide-chevron-down\"\n size=\"xs\"\n />\n </button>\n\n <!-- Loading overlay -->\n <div\n v-if=\"loading\"\n class=\"vc-gallery__loading-overlay\"\n >\n <VcIcon\n icon=\"lucide-loader-2\"\n size=\"xl\"\n class=\"vc-gallery__loading-spinner\"\n />\n </div>\n </div>\n\n <!-- Empty state / Full-width upload -->\n <div\n v-if=\"!hasImages && !disabled\"\n class=\"vc-gallery__empty-upload\"\n >\n <VcFileUpload\n :icon=\"uploadIcon\"\n :multiple=\"multiple\"\n :rules=\"rules\"\n :name=\"name\"\n :loading=\"loading\"\n :accept=\"accept\"\n :custom-text=\"uploadCustomText\"\n @upload=\"upload.onUpload\"\n />\n </div>\n\n <!-- Disabled + no images -->\n <div\n v-if=\"!hasImages && disabled\"\n class=\"vc-gallery__empty\"\n >\n <slot name=\"empty\">\n <VcHint>{{ t(\"COMPONENTS.ORGANISMS.VC_GALLERY.GALLERY_IS_EMPTY\") }}</VcHint>\n </slot>\n </div>\n\n <!-- Footer slot -->\n <slot\n name=\"footer\"\n :images=\"localImages\"\n />\n\n <!-- Drag-over overlay -->\n <div\n v-if=\"isDragOver && !disabled\"\n class=\"vc-gallery__drop-overlay\"\n >\n <VcIcon\n icon=\"lucide-cloud-upload\"\n size=\"xxl\"\n />\n <span>{{ t(\"COMPONENTS.ORGANISMS.VC_GALLERY.DROP_TO_UPLOAD\") }}</span>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, ref, watch } from \"vue\";\nimport type { IValidationRules } from \"@core/types\";\nimport type { AssetLike } from \"@core/composables/useAssetsManager\";\nimport { VcFileUpload } from \"@ui/components/molecules/vc-file-upload\";\nimport { VcHint } from \"@ui/components/atoms/vc-hint\";\nimport { VcLabel } from \"@ui/components/atoms/vc-label\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport VcGalleryItem from \"./_internal/vc-gallery-item/vc-gallery-item.vue\";\nimport VcGalleryFilmstrip from \"./_internal/vc-gallery-filmstrip/vc-gallery-filmstrip.vue\";\nimport VcImageUpload from \"@ui/components/organisms/vc-image-upload/vc-image-upload.vue\";\nimport { useGalleryReorder } from \"./composables/useGalleryReorder\";\nimport { useGalleryUpload } from \"./composables/useGalleryUpload\";\nimport { useGalleryPreview } from \"./composables/useGalleryPreview\";\nimport { useGalleryFilmstrip } from \"./composables/useGalleryFilmstrip\";\nimport type { ThumbnailSize } from \"@core/utilities/thumbnail\";\nimport { useI18n } from \"vue-i18n\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { VcSkeleton } from \"@ui/components/atoms/vc-skeleton\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\n\nexport interface Props {\n images?: AssetLike[];\n disabled?: boolean;\n multiple?: boolean;\n loading?: boolean;\n itemActions?: { preview?: boolean; edit?: boolean; remove?: boolean };\n rules?: keyof IValidationRules | IValidationRules;\n name?: string;\n accept?: string;\n // New props\n layout?: \"filmstrip\" | \"grid\";\n size?: \"sm\" | \"md\" | \"lg\";\n gap?: number;\n imagefit?: \"contain\" | \"cover\";\n /** Thumbnail size for gallery tiles. Auto-mapped from `size` if not set. */\n thumbnailSize?: ThumbnailSize;\n // Deprecated props (kept for backward compat)\n variant?: \"gallery\" | \"file-upload\";\n hideAfterUpload?: boolean;\n customText?: { dragHere: string; browse: string };\n uploadIcon?: string;\n label?: string;\n tooltip?: string;\n required?: boolean;\n}\n\nexport interface Emits {\n (event: \"upload\", files: FileList, startingSortOrder?: number): void;\n (event: \"sort\", sorted: AssetLike[]): void;\n (event: \"edit\", image: AssetLike): void;\n (event: \"remove\", image: AssetLike): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n images: () => [],\n layout: \"filmstrip\",\n size: \"md\",\n gap: 8,\n imagefit: \"contain\",\n variant: \"gallery\",\n uploadIcon: \"lucide-cloud-upload\",\n name: \"Gallery\",\n accept: \"image/*\",\n itemActions: () => ({ preview: true, edit: true, remove: true }),\n});\n\nconst emit = defineEmits<Emits>();\nconst { t } = useI18n({ useScope: \"global\" });\nconst { isMobile } = useResponsive();\nconst bladeLoading = useBladeLoading();\n\n// Deprecation warnings (dev only)\nif (import.meta.env?.DEV) {\n if (props.variant && props.variant !== \"gallery\") {\n console.warn(`[VcGallery] prop \"variant\" is deprecated. Use <VcImageUpload> component for single-image uploads.`);\n }\n if (props.hideAfterUpload) {\n console.warn(`[VcGallery] prop \"hideAfterUpload\" is deprecated. Use <VcImageUpload> instead.`);\n }\n if (props.customText) {\n console.warn(`[VcGallery] prop \"customText\" is deprecated. Use <VcImageUpload> instead.`);\n }\n if (props.uploadIcon && props.uploadIcon !== \"lucide-cloud-upload\") {\n console.warn(`[VcGallery] prop \"uploadIcon\" is deprecated. Use #empty slot for custom upload UI.`);\n }\n if (props.tooltip) {\n console.warn(`[VcGallery] prop \"tooltip\" is deprecated. Use external <VcLabel> instead.`);\n }\n}\n\n// Legacy single-image mode detection\nconst isLegacySingleImageMode = computed(() => props.variant === \"file-upload\");\nconst legacyPlaceholder = computed(() =>\n props.customText ? { text: props.customText.dragHere, link: props.customText.browse } : undefined,\n);\n\n// Local images state\nconst localImages = ref<AssetLike[]>([]);\nwatch(\n () => props.images,\n (newVal) => {\n localImages.value = [...(newVal ?? [])];\n },\n { deep: true, immediate: true },\n);\n\nconst hasImages = computed(() => localImages.value.length > 0);\nconst uploadCustomText = computed(() => ({\n dragHere: t(\"COMPONENTS.ORGANISMS.VC_GALLERY.DRAG_IMAGES_HERE\"),\n browse: t(\"COMPONENTS.ORGANISMS.VC_GALLERY.BROWSE_IMAGES\"),\n}));\n\n// Composables\nconst reorder = useGalleryReorder(localImages, {\n disabled: computed(() => !!props.disabled),\n onSort: (sorted) => emit(\"sort\", sorted),\n onReorderStart: () => {\n // Disable Swiper touch during drag to prevent slide movement\n const swiper = filmstrip.swiperRef.value;\n if (swiper) {\n swiper.allowTouchMove = false;\n }\n },\n onReorderEnd: () => {\n // Re-enable Swiper and update after reorder\n const swiper = filmstrip.swiperRef.value;\n if (swiper) {\n swiper.allowTouchMove = true;\n swiper.update();\n }\n },\n onDragEdge: (direction) => {\n const swiper = filmstrip.swiperRef.value;\n if (!swiper) return;\n // Use translateTo for reliable scrolling in freeMode\n const step = 40; // px per tick\n const currentTranslate = swiper.getTranslate();\n const minTranslate = swiper.minTranslate();\n const maxTranslate = swiper.maxTranslate();\n\n if (direction === 1) {\n const target = Math.max(currentTranslate - step, maxTranslate);\n swiper.setTranslate(target);\n swiper.update();\n } else if (direction === -1) {\n const target = Math.min(currentTranslate + step, minTranslate);\n swiper.setTranslate(target);\n swiper.update();\n }\n },\n});\n\nconst upload = useGalleryUpload(localImages, {\n onUpload: (files, sortOrder) => emit(\"upload\", files, sortOrder),\n});\n\nconst preview = useGalleryPreview(localImages);\n\n// Thumbnail size: explicit prop or auto-map from gallery size\nconst tileThumbnailSizeMap: Record<string, ThumbnailSize> = { sm: \"128x128\", md: \"216x216\", lg: \"348x348\" };\nconst resolvedThumbnailSize = computed(() => props.thumbnailSize ?? tileThumbnailSizeMap[props.size]);\n\n// Filmstrip\nconst filmstrip = useGalleryFilmstrip({\n imageCount: computed(() => localImages.value.length),\n});\n\n// Header upload (file input)\nconst fileInputRef = ref<HTMLInputElement>();\n\nfunction onHeaderUploadClick() {\n fileInputRef.value?.click();\n}\n\nfunction onFileInputChange(event: Event) {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length) {\n upload.onUpload(input.files);\n input.value = \"\";\n }\n}\n\n// Global drag-over (file from OS)\nconst isDragOver = ref(false);\nlet dragCounter = 0;\n\nfunction onGlobalDragEnter(event: DragEvent) {\n if (event.dataTransfer?.types.includes(\"Files\")) {\n dragCounter++;\n isDragOver.value = true;\n }\n}\n\nfunction onGlobalDragLeave(event: DragEvent) {\n if (!event.dataTransfer?.types.includes(\"Files\")) return;\n dragCounter--;\n if (dragCounter <= 0) {\n isDragOver.value = false;\n dragCounter = 0;\n }\n}\n\nfunction onGlobalDrop(event: DragEvent) {\n isDragOver.value = false;\n dragCounter = 0;\n const files = event.dataTransfer?.files;\n if (files && files.length) {\n upload.onUpload(files);\n }\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --gallery-gap: 8px;\n --gallery-tile-min: 160px;\n --gallery-tile-max: 200px;\n --gallery-upload-border: var(--secondary-300);\n --gallery-upload-border-hover: var(--primary-400);\n --gallery-upload-bg-hover: var(--primary-50);\n --gallery-drop-overlay-bg: rgba(255, 255, 255, 0.85);\n --gallery-drop-overlay-border: var(--primary-400);\n}\n\n.vc-gallery {\n @apply tw-relative;\n\n &--sm {\n --gallery-tile-min: 120px;\n --gallery-tile-max: 160px;\n }\n\n &--md {\n --gallery-tile-min: 160px;\n --gallery-tile-max: 200px;\n }\n\n &--lg {\n --gallery-tile-min: 200px;\n --gallery-tile-max: 260px;\n }\n\n // Mobile: adjusted tiles\n &--mobile {\n &.vc-gallery--sm {\n --gallery-tile-min: 120px;\n }\n\n &.vc-gallery--md {\n --gallery-tile-min: 140px;\n }\n\n &.vc-gallery--lg {\n --gallery-tile-min: 170px;\n }\n }\n\n &--skeleton {\n @apply tw-flex tw-flex-col tw-gap-2;\n }\n\n &__skeleton-filmstrip {\n @apply tw-flex tw-flex-row tw-overflow-hidden;\n gap: var(--gallery-grid-gap, 8px);\n }\n\n &__skeleton-tile {\n width: var(--gallery-tile-min);\n aspect-ratio: 1;\n @apply tw-shrink-0;\n }\n\n &--drag-over {\n @apply tw-rounded-lg tw-ring-2 tw-ring-[var(--gallery-drop-overlay-border)];\n background: var(--gallery-upload-bg-hover);\n }\n\n &__grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, var(--gallery-tile-min));\n gap: var(--gallery-gap);\n @apply tw-relative;\n }\n\n &__item {\n @apply tw-min-w-0;\n }\n\n // ── Header row ──\n &__header {\n @apply tw-flex tw-items-center tw-mb-2 tw-gap-2;\n }\n\n &__label {\n @apply tw-flex-1 tw-min-w-0;\n }\n\n &__header-actions {\n @apply tw-flex tw-items-center tw-gap-2;\n }\n\n &__upload-btn {\n @apply tw-flex tw-items-center tw-gap-1 tw-text-xs tw-font-medium\n tw-cursor-pointer tw-transition-all tw-duration-150\n tw-rounded-full tw-border tw-border-solid;\n color: var(--primary-500);\n border-color: var(--primary-200);\n background: var(--primary-50);\n padding: 4px 12px;\n\n &:hover {\n color: var(--primary-700);\n border-color: var(--primary-400);\n background: var(--primary-100);\n }\n\n &:disabled {\n @apply tw-opacity-50 tw-cursor-not-allowed;\n }\n }\n\n &__dnd-hint {\n @apply tw-text-[11px];\n color: var(--secondary-400);\n }\n\n // ── Dropzone wrapper ──\n &__dropzone {\n @apply tw-relative tw-rounded-md tw-transition-all tw-duration-200;\n border: 1.5px dashed var(--secondary-300);\n padding: 6px;\n\n &--loading {\n animation: gallery-dropzone-pulse 1.5s ease-in-out infinite;\n border-color: var(--primary-300);\n }\n\n &--mobile {\n border-color: transparent;\n }\n }\n\n // ── Expand toggle ──\n &__expand-toggle {\n @apply tw-flex tw-items-center tw-justify-center tw-gap-1 tw-w-full\n tw-text-xs tw-font-medium tw-border-0\n tw-cursor-pointer tw-transition-all tw-duration-150\n tw-rounded-md tw-mt-1;\n color: var(--secondary-600);\n background: var(--secondary-50);\n padding: 6px 0;\n\n &:hover {\n color: var(--primary-600);\n background: var(--primary-50);\n }\n\n .vc-icon {\n @apply tw-transition-transform tw-duration-200;\n }\n\n &--open .vc-icon {\n @apply tw-rotate-180;\n }\n }\n\n &__empty-upload {\n @apply tw-w-full;\n\n .vc-file-upload__drop-zone {\n min-height: 160px;\n }\n }\n\n &__empty {\n @apply tw-flex tw-justify-center tw-p-5 tw-h-full tw-items-center;\n }\n\n &__item--dragging {\n .vc-gallery-item,\n .vc-image-tile {\n box-shadow:\n 0 8px 24px -4px rgba(0, 0, 0, 0.15),\n 0 0 0 2px var(--primary-400) !important;\n cursor: grabbing !important;\n }\n }\n\n &__item--ghost {\n opacity: 0.4;\n }\n\n // ── Loading overlay ──\n &__loading-overlay {\n @apply tw-absolute tw-inset-0 tw-z-[var(--z-local-sticky)] tw-flex tw-items-center tw-justify-center tw-rounded-md tw-pointer-events-none;\n background: rgba(255, 255, 255, 0.7);\n backdrop-filter: blur(2px);\n }\n\n &__loading-spinner {\n color: var(--primary-500);\n animation: gallery-loading-spin 1s linear infinite;\n }\n\n &__drop-overlay {\n @apply tw-absolute tw-inset-0 tw-z-[var(--z-local-sticky)] tw-flex tw-flex-col tw-items-center tw-justify-center tw-gap-2 tw-rounded-lg tw-pointer-events-none;\n background: var(--gallery-drop-overlay-bg);\n border: 2px solid var(--gallery-drop-overlay-border);\n backdrop-filter: blur(4px);\n color: var(--gallery-drop-overlay-border);\n }\n}\n\n@keyframes gallery-dropzone-pulse {\n 0%,\n 100% {\n border-color: var(--primary-300);\n background: transparent;\n }\n 50% {\n border-color: var(--primary-400);\n background: var(--primary-50);\n }\n}\n\n@keyframes gallery-loading-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n","<template>\n <div\n role=\"table\"\n class=\"vc-table-composition\"\n :class=\"variant && `vc-table-composition--${variant}`\"\n >\n <slot />\n </div>\n</template>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any> = Record<string, any>\">\nimport { provide, reactive, computed, type ComputedRef } from \"vue\";\nimport { TableContextKey } from \"@ui/components/organisms/vc-data-table/keys\";\n\ninterface TableContext<_T> {\n selectedRowIndex: ComputedRef<number | undefined>;\n setSelectedRowIndex: (index: number | undefined) => void;\n variant: ComputedRef<string | undefined>;\n}\n\nconst props = withDefaults(\n defineProps<{\n /**\n * Visual variant of the table\n */\n variant?: \"default\" | \"striped\" | \"bordered\";\n }>(),\n {\n variant: \"default\",\n },\n);\n\n// Internal state for row actions\nconst state = reactive({\n selectedRowIndex: undefined as number | undefined,\n});\n\nconst selectedRowIndex = computed(() => state.selectedRowIndex);\n\nconst setSelectedRowIndex = (index: number | undefined) => {\n state.selectedRowIndex = index;\n};\n\n// Provide context to child components\nconst context: TableContext<T> = {\n selectedRowIndex,\n setSelectedRowIndex,\n variant: computed(() => props.variant),\n};\n\nprovide(TableContextKey, context);\n</script>\n\n<style lang=\"scss\">\n.vc-table-composition {\n // Key styles for layout:\n // - h-full: inherit parent height constraint\n // - flex-col: stack header, body, footer vertically\n // - overflow: hidden: columns shrink to fit; horizontal scroll is not used\n // - min-h-0: critical for nested flex containers to enable scrolling\n @apply tw-relative tw-box-border tw-w-full tw-h-full tw-flex tw-flex-col tw-overflow-hidden;\n min-height: 0;\n\n // Shared cell padding — single source of truth for head & body alignment.\n // Both TableHead and TableCell reference this variable so columns never drift.\n --table-cell-padding-x: 0.5rem;\n\n // CSS Variables from original vc-table\n --table-border-color: var(--neutrals-200);\n --table-header-border-color: var(--neutrals-200);\n --table-header-border:\n inset 0px 1px 0px var(--table-header-border-color), inset 0px -1px 0px var(--table-header-border-color);\n --table-resizer-color: var(--neutrals-200);\n --table-reorder-color: var(--primary-400);\n\n --table-header-bg: var(--primary-50);\n --table-row-bg-odd: var(--additional-50);\n --table-row-bg-even: var(--neutrals-50);\n --table-row-bg-hover: var(--primary-100);\n --table-row-bg-selected: var(--primary-100);\n\n --table-actions-bg: var(--primary-100);\n --table-actions-icon-color: var(--primary-500);\n --table-actions-icon-color-hover: var(--primary-600);\n --table-actions-color-danger: var(--danger-500);\n --table-actions-color-success: var(--success-500);\n\n --table-header-text-color: var(--neutrals-600);\n --table-text-color: var(--neutrals-950);\n --table-sort-icon-color: var(--neutrals-400);\n\n --table-footer-bg: var(--neutrals-50);\n --table-footer-border-color: var(--neutrals-200);\n\n --table-mobile-border-color: var(--secondary-200);\n\n &--striped {\n .vc-table-composition__row:nth-child(even) {\n background-color: var(--table-row-bg-even);\n }\n }\n\n &--bordered {\n .vc-table-composition__row {\n border-bottom: 1px solid var(--table-border-color);\n }\n }\n}\n</style>\n","<template>\n <div\n role=\"rowgroup\"\n class=\"vc-table-composition__header\"\n >\n <slot />\n </div>\n</template>\n\n<style lang=\"scss\">\n.vc-table-composition__header {\n @apply tw-flex tw-flex-col tw-flex-shrink-0 tw-border-y tw-border-solid tw-relative;\n border-color: var(--table-header-border-color);\n background-color: var(--table-header-bg);\n}\n</style>\n","<template>\r\n <div\r\n role=\"rowgroup\"\r\n class=\"vc-table-composition__body\"\r\n :data-items-count=\"items?.length\"\r\n >\r\n <template v-if=\"!loading && hasContent\">\r\n <slot :items=\"items\" />\r\n </template>\r\n <div\r\n v-else-if=\"!loading && !hasContent\"\r\n key=\"__empty__\"\r\n class=\"vc-table-composition__body-state\"\r\n >\r\n <slot name=\"empty\">\r\n <div class=\"vc-table-composition__empty\">\r\n <slot name=\"empty-content\">No data available</slot>\r\n </div>\r\n </slot>\r\n </div>\r\n <div\r\n v-else\r\n key=\"__loading__\"\r\n class=\"vc-table-composition__body-state\"\r\n >\r\n <slot name=\"loading\">\r\n <div class=\"vc-table-composition__loading\">\r\n <div class=\"vc-table-composition__loading-spinner\">Loading...</div>\r\n </div>\r\n </slot>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, useSlots } from \"vue\";\r\n\r\nconst props = defineProps<{\r\n /**\r\n * Loading state\r\n */\r\n loading?: boolean;\r\n /**\r\n * Items array to check if empty\r\n */\r\n items?: unknown[];\r\n}>();\r\n\r\nconst slots = useSlots();\r\n\r\nconst hasContent = computed(() => {\r\n if (props.items !== undefined) {\r\n return props.items.length > 0;\r\n }\r\n return !!slots.default;\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n.vc-table-composition__body {\r\n @apply tw-flex tw-flex-col tw-overflow-auto;\r\n // flex: 1 1 0 ensures body takes remaining space and enables scrolling\r\n // min-height: 0 is critical for flex children to allow shrinking below content size\r\n flex: 1 1 0;\r\n min-height: 0;\r\n}\r\n\r\n.vc-table-composition__body-state {\r\n @apply tw-flex tw-flex-col tw-flex-1 tw-items-center tw-justify-center;\r\n}\r\n\r\n.vc-table-composition__empty,\r\n.vc-table-composition__loading {\r\n @apply tw-flex tw-items-center tw-justify-center tw-py-8 tw-text-neutrals-400;\r\n}\r\n\r\n.vc-table-composition__loading-spinner {\r\n @apply tw-text-sm;\r\n}\r\n\r\n/* FLIP move animation for row reorder */\r\n.vc-table-row-swap-move {\r\n transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1) !important;\r\n}\r\n\r\n/* Disable transitions on enter/leave so only moves animate */\r\n.vc-table-row-swap-enter-active,\r\n.vc-table-row-swap-leave-active {\r\n transition: none !important;\r\n}\r\n</style>\r\n","<template>\n <div\n role=\"row\"\n class=\"vc-table-composition__row\"\n :class=\"{\n 'vc-table-composition__row--selected': selected || active,\n 'vc-table-composition__row--clickable': isClickable,\n 'vc-table-composition__row--header': variant === 'header',\n 'vc-table-composition__row--reorderable': reorderable,\n }\"\n :tabindex=\"isClickable ? 0 : undefined\"\n @click=\"handleClick\"\n @keydown.enter.prevent=\"isClickable && handleClick($event as unknown as MouseEvent)\"\n @keydown.space.prevent=\"handleSpacePress($event)\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n >\n <!-- Drag handle / spacer (shown when showDragHandle is true, even for non-reorderable header rows) -->\n <div\n v-if=\"showDragHandle\"\n class=\"vc-table-composition__row-drag-handle\"\n role=\"presentation\"\n aria-hidden=\"true\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n >\n <rect\n x=\"2\"\n y=\"4\"\n width=\"12\"\n height=\"1.5\"\n rx=\"0.75\"\n />\n <rect\n x=\"2\"\n y=\"7.25\"\n width=\"12\"\n height=\"1.5\"\n rx=\"0.75\"\n />\n <rect\n x=\"2\"\n y=\"10.5\"\n width=\"12\"\n height=\"1.5\"\n rx=\"0.75\"\n />\n </svg>\n </div>\n <TransitionGroup\n tag=\"div\"\n role=\"presentation\"\n :name=\"isColumnReordering ? 'vc-table-col-swap' : ''\"\n class=\"vc-table-composition__row-transition-wrapper\"\n :style=\"{ '--filler-width': fillerWidth > 0 ? `${fillerWidth}px` : '0px' }\"\n >\n <slot />\n </TransitionGroup>\n <!-- Row actions: overlay mode (absolute positioned, current behavior).\n Wrapped in a cell so it is a valid child of role=\"row\". -->\n <div\n v-if=\"actionsPosition !== 'column' && $slots.actions\"\n :role=\"actionsCellRole\"\n class=\"vc-table-composition__row-actions-cell\"\n >\n <slot name=\"actions\" />\n </div>\n\n <!-- Row actions: column mode (fixed zone, always visible) -->\n <div\n v-if=\"actionsPosition === 'column'\"\n :role=\"actionsCellRole\"\n class=\"vc-table-composition__row-actions-column\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, ref } from \"vue\";\nimport { TableContextKey, FillerWidthKey, IsColumnReorderingKey } from \"@ui/components/organisms/vc-data-table/keys\";\n\nconst props = withDefaults(\n defineProps<{\n /**\n * Whether the row is selected\n */\n selected?: boolean;\n /**\n * Whether the row is the active (highlighted) row — visual only, does not affect checkbox\n */\n active?: boolean;\n /**\n * Row variant\n */\n variant?: \"default\" | \"header\";\n /**\n * Row index (for actions)\n */\n index?: number;\n /**\n * Whether row is reorderable\n */\n reorderable?: boolean;\n /**\n * Whether to show drag handle icon\n */\n showDragHandle?: boolean;\n /**\n * Whether the row is clickable (adds cursor pointer and hover styles)\n */\n clickable?: boolean;\n /**\n * Position of row actions: overlay (absolute) or column (fixed zone)\n */\n actionsPosition?: \"overlay\" | \"column\";\n }>(),\n {\n reorderable: false,\n showDragHandle: false,\n },\n);\n\nconst emit = defineEmits<{\n /** Row clicked */\n click: [event: MouseEvent];\n /** Mouse entered row */\n hover: [index: number];\n /** Mouse left row */\n leave: [];\n /** Space pressed on focusable row (for selection toggle, distinct from click) */\n \"space-press\": [event: KeyboardEvent];\n}>();\n\nconst tableContext = inject(TableContextKey, null);\nconst fillerWidth = inject(\n FillerWidthKey,\n computed(() => 0),\n);\nconst isColumnReordering = inject(IsColumnReorderingKey, ref(false));\n\nconst isClickable = computed(() => {\n return !!props.clickable;\n});\n\n// Auxiliary controls (row actions / column switcher) must be a valid child of\n// role=\"row\" — a cell in body rows, a columnheader in the header row.\nconst actionsCellRole = computed(() => (props.variant === \"header\" ? \"columnheader\" : \"cell\"));\n\nconst handleClick = (event: MouseEvent) => {\n emit(\"click\", event);\n};\n\nconst handleSpacePress = (event: KeyboardEvent) => {\n if (isClickable.value) {\n emit(\"space-press\", event);\n }\n};\n\nconst handleMouseEnter = () => {\n if (props.index !== undefined) {\n // Update table context if available\n if (tableContext) {\n tableContext.setSelectedRowIndex(props.index);\n }\n // Always emit the event so parent can handle hover state\n emit(\"hover\", props.index);\n }\n};\n\nconst handleMouseLeave = () => {\n // Update table context if available\n if (tableContext) {\n tableContext.setSelectedRowIndex(undefined);\n }\n // Always emit the event\n emit(\"leave\");\n};\n</script>\n\n<style lang=\"scss\">\n.vc-table-composition__row {\n @apply tw-relative tw-flex tw-items-center tw-gap-2 tw-py-1 tw-px-4 tw-transition-colors;\n // Width is determined by flex children, min-width ensures row fills container\n min-width: 100%;\n min-height: 53px;\n color: var(--table-text-color);\n\n &--clickable {\n @apply tw-cursor-pointer;\n\n &:hover {\n background-color: var(--table-row-bg-hover);\n }\n }\n\n &--selected {\n background-color: var(--table-row-bg-selected);\n }\n\n &--header {\n @apply tw-font-medium tw-sticky tw-top-0 tw-z-[var(--z-local-above)];\n background-color: var(--table-header-bg);\n color: var(--table-header-text-color);\n border-bottom: 1px solid var(--table-header-border-color);\n @apply tw-py-0 #{!important};\n\n // Hide drag handle icon in header — it's only a spacer for layout alignment with body rows\n .vc-table-composition__row-drag-handle {\n visibility: hidden;\n }\n }\n\n &-drag-handle {\n @apply tw-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-flex-shrink-0 tw-rounded;\n cursor: grab;\n color: var(--table-drag-handle-color, var(--neutrals-400));\n transition:\n color 0.15s ease,\n background-color 0.15s ease;\n\n &:hover {\n color: var(--table-drag-handle-color-hover, var(--neutrals-600));\n background-color: var(--neutrals-100);\n }\n\n &:active {\n cursor: grabbing;\n }\n }\n\n &-transition-wrapper {\n @apply tw-flex tw-items-center;\n // No inter-column gap — spacing is handled exclusively by cell padding\n // (--table-cell-padding-x in TableHead/TableCell). This ensures header and\n // body columns always align, matching the ag-grid approach.\n gap: 0;\n // Critical: min-width: 0 allows flex children to shrink below content size\n // This enables text truncation/line-clamping in cells\n min-width: 0;\n // flex: 1 with min-width: 0 allows wrapper to fill available space and shrink\n flex: 1 1 0;\n // Note: Do NOT use overflow: hidden here - it clips positioned elements\n // like dropdown menus. Individual cells handle their own overflow.\n\n // Filler pseudo-element absorbs leftover space computed by the weight engine.\n // Width is controlled via --filler-width CSS variable set on the element.\n &::after {\n content: \"\";\n flex: 0 0 var(--filler-width, 0px);\n min-width: 0;\n }\n }\n\n &-actions-column {\n @apply tw-flex tw-items-center tw-justify-end tw-flex-shrink-0;\n min-width: 40px;\n }\n\n // Overlay actions wrapper adds a valid role=\"cell\" around the actions without\n // affecting layout — the actions inside position themselves absolutely.\n &-actions-cell {\n display: contents;\n }\n}\n\n/* FLIP move animation for column reorder */\n.vc-table-col-swap-move {\n transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1) !important;\n}\n\n.vc-table-col-swap-enter-active,\n.vc-table-col-swap-leave-active {\n transition: none !important;\n}\n</style>\n","<template>\n <div\n class=\"vc-table-composition__head\"\n :class=\"{\n 'vc-table-composition__head--sortable': sortable,\n 'vc-table-composition__head--sorted': sortDirection,\n 'vc-table-composition__head--resizable': resizable,\n 'vc-table-composition__head--reorderable': reorderable,\n }\"\n :style=\"cellStyle\"\n :draggable=\"reorderable\"\n :data-column-id=\"columnId\"\n role=\"columnheader\"\n :tabindex=\"sortable ? 0 : undefined\"\n :aria-sort=\"ariaSort\"\n @click=\"handleSort\"\n @keydown.enter=\"handleSort\"\n @keydown.space.prevent=\"handleSort\"\n @mousedown=\"handleMouseDown\"\n @dragstart=\"handleDragStart\"\n @dragover=\"handleDragOver\"\n @dragleave=\"handleDragLeave\"\n @drop=\"handleDrop\"\n >\n <div class=\"vc-table-composition__head-content\">\n <slot />\n </div>\n <div\n v-if=\"sortable\"\n class=\"vc-table-composition__head-sort\"\n >\n <span\n v-if=\"sortIndex\"\n class=\"vc-table-composition__head-sort-badge\"\n >\n {{ sortIndex }}\n </span>\n <VcIcon\n v-if=\"sortDirection\"\n :icon=\"sortDirection === 'asc' ? 'lucide-arrow-up' : 'lucide-arrow-down'\"\n size=\"xs\"\n />\n <VcIcon\n v-else\n icon=\"lucide-arrow-up-down\"\n size=\"xs\"\n class=\"tw-opacity-30\"\n />\n </div>\n <!-- AG Grid / TanStack style resizer -->\n <div\n v-if=\"resizable\"\n class=\"vc-table-composition__head-resizer\"\n :class=\"{ 'vc-table-composition__head-resizer--last': isLastResizable }\"\n @mousedown.stop.prevent=\"handleResizerMouseDown\"\n @click.stop.prevent\n >\n <div class=\"vc-table-composition__head-resizer-line\" />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms\";\n\nconst props = defineProps<{\n /**\n * Whether the column is sortable\n */\n sortable?: boolean;\n /**\n * Current sort direction\n */\n sortDirection?: \"asc\" | \"desc\";\n /**\n * Sort index for multi-sort (1-based, shown as badge when multiple columns sorted)\n */\n sortIndex?: number;\n /**\n * Whether the column is resizable\n */\n resizable?: boolean;\n /**\n * Whether the column can be reordered via drag & drop\n */\n reorderable?: boolean;\n /**\n * Column ID (required for resizable/reorderable columns)\n */\n columnId?: string;\n /**\n * Column width\n */\n width?: string;\n /**\n * Minimum column width\n */\n minWidth?: string;\n /**\n * Maximum column width\n */\n maxWidth?: string;\n /**\n * Text alignment\n */\n align?: \"left\" | \"center\" | \"right\";\n /**\n * Whether this is the last resizable column (offsets resizer from scrollbar)\n */\n isLastResizable?: boolean;\n}>();\n\nconst emit = defineEmits<{\n /** Emitted when the column header is clicked for sorting */\n sort: [event: Event];\n /** Emitted when column resize begins */\n resizeStart: [columnId: string | undefined, event: MouseEvent];\n /** Emitted when mouse is pressed down for reordering */\n reorderMouseDown: [columnId: string | undefined, event: MouseEvent];\n /** Emitted when column drag starts for reordering */\n reorderDragStart: [columnId: string | undefined, event: DragEvent];\n /** Emitted when dragged column is over this column during reorder */\n reorderDragOver: [event: DragEvent];\n /** Emitted when dragged column leaves this column during reorder */\n reorderDragLeave: [event: DragEvent];\n /** Emitted when dragged column is dropped on this column */\n reorderDrop: [columnId: string | undefined, event: DragEvent];\n}>();\n\nconst ariaSort = computed<\"ascending\" | \"descending\" | \"none\" | undefined>(() => {\n if (!props.sortable) return undefined;\n if (props.sortDirection === \"asc\") return \"ascending\";\n if (props.sortDirection === \"desc\") return \"descending\";\n return \"none\";\n});\n\nconst cellStyle = computed(() => ({\n width: props.width,\n minWidth: props.minWidth || undefined,\n maxWidth: props.maxWidth,\n textAlign: props.align,\n // Engine-provided widths are fixed. Before first compute, keep columns\n // evenly distributed to avoid initial left-pack flash.\n flex: props.width ? `0 0 ${props.width}` : \"1 1 0px\",\n}));\n\nconst handleSort = (event: Event) => {\n if (props.sortable) {\n emit(\"sort\", event);\n }\n};\n\nconst isResizing = ref(false);\n\nconst handleResizerMouseDown = (event: MouseEvent) => {\n isResizing.value = true;\n emit(\"resizeStart\", props.columnId, event);\n\n // Reset resizing flag when mouse is released\n const handleMouseUp = () => {\n isResizing.value = false;\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n document.addEventListener(\"mouseup\", handleMouseUp);\n};\n\nconst handleMouseDown = (event: MouseEvent) => {\n if (props.reorderable && !isResizing.value) {\n emit(\"reorderMouseDown\", props.columnId, event);\n }\n};\n\nconst handleDragStart = (event: DragEvent) => {\n // Don't allow drag if resizing\n if (isResizing.value) {\n event.preventDefault();\n return;\n }\n\n if (props.reorderable) {\n emit(\"reorderDragStart\", props.columnId, event);\n }\n};\n\nconst handleDragOver = (event: DragEvent) => {\n if (props.reorderable) {\n emit(\"reorderDragOver\", event);\n }\n};\n\nconst handleDragLeave = (event: DragEvent) => {\n if (props.reorderable) {\n emit(\"reorderDragLeave\", event);\n }\n};\n\nconst handleDrop = (event: DragEvent) => {\n if (props.reorderable) {\n emit(\"reorderDrop\", props.columnId, event);\n }\n};\n</script>\n\n<style lang=\"scss\">\n.vc-table-composition__head {\n @apply tw-relative tw-flex tw-items-center tw-gap-1 tw-font-medium tw-text-sm tw-h-[60px];\n // Horizontal padding from shared variable — matches TableCell exactly.\n padding-left: var(--table-cell-padding-x);\n padding-right: var(--table-cell-padding-x);\n transition: color 0.2s ease;\n min-width: 0;\n // Clip internal overflow (sort icon, content) so it doesn't extend the parent's\n // scrollWidth when many columns compress cells below their content size.\n overflow: hidden;\n color: var(--table-header-text-color);\n\n &--sortable {\n @apply tw-cursor-pointer;\n\n &:hover {\n color: var(--primary-600);\n }\n\n &:focus-visible {\n @apply tw-outline-none tw-ring-2 tw-ring-inset;\n --tw-ring-color: var(--primary-500);\n }\n }\n\n &--sorted {\n color: var(--primary-700);\n }\n\n &-content {\n @apply tw-flex-1 tw-truncate;\n }\n\n &-sort {\n @apply tw-flex tw-items-center tw-gap-1 tw-flex-shrink-0;\n color: var(--table-sort-icon-color);\n\n .vc-table-composition__head--sorted & {\n color: var(--primary-600);\n }\n }\n\n &-sort-badge {\n @apply tw-inline-flex tw-items-center tw-justify-center tw-min-w-[16px] tw-h-[16px] tw-px-1 tw-text-[10px] tw-font-semibold tw-rounded-full;\n background-color: var(--primary-100);\n color: var(--primary-700);\n }\n\n // AG Grid / TanStack style resizer\n &-resizer {\n @apply tw-absolute tw-top-0 tw-right-0 tw-h-full tw-w-1 tw-cursor-col-resize tw-z-[var(--z-local-sticky)];\n @apply tw-flex tw-items-center tw-justify-center;\n margin-right: -2px; // Center on border\n\n // Hit area - wider invisible zone for easier grabbing\n &::before {\n content: \"\";\n @apply tw-absolute tw-inset-0 tw-w-[10px];\n transform: translateX(-4px); // Center the hit area\n }\n\n &-line {\n @apply tw-h-[60%] tw-w-[2px] tw-rounded-full tw-transition-all tw-duration-200;\n background-color: var(--neutrals-300);\n opacity: 1; // Always visible\n }\n\n // Change color on hover\n &:hover &-line,\n .vc-table-composition__head--resizing &-line {\n background-color: var(--primary-500);\n }\n\n // Active state during drag\n &:active &-line {\n background-color: var(--primary-600);\n @apply tw-h-full;\n }\n\n // Last resizable column — no offset needed, resizer stays at edge\n &--last {\n right: 0;\n margin-right: -2px;\n }\n }\n\n // When resizing, show cursor everywhere and disable text selection\n &--resizing {\n @apply tw-select-none;\n }\n\n // Reorderable column styles\n &--reorderable {\n cursor: grab;\n transition: color 0.2s ease-out;\n\n &:active {\n cursor: grabbing;\n }\n }\n\n // Style for column being dragged — matches row dragging style\n &--dragging {\n @apply tw-relative;\n z-index: var(--z-local-sticky);\n background-color: var(--primary-50) !important;\n box-shadow:\n 0 4px 12px -2px rgba(0, 0, 0, 0.12),\n 0 0 0 1px var(--primary-200) !important;\n border-radius: 6px !important;\n transform: scale(1.01) !important;\n cursor: grabbing !important;\n transition:\n box-shadow 0.15s ease,\n transform 0.15s ease,\n background-color 0.15s ease;\n }\n}\n</style>\n","<template>\n <div\n role=\"cell\"\n class=\"vc-table-composition__cell\"\n :class=\"cellClass\"\n :style=\"cellStyle\"\n :data-column-id=\"columnId\"\n >\n <div\n class=\"vc-table-composition__cell-content\"\n :class=\"contentClasses\"\n :style=\"contentStyle\"\n >\n <slot />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nconst props = defineProps<{\n /**\n * Column width\n */\n width?: string;\n /**\n * Minimum cell width\n */\n minWidth?: string;\n /**\n * Maximum cell width\n */\n maxWidth?: string;\n /**\n * Text alignment\n */\n align?: \"left\" | \"center\" | \"right\";\n /**\n * Custom CSS class from column config\n */\n cellClass?: string;\n /**\n * Number of lines to clamp text to (0 = no clamp, undefined = default 2 line clamp)\n */\n lineClamp?: number;\n /**\n * Column ID for resize tracking\n */\n columnId?: string;\n}>();\n\n// Default line clamp when not specified (matches VcColumn default)\nconst DEFAULT_LINE_CLAMP = 2;\n\nconst effectiveLineClamp = computed(() => props.lineClamp ?? DEFAULT_LINE_CLAMP);\n\n// Truncation/clamp classes go on the INNER content wrapper (not the outer flex cell)\n// so that text-overflow: ellipsis works correctly on block-level content.\nconst contentClasses = computed(() => {\n const clamp = effectiveLineClamp.value;\n if (clamp === 0) {\n return {};\n }\n if (clamp === 1) {\n return { \"vc-table-composition__cell-content--truncate\": true };\n }\n if (clamp > 1) {\n return { \"vc-table-composition__cell-content--line-clamp\": true };\n }\n return {};\n});\n\n// Outer cell: handles flex sizing, alignment, padding\nconst cellStyle = computed(() => {\n return {\n width: props.width,\n minWidth: props.minWidth || undefined,\n maxWidth: props.maxWidth,\n textAlign: props.align,\n // Engine-provided widths are fixed. Before first compute, keep cells\n // evenly distributed to match headers and avoid initial left-pack flash.\n flex: props.width ? `0 0 ${props.width}` : \"1 1 0px\",\n } as Record<string, string | number | undefined>;\n});\n\n// Inner content: line-clamp CSS variable\nconst contentStyle = computed(() => {\n const clamp = effectiveLineClamp.value;\n if (clamp > 1) {\n return { \"--line-clamp\": clamp } as Record<string, string | number>;\n }\n return undefined;\n});\n</script>\n\n<style lang=\"scss\">\n.vc-table-composition__cell {\n @apply tw-flex tw-items-center tw-text-sm;\n // Horizontal padding — matches TableHead via shared --table-cell-padding-x variable.\n // This ensures body content aligns exactly with header text.\n padding: 0 var(--table-cell-padding-x);\n // Allow flex items to shrink below content width\n min-width: 0;\n color: var(--table-text-color);\n // Prevent width/flex animation during container resize (blade expand/collapse)\n transition: none;\n}\n\n// Inner content wrapper — fills cell and handles text clipping.\n// Separated from the flex cell so that text-overflow/line-clamp works on\n// all content (including custom slot content that doesn't add its own truncation).\n.vc-table-composition__cell-content {\n flex: 1 1 0;\n min-width: 0;\n}\n\n// Ensure inner renderers (including custom slot roots) can shrink with the cell.\n// Without this, intrinsic-width content (e.g. inline-flex badges) can overflow\n// and bypass effective ellipsis/line-clamp behavior.\n.vc-table-composition__cell-content--truncate > *,\n.vc-table-composition__cell-content--line-clamp > * {\n min-width: 0;\n max-width: 100%;\n}\n\n.vc-table-composition__cell-content--truncate > * *,\n.vc-table-composition__cell-content--line-clamp > * * {\n min-width: 0;\n}\n\n.vc-table-composition__cell-content--truncate > .vc-status,\n.vc-table-composition__cell-content--line-clamp > .vc-status {\n width: 100%;\n max-width: 100%;\n}\n\n// Single-line truncation with ellipsis\n.vc-table-composition__cell-content--truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n// Multi-line clamp (e.g. 2 or 3 lines)\n// IMPORTANT: line-clamp must be on the CHILD element (where text lives), not the parent.\n// -webkit-line-clamp on a parent with -webkit-box counts children as box items, not visual\n// text lines. A single <span> child = 1 item, so line-clamp: 2 never activates.\n.vc-table-composition__cell-content--line-clamp {\n overflow: hidden; // Safety: clip anything that escapes the child's own clamp\n}\n\n// Apply line-clamp directly on the cell renderer element (span/div)\n.vc-table-composition__cell-content--line-clamp > * {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: var(--line-clamp, 2);\n overflow: hidden;\n // Override white-space:nowrap from tw-truncate so text can wrap for multi-line clamp\n white-space: normal;\n}\n</style>\n","<template>\r\n <div class=\"vc-table-composition__footer\">\r\n <slot />\r\n </div>\r\n</template>\r\n\r\n<style lang=\"scss\">\r\n.vc-table-composition__footer {\r\n @apply tw-flex tw-items-center tw-justify-between tw-gap-4 tw-py-4 tw-px-4 tw-flex-shrink-0;\r\n background-color: var(--table-footer-bg);\r\n border-top: 1px solid var(--table-footer-border-color);\r\n}\r\n</style>\r\n","<template>\n <div class=\"vc-table-composition__empty-state\">\n <VcIcon\n v-if=\"icon\"\n :icon=\"icon\"\n size=\"xxl\"\n class=\"vc-table-composition__empty-icon\"\n />\n <div class=\"vc-table-composition__empty-content\">\n <slot>\n <div class=\"vc-table-composition__empty-title\">\n {{ title || \"No data\" }}\n </div>\n <div\n v-if=\"description\"\n class=\"vc-table-composition__empty-description\"\n >\n {{ description }}\n </div>\n </slot>\n </div>\n <div\n v-if=\"actionLabel || $slots.action\"\n class=\"vc-table-composition__empty-action\"\n >\n <slot name=\"action\">\n <VcButton\n v-if=\"actionLabel\"\n variant=\"outline\"\n @click=\"actionHandler?.()\"\n >\n {{ actionLabel }}\n </VcButton>\n </slot>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { VcIcon, VcButton } from \"@ui/components/atoms\";\n\ndefineProps<{\n /** Icon to display */\n icon?: string;\n /** Title text */\n title?: string;\n /** Description text */\n description?: string;\n /** Action button label — renders VcButton when provided */\n actionLabel?: string;\n /** Action button click handler */\n actionHandler?: () => void;\n}>();\n</script>\n\n<style lang=\"scss\">\n.vc-table-composition__empty-state {\n @apply tw-flex tw-flex-col tw-items-center tw-justify-center tw-gap-4 tw-py-12 tw-px-4 tw-flex-1;\n}\n\n.vc-table-composition__empty-icon {\n @apply tw-text-neutrals-300;\n}\n\n.vc-table-composition__empty-content {\n @apply tw-flex tw-flex-col tw-items-center tw-gap-2 tw-text-center;\n}\n\n.vc-table-composition__empty-title {\n @apply tw-text-base tw-font-medium tw-text-neutrals-700;\n}\n\n.vc-table-composition__empty-description {\n @apply tw-text-sm tw-text-neutrals-500 tw-max-w-md;\n}\n\n.vc-table-composition__empty-action {\n @apply tw-mt-2;\n}\n</style>\n","<template>\n <VcDropdownPanel\n :show=\"show\"\n :anchor-ref=\"anchorRef\"\n :title=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_SWITCHER.TITLE')\"\n width=\"240px\"\n max-width=\"320px\"\n @update:show=\"emit('update:show', $event)\"\n >\n <!-- Columns list -->\n <div class=\"vc-column-switcher-panel__content\">\n <label\n v-for=\"column in columns\"\n :key=\"column.id\"\n class=\"vc-column-switcher-panel__item\"\n >\n <VcCheckbox\n :model-value=\"isColumnVisible(column.id)\"\n @update:model-value=\"toggleColumn(column.id)\"\n />\n <span class=\"vc-column-switcher-panel__label\">\n {{ column.label || column.id }}\n </span>\n </label>\n </div>\n\n <!-- Actions -->\n <template #footer>\n <VcButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"handleShowAll\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_SWITCHER.SHOW_ALL\") }}\n </VcButton>\n <VcButton\n variant=\"primary\"\n size=\"sm\"\n @click=\"handleReset\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_SWITCHER.RESET\") }}\n </VcButton>\n </template>\n </VcDropdownPanel>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * TableColumnSwitcher - Panel for toggling column visibility\n *\n * Displays a list of columns with checkboxes to show/hide them.\n * Uses VcDropdownPanel for positioning and backdrop.\n */\nimport { VcDropdownPanel } from \"@ui/components/molecules\";\nimport { VcButton } from \"@ui/components/atoms\";\nimport { VcCheckbox } from \"@ui/components/molecules/vc-checkbox\";\nimport type { ReferenceElement } from \"@floating-ui/vue\";\n\ninterface Column {\n id: string;\n label?: string;\n visible?: boolean;\n /** Initial/default visibility (used by Reset button) */\n defaultVisible?: boolean;\n}\n\ninterface Props {\n /** Array of columns with id, label, and visibility state */\n columns: Column[];\n /** Array of visible column IDs (controlled mode) */\n visibleColumns?: string[];\n /** Whether panel is visible */\n show: boolean;\n /** Anchor for positioning the floating panel — HTMLElement or floating-ui VirtualElement. */\n anchorRef?: ReferenceElement | null;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n anchorRef: null,\n visibleColumns: undefined,\n});\n\nconst emit = defineEmits<{\n /** Emitted when visible columns change */\n \"update:visibleColumns\": [columnIds: string[]];\n /** Emitted to close panel */\n \"update:show\": [boolean];\n /** Full table reset (widths + order + visibility) */\n reset: [];\n}>();\n\nconst isColumnVisible = (columnId: string): boolean => {\n if (props.visibleColumns) {\n return props.visibleColumns.includes(columnId);\n }\n const column = props.columns.find((c) => c.id === columnId);\n return column?.visible !== false;\n};\n\nconst toggleColumn = (columnId: string) => {\n const currentVisible = props.visibleColumns || props.columns.filter((c) => c.visible !== false).map((c) => c.id);\n\n const newVisible = isColumnVisible(columnId)\n ? currentVisible.filter((id) => id !== columnId)\n : [...currentVisible, columnId];\n\n emit(\"update:visibleColumns\", newVisible);\n};\n\nconst handleShowAll = () => {\n emit(\n \"update:visibleColumns\",\n props.columns.map((c) => c.id),\n );\n};\n\nconst handleReset = () => {\n emit(\"reset\");\n};\n</script>\n\n<style lang=\"scss\">\n.vc-column-switcher-panel {\n &__content {\n @apply tw-p-2;\n }\n\n &__item {\n @apply tw-flex tw-items-center tw-gap-3 tw-px-3 tw-py-2 tw-rounded tw-cursor-pointer;\n @apply tw-transition-colors tw-duration-150;\n\n &:hover {\n @apply tw-bg-neutrals-50;\n }\n }\n\n &__label {\n @apply tw-flex-1 tw-text-sm tw-text-neutrals-900;\n }\n}\n</style>\n","<template>\n <div\n v-show=\"isDropdownMode || isActionsVisible || isOpen\"\n class=\"vc-table-row-actions\"\n :class=\"{\n 'vc-table-row-actions--dropdown-mode': isDropdownMode,\n 'vc-table-row-actions--column': position === 'column',\n }\"\n @click.stop\n >\n <!-- Quick action buttons (first N actions) - only in inline mode -->\n <template v-if=\"!isDropdownMode\">\n <div\n v-for=\"(action, idx) in quickActions\"\n :key=\"idx\"\n class=\"vc-table-row-actions__action\"\n >\n <VcTooltip placement=\"top\">\n <VcButton\n :variant=\"action.variant === 'danger' ? 'danger' : 'ghost'\"\n size=\"icon\"\n :icon=\"action.icon\"\n icon-size=\"s\"\n :aria-label=\"action.title || action.name\"\n :disabled=\"action.disabled\"\n class=\"vc-table-row-actions__btn\"\n @click=\"handleActionClick(action)\"\n />\n <template #tooltip>\n {{ action.title || action.name }}\n </template>\n </VcTooltip>\n </div>\n </template>\n\n <!-- Dropdown trigger (three dots menu) -->\n <div\n v-if=\"showDropdownTrigger\"\n ref=\"referenceRef\"\n class=\"vc-table-row-actions__overflow\"\n @click.stop\n >\n <button\n ref=\"triggerBtnRef\"\n type=\"button\"\n class=\"vc-table-row-actions__btn vc-table-row-actions__btn--more\"\n :title=\"isDropdownMode ? 'Actions' : 'More actions'\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click.stop.prevent=\"toggleDropdown\"\n @keydown.down.prevent=\"openAndFocusFirst\"\n @mousedown.stop\n >\n <VcIcon\n icon=\"lucide-ellipsis-vertical\"\n size=\"s\"\n />\n </button>\n\n <!-- Backdrop (must be before dropdown in DOM for correct z-index stacking) -->\n <Teleport :to=\"teleportTarget\">\n <div\n v-if=\"isBackdropVisible\"\n class=\"vc-table-row-actions__backdrop\"\n @click=\"closeDropdown\"\n />\n </Teleport>\n\n <!-- Dropdown Menu -->\n <Teleport :to=\"teleportTarget\">\n <Transition name=\"dropdown\">\n <div\n v-if=\"isOpen\"\n ref=\"floatingRef\"\n role=\"menu\"\n class=\"vc-table-row-actions__dropdown\"\n :style=\"floatingStyle\"\n @click.stop\n @keydown=\"handleDropdownKeydown\"\n >\n <div\n v-for=\"(action, idx) in overflowActions\"\n :key=\"idx\"\n role=\"menuitem\"\n :tabindex=\"action.disabled ? -1 : 0\"\n class=\"vc-table-row-actions__dropdown-item\"\n :class=\"{\n 'vc-table-row-actions__dropdown-item--disabled': action.disabled,\n 'vc-table-row-actions__dropdown-item--danger': action.variant === 'danger',\n }\"\n :aria-disabled=\"action.disabled || undefined\"\n @click=\"handleActionClick(action)\"\n @keydown.enter.prevent=\"handleActionClick(action)\"\n @keydown.space.prevent=\"handleActionClick(action)\"\n >\n <VcIcon\n v-if=\"action.icon\"\n :icon=\"action.icon\"\n size=\"s\"\n class=\"vc-table-row-actions__dropdown-icon\"\n />\n <span class=\"vc-table-row-actions__dropdown-text\">{{ action.title || action.name }}</span>\n </div>\n </div>\n </Transition>\n </Teleport>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onBeforeUnmount, inject, nextTick } from \"vue\";\nimport { offset, flip, shift } from \"@floating-ui/vue\";\nimport { VcIcon, VcButton } from \"@ui/components/atoms\";\nimport { VcTooltip } from \"@ui/components/atoms/vc-tooltip\";\nimport type { TableAction } from \"@ui/components/organisms/vc-data-table/types\";\nimport { TableContextKey } from \"@ui/components/organisms/vc-data-table/keys\";\nimport { useFloatingPosition, useTeleportTarget } from \"@ui/composables\";\n\nconst props = withDefaults(\n defineProps<{\n /**\n * Actions to display\n */\n actions?: TableAction[];\n /**\n * Whether to show actions (controlled by parent via hover).\n * If not provided, uses tableContext to auto-detect hover state.\n */\n visible?: boolean;\n /**\n * Row index for auto-detecting hover state via tableContext.\n * Required when visible prop is not explicitly controlled.\n */\n rowIndex?: number;\n /**\n * Maximum number of quick action buttons to show.\n * Actions beyond this will go into overflow menu.\n * Only applies when mode is 'inline'.\n * @default 4\n */\n maxQuickActions?: number;\n /**\n * Display mode for actions:\n * - 'inline': Quick action buttons shown on hover, overflow in dropdown (Google Drive style)\n * - 'dropdown': All actions in dropdown menu triggered by three dots\n * @default 'inline'\n */\n mode?: \"inline\" | \"dropdown\";\n /**\n * Position of row actions:\n * - 'overlay': Actions float over the row on hover (default)\n * - 'column': Actions render in a fixed zone, always visible\n * @default 'overlay'\n */\n position?: \"overlay\" | \"column\";\n }>(),\n {\n maxQuickActions: 4,\n visible: undefined, // undefined means auto-detect from context\n mode: \"inline\",\n position: \"overlay\",\n },\n);\n\nconst emit = defineEmits<{\n /** Emitted when an action is clicked */\n action: [action: TableAction];\n}>();\n\n// Inject table context for auto-detecting hover state\nconst tableContext = inject(TableContextKey, null);\n\nconst isOpen = ref(false);\nconst isBackdropVisible = ref(false);\nconst referenceRef = ref<HTMLElement | null>(null);\nconst floatingRef = ref<HTMLElement | null>(null);\nconst triggerBtnRef = ref<HTMLElement | null>(null);\nconst { teleportTarget } = useTeleportTarget();\n\n// Visibility: use prop if provided, otherwise auto-detect from tableContext\nconst isActionsVisible = computed(() => {\n // Must have actions to show\n if (!props.actions?.length) {\n return false;\n }\n\n // Column mode: always visible\n if (props.position === \"column\") {\n return true;\n }\n\n // If visible prop is explicitly set, use it\n if (props.visible !== undefined) {\n return props.visible;\n }\n // Otherwise, auto-detect from tableContext using rowIndex\n if (tableContext && props.rowIndex !== undefined) {\n return tableContext.selectedRowIndex.value === props.rowIndex;\n }\n return false;\n});\n\n// Filter hidden actions\nconst visibleActions = computed(() => {\n return props.actions?.filter((action) => !action.hidden) || [];\n});\n\n// Computed: is dropdown mode\nconst isDropdownMode = computed(() => props.mode === \"dropdown\");\n\n// Split actions into quick and overflow (only for inline mode)\nconst quickActions = computed(() => {\n if (isDropdownMode.value) return [];\n return visibleActions.value.slice(0, props.maxQuickActions);\n});\n\nconst overflowActions = computed(() => {\n if (isDropdownMode.value) return visibleActions.value;\n return visibleActions.value.slice(props.maxQuickActions);\n});\n\n// For dropdown mode: always show the trigger button\nconst showDropdownTrigger = computed(() => {\n return isDropdownMode.value || overflowActions.value.length > 0;\n});\n\n// Use floating-ui for dropdown positioning\nconst { floatingStyle } = useFloatingPosition(referenceRef, floatingRef, {\n placement: \"bottom-end\",\n middleware: () => [offset(4), flip(), shift({ padding: 8 })],\n});\n\n// Close dropdown when visibility changes (only in inline mode and if dropdown is NOT open)\nwatch(isActionsVisible, (newValue) => {\n if (!newValue && !isDropdownMode.value && !isOpen.value) {\n isBackdropVisible.value = false;\n isOpen.value = false;\n }\n});\n\nconst toggleDropdown = async () => {\n if (isOpen.value) {\n // Closing\n isBackdropVisible.value = false;\n isOpen.value = false;\n } else {\n // Opening: show dropdown first, then backdrop after next tick\n isOpen.value = true;\n await nextTick();\n isBackdropVisible.value = true;\n }\n};\n\nconst closeDropdown = () => {\n isBackdropVisible.value = false;\n isOpen.value = false;\n // Return focus to trigger button\n nextTick(() => {\n triggerBtnRef.value?.focus();\n });\n};\n\nconst handleActionClick = (action: TableAction) => {\n if (!action.disabled) {\n emit(\"action\", action);\n // Note: clickHandler is NOT called here because TableRowActions lacks item/index context.\n // VcDataTable's handleRowAction calls clickHandler(item, index) with proper arguments.\n closeDropdown();\n }\n};\n\n/** Focus first enabled menu item in the dropdown */\nconst focusFirstItem = () => {\n nextTick(() => {\n const items = floatingRef.value?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled])');\n items?.[0]?.focus();\n });\n};\n\n/** Open dropdown and focus first item (triggered by ArrowDown on trigger) */\nconst openAndFocusFirst = async () => {\n if (!isOpen.value) {\n isOpen.value = true;\n await nextTick();\n isBackdropVisible.value = true;\n }\n focusFirstItem();\n};\n\n/** Arrow key navigation within dropdown menu */\nconst handleDropdownKeydown = (event: KeyboardEvent) => {\n const items = Array.from(\n floatingRef.value?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled])') || [],\n );\n if (!items.length) return;\n\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n const next = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n items[next]?.focus();\n } else if (event.key === \"ArrowUp\") {\n event.preventDefault();\n const prev = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n items[prev]?.focus();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n closeDropdown();\n } else if (event.key === \"Tab\") {\n // Tab should close the menu (standard menu pattern)\n closeDropdown();\n }\n};\n\n// Close on escape key (document-level fallback for when focus is outside dropdown)\nconst handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && isOpen.value) {\n closeDropdown();\n }\n};\n\nlet escapeListenerAttached = false;\n\nconst attachEscapeListener = () => {\n if (escapeListenerAttached || typeof document === \"undefined\") return;\n document.addEventListener(\"keydown\", handleEscape);\n escapeListenerAttached = true;\n};\n\nconst detachEscapeListener = () => {\n if (!escapeListenerAttached || typeof document === \"undefined\") return;\n document.removeEventListener(\"keydown\", handleEscape);\n escapeListenerAttached = false;\n};\n\nwatch(isOpen, (opened) => {\n if (opened) {\n attachEscapeListener();\n } else {\n detachEscapeListener();\n }\n});\n\nonBeforeUnmount(() => {\n detachEscapeListener();\n});\n</script>\n\n<style lang=\"scss\">\n.vc-table-row-actions {\n @apply tw-absolute tw-flex tw-right-0 tw-px-2 tw-items-center tw-gap-1;\n // Theme-aware row background (NOT hardcoded white) so dark theme doesn't flash white\n background: var(--table-row-bg-odd);\n box-shadow: -8px 0 8px var(--table-row-bg-odd);\n z-index: var(--z-local-sticky);\n\n // Selected row: match selected background (class toggle, no timing issue)\n .vc-table-composition__row--selected & {\n background: var(--table-row-bg-selected);\n box-shadow: -8px 0 8px var(--table-row-bg-selected);\n }\n\n // Hovered clickable row: animate bg in sync with row's tw-transition-colors (150ms).\n // CSS animation (not transition) is needed because v-show toggles display:none,\n // which prevents transitions from having a \"from\" state.\n .vc-table-composition__row--clickable:hover & {\n animation: row-actions-bg-to-hover 150ms ease forwards;\n }\n pointer-events: auto;\n top: 50%;\n transform: translateY(-50%);\n\n // Column mode: static positioning, always visible, transparent background\n &--column {\n @apply tw-relative tw-px-1;\n background: transparent;\n box-shadow: none;\n top: auto;\n transform: none;\n\n .vc-table-composition__row--clickable:hover & {\n animation: none;\n background: transparent;\n box-shadow: none;\n }\n\n .vc-table-composition__row--selected & {\n background: transparent;\n box-shadow: none;\n }\n }\n\n // Dropdown mode: static positioning, always visible\n &--dropdown-mode {\n @apply tw-relative tw-px-0;\n background: transparent;\n box-shadow: none;\n top: auto;\n transform: none;\n }\n\n &__action {\n @apply tw-flex-shrink-0;\n }\n\n &__btn {\n @apply tw-flex tw-items-center tw-justify-center tw-w-8 tw-h-8 tw-rounded tw-cursor-pointer tw-transition-colors;\n @apply tw-border-0 tw-bg-transparent;\n color: var(--table-actions-icon-color, var(--primary-500));\n\n &:hover:not(&--disabled) {\n background-color: var(--table-actions-bg, var(--primary-100));\n color: var(--table-actions-icon-color-hover, var(--primary-600));\n }\n\n &:focus-visible {\n @apply tw-outline-none tw-ring-2 tw-ring-primary-500 tw-ring-offset-1;\n }\n\n &--disabled {\n @apply tw-opacity-30 tw-cursor-not-allowed;\n }\n\n &--danger {\n color: var(--table-actions-color-danger, var(--danger-500));\n\n &:hover:not(.vc-table-row-actions__btn--disabled) {\n background-color: rgba(220, 38, 38, 0.1);\n color: var(--danger-600);\n }\n }\n\n &--more {\n color: var(--neutrals-500);\n }\n }\n\n &__overflow {\n @apply tw-relative tw-flex tw-items-center;\n }\n\n &__backdrop {\n @apply tw-fixed tw-inset-0;\n z-index: var(--z-overlay-row-actions);\n }\n\n &__dropdown {\n @apply tw-bg-additional-50 tw-rounded-lg tw-shadow-lg tw-border tw-border-neutrals-200;\n @apply tw-py-1 tw-min-w-[160px];\n z-index: var(--z-overlay-row-actions);\n max-height: 300px;\n overflow-y: auto;\n }\n\n &__dropdown-item {\n @apply tw-flex tw-items-center tw-gap-3 tw-px-3 tw-py-2 tw-cursor-pointer tw-transition-colors;\n @apply tw-text-sm;\n color: var(--neutrals-900);\n\n &:hover:not(&--disabled) {\n background-color: var(--neutrals-100);\n }\n\n &:focus-visible {\n @apply tw-outline-none;\n background-color: var(--neutrals-100);\n }\n\n &--disabled {\n @apply tw-opacity-50 tw-cursor-not-allowed;\n }\n\n &--danger {\n color: var(--table-actions-color-danger, var(--danger-500));\n\n &:hover:not(.vc-table-row-actions__dropdown-item--disabled) {\n background-color: rgba(220, 38, 38, 0.1);\n }\n }\n }\n\n &__dropdown-icon {\n @apply tw-flex-shrink-0;\n }\n\n &__dropdown-text {\n @apply tw-flex-1;\n }\n}\n\n// Dropdown animation\n.dropdown-enter-active {\n transition:\n opacity 150ms ease-out,\n transform 150ms ease-out;\n}\n\n.dropdown-leave-active {\n transition:\n opacity 100ms ease-in,\n transform 100ms ease-in;\n}\n\n.dropdown-enter-from {\n opacity: 0;\n transform: scale(0.95) translateY(-4px);\n}\n\n.dropdown-leave-to {\n opacity: 0;\n transform: scale(0.95) translateY(-4px);\n}\n\n.dropdown-enter-to,\n.dropdown-leave-from {\n opacity: 1;\n transform: scale(1) translateY(0);\n}\n\n// Syncs row-actions bg with row hover transition (150ms ease from tw-transition-colors).\n// Animation works despite v-show (display:none→flex) because keyframes define their own \"from\" state.\n@keyframes row-actions-bg-to-hover {\n from {\n background: var(--table-row-bg-odd);\n box-shadow: -8px 0 8px var(--table-row-bg-odd);\n }\n to {\n background: var(--table-row-bg-hover);\n box-shadow: -8px 0 8px var(--table-row-bg-hover);\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-table-composition__checkbox\"\n @click.stop\n >\n <VcCheckbox\n :model-value=\"isChecked\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate\"\n :aria-label=\"ariaLabel\"\n @update:model-value=\"handleChange\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { VcCheckbox } from \"@ui/components/molecules/vc-checkbox\";\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: boolean;\n checked?: boolean;\n disabled?: boolean;\n indeterminate?: boolean;\n /** Accessible name for the selection checkbox. */\n ariaLabel?: string;\n }>(),\n {\n ariaLabel: \"Select row\",\n },\n);\n\nconst emit = defineEmits<{\n \"update:modelValue\": [value: boolean];\n change: [value: boolean];\n}>();\n\nconst isChecked = computed(() => props.modelValue ?? props.checked ?? false);\n\nconst handleChange = (value: boolean | unknown[]) => {\n const boolValue = typeof value === \"boolean\" ? value : value.length > 0;\n emit(\"update:modelValue\", boolValue);\n emit(\"change\", boolValue);\n};\n</script>\n\n<style lang=\"scss\">\n.vc-table-composition__checkbox {\n @apply tw-flex tw-items-center tw-justify-center;\n}\n</style>\n","<template>\r\n <Transition name=\"select-bar\">\r\n <div\r\n v-if=\"visible\"\r\n class=\"vc-table-select-all-bar\"\r\n >\r\n <span class=\"vc-table-select-all-bar__text\">\r\n <!-- State 1: Select all active (all items across all pages) -->\r\n <template v-if=\"allSelected\">\r\n <strong>{{ allSelectedText }}</strong>\r\n </template>\r\n\r\n <!-- State 2: All items on current page selected, more exist -->\r\n <template v-else-if=\"showSelectAllPrompt\">\r\n {{ currentPageSelectedText }}\r\n <VcButton\r\n variant=\"link\"\r\n size=\"sm\"\r\n class=\"vc-table-select-all-bar__select-all-link\"\r\n @click=\"emit('selectAll')\"\r\n >\r\n {{ selectAllItemsText }}\r\n </VcButton>\r\n </template>\r\n </span>\r\n\r\n <VcButton\r\n variant=\"link\"\r\n size=\"sm\"\r\n class=\"vc-table-select-all-bar__clear\"\r\n @click=\"emit('cancel')\"\r\n >\r\n {{ cancelText }}\r\n </VcButton>\r\n </div>\r\n </Transition>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from \"vue\";\r\nimport { useI18n } from \"vue-i18n\";\r\nimport { VcButton } from \"@ui/components/atoms\";\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Number of selected items on the current page */\r\n selectionCount: number;\r\n /** Total number of items across all pages */\r\n totalCount: number;\r\n /** Whether \"select all\" mode is active (all items across all pages) */\r\n allSelected?: boolean;\r\n /** Whether to show the \"Select all X items\" prompt */\r\n showSelectAllPrompt?: boolean;\r\n /** Custom \"Selected\" label override */\r\n selectedLabel?: string;\r\n /** Custom \"Select all X items\" label override */\r\n selectAllLabel?: string;\r\n /** Custom \"Clear selection\" label override */\r\n cancelLabel?: string;\r\n }>(),\r\n {\r\n allSelected: false,\r\n showSelectAllPrompt: false,\r\n },\r\n);\r\n\r\nconst emit = defineEmits<{\r\n /** Emitted when \"Select all items\" is clicked */\r\n selectAll: [];\r\n /** Emitted when \"Clear selection\" is clicked */\r\n cancel: [];\r\n}>();\r\n\r\nconst { t } = useI18n({ useScope: \"global\" });\r\n\r\nconst visible = computed(() => {\r\n return props.allSelected || props.showSelectAllPrompt;\r\n});\r\n\r\nconst allSelectedText = computed(() => {\r\n return t(\r\n \"COMPONENTS.ORGANISMS.VC_TABLE.ALL_SELECTED_COUNT\",\r\n { count: props.totalCount },\r\n `All ${props.totalCount} items selected`,\r\n );\r\n});\r\n\r\nconst currentPageSelectedText = computed(() => {\r\n return t(\r\n \"COMPONENTS.ORGANISMS.VC_TABLE.CURRENT_PAGE_SELECTED\",\r\n `All ${props.selectionCount} items on this page are selected.`,\r\n );\r\n});\r\n\r\nconst selectAllItemsText = computed(() => {\r\n if (props.selectAllLabel) return props.selectAllLabel;\r\n return t(\r\n \"COMPONENTS.ORGANISMS.VC_TABLE.SELECT_ALL_COUNT\",\r\n { count: props.totalCount },\r\n `Select all ${props.totalCount} items`,\r\n );\r\n});\r\n\r\nconst cancelText = computed(() => {\r\n return props.cancelLabel || t(\"COMPONENTS.ORGANISMS.VC_TABLE.CANCEL\", \"Clear selection\");\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n.vc-table-select-all-bar {\r\n @apply tw-flex tw-items-center tw-justify-between tw-flex-wrap tw-gap-2 tw-px-4 tw-py-2.5;\r\n background-color: var(--table-select-bar-bg, var(--warning-50));\r\n border-bottom: 1px solid var(--table-select-bar-border, var(--warning-300));\r\n\r\n &__text {\r\n @apply tw-text-sm;\r\n color: var(--table-select-bar-text, var(--warning-800));\r\n }\r\n\r\n &__select-all-link {\r\n @apply tw-underline;\r\n color: var(--table-select-bar-link, var(--primary-700));\r\n }\r\n\r\n &__clear {\r\n color: var(--table-select-bar-clear, var(--danger-600));\r\n }\r\n}\r\n\r\n// Transition\r\n.select-bar-enter-active,\r\n.select-bar-leave-active {\r\n @apply tw-transition-all tw-duration-200 tw-ease-in-out;\r\n}\r\n\r\n.select-bar-enter-from,\r\n.select-bar-leave-to {\r\n @apply tw-opacity-0 tw-transform tw--translate-y-2;\r\n}\r\n\r\n.select-bar-enter-to,\r\n.select-bar-leave-from {\r\n @apply tw-opacity-100 tw-transform tw-translate-y-0;\r\n}\r\n</style>\r\n","<template>\n <Transition name=\"search-header\">\n <div\n v-if=\"visible\"\n class=\"vc-table-search-header\"\n >\n <!-- Toolbar row: actions + filters on the left, search on the right -->\n <div class=\"vc-table-search-header__toolbar\">\n <div\n v-if=\"$slots.actions\"\n class=\"vc-table-search-header__actions\"\n >\n <slot name=\"actions\" />\n </div>\n\n <div\n v-if=\"$slots.filters || showFilterButton\"\n class=\"vc-table-search-header__filters\"\n >\n <VcButton\n variant=\"outline\"\n size=\"sm\"\n icon=\"lucide-funnel\"\n :disabled=\"disableFilter\"\n :class=\"{ 'vc-table-search-header__filter-button--active': isFilterOpen || activeFilterCount > 0 }\"\n @click=\"toggleFilter\"\n >\n <span v-if=\"filterLabel\">{{ filterLabel }}</span>\n <span\n v-if=\"activeFilterCount > 0\"\n class=\"vc-table-search-header__filter-badge\"\n >\n {{ activeFilterCount }}\n </span>\n </VcButton>\n </div>\n\n <!-- Spacer pushes search to the right -->\n <div class=\"vc-table-search-header__spacer\" />\n\n <!-- Compact search input (right-aligned, hidden when searchable is false) -->\n <div\n v-if=\"searchable\"\n class=\"vc-table-search-header__search\"\n >\n <VcInput\n ref=\"searchInputRef\"\n :model-value=\"modelValue\"\n :placeholder=\"placeholder\"\n size=\"small\"\n clearable\n @update:model-value=\"handleInput\"\n >\n <template #prepend-inner>\n <VcIcon\n icon=\"lucide-search\"\n size=\"s\"\n class=\"vc-table-search-header__search-icon\"\n />\n </template>\n </VcInput>\n </div>\n </div>\n\n <!-- Filter panel -->\n <Transition name=\"filter-panel\">\n <div\n v-if=\"isFilterOpen && $slots.filters\"\n class=\"vc-table-search-header__filter-panel\"\n >\n <slot\n name=\"filters\"\n :close-panel=\"closeFilter\"\n />\n </div>\n </Transition>\n </div>\n </Transition>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, useSlots } from \"vue\";\nimport { VcIcon } from \"@ui/components/atoms\";\nimport { VcButton } from \"@ui/components/atoms\";\nimport { VcInput } from \"@ui/components/molecules\";\n\nconst _props = withDefaults(\n defineProps<{\n /**\n * Search input value\n */\n modelValue?: string;\n /**\n * Placeholder text for search input\n */\n placeholder?: string;\n /**\n * Number of active filters\n */\n activeFilterCount?: number;\n /**\n * Whether to disable the filter button\n */\n disableFilter?: boolean;\n /**\n * Label for filter button\n */\n filterLabel?: string;\n /**\n * Whether to show the filter button (even without slots.filters)\n */\n showFilterButton?: boolean;\n /**\n * Whether the search input is shown\n */\n searchable?: boolean;\n /**\n * Whether the header is visible\n */\n visible?: boolean;\n }>(),\n {\n modelValue: \"\",\n placeholder: \"Search...\",\n activeFilterCount: 0,\n disableFilter: false,\n showFilterButton: false,\n searchable: true,\n visible: true,\n },\n);\n\nconst emit = defineEmits<{\n /** Emitted when search input value changes */\n \"update:modelValue\": [value: string];\n /** Emitted when filter panel is toggled */\n filterToggle: [isOpen: boolean];\n}>();\n\nconst _slots = useSlots();\nconst searchInputRef = ref<InstanceType<typeof VcInput> | null>(null);\nconst isFilterOpen = ref(false);\n\nconst handleInput = (value: string | number | Date | null | undefined) => {\n emit(\"update:modelValue\", (value as string) ?? \"\");\n};\n\nconst toggleFilter = () => {\n isFilterOpen.value = !isFilterOpen.value;\n emit(\"filterToggle\", isFilterOpen.value);\n};\n\nconst closeFilter = () => {\n isFilterOpen.value = false;\n emit(\"filterToggle\", false);\n};\n\n// Expose for parent access\ndefineExpose({\n focus: () => (searchInputRef.value as any)?.focus?.(),\n closeFilter,\n});\n</script>\n\n<style lang=\"scss\">\n.vc-table-search-header {\n @apply tw-flex tw-flex-col tw-border-b tw-border-solid;\n background-color: var(--table-header-bg, var(--neutrals-50));\n border-color: var(--table-header-border, var(--neutrals-200));\n\n &__toolbar {\n @apply tw-flex tw-items-center tw-gap-3 tw-px-4 tw-py-2;\n }\n\n &__spacer {\n @apply tw-flex-1;\n }\n\n &__search {\n max-width: 240px;\n width: 100%;\n }\n\n &__search-icon {\n @apply tw-flex-shrink-0;\n color: var(--table-search-icon, var(--neutrals-400));\n }\n\n &__actions {\n @apply tw-flex tw-items-center tw-gap-2 tw-flex-shrink-0 tw-flex-grow tw-min-w-0;\n }\n\n &__filters {\n @apply tw-flex-shrink-0;\n }\n\n &__filter-button--active {\n background-color: var(--table-filter-active-bg, var(--primary-50)) !important;\n border-color: var(--table-filter-active-border, var(--primary-500)) !important;\n color: var(--table-filter-active-text, var(--primary-700)) !important;\n }\n\n &__filter-badge {\n @apply tw-flex tw-items-center tw-justify-center tw-min-w-5 tw-h-5 tw-px-1.5 tw-rounded-full tw-text-xs tw-font-semibold;\n background-color: var(--table-filter-badge-bg, var(--primary-500));\n color: var(--table-filter-badge-text, white);\n }\n\n &__filter-panel {\n @apply tw-border-t tw-border-solid tw-p-4;\n border-color: var(--table-filter-panel-border, var(--neutrals-200));\n background-color: var(--table-filter-panel-bg, white);\n }\n}\n\n// Transitions\n.search-header-enter-active,\n.search-header-leave-active {\n @apply tw-transition-all tw-duration-200 tw-ease-in-out;\n}\n\n.search-header-enter-from,\n.search-header-leave-to {\n @apply tw-opacity-0 tw-transform tw--translate-y-2;\n}\n\n.filter-panel-enter-active,\n.filter-panel-leave-active {\n @apply tw-transition-all tw-duration-150 tw-ease-in-out;\n}\n\n.filter-panel-enter-from,\n.filter-panel-leave-to {\n @apply tw-opacity-0 tw-max-h-0 tw-overflow-hidden;\n}\n\n.filter-panel-enter-to,\n.filter-panel-leave-from {\n @apply tw-opacity-100 tw-max-h-96;\n}\n</style>\n","<template>\r\n <div\r\n class=\"vc-table-composition__group-header\"\r\n role=\"row\"\r\n :class=\"{\r\n 'vc-table-composition__group-header--expandable': expandable,\r\n 'vc-table-composition__group-header--expanded': expanded,\r\n 'vc-table-composition__group-header--collapsed': !expanded,\r\n }\"\r\n @click=\"handleClick\"\r\n >\r\n <div\r\n class=\"vc-table-composition__group-header-content\"\r\n role=\"cell\"\r\n >\r\n <!-- Expand/Collapse toggle button -->\r\n <VcButton\r\n v-if=\"expandable\"\r\n variant=\"ghost\"\r\n size=\"icon-sm\"\r\n :aria-expanded=\"expanded\"\r\n :aria-label=\"expanded ? 'Collapse group' : 'Expand group'\"\r\n @click.stop=\"handleToggle\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"currentColor\"\r\n class=\"vc-table-composition__group-toggle-icon\"\r\n :class=\"{ 'vc-table-composition__group-toggle-icon--expanded': expanded }\"\r\n >\r\n <path d=\"M6 4l4 4-4 4V4z\" />\r\n </svg>\r\n </VcButton>\r\n\r\n <!-- Group header content slot or default -->\r\n <div class=\"vc-table-composition__group-header-label\">\r\n <slot>\r\n <span class=\"vc-table-composition__group-header-key\">{{ groupKey }}</span>\r\n <span class=\"vc-table-composition__group-header-count\">({{ count }})</span>\r\n </slot>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\r\n\r\ndefineProps<{\r\n /** The group key (value of the grouping field) */\r\n groupKey: string;\r\n /** Number of items in this group */\r\n count: number;\r\n /** Whether the group can be expanded/collapsed */\r\n expandable?: boolean;\r\n /** Whether the group is currently expanded */\r\n expanded?: boolean;\r\n}>();\r\n\r\nconst emit = defineEmits<{\r\n /** Emitted when toggle button is clicked */\r\n toggle: [event: MouseEvent];\r\n /** Emitted when group header row is clicked */\r\n click: [event: MouseEvent];\r\n}>();\r\n\r\nconst handleToggle = (event: Event) => {\r\n emit(\"toggle\", event as MouseEvent);\r\n};\r\n\r\nconst handleClick = (event: MouseEvent) => {\r\n emit(\"click\", event);\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n.vc-table-composition__group-header {\r\n @apply tw-relative tw-flex tw-items-center tw-w-full;\r\n background-color: var(--vc-table-group-header-bg, var(--neutrals-50));\r\n border-bottom: 1px solid var(--table-border-color, var(--neutrals-200));\r\n\r\n &--expandable {\r\n @apply tw-cursor-pointer;\r\n\r\n &:hover {\r\n background-color: var(--vc-table-group-header-bg-hover, var(--neutrals-200));\r\n }\r\n }\r\n\r\n &-content {\r\n @apply tw-flex tw-items-center tw-gap-2 tw-py-3 tw-px-4 tw-w-full;\r\n }\r\n\r\n &-label {\r\n @apply tw-flex tw-items-center tw-gap-2 tw-flex-1;\r\n }\r\n\r\n &-key {\r\n @apply tw-font-semibold tw-text-sm;\r\n color: var(--vc-table-group-header-text, var(--neutrals-700));\r\n }\r\n\r\n &-count {\r\n @apply tw-text-sm;\r\n color: var(--vc-table-group-header-count, var(--neutrals-500));\r\n }\r\n}\r\n\r\n.vc-table-composition__group-toggle-icon {\r\n @apply tw-transition-transform tw-duration-200;\r\n\r\n &--expanded {\r\n transform: rotate(90deg);\r\n }\r\n}\r\n</style>\r\n","<template>\n <div\n ref=\"filterRef\"\n class=\"vc-column-filter\"\n >\n <!-- Filter button -->\n <VcButton\n ref=\"triggerRef\"\n variant=\"ghost\"\n size=\"icon\"\n icon=\"lucide-funnel\"\n icon-size=\"xs\"\n class=\"vc-column-filter__trigger\"\n :class=\"{ 'vc-column-filter__trigger--active': hasActiveFilter }\"\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.TITLE')\"\n :aria-expanded=\"isOpen\"\n aria-haspopup=\"dialog\"\n @click=\"toggleOverlay\"\n />\n\n <!-- Filter popup overlay -->\n <Teleport to=\"body\">\n <Transition name=\"vc-column-filter-fade\">\n <div\n v-if=\"isOpen\"\n ref=\"overlayRef\"\n class=\"vc-column-filter__overlay\"\n :style=\"overlayStyle\"\n role=\"dialog\"\n aria-modal=\"true\"\n @click.stop\n @keydown=\"handleOverlayKeydown\"\n >\n <!-- Custom filter slot -->\n <div\n v-if=\"$slots.filter\"\n class=\"vc-column-filter__content\"\n >\n <slot\n name=\"filter\"\n :value=\"localValue\"\n :update-value=\"updateLocalValue\"\n :start-date=\"localStartDate\"\n :update-start-date=\"updateLocalStartDate\"\n :end-date=\"localEndDate\"\n :update-end-date=\"updateLocalEndDate\"\n :apply-filter=\"applyFilter\"\n :clear-filter=\"clearFilter\"\n />\n </div>\n\n <!-- Default filter content by type -->\n <div\n v-else\n class=\"vc-column-filter__content\"\n >\n <!-- Text filter -->\n <div\n v-if=\"filterType === 'text'\"\n class=\"vc-column-filter__input-wrapper\"\n >\n <VcInput\n ref=\"inputRef\"\n :model-value=\"localValue as string\"\n :placeholder=\"placeholder || 'Filter...'\"\n size=\"small\"\n @update:model-value=\"updateLocalValue($event)\"\n @keydown.enter=\"applyFilter\"\n @keydown.escape=\"closeOverlay\"\n />\n </div>\n\n <!-- Select filter -->\n <div\n v-else-if=\"filterType === 'select'\"\n class=\"vc-column-filter__input-wrapper\"\n >\n <!-- eslint-disable vue/no-deprecated-filter -- TS union, not a filter -->\n <VcSelect\n :model-value=\"localValue as string | string[] | null\"\n :options=\"filterOptions || []\"\n option-value=\"value\"\n option-label=\"label\"\n size=\"small\"\n :placeholder=\"placeholder || ''\"\n :multiple=\"multiple\"\n clearable\n emit-value\n @update:model-value=\"updateLocalValue($event)\"\n />\n <!-- eslint-enable vue/no-deprecated-filter -->\n </div>\n\n <!-- DateRange filter -->\n <div\n v-else-if=\"filterType === 'dateRange'\"\n class=\"vc-column-filter__range\"\n >\n <div class=\"vc-column-filter__range-field\">\n <span class=\"vc-column-filter__range-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.FROM\") }}\n </span>\n <VcInput\n :model-value=\"localStartDate\"\n type=\"date\"\n size=\"small\"\n @update:model-value=\"updateLocalStartDate($event as string)\"\n />\n </div>\n <div class=\"vc-column-filter__range-field\">\n <span class=\"vc-column-filter__range-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.TO\") }}\n </span>\n <VcInput\n :model-value=\"localEndDate\"\n type=\"date\"\n size=\"small\"\n @update:model-value=\"updateLocalEndDate($event as string)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"vc-column-filter__actions\">\n <VcButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"clearFilter\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.CLEAR\") }}\n </VcButton>\n <VcButton\n variant=\"primary\"\n size=\"sm\"\n @click=\"applyFilter\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.APPLY\") }}\n </VcButton>\n </div>\n </div>\n </Transition>\n </Teleport>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick, onBeforeUnmount } from \"vue\";\nimport { VcInput, VcSelect } from \"@ui/components/molecules\";\nimport { VcButton } from \"@ui/components/atoms\";\nimport type { FilterType, FilterOption, FilterValue } from \"@ui/components/organisms/vc-data-table/types\";\n\ninterface Props {\n /** Backend field name for this filter */\n field: string;\n /** Filter type: text, select, or dateRange */\n filterType?: FilterType;\n /** Options array for select filter (value/label pairs) */\n filterOptions?: FilterOption[];\n /** Whether to allow multiple selection for select filter */\n multiple?: boolean;\n /** Field names for dateRange filter: [startField, endField] */\n rangeFields?: [string, string];\n /** Placeholder text for the input */\n placeholder?: string;\n /** Current filter value for showing active state */\n modelValue?: FilterValue;\n}\n\ninterface Emits {\n /** Emitted when filter is applied with flat payload: { fieldName: value } or { startField: date, endField: date } */\n (e: \"apply\", payload: Record<string, unknown>): void;\n /** Emitted when filter is cleared */\n (e: \"clear\"): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n filterType: \"text\",\n filterOptions: undefined,\n multiple: false,\n rangeFields: undefined,\n placeholder: undefined,\n modelValue: undefined,\n});\n\nconst emit = defineEmits<Emits>();\n\n// Refs\nconst filterRef = ref<HTMLElement | null>(null);\nconst overlayRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst triggerRef = ref<InstanceType<typeof VcButton> | null>(null);\nconst isOpen = ref(false);\n\n// Local working state (not synced until Apply)\nconst localValue = ref<FilterValue>(null);\nconst localStartDate = ref(\"\");\nconst localEndDate = ref(\"\");\n\n// Initialize local state from modelValue\nconst initLocalState = () => {\n if (\n props.filterType === \"dateRange\" &&\n props.modelValue &&\n typeof props.modelValue === \"object\" &&\n !Array.isArray(props.modelValue)\n ) {\n const rangeVal = props.modelValue as { start?: string; end?: string };\n localStartDate.value = rangeVal.start ?? \"\";\n localEndDate.value = rangeVal.end ?? \"\";\n localValue.value = null;\n } else {\n localValue.value = props.modelValue ?? null;\n localStartDate.value = \"\";\n localEndDate.value = \"\";\n }\n};\n\n// Update helpers (exposed to slot)\nconst updateLocalValue = (val: unknown) => {\n localValue.value = val as FilterValue;\n};\n\nconst updateLocalStartDate = (val: string) => {\n localStartDate.value = val;\n};\n\nconst updateLocalEndDate = (val: string) => {\n localEndDate.value = val;\n};\n\n// Active filter indicator\nconst hasActiveFilter = computed(() => {\n const val = props.modelValue;\n if (val === null || val === undefined || val === \"\") return false;\n if (Array.isArray(val) && val.length === 0) return false;\n if (typeof val === \"object\" && !Array.isArray(val)) {\n // Check if any property has a non-empty value (covers dateRange {start,end}, custom {min,max}, etc.)\n return Object.values(val).some((v) => v !== null && v !== undefined && v !== \"\");\n }\n return true;\n});\n\n// Overlay positioning\nconst overlayStyle = ref<Record<string, string>>({});\n\nconst updateOverlayPosition = () => {\n if (!filterRef.value || !overlayRef.value) return;\n\n const triggerRect = filterRef.value.getBoundingClientRect();\n const overlayRect = overlayRef.value.getBoundingClientRect();\n\n let top = triggerRect.bottom + 4;\n let left = triggerRect.left;\n\n // Adjust if overflow right\n if (left + overlayRect.width > window.innerWidth) {\n left = window.innerWidth - overlayRect.width - 8;\n }\n\n // Adjust if overflow bottom\n if (top + overlayRect.height > window.innerHeight) {\n top = triggerRect.top - overlayRect.height - 4;\n }\n\n overlayStyle.value = {\n top: `${top}px`,\n left: `${left}px`,\n };\n};\n\n// Toggle overlay\nconst toggleOverlay = () => {\n isOpen.value = !isOpen.value;\n\n if (isOpen.value) {\n nextTick(() => {\n // Focus first focusable element inside the overlay (works for all filter types)\n nextTick(() => {\n const firstFocusable = overlayRef.value?.querySelector<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n firstFocusable?.focus();\n });\n });\n }\n};\n\nconst closeOverlay = () => {\n isOpen.value = false;\n // Return focus to trigger button\n nextTick(() => {\n (triggerRef.value as any)?.$el?.focus();\n });\n};\n\n// Focus trap: cycle Tab within overlay, Escape closes\nconst handleOverlayKeydown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n closeOverlay();\n return;\n }\n\n if (event.key !== \"Tab\" || !overlayRef.value) return;\n\n const focusable = overlayRef.value.querySelectorAll<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n if (focusable.length === 0) return;\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n};\n\n// Build flat payload from local state\nconst buildPayload = (): Record<string, unknown> => {\n const payload: Record<string, unknown> = {};\n\n if (props.filterType === \"dateRange\" && props.rangeFields) {\n if (localStartDate.value) {\n payload[props.rangeFields[0]] = localStartDate.value;\n }\n if (localEndDate.value) {\n payload[props.rangeFields[1]] = localEndDate.value;\n }\n } else {\n const val = localValue.value;\n if (val !== null && val !== undefined && val !== \"\") {\n if (Array.isArray(val) && val.length === 0) {\n // Empty array — skip\n } else {\n payload[props.field] = val;\n }\n }\n }\n\n return payload;\n};\n\n// Apply filter\nconst applyFilter = () => {\n emit(\"apply\", buildPayload());\n closeOverlay();\n};\n\n// Clear filter\nconst clearFilter = () => {\n localValue.value = null;\n localStartDate.value = \"\";\n localEndDate.value = \"\";\n emit(\"clear\");\n closeOverlay();\n};\n\n// Click outside handler\nconst handleClickOutside = (event: MouseEvent) => {\n if (!isOpen.value) return;\n\n const target = event.target as HTMLElement;\n if (filterRef.value?.contains(target) || overlayRef.value?.contains(target)) {\n return;\n }\n\n // Don't close if clicking on VcSelect dropdown (teleported to body)\n if (target.closest(\".vc-select__dropdown\") || target.closest(\".vc-select__option\")) {\n return;\n }\n\n closeOverlay();\n};\n\nlet overlayListenersAttached = false;\n\nconst attachOverlayListeners = () => {\n if (overlayListenersAttached || typeof window === \"undefined\" || typeof document === \"undefined\") return;\n document.addEventListener(\"click\", handleClickOutside);\n window.addEventListener(\"resize\", updateOverlayPosition);\n window.addEventListener(\"scroll\", updateOverlayPosition, true);\n overlayListenersAttached = true;\n};\n\nconst detachOverlayListeners = () => {\n if (!overlayListenersAttached || typeof window === \"undefined\" || typeof document === \"undefined\") return;\n document.removeEventListener(\"click\", handleClickOutside);\n window.removeEventListener(\"resize\", updateOverlayPosition);\n window.removeEventListener(\"scroll\", updateOverlayPosition, true);\n overlayListenersAttached = false;\n};\n\n// Sync active state: re-init when overlay reopens and attach listeners lazily.\nwatch(isOpen, (opened) => {\n if (opened) {\n initLocalState();\n attachOverlayListeners();\n nextTick(() => {\n updateOverlayPosition();\n });\n } else {\n detachOverlayListeners();\n }\n});\n\nonBeforeUnmount(() => {\n detachOverlayListeners();\n});\n</script>\n\n<style lang=\"scss\">\n.vc-column-filter {\n display: inline-flex;\n align-items: center;\n\n &__trigger {\n @apply tw-w-6 tw-h-6;\n color: var(--neutrals-400);\n\n &--active {\n color: var(--primary-500);\n background-color: var(--primary-100);\n }\n }\n\n &__overlay {\n @apply tw-fixed tw-z-[var(--z-overlay-dropdown)] tw-bg-additional-50 tw-rounded-lg tw-shadow-lg tw-border tw-border-neutrals-200;\n min-width: 200px;\n max-width: 300px;\n }\n\n &__content {\n @apply tw-p-3;\n }\n\n &__input-wrapper {\n @apply tw-relative;\n }\n\n &__range {\n @apply tw-flex tw-flex-col tw-gap-2;\n }\n\n &__range-field {\n @apply tw-space-y-1;\n }\n\n &__range-label {\n @apply tw-block tw-text-xs tw-text-neutrals-500;\n }\n\n &__actions {\n @apply tw-flex tw-justify-end tw-gap-2 tw-px-3 tw-py-2 tw-border-t tw-border-neutrals-200 tw-bg-neutrals-50 tw-rounded-b-lg;\n }\n}\n\n// Transition\n.vc-column-filter-fade-enter-active,\n.vc-column-filter-fade-leave-active {\n transition:\n opacity 0.15s ease,\n transform 0.15s ease;\n}\n\n.vc-column-filter-fade-enter-from,\n.vc-column-filter-fade-leave-to {\n opacity: 0;\n transform: translateY(-4px);\n}\n</style>\n","<template>\n <VcButton\n variant=\"secondary\"\n size=\"sm\"\n icon=\"lucide-funnel\"\n :selected=\"activeCount > 0\"\n :disabled=\"disabled\"\n @click=\"$emit('click', $event)\"\n >\n <span class=\"vc-global-filters-button__label\">{{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.GLOBAL_FILTERS.BUTTON\") }}</span>\n <span\n v-if=\"activeCount > 0\"\n class=\"vc-global-filters-button__badge\"\n >\n {{ activeCount }}\n </span>\n </VcButton>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * GlobalFiltersButton - Button to open global filters panel\n *\n * Shows a filter icon with optional badge indicating active filter count.\n * Uses VcButton with secondary variant; `selected` prop activates highlight.\n */\nimport { VcButton } from \"@ui/components/atoms\";\n\nwithDefaults(\n defineProps<{\n /** Number of active filters (shown as badge) */\n activeCount?: number;\n /** Whether button is disabled */\n disabled?: boolean;\n }>(),\n {\n activeCount: 0,\n disabled: false,\n },\n);\n\ndefineEmits<{\n /** Emitted when button is clicked */\n click: [event: Event];\n}>();\n</script>\n\n<style lang=\"scss\">\n.vc-global-filters-button {\n &__label {\n @apply tw-hidden sm:tw-inline;\n }\n\n &__badge {\n @apply tw-inline-flex tw-items-center tw-justify-center tw-ml-1;\n @apply tw-min-w-5 tw-h-5 tw-px-1.5 tw-rounded-full;\n @apply tw-text-xs tw-font-semibold tw-text-additional-50;\n background-color: var(--primary-500);\n }\n}\n</style>\n","/**\r\n * useColumnFilter - Composable for working with declarative column filter configuration\r\n *\r\n * Provides utilities to:\r\n * - Determine filter type from config\r\n * - Extract backend field names\r\n * - Get select options\r\n */\r\n\r\nimport type {\r\n ColumnFilterConfig,\r\n FilterType,\r\n FilterOption,\r\n SelectFilterConfig,\r\n SelectFilterWithFieldConfig,\r\n DateRangeFilterConfig,\r\n} from \"@ui/components/organisms/vc-data-table/types\";\r\n\r\n/**\r\n * Type guard: check if config is a select filter with options\r\n */\r\nfunction isSelectFilter(config: ColumnFilterConfig): config is SelectFilterConfig | SelectFilterWithFieldConfig {\r\n return typeof config === \"object\" && \"options\" in config;\r\n}\r\n\r\n/**\r\n * Type guard: check if config is a select filter with custom field\r\n */\r\nfunction isSelectFilterWithField(config: ColumnFilterConfig): config is SelectFilterWithFieldConfig {\r\n return typeof config === \"object\" && \"options\" in config && \"field\" in config;\r\n}\r\n\r\n/**\r\n * Type guard: check if config is a date range filter\r\n */\r\nfunction isDateRangeFilter(config: ColumnFilterConfig): config is DateRangeFilterConfig {\r\n return typeof config === \"object\" && \"range\" in config;\r\n}\r\n\r\n/**\r\n * Composable for working with column filter configuration\r\n */\r\nexport function useColumnFilter() {\r\n /**\r\n * Determine filter type from configuration\r\n *\r\n * @example\r\n * getFilterType(true) // \"text\"\r\n * getFilterType(\"keyword\") // \"text\"\r\n * getFilterType({ options: [...] }) // \"select\"\r\n * getFilterType({ range: [\"a\", \"b\"] }) // \"dateRange\"\r\n * getFilterType(undefined) // \"none\"\r\n */\r\n const getFilterType = (filter?: ColumnFilterConfig): FilterType => {\r\n if (!filter) return \"none\";\r\n if (filter === true || typeof filter === \"string\") return \"text\";\r\n if (isDateRangeFilter(filter)) return \"dateRange\";\r\n if (isSelectFilter(filter)) return \"select\";\r\n return \"none\";\r\n };\r\n\r\n /**\r\n * Get backend field name for text/select filters\r\n *\r\n * @param columnId - The column's id (used as default)\r\n * @param filter - Filter configuration\r\n * @returns Field name to send to backend\r\n *\r\n * @example\r\n * getFilterField(\"status\", true) // \"status\"\r\n * getFilterField(\"search\", \"keyword\") // \"keyword\"\r\n * getFilterField(\"status\", { options: [...] }) // \"status\"\r\n * getFilterField(\"type\", { field: \"orderType\", options }) // \"orderType\"\r\n */\r\n const getFilterField = (columnId: string, filter?: ColumnFilterConfig): string => {\r\n if (!filter) return columnId;\r\n if (filter === true) return columnId;\r\n if (typeof filter === \"string\") return filter;\r\n if (isSelectFilterWithField(filter)) return filter.field;\r\n if (isSelectFilter(filter)) return columnId;\r\n // For dateRange, field is not applicable (use getRangeFields instead)\r\n return columnId;\r\n };\r\n\r\n /**\r\n * Get range field names for dateRange filters\r\n *\r\n * @param filter - Filter configuration\r\n * @returns Tuple of [startField, endField] or undefined if not a range filter\r\n *\r\n * @example\r\n * getRangeFields({ range: [\"startDate\", \"endDate\"] }) // [\"startDate\", \"endDate\"]\r\n * getRangeFields(true) // undefined\r\n */\r\n const getRangeFields = (filter?: ColumnFilterConfig): [string, string] | undefined => {\r\n if (filter && isDateRangeFilter(filter)) {\r\n return filter.range;\r\n }\r\n return undefined;\r\n };\r\n\r\n /**\r\n * Get select options from filter configuration\r\n *\r\n * @param filter - Filter configuration\r\n * @returns Array of FilterOption or undefined if not a select filter\r\n *\r\n * @example\r\n * getFilterOptions({ options: [{ value: \"a\", label: \"A\" }] }) // [{ value: \"a\", label: \"A\" }]\r\n * getFilterOptions(true) // undefined\r\n */\r\n const getFilterOptions = (filter?: ColumnFilterConfig): FilterOption[] | undefined => {\r\n if (filter && isSelectFilter(filter)) {\r\n return filter.options;\r\n }\r\n return undefined;\r\n };\r\n\r\n /**\r\n * Check if select filter allows multiple selection\r\n *\r\n * @param filter - Filter configuration\r\n * @returns true if multiple selection is enabled\r\n *\r\n * @example\r\n * isMultipleSelect({ options: [...], multiple: true }) // true\r\n * isMultipleSelect({ options: [...] }) // false\r\n * isMultipleSelect(true) // false\r\n */\r\n const isMultipleSelect = (filter?: ColumnFilterConfig): boolean => {\r\n if (filter && isSelectFilter(filter)) {\r\n return filter.multiple === true;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Check if column has filter configured\r\n */\r\n const hasFilter = (filter?: ColumnFilterConfig): boolean => {\r\n return filter !== undefined && filter !== null;\r\n };\r\n\r\n return {\r\n getFilterType,\r\n getFilterField,\r\n getRangeFields,\r\n getFilterOptions,\r\n isMultipleSelect,\r\n hasFilter,\r\n // Export type guards for external use\r\n isSelectFilter,\r\n isSelectFilterWithField,\r\n isDateRangeFilter,\r\n };\r\n}\r\n\r\nexport type UseColumnFilterReturn = ReturnType<typeof useColumnFilter>;\r\n","<template>\n <!-- Desktop: dropdown panel anchored to the button -->\n <VcDropdownPanel\n v-if=\"!isMobile\"\n :show=\"show\"\n :anchor-ref=\"anchorRef\"\n :title=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.GLOBAL_FILTERS.TITLE')\"\n width=\"280px\"\n max-width=\"400px\"\n @update:show=\"emit('update:show', $event)\"\n >\n <!-- Filters list -->\n <div class=\"vc-global-filters-panel__content\">\n <div\n v-for=\"filter in filters\"\n :key=\"filter.id\"\n class=\"vc-global-filters-panel__filter\"\n >\n <label class=\"vc-global-filters-panel__label\">{{ filter.label }}</label>\n\n <!-- Custom filter slot -->\n <slot\n v-if=\"$slots[`filter-${filter.id}`]\"\n :name=\"`filter-${filter.id}`\"\n :value=\"localValues[filter.id]\"\n :update-value=\"(val: unknown) => updateFilterValue(filter.id, val)\"\n />\n\n <!-- Text filter -->\n <VcInput\n v-else-if=\"getType(filter.id) === 'text'\"\n :model-value=\"localValues[filter.id] as string\"\n :placeholder=\"filter.placeholder ?? ''\"\n size=\"small\"\n @update:model-value=\"updateFilterValue(filter.id, $event)\"\n />\n\n <!-- Select filter -->\n <!-- eslint-disable vue/no-deprecated-filter -- TS union, not a filter -->\n <VcSelect\n v-else-if=\"getType(filter.id) === 'select'\"\n :model-value=\"localValues[filter.id] as string | string[] | null\"\n :options=\"getFilterOptions(filter.filter)\"\n option-value=\"value\"\n option-label=\"label\"\n size=\"small\"\n :placeholder=\"filter.placeholder ?? ''\"\n :multiple=\"isMultipleSelect(filter.filter)\"\n clearable\n emit-value\n @update:model-value=\"updateFilterValue(filter.id, $event)\"\n />\n <!-- eslint-enable vue/no-deprecated-filter -->\n\n <!-- DateRange filter -->\n <div\n v-else-if=\"getType(filter.id) === 'dateRange'\"\n class=\"vc-global-filters-panel__range\"\n >\n <div class=\"vc-global-filters-panel__range-field\">\n <span class=\"vc-global-filters-panel__range-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.FROM\") }}\n </span>\n <VcInput\n :model-value=\"getDateRangeStart(filter.id)\"\n type=\"date\"\n size=\"small\"\n @update:model-value=\"updateDateRangeStart(filter, $event)\"\n />\n </div>\n <div class=\"vc-global-filters-panel__range-field\">\n <span class=\"vc-global-filters-panel__range-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.TO\") }}\n </span>\n <VcInput\n :model-value=\"getDateRangeEnd(filter.id)\"\n type=\"date\"\n size=\"small\"\n @update:model-value=\"updateDateRangeEnd(filter, $event)\"\n />\n </div>\n </div>\n </div>\n </div>\n\n <!-- Actions -->\n <template #footer>\n <VcButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"clearAll\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.CLEAR\") }}\n </VcButton>\n <VcButton\n variant=\"primary\"\n size=\"sm\"\n @click=\"applyAll\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.APPLY\") }}\n </VcButton>\n </template>\n </VcDropdownPanel>\n\n <!-- Mobile: bottom-sheet sidebar -->\n <VcSidebar\n v-else\n :model-value=\"show\"\n position=\"bottom\"\n size=\"sm\"\n draggable\n drag-handle\n :close-button=\"false\"\n :inset=\"false\"\n :title=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.GLOBAL_FILTERS.TITLE')\"\n @update:model-value=\"emit('update:show', $event)\"\n >\n <!-- Filters list (same content as desktop) -->\n <div class=\"vc-global-filters-panel__content\">\n <div\n v-for=\"filter in filters\"\n :key=\"filter.id\"\n class=\"vc-global-filters-panel__filter\"\n >\n <label class=\"vc-global-filters-panel__label\">{{ filter.label }}</label>\n\n <slot\n v-if=\"$slots[`filter-${filter.id}`]\"\n :name=\"`filter-${filter.id}`\"\n :value=\"localValues[filter.id]\"\n :update-value=\"(val: unknown) => updateFilterValue(filter.id, val)\"\n />\n\n <VcInput\n v-else-if=\"getType(filter.id) === 'text'\"\n :model-value=\"localValues[filter.id] as string\"\n :placeholder=\"filter.placeholder ?? ''\"\n size=\"small\"\n @update:model-value=\"updateFilterValue(filter.id, $event)\"\n />\n\n <!-- eslint-disable vue/no-deprecated-filter -- TS union, not a filter -->\n <VcSelect\n v-else-if=\"getType(filter.id) === 'select'\"\n :model-value=\"localValues[filter.id] as string | string[] | null\"\n :options=\"getFilterOptions(filter.filter)\"\n option-value=\"value\"\n option-label=\"label\"\n size=\"small\"\n :placeholder=\"filter.placeholder ?? ''\"\n :multiple=\"isMultipleSelect(filter.filter)\"\n clearable\n emit-value\n @update:model-value=\"updateFilterValue(filter.id, $event)\"\n />\n <!-- eslint-enable vue/no-deprecated-filter -->\n\n <div\n v-else-if=\"getType(filter.id) === 'dateRange'\"\n class=\"vc-global-filters-panel__range\"\n >\n <div class=\"vc-global-filters-panel__range-field\">\n <span class=\"vc-global-filters-panel__range-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.FROM\") }}\n </span>\n <VcInput\n :model-value=\"getDateRangeStart(filter.id)\"\n type=\"date\"\n size=\"small\"\n @update:model-value=\"updateDateRangeStart(filter, $event)\"\n />\n </div>\n <div class=\"vc-global-filters-panel__range-field\">\n <span class=\"vc-global-filters-panel__range-label\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.TO\") }}\n </span>\n <VcInput\n :model-value=\"getDateRangeEnd(filter.id)\"\n type=\"date\"\n size=\"small\"\n @update:model-value=\"updateDateRangeEnd(filter, $event)\"\n />\n </div>\n </div>\n </div>\n </div>\n\n <!-- Actions -->\n <template #footer>\n <div class=\"vc-global-filters-panel__footer-actions\">\n <VcButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"clearAll\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.CLEAR\") }}\n </VcButton>\n <VcButton\n variant=\"primary\"\n size=\"sm\"\n @click=\"applyAll\"\n >\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_FILTER.APPLY\") }}\n </VcButton>\n </div>\n </template>\n </VcSidebar>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * GlobalFiltersPanel - Responsive filter panel\n *\n * Desktop: floating VcDropdownPanel anchored to the filter button.\n * Mobile: VcSidebar bottom sheet with drag-to-dismiss.\n *\n * Supports text, select (single/multi), and dateRange filter types.\n * Custom filter UI can be provided via named slots.\n */\nimport { ref, computed, watch } from \"vue\";\nimport { VcDropdownPanel } from \"@ui/components/molecules\";\nimport { VcInput, VcSelect } from \"@ui/components/molecules\";\nimport { VcButton } from \"@ui/components/atoms\";\nimport { VcSidebar } from \"@ui/components/organisms/vc-sidebar\";\nimport type { GlobalFilterConfig } from \"@ui/components/organisms/vc-data-table/types\";\nimport { useColumnFilter } from \"@ui/components/organisms/vc-data-table/composables/useColumnFilter\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport type { ReferenceElement } from \"@floating-ui/vue\";\n\ninterface Props {\n /** List of filter configurations (id, label, type, options) */\n filters: GlobalFilterConfig[];\n /** Current filter values as key-value pairs (controlled) */\n modelValue: Record<string, unknown>;\n /** Whether panel is visible */\n show: boolean;\n /** Anchor for positioning the floating panel — HTMLElement or floating-ui VirtualElement. */\n anchorRef?: ReferenceElement | null;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n anchorRef: null,\n});\n\nconst emit = defineEmits<{\n /** Emitted when filter values change */\n \"update:modelValue\": [Record<string, unknown>];\n /** Emitted to close panel */\n \"update:show\": [boolean];\n /** Emitted when Apply is clicked */\n apply: [Record<string, unknown>];\n /** Emitted when Clear is clicked */\n clear: [];\n}>();\n\nconst { isMobile } = useResponsive();\n\n// Use the same helpers as ColumnFilter\nconst { getFilterType, getFilterOptions, isMultipleSelect, getRangeFields } = useColumnFilter();\n\n// Pre-compute filter types for each filter (for debugging and reactivity)\nconst filterTypes = computed(() => {\n const types: Record<string, string> = {};\n for (const filter of props.filters) {\n types[filter.id] = getFilterType(filter.filter);\n }\n return types;\n});\n\n// Helper to get pre-computed filter type\nconst getType = (filterId: string) => filterTypes.value[filterId] || \"none\";\n\n// Local working copy of filter values\nconst localValues = ref<Record<string, unknown>>({});\n\n// Initialize local values from props\nconst initLocalValues = () => {\n const values: Record<string, unknown> = {};\n for (const filter of props.filters) {\n values[filter.id] = props.modelValue[filter.id] ?? null;\n }\n localValues.value = values;\n};\n\n// Watch for external changes when panel is closed\nwatch(\n () => props.modelValue,\n () => {\n if (!props.show) {\n initLocalValues();\n }\n },\n { deep: true },\n);\n\n// Initialize when panel opens\nwatch(\n () => props.show,\n (newShow) => {\n if (newShow) {\n initLocalValues();\n }\n },\n);\n\n// Update filter value\nconst updateFilterValue = (filterId: string, value: unknown) => {\n localValues.value = {\n ...localValues.value,\n [filterId]: value,\n };\n};\n\n// DateRange helpers\nconst getDateRangeStart = (filterId: string): string => {\n const val = localValues.value[filterId];\n if (val && typeof val === \"object\" && \"start\" in val) {\n return (val as { start?: string }).start ?? \"\";\n }\n return \"\";\n};\n\nconst getDateRangeEnd = (filterId: string): string => {\n const val = localValues.value[filterId];\n if (val && typeof val === \"object\" && \"end\" in val) {\n return (val as { end?: string }).end ?? \"\";\n }\n return \"\";\n};\n\nconst toDateOnly = (value: string | number | Date | null | undefined): string | undefined => {\n if (value == null) return undefined;\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) return undefined;\n const y = value.getFullYear();\n const m = String(value.getMonth() + 1).padStart(2, \"0\");\n const d = String(value.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n }\n const s = String(value);\n return s === \"\" ? undefined : s;\n};\n\nconst updateDateRangeStart = (filter: GlobalFilterConfig, value: string | number | Date | null | undefined) => {\n const current = localValues.value[filter.id] as { start?: string; end?: string } | null;\n localValues.value = {\n ...localValues.value,\n [filter.id]: {\n start: toDateOnly(value),\n end: current?.end,\n },\n };\n};\n\nconst updateDateRangeEnd = (filter: GlobalFilterConfig, value: string | number | Date | null | undefined) => {\n const current = localValues.value[filter.id] as { start?: string; end?: string } | null;\n localValues.value = {\n ...localValues.value,\n [filter.id]: {\n start: current?.start,\n end: toDateOnly(value),\n },\n };\n};\n\n// Build flat payload for backend\nconst buildPayload = (): Record<string, unknown> => {\n const payload: Record<string, unknown> = {};\n\n for (const filter of props.filters) {\n const value = localValues.value[filter.id];\n const filterType = getFilterType(filter.filter);\n\n if (filterType === \"dateRange\") {\n // Expand dateRange to separate fields\n const rangeFields = getRangeFields(filter.filter);\n const rangeVal = value as { start?: string; end?: string } | null;\n if (rangeFields && rangeVal) {\n if (rangeVal.start) {\n payload[rangeFields[0]] = rangeVal.start;\n }\n if (rangeVal.end) {\n payload[rangeFields[1]] = rangeVal.end;\n }\n }\n } else {\n // Text and select filters\n if (value !== null && value !== undefined && value !== \"\") {\n // For multi-select, only include if array has items\n if (Array.isArray(value) && value.length === 0) {\n continue;\n }\n const field = typeof filter.filter === \"string\" ? filter.filter : filter.id;\n payload[field] = value;\n }\n }\n }\n\n return payload;\n};\n\n// Actions\nconst close = () => {\n emit(\"update:show\", false);\n};\n\nconst applyAll = () => {\n const payload = buildPayload();\n emit(\"update:modelValue\", { ...localValues.value });\n emit(\"apply\", payload);\n close();\n};\n\nconst clearAll = () => {\n // Reset all local values\n const cleared: Record<string, unknown> = {};\n for (const filter of props.filters) {\n cleared[filter.id] = null;\n }\n localValues.value = cleared;\n emit(\"update:modelValue\", cleared);\n emit(\"clear\");\n close();\n};\n</script>\n\n<style lang=\"scss\">\n.vc-global-filters-panel {\n &__content {\n @apply tw-px-4 tw-py-3;\n @apply tw-space-y-4;\n }\n\n &__filter {\n @apply tw-space-y-1.5;\n }\n\n &__label {\n @apply tw-block tw-text-sm tw-font-medium tw-text-neutrals-700;\n }\n\n &__range {\n @apply tw-flex tw-gap-3;\n }\n\n &__range-field {\n @apply tw-flex-1 tw-space-y-1;\n }\n\n &__range-label {\n @apply tw-block tw-text-xs tw-text-neutrals-500;\n }\n\n &__footer-actions {\n @apply tw-flex tw-justify-end tw-gap-2 tw-px-4 tw-py-3;\n }\n}\n</style>\n","<template>\n <div\n class=\"vc-table-add-row\"\n role=\"row\"\n >\n <div role=\"cell\">\n <VcButton\n variant=\"link\"\n :icon=\"icon\"\n icon-size=\"s\"\n @click=\"$emit('add')\"\n >\n {{ displayLabel }}\n </VcButton>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * TableAddRowButton - Button component for adding new rows to the table\n *\n * Can be placed in header or footer position via VcDataTable's `addRow` prop.\n * Emits 'add' event when clicked.\n */\nimport { computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { VcButton } from \"@ui/components/atoms\";\n\nconst { t } = useI18n({ useScope: \"global\" });\n\nconst props = withDefaults(\n defineProps<{\n /** Button label (overrides i18n default) */\n label?: string;\n /** Button icon */\n icon?: string;\n }>(),\n {\n label: undefined,\n icon: \"lucide-plus\",\n },\n);\n\ndefineEmits<{\n /** Emitted when button is clicked */\n add: [];\n}>();\n\nconst displayLabel = computed(() => props.label ?? t(\"COMPONENTS.ORGANISMS.VC_TABLE.ADD_ROW\"));\n</script>\n\n<style lang=\"scss\">\n.vc-table-add-row {\n @apply tw-py-3 tw-px-4 tw-border-t;\n border-color: var(--table-border-color, var(--neutrals-200));\n}\n</style>\n","<template>\n <Field\n ref=\"fieldRef\"\n v-slot=\"{ errors, errorMessage }\"\n :label=\"label\"\n :name=\"fieldName\"\n :model-value=\"modelValue\"\n :rules=\"rules\"\n >\n <VcTooltip placement=\"bottom\">\n <template #default>\n <slot\n :errors=\"errors\"\n :error-message=\"errorMessage\"\n />\n </template>\n <template\n v-if=\"errorMessage\"\n #tooltip\n >\n <div class=\"vc-table-cell-editable__error-tooltip\">\n {{ errorMessage }}\n </div>\n </template>\n </VcTooltip>\n </Field>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, ref } from \"vue\";\nimport { Field } from \"vee-validate\";\nimport VcTooltip from \"@ui/components/atoms/vc-tooltip/vc-tooltip.vue\";\n\nconst props = defineProps<{\n /** Label for the editable field (used for validation) */\n label: string;\n /** Field name for validation */\n fieldName: string;\n /** Current value of the field */\n modelValue?: unknown;\n /** Validation rules for the field */\n rules?: Record<string, unknown>;\n /** Trigger validation immediately on mount (for new rows) */\n validateOnMount?: boolean;\n}>();\n\nconst fieldRef = ref<InstanceType<typeof Field> | null>(null);\n\nonMounted(() => {\n // Validate on mount when explicitly requested (new rows) OR\n // when field is empty and has validation rules (catches required fields)\n const isEmpty = props.modelValue === undefined || props.modelValue === null || props.modelValue === \"\";\n if (props.validateOnMount || (isEmpty && props.rules)) {\n fieldRef.value?.validate();\n }\n});\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-editable {\n &__error-tooltip {\n @apply tw-text-danger-500;\n }\n}\n</style>\n","<template>\n <!-- Editable mode -->\n <CellEditableWrapper\n v-if=\"editable\"\n :label=\"label || ''\"\n :field-name=\"fieldName || ''\"\n :model-value=\"value\"\n :rules=\"rules\"\n :validate-on-mount=\"validateOnMount\"\n >\n <template #default=\"{ errors, errorMessage }\">\n <!-- eslint-disable vue/no-deprecated-filter -- TS union, not a filter -->\n <VcInput\n :model-value=\"value as string | null\"\n class=\"vc-table-cell-default__input\"\n :error=\"errors.length > 0\"\n :error-message=\"isMobile ? errorMessage : undefined\"\n @update:model-value=\"$emit('update', { field: fieldId || '', value: $event })\"\n @blur=\"onBlur(errors)\"\n >\n <template\n v-if=\"isDesktop && errors.length > 0\"\n #append-inner\n >\n <VcIcon\n icon=\"lucide-circle-alert\"\n class=\"vc-table-cell-default__error-icon\"\n />\n </template>\n </VcInput>\n <!-- eslint-enable vue/no-deprecated-filter -->\n </template>\n </CellEditableWrapper>\n\n <!-- Display mode -->\n <span\n v-else\n class=\"vc-table-cell-default\"\n >{{ value }}</span\n >\n</template>\n\n<script setup lang=\"ts\">\nimport VcInput from \"@ui/components/molecules/vc-input/vc-input.vue\";\nimport { VcIcon } from \"@ui/components/atoms\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport CellEditableWrapper from \"@ui/components/organisms/vc-data-table/components/cells/CellEditableWrapper.vue\";\n\nconst props = defineProps<{\n /** The cell value to display or edit */\n value?: unknown;\n /** Whether the cell is in editable mode */\n editable?: boolean;\n /** Label for the editable field (used for validation) */\n label?: string;\n /** Field name for validation */\n fieldName?: string;\n /** Field identifier for update/blur events */\n fieldId?: string;\n /** Validation rules for the editable field */\n rules?: Record<string, unknown>;\n /** Row index for blur event payload */\n rowIndex?: number;\n /** Trigger validation immediately on mount (for new rows) */\n validateOnMount?: boolean;\n}>();\n\nconst emit = defineEmits<{\n /** Emitted when cell value is updated */\n (e: \"update\", payload: { field: string; value: unknown }): void;\n /** Emitted when editable cell loses focus (only if no validation errors) */\n (e: \"blur\", payload: { row: number | undefined; field: string }): void;\n}>();\n\nconst { isMobile, isDesktop } = useResponsive();\n\nconst onBlur = (errors: string[]) => {\n if (errors && errors.length > 0) return;\n emit(\"blur\", { row: props.rowIndex, field: props.fieldId || \"\" });\n};\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-default {\n @apply tw-truncate;\n\n &__input {\n @apply tw-w-full;\n }\n\n &__error-icon {\n @apply tw-text-danger-500;\n }\n}\n</style>\n","<template>\n <!-- Editable mode -->\n <CellEditableWrapper\n v-if=\"editable\"\n :label=\"label || ''\"\n :field-name=\"fieldName || ''\"\n :model-value=\"value\"\n :rules=\"rules\"\n :validate-on-mount=\"validateOnMount\"\n >\n <template #default=\"{ errors, errorMessage }\">\n <!-- eslint-disable vue/no-deprecated-filter -- TS union, not a filter -->\n <VcInputCurrency\n :model-value=\"value as number | null | undefined\"\n :options=\"[]\"\n :option=\"currency || 'USD'\"\n currency-display=\"symbol\"\n class=\"vc-table-cell-money__input\"\n :error=\"errors.length > 0\"\n :error-message=\"isMobile ? errorMessage : undefined\"\n @update:model-value=\"$emit('update', { field: fieldId || '', value: $event })\"\n @blur=\"onBlur(errors)\"\n >\n <template\n v-if=\"isDesktop && errors.length > 0\"\n #append-inner\n >\n <VcIcon\n icon=\"lucide-circle-alert\"\n class=\"vc-table-cell-money__error-icon\"\n />\n </template>\n </VcInputCurrency>\n <!-- eslint-enable vue/no-deprecated-filter -->\n </template>\n </CellEditableWrapper>\n\n <!-- Display mode -->\n <span\n v-else-if=\"!isEmpty\"\n class=\"vc-table-cell-money\"\n >{{ formatted }}</span\n >\n <span\n v-else\n class=\"vc-table-cell-money vc-table-cell-money--not-set\"\n >\n {{ t(\"COMPONENTS.ORGANISMS.VC_TABLE.NOT_SET\") }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport VcInputCurrency from \"@ui/components/molecules/vc-input-currency/vc-input-currency.vue\";\nimport { VcIcon } from \"@ui/components/atoms\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport CellEditableWrapper from \"@ui/components/organisms/vc-data-table/components/cells/CellEditableWrapper.vue\";\n\nconst props = defineProps<{\n /** The monetary value to display or edit */\n value?: unknown;\n /** Currency code (e.g., 'USD', 'EUR') for formatting */\n currency?: string;\n /** Whether the cell is in editable mode */\n editable?: boolean;\n /** Label for the editable field (used for validation) */\n label?: string;\n /** Field name for validation */\n fieldName?: string;\n /** Field identifier for update/blur events */\n fieldId?: string;\n /** Validation rules for the editable field */\n rules?: Record<string, unknown>;\n /** Row index for blur event payload */\n rowIndex?: number;\n /** Trigger validation immediately on mount (for new rows) */\n validateOnMount?: boolean;\n}>();\n\nconst emit = defineEmits<{\n /** Emitted when cell value is updated */\n (e: \"update\", payload: { field: string; value: unknown }): void;\n /** Emitted when editable cell loses focus (only if no validation errors) */\n (e: \"blur\", payload: { row: number | undefined; field: string }): void;\n}>();\n\nconst { t } = useI18n({ useScope: \"global\" });\nconst locale = window.navigator.language;\n\nconst { isMobile, isDesktop } = useResponsive();\n\nconst isEmpty = computed(() => typeof props.value === \"undefined\" || props.value === null || Number(props.value) === 0);\n\nconst formatted = computed(() => {\n const num = Number(props.value);\n if (isNaN(num)) return String(props.value);\n return new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency: props.currency || \"USD\",\n }).format(num);\n});\n\nconst onBlur = (errors: string[]) => {\n if (errors && errors.length > 0) return;\n emit(\"blur\", { row: props.rowIndex, field: props.fieldId || \"\" });\n};\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-money {\n @apply tw-truncate tw-font-medium tw-tabular-nums;\n\n &--not-set {\n @apply tw-font-normal;\n color: var(--neutrals-400);\n }\n\n &__input {\n @apply tw-w-full;\n }\n\n &__error-icon {\n @apply tw-text-danger-500;\n }\n}\n</style>\n","<template>\n <!-- Editable mode -->\n <CellEditableWrapper\n v-if=\"editable\"\n :label=\"label || ''\"\n :field-name=\"fieldName || ''\"\n :model-value=\"value\"\n :rules=\"rules\"\n :validate-on-mount=\"validateOnMount\"\n >\n <template #default=\"{ errors, errorMessage }\">\n <!-- eslint-disable vue/no-deprecated-filter -- TS union, not a filter -->\n <VcInput\n :model-value=\"value as number | null\"\n class=\"vc-table-cell-number__input\"\n type=\"number\"\n :error=\"errors.length > 0\"\n :error-message=\"isMobile ? errorMessage : undefined\"\n @update:model-value=\"$emit('update', { field: fieldId || '', value: $event })\"\n @blur=\"onBlur(errors)\"\n >\n <template\n v-if=\"isDesktop && errors.length > 0\"\n #append-inner\n >\n <VcIcon\n icon=\"lucide-circle-alert\"\n class=\"vc-table-cell-number__error-icon\"\n />\n </template>\n </VcInput>\n <!-- eslint-enable vue/no-deprecated-filter -->\n </template>\n </CellEditableWrapper>\n\n <!-- Display mode -->\n <span\n v-else-if=\"!isEmpty\"\n class=\"vc-table-cell-number\"\n >{{ formatted }}</span\n >\n <span\n v-else\n class=\"vc-table-cell-number vc-table-cell-number--not-set\"\n >\n {{ t(\"COMPONENTS.ORGANISMS.VC_TABLE.NOT_SET\") }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport VcInput from \"@ui/components/molecules/vc-input/vc-input.vue\";\nimport { VcIcon } from \"@ui/components/atoms\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport CellEditableWrapper from \"@ui/components/organisms/vc-data-table/components/cells/CellEditableWrapper.vue\";\n\nconst props = defineProps<{\n /** The numeric value to display or edit */\n value?: unknown;\n /** Whether the cell is in editable mode */\n editable?: boolean;\n /** Label for the editable field (used for validation) */\n label?: string;\n /** Field name for validation */\n fieldName?: string;\n /** Field identifier for update/blur events */\n fieldId?: string;\n /** Validation rules for the editable field */\n rules?: Record<string, unknown>;\n /** Row index for blur event payload */\n rowIndex?: number;\n /** Trigger validation immediately on mount (for new rows) */\n validateOnMount?: boolean;\n}>();\n\nconst emit = defineEmits<{\n /** Emitted when cell value is updated */\n (e: \"update\", payload: { field: string; value: unknown }): void;\n /** Emitted when editable cell loses focus (only if no validation errors) */\n (e: \"blur\", payload: { row: number | undefined; field: string }): void;\n}>();\n\nconst { t } = useI18n({ useScope: \"global\" });\n\nconst { isMobile, isDesktop } = useResponsive();\n\nconst isEmpty = computed(() => {\n if (props.value === null || props.value === undefined) return true;\n const num = Number(props.value);\n return isNaN(num) || num < 0;\n});\n\nconst formatted = computed(() => {\n const num = Number(props.value);\n return isNaN(num) ? String(props.value) : num.toFixed(0);\n});\n\nconst onBlur = (errors: string[]) => {\n if (errors && errors.length > 0) return;\n emit(\"blur\", { row: props.rowIndex, field: props.fieldId || \"\" });\n};\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-number {\n @apply tw-truncate tw-tabular-nums;\n\n &--not-set {\n @apply tw-font-normal;\n color: var(--neutrals-400);\n }\n\n &__input {\n @apply tw-w-full;\n }\n\n &__error-icon {\n @apply tw-text-danger-500;\n }\n}\n</style>\n","<template>\n <span\n v-if=\"value\"\n class=\"vc-table-cell-date\"\n >{{ formatted }}</span\n >\n <span\n v-else\n class=\"vc-table-cell-date vc-table-cell-date--not-set\"\n >\n {{ t(\"COMPONENTS.ORGANISMS.VC_TABLE.NOT_SET\") }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { formatDateWithPattern } from \"@core/utilities/date\";\n\nconst props = defineProps<{\n /** The date value to display (Date, string, or number) */\n value?: unknown;\n /** Format variant: 'date', 'time', or 'date-time' */\n variant?: \"date\" | \"time\" | \"date-time\";\n /** Custom date format string (moment.js tokens auto-converted) */\n format?: string;\n}>();\n\nconst { t } = useI18n({ useScope: \"global\" });\nconst locale = window.navigator.language;\n\nconst formatted = computed(() => {\n if (!props.value) return \"\";\n\n // Custom date format\n if (props.format) {\n return formatDateWithPattern(props.value as string | number | Date, props.format, locale);\n }\n\n // Native locale formatting\n const d = props.value instanceof Date ? props.value : new Date(props.value as string | number);\n const variant = props.variant || \"date\";\n\n if (variant === \"time\") return d.toLocaleTimeString(locale);\n if (variant === \"date-time\") return d.toLocaleString(locale);\n return d.toLocaleDateString(locale);\n});\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-date {\n @apply tw-truncate;\n color: var(--neutrals-400);\n\n &--not-set {\n color: var(--neutrals-400);\n }\n}\n</style>\n","<template>\n <span\n v-if=\"value\"\n class=\"vc-table-cell-date-ago\"\n :title=\"titleText\"\n >\n {{ agoText }}\n </span>\n <span\n v-else\n class=\"vc-table-cell-date-ago vc-table-cell-date-ago--not-set\"\n >\n {{ t(\"COMPONENTS.ORGANISMS.VC_TABLE.NOT_SET\") }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { formatDateRelative } from \"@core/utilities/date\";\n\nconst props = defineProps<{\n /** The date value to display as relative time (e.g., '2 hours ago') */\n value?: unknown;\n}>();\n\nconst { t } = useI18n({ useScope: \"global\" });\nconst locale = window.navigator.language;\n\nconst titleText = computed(() => {\n if (!props.value) return \"\";\n const d = props.value instanceof Date ? props.value : new Date(props.value as string | number);\n return d.toLocaleString(locale);\n});\n\nconst agoText = computed(() => {\n if (!props.value) return \"\";\n return formatDateRelative(props.value as string | number | Date);\n});\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-date-ago {\n @apply tw-truncate;\n color: var(--neutrals-400);\n\n &--not-set {\n color: var(--neutrals-400);\n }\n}\n</style>\n","<template>\n <VcImage\n class=\"vc-table-cell-image\"\n :bordered=\"true\"\n size=\"s\"\n aspect=\"1x1\"\n :src=\"value as string\"\n :empty-icon=\"emptyIcon\"\n background=\"contain\"\n thumbnail-size=\"sm\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { VcImage } from \"@ui/components/atoms\";\n\ndefineProps<{\n /** The image URL to display */\n value?: unknown;\n /** Icon to display when image is empty or missing */\n emptyIcon?: string;\n}>();\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-image {\n @apply tw-flex-shrink-0;\n}\n</style>\n","<template>\n <VcStatus class=\"vc-table-cell-status\">{{ value }}</VcStatus>\n</template>\n\n<script setup lang=\"ts\">\nimport { VcStatus } from \"@ui/components/atoms\";\n\ndefineProps<{\n /** The status text to display in a status badge */\n value?: unknown;\n}>();\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-status {\n @apply tw-inline-flex;\n}\n</style>\n","<template>\n <div class=\"vc-table-cell-status-icon\">\n <VcStatusIcon\n v-if=\"typeof value === 'boolean'\"\n :status=\"value as boolean\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { VcStatusIcon } from \"@ui/components/atoms\";\n\ndefineProps<{\n /** Boolean value indicating status (true = success, false = error) */\n value?: unknown;\n}>();\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-status-icon {\n @apply tw-flex tw-justify-center;\n}\n</style>\n","<template>\n <VcLink class=\"vc-table-cell-link\">{{ value }}</VcLink>\n</template>\n\n<script setup lang=\"ts\">\nimport { VcLink } from \"@ui/components/atoms\";\n\ndefineProps<{\n /** The link text to display */\n value?: unknown;\n}>();\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-link {\n @apply tw-truncate;\n}\n</style>\n","<template>\n <div\n class=\"vc-table-cell-html\"\n v-html=\"truncatedHtml\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport htmlTruncate from \"truncate-html\";\nimport * as DOMPurify from \"dompurify\";\n\nconst props = defineProps<{\n /** The HTML content to sanitize and display */\n value?: unknown;\n /** Maximum character length before truncation (default: 30) */\n maxLength?: number;\n}>();\n\n// Cache for sanitized HTML to avoid repeated DOMPurify calls\nconst sanitizedHtmlCache = new Map<string, string>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getSanitizedHtml(html: string): string {\n if (sanitizedHtmlCache.has(html)) {\n return sanitizedHtmlCache.get(html)!;\n }\n\n const sanitized = DOMPurify.default.sanitize(html, {\n ALLOWED_TAGS: [\n \"p\",\n \"br\",\n \"strong\",\n \"em\",\n \"u\",\n \"s\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"a\",\n \"img\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n \"hr\",\n \"div\",\n \"span\",\n ],\n ALLOWED_ATTR: [\"href\", \"src\", \"alt\", \"title\", \"class\", \"id\", \"colspan\", \"rowspan\", \"align\", \"valign\"],\n FORBID_TAGS: [\"script\", \"object\", \"embed\", \"form\", \"input\"],\n FORBID_ATTR: [\"onerror\", \"onload\", \"onclick\", \"onmouseover\", \"onfocus\", \"onblur\", \"style\"],\n });\n\n if (sanitizedHtmlCache.size >= MAX_CACHE_SIZE) {\n const firstKey = sanitizedHtmlCache.keys().next().value;\n if (firstKey !== undefined) {\n sanitizedHtmlCache.delete(firstKey);\n }\n }\n\n sanitizedHtmlCache.set(html, sanitized);\n return sanitized;\n}\n\nconst sanitizedHtml = computed(() => {\n if (!props.value) return \"\";\n return getSanitizedHtml(String(props.value));\n});\n\nconst truncatedHtml = computed(() => htmlTruncate(sanitizedHtml.value, props.maxLength || 30));\n</script>\n\n<style lang=\"scss\">\n.vc-table-cell-html {\n @apply tw-p-1 tw-truncate;\n}\n</style>\n","<template>\r\n <component\r\n :is=\"cellComponent\"\r\n v-bind=\"cellProps\"\r\n @update=\"$emit('update', $event)\"\r\n @blur=\"$emit('blur', $event)\"\r\n />\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n/**\r\n * DynamicCellRenderer - Renders cell content based on registered cell types.\r\n *\r\n * Uses CellRegistry to lookup and render the appropriate cell component\r\n * based on the column type. This enables the Open/Closed Principle -\r\n * new cell types can be added without modifying this component.\r\n *\r\n * @example\r\n * ```vue\r\n * <DynamicCellRenderer\r\n * type=\"money\"\r\n * :value=\"item.price\"\r\n * :currency=\"item.currency\"\r\n * :editable=\"isEditing\"\r\n * @update=\"handleUpdate\"\r\n * />\r\n * ```\r\n */\r\nimport { computed, type Component } from \"vue\";\r\nimport { useCellRegistry } from \"@ui/components/organisms/vc-data-table/composables/useCellRegistry\";\r\n\r\n// Import cell components for fallback and default registration\r\nimport CellDefault from \"@ui/components/organisms/vc-data-table/components/cells/CellDefault.vue\";\r\nimport CellMoney from \"@ui/components/organisms/vc-data-table/components/cells/CellMoney.vue\";\r\nimport CellNumber from \"@ui/components/organisms/vc-data-table/components/cells/CellNumber.vue\";\r\nimport CellDate from \"@ui/components/organisms/vc-data-table/components/cells/CellDate.vue\";\r\nimport CellDateAgo from \"@ui/components/organisms/vc-data-table/components/cells/CellDateAgo.vue\";\r\nimport CellImage from \"@ui/components/organisms/vc-data-table/components/cells/CellImage.vue\";\r\nimport CellStatus from \"@ui/components/organisms/vc-data-table/components/cells/CellStatus.vue\";\r\nimport CellStatusIcon from \"@ui/components/organisms/vc-data-table/components/cells/CellStatusIcon.vue\";\r\nimport CellLink from \"@ui/components/organisms/vc-data-table/components/cells/CellLink.vue\";\r\nimport CellHtml from \"@ui/components/organisms/vc-data-table/components/cells/CellHtml.vue\";\r\n\r\n// Get composable methods\r\nconst { register, has, get } = useCellRegistry();\r\n\r\n// Register built-in cell types if not already registered\r\nif (!has(\"text\")) {\r\n register({ type: \"text\", component: CellDefault, config: { editable: true } });\r\n}\r\nif (!has(\"number\")) {\r\n register({ type: \"number\", component: CellNumber, config: { editable: true } });\r\n}\r\nif (!has(\"money\")) {\r\n register({ type: \"money\", component: CellMoney, config: { editable: true } });\r\n}\r\nif (!has(\"date\")) {\r\n register({ type: \"date\", component: CellDate, config: { editable: false } });\r\n}\r\nif (!has(\"time\")) {\r\n register({ type: \"time\", component: CellDate, config: { editable: false } });\r\n}\r\nif (!has(\"datetime\")) {\r\n register({ type: \"datetime\", component: CellDate, config: { editable: false } });\r\n}\r\nif (!has(\"date-ago\")) {\r\n register({ type: \"date-ago\", component: CellDateAgo, config: { editable: false } });\r\n}\r\nif (!has(\"image\")) {\r\n register({ type: \"image\", component: CellImage, config: { editable: false } });\r\n}\r\nif (!has(\"status\")) {\r\n register({ type: \"status\", component: CellStatus, config: { editable: false } });\r\n}\r\nif (!has(\"status-icon\")) {\r\n register({ type: \"status-icon\", component: CellStatusIcon, config: { editable: false } });\r\n}\r\nif (!has(\"link\")) {\r\n register({ type: \"link\", component: CellLink, config: { editable: false } });\r\n}\r\nif (!has(\"html\")) {\r\n register({ type: \"html\", component: CellHtml, config: { editable: false } });\r\n}\r\n\r\nconst props = defineProps<{\r\n /** Cell type to render */\r\n type: string;\r\n /** Cell value */\r\n value?: unknown;\r\n /** Whether the cell is in edit mode */\r\n editable?: boolean;\r\n /** Label for the field (used in validation) */\r\n label?: string;\r\n /** Field name for VeeValidate (unique per row) */\r\n fieldName?: string;\r\n /** Field identifier */\r\n fieldId?: string;\r\n /** Validation rules */\r\n rules?: Record<string, unknown>;\r\n /** Row index */\r\n rowIndex?: number;\r\n /** Currency for money cells */\r\n currency?: string;\r\n /** Date format for date cells */\r\n format?: string;\r\n /** Date variant (date, time, date-time) */\r\n variant?: \"date\" | \"time\" | \"date-time\";\r\n /** Whether to trigger validation on mount (for new rows) */\r\n validateOnMount?: boolean;\r\n}>();\r\n\r\ndefineEmits<{\r\n /** Cell value updated during editing */\r\n (e: \"update\", payload: { field: string; value: unknown }): void;\r\n /** Cell input blurred */\r\n (e: \"blur\", payload: { row: number | undefined; field: string }): void;\r\n}>();\r\n\r\n/**\r\n * Get the component to render based on cell type.\r\n * Falls back to CellDefault if type is not registered.\r\n */\r\nconst cellComponent = computed<Component>(() => {\r\n const registration = get(props.type);\r\n return registration?.component || CellDefault;\r\n});\r\n\r\n/**\r\n * Build props to pass to the cell component.\r\n * Only includes props relevant to the specific cell type.\r\n */\r\nconst cellProps = computed(() => {\r\n const registration = get(props.type);\r\n const isEditable = registration?.config?.editable ?? false;\r\n\r\n // Base props for all cells\r\n const baseProps: Record<string, unknown> = {\r\n value: props.value,\r\n };\r\n\r\n // Add editable props only if the cell type supports editing\r\n if (isEditable && props.editable) {\r\n baseProps.editable = props.editable;\r\n baseProps.label = props.label;\r\n baseProps.fieldName = props.fieldName;\r\n baseProps.fieldId = props.fieldId;\r\n baseProps.rules = props.rules;\r\n baseProps.rowIndex = props.rowIndex;\r\n if (props.validateOnMount) {\r\n baseProps.validateOnMount = true;\r\n }\r\n }\r\n\r\n // Add type-specific props\r\n if (props.type === \"money\" && props.currency) {\r\n baseProps.currency = props.currency;\r\n }\r\n\r\n if ((props.type === \"date\" || props.type === \"time\" || props.type === \"datetime\") && props.variant) {\r\n baseProps.variant = props.variant;\r\n }\r\n\r\n if (props.format) {\r\n baseProps.format = props.format;\r\n }\r\n\r\n return baseProps;\r\n});\r\n</script>\r\n","<template>\r\n <!-- Selection column body (checkbox for multiple, radio for single) -->\r\n <template v-if=\"column.props.selectionMode\">\r\n <TableCheckbox\r\n v-if=\"column.props.selectionMode === 'multiple'\"\r\n :model-value=\"isSelected\"\r\n :disabled=\"!isSelectable\"\r\n @update:model-value=\"$emit('selection-change', $event)\"\r\n />\r\n <VcRadioButton\r\n v-else\r\n :model-value=\"isSelected ?? false\"\r\n :value=\"true\"\r\n :disabled=\"!isSelectable\"\r\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.SELECT_ROW')\"\r\n @update:model-value=\"$emit('selection-change', true)\"\r\n />\r\n </template>\r\n\r\n <!-- Expander column body (expand/collapse button) -->\r\n <template v-else-if=\"column.props.expander\">\r\n <VcButton\r\n v-if=\"canExpand\"\r\n variant=\"ghost\"\r\n size=\"icon-sm\"\r\n :aria-label=\"isExpanded ? 'Collapse row' : 'Expand row'\"\r\n :aria-expanded=\"isExpanded\"\r\n :data-is-expanded=\"isExpanded\"\r\n @click.stop=\"$emit('expand-toggle', $event)\"\r\n >\r\n <VcIcon\r\n :icon=\"isExpanded ? expandedIcon : collapsedIcon\"\r\n size=\"xs\"\r\n class=\"vc-cell-renderer__expander-icon\"\r\n />\r\n </VcButton>\r\n </template>\r\n\r\n <!-- Row reorder column: empty placeholder (handle is rendered by TableRow) -->\r\n <template v-else-if=\"column.props.rowReorder\">\r\n <div class=\"vc-cell-renderer__row-reorder-placeholder\" />\r\n </template>\r\n\r\n <!-- Row editor column (Edit/Save/Cancel buttons) -->\r\n <template v-else-if=\"column.props.rowEditor\">\r\n <div class=\"vc-cell-renderer__row-editor\">\r\n <template v-if=\"isRowEditing\">\r\n <VcButton\r\n variant=\"success\"\r\n size=\"icon-sm\"\r\n @click.stop=\"$emit('row-save')\"\r\n >\r\n ✓\r\n </VcButton>\r\n <VcButton\r\n variant=\"danger\"\r\n size=\"icon-sm\"\r\n @click.stop=\"$emit('row-cancel')\"\r\n >\r\n ✕\r\n </VcButton>\r\n </template>\r\n <template v-else>\r\n <VcButton\r\n variant=\"outline\"\r\n size=\"icon-sm\"\r\n @click.stop=\"$emit('row-edit')\"\r\n >\r\n ✎\r\n </VcButton>\r\n </template>\r\n </div>\r\n </template>\r\n\r\n <!-- Editor slot (when cell or row is being edited) -->\r\n <template v-else-if=\"column.slots.editor && (isCellEditing || (isRowEditing && column.props.editable))\">\r\n <div\r\n class=\"vc-cell-renderer__editor-wrapper\"\r\n @focusout=\"handleEditorFocusOut\"\r\n @keydown=\"handleEditorKeyDown\"\r\n >\r\n <SlotProxy\r\n :slot-fn=\"column.slots.editor!\"\r\n :scope=\"{\r\n data: editingRowData,\r\n field: fieldName,\r\n index,\r\n editorCallback: handleEditorCallback,\r\n editorSaveCallback: completeEdit,\r\n editorCancelCallback: cancelEdit,\r\n }\"\r\n />\r\n </div>\r\n </template>\r\n\r\n <!-- Custom body slot from VcColumn -->\r\n <template v-else-if=\"column.slots.body || column.slots.default\">\r\n <div class=\"vc-cell-renderer__body-slot\">\r\n <SlotProxy\r\n :slot-fn=\"(column.slots.body || column.slots.default)!\"\r\n :scope=\"{\r\n data: item,\r\n field: fieldName,\r\n index,\r\n }\"\r\n />\r\n </div>\r\n </template>\r\n\r\n <!-- Type-specific cell formatters with inline editing support -->\r\n <DynamicCellRenderer\r\n v-else\r\n :type=\"column.props.type || 'text'\"\r\n :value=\"cellValue\"\r\n :editable=\"isInlineEditing\"\r\n :label=\"column.props.title || fieldName\"\r\n :field-name=\"uniqueFieldName\"\r\n :field-id=\"fieldName\"\r\n :rules=\"column.props.rules\"\r\n :row-index=\"index\"\r\n :currency=\"currency\"\r\n :format=\"column.props.format\"\r\n :variant=\"dateVariant\"\r\n :validate-on-mount=\"isNewRow && column.props.editable\"\r\n @update=\"handleCellUpdate\"\r\n @blur=\"handleCellBlur\"\r\n />\r\n</template>\r\n\r\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\r\n/**\r\n * DataTableCellRenderer - Renders cell content based on column configuration\r\n *\r\n * Handles all cell types and special columns (selection, expander, rowEditor, rowReorder).\r\n * Extracted from VcDataTable.vue to reduce template complexity.\r\n */\r\nimport { computed } from \"vue\";\r\nimport { get } from \"lodash-es\";\r\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\r\nimport TableCheckbox from \"@ui/components/organisms/vc-data-table/components/TableCheckbox.vue\";\r\nimport { VcRadioButton } from \"@ui/components/molecules/vc-radio-button\";\r\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\r\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\r\nimport DynamicCellRenderer from \"@ui/components/organisms/vc-data-table/components/cells/DynamicCellRenderer.vue\";\r\nimport { SlotProxy } from \"@ui/components/organisms/vc-data-table/components/_internal/SlotProxy\";\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Column instance from ColumnCollector */\r\n column: ColumnInstance;\r\n /** Row data item (original) */\r\n item: T;\r\n /** Row data for editing (copy from editingMeta, or same as item if not editing) */\r\n editingRowData: T;\r\n /** Row index */\r\n index: number;\r\n /** Is this cell currently being edited */\r\n isCellEditing?: boolean;\r\n /** Is this row currently being edited */\r\n isRowEditing?: boolean;\r\n /** Is this row selected */\r\n isSelected?: boolean;\r\n /** Can this row be selected */\r\n isSelectable?: boolean;\r\n /** Is this row expanded */\r\n isExpanded?: boolean;\r\n /** Whether this row is allowed to expand. When false, the expander button is hidden. */\r\n canExpand?: boolean;\r\n /** Icon for expanded state */\r\n expandedIcon?: string;\r\n /** Icon for collapsed state */\r\n collapsedIcon?: string;\r\n /** Whether this row is newly added (for eager validation) */\r\n isNewRow?: boolean;\r\n }>(),\r\n {\r\n canExpand: true,\r\n },\r\n);\r\n\r\nconst emit = defineEmits<{\r\n /** Selection checkbox changed */\r\n \"selection-change\": [value: boolean];\r\n /** Expand/collapse toggled */\r\n \"expand-toggle\": [event: Event];\r\n /** Row edit started */\r\n \"row-edit\": [];\r\n /** Row edit saved */\r\n \"row-save\": [];\r\n /** Row edit cancelled */\r\n \"row-cancel\": [];\r\n /** Cell edit completed with new value */\r\n \"edit-complete\": [value: unknown];\r\n /** Cell edit cancelled */\r\n \"edit-cancel\": [];\r\n /** Cell value changed during editing (for inline edit tracking) */\r\n \"cell-value-change\": [value: unknown];\r\n}>();\r\n\r\n/**\r\n * Editor callback - updates the value in editingRowData (the copy).\r\n * This doesn't trigger parent re-renders since editingRowData is a separate object.\r\n * Also emits cell-value-change for inline edit tracking.\r\n */\r\nconst handleEditorCallback = (value: unknown) => {\r\n const field = fieldName.value;\r\n if (field && props.editingRowData) {\r\n // Update the copy - this won't trigger re-renders of the table\r\n (props.editingRowData as Record<string, unknown>)[field] = value;\r\n }\r\n // Emit value change for inline edit dirty tracking\r\n emit(\"cell-value-change\", value);\r\n};\r\n\r\n/**\r\n * Complete editing and emit the final value.\r\n * Called when user finishes editing (blur/Enter).\r\n */\r\nconst completeEdit = () => {\r\n const field = fieldName.value;\r\n const newValue = field ? (props.editingRowData as Record<string, unknown>)[field] : undefined;\r\n emit(\"edit-complete\", newValue);\r\n};\r\n\r\n/**\r\n * Cancel editing.\r\n * Called when user presses Escape.\r\n */\r\nconst cancelEdit = () => {\r\n emit(\"edit-cancel\");\r\n};\r\n\r\n/**\r\n * Handle focusout from editor wrapper.\r\n * Completes editing when focus leaves the editor.\r\n */\r\nconst handleEditorFocusOut = (event: FocusEvent) => {\r\n // Check if focus is moving to another element within the editor\r\n const wrapper = event.currentTarget as HTMLElement;\r\n const relatedTarget = event.relatedTarget as HTMLElement | null;\r\n\r\n // If focus is staying within the wrapper, don't complete\r\n if (relatedTarget && wrapper.contains(relatedTarget)) {\r\n return;\r\n }\r\n\r\n // Focus left the editor - complete the edit\r\n completeEdit();\r\n};\r\n\r\n/**\r\n * Handle keydown in editor wrapper.\r\n * Enter = save, Escape = cancel.\r\n */\r\nconst handleEditorKeyDown = (event: KeyboardEvent) => {\r\n if (event.key === \"Enter\" && !event.shiftKey) {\r\n event.preventDefault();\r\n completeEdit();\r\n } else if (event.key === \"Escape\") {\r\n event.preventDefault();\r\n cancelEdit();\r\n }\r\n};\r\n\r\n// Field name from column\r\nconst fieldName = computed(() => props.column.props.field || props.column.props.id);\r\n\r\n// Unique field name for VeeValidate (includes row index to prevent conflicts)\r\nconst uniqueFieldName = computed(() => `${fieldName.value}_${props.index}`);\r\n\r\n// Check if this cell should be in inline editing mode\r\n// This is true when:\r\n// 1. Cell-level editing (isCellEditing) OR\r\n// 2. Row-level editing (isRowEditing) AND column is marked as editable\r\n// AND no custom editor slot is provided (custom editors handle their own rendering)\r\nconst isInlineEditing = computed(() => {\r\n if (props.column.slots.editor) return false; // Custom editor handles its own rendering\r\n return props.isCellEditing || (props.isRowEditing && props.column.props.editable);\r\n});\r\n\r\n// Get cell value using lodash _.get for nested fields\r\nconst cellValue = computed(() => {\r\n return get(props.item, fieldName.value || \"\");\r\n});\r\n\r\n// Currency for money cells\r\nconst currency = computed(() => {\r\n const field = props.column.props.currencyField || \"currency\";\r\n return ((props.item as Record<string, unknown>)[field] as string) || \"USD\";\r\n});\r\n\r\n// Date variant based on column type\r\nconst dateVariant = computed<\"date\" | \"time\" | \"date-time\">(() => {\r\n const type = props.column.props.type;\r\n if (type === \"time\") return \"time\";\r\n if (type === \"datetime\") return \"date-time\";\r\n return \"date\";\r\n});\r\n\r\n/**\r\n * Handle cell update from Cell components (CellDefault, CellMoney, CellNumber).\r\n * Updates editingRowData and emits cell-value-change for dirty tracking.\r\n */\r\nconst handleCellUpdate = (payload: { field: string; value: unknown }) => {\r\n const field = fieldName.value;\r\n if (field && props.editingRowData) {\r\n (props.editingRowData as Record<string, unknown>)[field] = payload.value;\r\n }\r\n emit(\"cell-value-change\", payload.value);\r\n};\r\n\r\n/**\r\n * Handle blur from Cell components.\r\n * Can be used for additional logic if needed.\r\n */\r\nconst handleCellBlur = (_payload: { row: number | undefined; field: string }) => {\r\n // Complete edit on blur when using DynamicCellRenderer path (no custom #editor slot):\r\n // 1. Cell editing mode (isCellEditing) — single cell click-to-edit\r\n // 2. Inline editing mode (isRowEditing && editable) — all editable cells always active\r\n if (!props.column.slots.editor && (props.isCellEditing || (props.isRowEditing && props.column.props.editable))) {\r\n completeEdit();\r\n }\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n.vc-cell-renderer {\r\n &__body-slot {\r\n @apply tw-w-full tw-min-w-0 tw-overflow-hidden;\r\n\r\n // Constrain custom slot roots to cell width for truncation/clamp,\r\n // without forcing stretch — components with intrinsic sizes (e.g. VcImage) keep their own width.\r\n > * {\r\n min-width: 0 !important;\r\n max-width: 100% !important;\r\n }\r\n\r\n // Allow nested flex/text containers inside custom cells to shrink and truncate.\r\n > * * {\r\n min-width: 0;\r\n }\r\n\r\n // Common case for custom status-like cells (e.g. VcStatus in body slot):\r\n // force the badge container to follow cell width so internal truncate can show ellipsis.\r\n .vc-status {\r\n width: 100% !important;\r\n max-width: 100% !important;\r\n }\r\n\r\n .vc-status__content {\r\n min-width: 0 !important;\r\n }\r\n }\r\n\r\n &__editor-wrapper {\r\n @apply tw-w-full tw-h-full;\r\n }\r\n\r\n &__default-editor {\r\n @apply tw-w-full tw-h-8 tw-px-2 tw-py-1 tw-text-sm tw-border tw-rounded;\r\n @apply tw-border-primary-300 tw-outline-none;\r\n @apply focus:tw-border-primary-500 focus:tw-ring-1 focus:tw-ring-primary-200;\r\n }\r\n\r\n &__expander-icon {\r\n @apply tw-text-neutrals-500 tw-text-xs;\r\n }\r\n\r\n &__drag-handle {\r\n @apply tw-cursor-grab tw-text-neutrals-400;\r\n @apply hover:tw-text-neutrals-600;\r\n }\r\n\r\n &__row-editor {\r\n @apply tw-flex tw-gap-1 tw-justify-center tw-items-center;\r\n }\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"vc-data-table__row-wrapper\">\r\n <!-- Group header (before main row, only for first item in group) -->\r\n <TableGroupRow\r\n v-if=\"groupingEnabled && isFirstInGroup\"\r\n :group-key=\"groupKey ?? ''\"\r\n :count=\"groupCount ?? 0\"\r\n :expandable=\"expandableRowGroups\"\r\n :expanded=\"isGroupRowExpanded\"\r\n @toggle=\"handleGroupToggle\"\r\n >\r\n <slot\r\n name=\"groupheader\"\r\n :data=\"item\"\r\n :index=\"index\"\r\n >\r\n <span class=\"vc-data-table__group-label\">{{ groupKey }}</span>\r\n <span class=\"vc-data-table__group-count\">({{ groupCount }})</span>\r\n </slot>\r\n </TableGroupRow>\r\n\r\n <!-- Main row (hidden when group is collapsed) -->\r\n <TableRow\r\n v-if=\"!groupingEnabled || !expandableRowGroups || isGroupRowExpanded\"\r\n :selected=\"isSelected\"\r\n :active=\"isActive\"\r\n :reorderable=\"reorderable\"\r\n :show-drag-handle=\"showDragHandle\"\r\n :index=\"index\"\r\n :clickable=\"true\"\r\n :actions-position=\"actionsPosition\"\r\n :class=\"rowClass\"\r\n @click=\"handleRowClick\"\r\n @space-press=\"handleRowSpacePress\"\r\n @mouseenter=\"handleRowMouseEnter\"\r\n @mouseleave=\"handleRowMouseLeave\"\r\n >\r\n <!-- Selection control (only if NOT defined via VcColumn) -->\r\n <!-- @click.stop prevents checkbox/radio click from bubbling to row-click -->\r\n <TableCell\r\n v-if=\"showSelectionCell\"\r\n class=\"vc-data-table__selection-cell\"\r\n :line-clamp=\"0\"\r\n @click.stop\r\n >\r\n <TableCheckbox\r\n v-if=\"selectionMode === 'multiple'\"\r\n :model-value=\"isSelected\"\r\n :disabled=\"!isSelectable\"\r\n @update:model-value=\"handleSelectionChange\"\r\n />\r\n <VcRadioButton\r\n v-else\r\n :model-value=\"isSelected ?? false\"\r\n :value=\"true\"\r\n :disabled=\"!isSelectable\"\r\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.SELECT_ROW')\"\r\n @update:model-value=\"handleSelectionChange($event === true)\"\r\n />\r\n </TableCell>\r\n\r\n <!-- Data cells -->\r\n <TableCell\r\n v-for=\"col in columns\"\r\n :key=\"col.props.id\"\r\n :column-id=\"col.props.id\"\r\n :width=\"getColumnWidth(col.props)\"\r\n :align=\"getCellAlign(col.props)\"\r\n :cell-class=\"col.props.bodyClass\"\r\n :line-clamp=\"col.props.lineClamp\"\r\n :style=\"getCellStyle(col.props)\"\r\n @click=\"handleCellClick(col)\"\r\n >\r\n <DataTableCellRenderer\r\n :column=\"col\"\r\n :item=\"item\"\r\n :editing-row-data=\"editingRowData\"\r\n :index=\"index\"\r\n :is-cell-editing=\"isCellEditing(index, col.props.field || col.props.id)\"\r\n :is-row-editing=\"isRowEditing || isInlineEditing\"\r\n :is-selected=\"isSelected\"\r\n :is-selectable=\"isSelectable\"\r\n :is-expanded=\"isExpanded\"\r\n :can-expand=\"expandable\"\r\n :expanded-icon=\"expandedIcon\"\r\n :collapsed-icon=\"collapsedIcon\"\r\n :is-new-row=\"isNewRow\"\r\n @selection-change=\"handleCellSelectionChange\"\r\n @expand-toggle=\"handleExpandToggle\"\r\n @row-edit=\"handleRowEdit\"\r\n @row-save=\"handleRowSave\"\r\n @row-cancel=\"handleRowCancel\"\r\n @edit-complete=\"handleEditComplete(col.props.field || col.props.id, $event)\"\r\n @edit-cancel=\"handleEditCancel(col.props.field || col.props.id)\"\r\n @cell-value-change=\"handleCellValueChange(col.props.field || col.props.id, $event)\"\r\n />\r\n </TableCell>\r\n\r\n <!-- Row Actions (hover-visible) - use named slot for proper positioning -->\r\n <template\r\n v-if=\"hasActions\"\r\n #actions\r\n >\r\n <slot name=\"actions\" />\r\n </template>\r\n </TableRow>\r\n\r\n <!-- Expansion row (immediately after parent row, also hidden when group is collapsed) -->\r\n <div\r\n v-if=\"expandable && isExpanded && (!groupingEnabled || !expandableRowGroups || isGroupRowExpanded)\"\r\n class=\"vc-data-table__expansion-row\"\r\n >\r\n <div class=\"vc-data-table__expansion-content\">\r\n <slot name=\"expansion\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Group footer (after last row in group) -->\r\n <div\r\n v-if=\"groupingEnabled && isLastInGroup && $slots.groupfooter && (!expandableRowGroups || isGroupRowExpanded)\"\r\n class=\"vc-data-table__group-footer\"\r\n >\r\n <slot\r\n name=\"groupfooter\"\r\n :data=\"item\"\r\n :index=\"index\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\r\n/**\r\n * DataTableRow - Reusable row rendering component for VcDataTable\r\n *\r\n * Extracts duplicated row rendering logic from VcDataTable.vue to provide\r\n * a single, unified component for rendering both grouped and non-grouped rows.\r\n *\r\n * Features:\r\n * - Selection (checkbox for multiple, radio for single)\r\n * - Cell rendering via DataTableCellRenderer\r\n * - Row actions slot\r\n * - Row reorder drag handles\r\n * - Row expansion support\r\n * - Inline editing support\r\n * - Group header/footer rendering (when grouping is enabled)\r\n */\r\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\r\nimport type { VcColumnProps } from \"@ui/components/organisms/vc-data-table/types\";\r\nimport TableRow from \"@ui/components/organisms/vc-data-table/components/TableRow.vue\";\r\nimport TableCell from \"@ui/components/organisms/vc-data-table/components/TableCell.vue\";\r\nimport TableCheckbox from \"@ui/components/organisms/vc-data-table/components/TableCheckbox.vue\";\r\nimport TableGroupRow from \"@ui/components/organisms/vc-data-table/components/TableGroupRow.vue\";\r\nimport DataTableCellRenderer from \"@ui/components/organisms/vc-data-table/components/DataTableCellRenderer.vue\";\r\nimport { VcRadioButton } from \"@ui/components/molecules/vc-radio-button\";\r\n\r\n// Props interface\r\nconst props = defineProps<{\r\n /** Row data item */\r\n item: T;\r\n /** Row index in the data array */\r\n index: number;\r\n /** Column instances from ColumnCollector */\r\n columns: ColumnInstance[];\r\n\r\n // === Selection ===\r\n /** Whether this row is selected */\r\n isSelected?: boolean;\r\n /** Whether this row is the active (highlighted) row */\r\n isActive?: boolean;\r\n /** Whether this row can be selected */\r\n isSelectable?: boolean;\r\n /** Selection mode: 'single' or 'multiple' */\r\n selectionMode?: \"single\" | \"multiple\";\r\n /** Whether to show selection cell (checkbox/radio) */\r\n showSelectionCell?: boolean;\r\n\r\n // === Reorder ===\r\n /** Whether row reordering is enabled */\r\n reorderable?: boolean;\r\n /** Whether to show drag handle icon */\r\n showDragHandle?: boolean;\r\n\r\n // === Expansion ===\r\n /** Whether row expansion is enabled */\r\n expandable?: boolean;\r\n /** Whether this row is expanded */\r\n isExpanded?: boolean;\r\n /** Icon for expanded state */\r\n expandedIcon?: string;\r\n /** Icon for collapsed state */\r\n collapsedIcon?: string;\r\n\r\n // === Editing ===\r\n /** Row data for editing (copy from editingMeta, or same as item if not editing) */\r\n editingRowData: T;\r\n /** Whether this row is currently being edited */\r\n isRowEditing?: boolean;\r\n /** Whether inline editing mode is active for the table */\r\n isInlineEditing?: boolean;\r\n /** Function to check if a specific cell is being edited */\r\n isCellEditing: (rowIndex: number, field: string) => boolean;\r\n /** Whether this row is newly added (for eager validation) */\r\n isNewRow?: boolean;\r\n\r\n // === Actions ===\r\n /** Whether this row has actions to display */\r\n hasActions?: boolean;\r\n /** Position of row actions: overlay (absolute) or column (fixed zone) */\r\n actionsPosition?: \"overlay\" | \"column\";\r\n\r\n // === Column helpers ===\r\n /** Function to get effective column width */\r\n getColumnWidth: (colProps: VcColumnProps) => string | undefined;\r\n /** Function to get cell alignment */\r\n getCellAlign: (colProps: VcColumnProps) => \"left\" | \"center\" | \"right\" | undefined;\r\n /** Function to get cell style */\r\n getCellStyle: (colProps: VcColumnProps) => Record<string, string> | object | undefined;\r\n\r\n // === Custom class ===\r\n /** Additional row classes (e.g., for dragging state, user-provided rowClass) */\r\n rowClass?: string | Record<string, boolean> | (string | Record<string, boolean> | undefined)[];\r\n\r\n // === Grouping ===\r\n /** Whether grouping is enabled */\r\n groupingEnabled?: boolean;\r\n /** Group key for this row */\r\n groupKey?: string;\r\n /** Whether this row is the first in its group */\r\n isFirstInGroup?: boolean;\r\n /** Whether this row is the last in its group */\r\n isLastInGroup?: boolean;\r\n /** Number of items in the group (only meaningful for first item) */\r\n groupCount?: number;\r\n /** Whether row groups are expandable */\r\n expandableRowGroups?: boolean;\r\n /** Whether this row's group is currently expanded */\r\n isGroupRowExpanded?: boolean;\r\n}>();\r\n\r\n// Emits\r\nconst emit = defineEmits<{\r\n /** Row clicked */\r\n click: [event: MouseEvent];\r\n /** Mouse entered row */\r\n mouseenter: [index: number];\r\n /** Mouse left row */\r\n mouseleave: [];\r\n /** Selection changed (from selection cell) */\r\n \"selection-change\": [value?: boolean];\r\n /** Expand/collapse toggled */\r\n \"expand-toggle\": [event: Event];\r\n /** Row edit started */\r\n \"row-edit\": [];\r\n /** Row edit saved */\r\n \"row-save\": [];\r\n /** Row edit cancelled */\r\n \"row-cancel\": [];\r\n /** Cell edit completed */\r\n \"edit-complete\": [field: string, value: unknown];\r\n /** Cell edit cancelled */\r\n \"edit-cancel\": [field: string];\r\n /** Cell value changed during editing */\r\n \"cell-value-change\": [field: string, value: unknown];\r\n /** Cell clicked */\r\n \"cell-click\": [col: ColumnInstance];\r\n /** Group expansion toggled */\r\n \"group-toggle\": [event: Event];\r\n}>();\r\n\r\n// Event handlers\r\n\r\nconst handleRowClick = (event: MouseEvent) => {\r\n // Skip row-click if click originated from a selection control (checkbox/radio)\r\n const target = event.target as HTMLElement;\r\n if (target?.closest(\".vc-data-table__selection-cell, .vc-table-composition__checkbox, .vc-radio-button\")) {\r\n return;\r\n }\r\n emit(\"click\", event);\r\n};\r\n\r\nconst handleRowSpacePress = (_event: KeyboardEvent) => {\r\n // Space routes to selection toggle only — never triggers row click / blade navigation\r\n if (props.selectionMode === \"multiple\" && props.showSelectionCell) {\r\n emit(\"selection-change\", !props.isSelected);\r\n }\r\n};\r\n\r\nconst handleRowMouseEnter = () => {\r\n emit(\"mouseenter\", props.index);\r\n};\r\n\r\nconst handleRowMouseLeave = () => {\r\n emit(\"mouseleave\");\r\n};\r\n\r\nconst handleSelectionChange = (value?: boolean) => {\r\n emit(\"selection-change\", value);\r\n};\r\n\r\nconst handleCellSelectionChange = (value: boolean) => {\r\n emit(\"selection-change\", value);\r\n};\r\n\r\nconst handleExpandToggle = (event: Event) => {\r\n emit(\"expand-toggle\", event);\r\n};\r\n\r\nconst handleRowEdit = () => {\r\n emit(\"row-edit\");\r\n};\r\n\r\nconst handleRowSave = () => {\r\n emit(\"row-save\");\r\n};\r\n\r\nconst handleRowCancel = () => {\r\n emit(\"row-cancel\");\r\n};\r\n\r\nconst handleEditComplete = (field: string, value: unknown) => {\r\n emit(\"edit-complete\", field, value);\r\n};\r\n\r\nconst handleEditCancel = (field: string) => {\r\n emit(\"edit-cancel\", field);\r\n};\r\n\r\nconst handleCellValueChange = (field: string, value: unknown) => {\r\n emit(\"cell-value-change\", field, value);\r\n};\r\n\r\nconst handleCellClick = (col: ColumnInstance) => {\r\n emit(\"cell-click\", col);\r\n};\r\n\r\nconst handleGroupToggle = (event: Event) => {\r\n emit(\"group-toggle\", event);\r\n};\r\n</script>\r\n","<template>\n <div class=\"vc-data-table__skeleton\">\n <!-- Column-aware skeleton when columns are available -->\n <template v-if=\"columns.length > 0\">\n <TableRow\n v-for=\"rowIndex in rows\"\n :key=\"rowIndex\"\n >\n <TableCell\n v-if=\"showSelectionCell\"\n class=\"vc-data-table__selection-cell\"\n :line-clamp=\"0\"\n >\n <VcSkeleton\n variant=\"circle\"\n width=\"18px\"\n height=\"18px\"\n />\n </TableCell>\n <TableCell\n v-for=\"col in columns\"\n :key=\"col.props.id\"\n :width=\"getColumnWidth(col.props)\"\n :style=\"getCellStyle(col.props)\"\n :line-clamp=\"0\"\n >\n <VcSkeleton v-bind=\"getSkeletonProps(col.props, rowIndex)\" />\n </TableCell>\n </TableRow>\n </template>\n\n <!-- Fallback: simple full-width skeleton rows when columns aren't parsed yet -->\n <div\n v-for=\"rowIndex in rows\"\n v-else\n :key=\"`fallback-${rowIndex}`\"\n class=\"vc-data-table__skeleton-fallback-row\"\n >\n <VcSkeleton\n variant=\"block\"\n :width=\"ROW_WIDTHS[(rowIndex - 1) % ROW_WIDTHS.length]\"\n height=\"16px\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * TableSkeletonRows — renders skeleton placeholder rows matching\n * the real column layout. Each cell gets a VcSkeleton shaped by\n * column type (image → square, status → badge, text → line, etc.).\n */\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\nimport type { VcColumnProps } from \"@ui/components/organisms/vc-data-table/types\";\nimport TableRow from \"@ui/components/organisms/vc-data-table/components/TableRow.vue\";\nimport TableCell from \"@ui/components/organisms/vc-data-table/components/TableCell.vue\";\nimport VcSkeleton from \"@ui/components/atoms/vc-skeleton/vc-skeleton.vue\";\n\ndefineProps<{\n /** Visible columns to render skeleton cells for */\n columns: ColumnInstance[];\n /** Number of skeleton rows */\n rows: number;\n /** Column width resolver (same as used by real rows) */\n getColumnWidth: (col: VcColumnProps) => string | undefined;\n /** Cell style resolver (handles special columns: selection, expander, etc.) */\n getCellStyle: (col: VcColumnProps) => object | undefined;\n /** Whether to show a selection cell (checkbox/radio) before data cells */\n showSelectionCell?: boolean;\n}>();\n\n// Pseudo-random width per row index to avoid uniform look\nconst ROW_WIDTHS = [\"95%\", \"80%\", \"88%\", \"72%\", \"90%\"];\n\nfunction getSkeletonProps(\n col: VcColumnProps,\n _rowIndex: number,\n): { variant: \"block\" | \"circle\"; width?: string; height?: string } {\n const type = col.type || \"text\";\n\n // Special columns: selection checkbox, expander, row reorder\n if (col.selectionMode) {\n return { variant: \"circle\", width: \"18px\", height: \"18px\" };\n }\n if (col.expander || col.rowReorder || col.rowEditor) {\n return { variant: \"block\", width: \"20px\", height: \"20px\" };\n }\n\n // Cell handles column width via getColumnWidth — skeleton fills the cell\n switch (type) {\n case \"image\":\n return { variant: \"block\", width: \"36px\", height: \"36px\" };\n case \"status\":\n case \"status-icon\":\n return { variant: \"block\", width: \"100%\", height: \"22px\" };\n default:\n return { variant: \"block\", width: \"100%\", height: \"16px\" };\n }\n}\n</script>\n\n<style lang=\"scss\">\n.vc-data-table__skeleton {\n @apply tw-flex tw-flex-col tw-flex-auto tw-overflow-hidden;\n}\n\n.vc-data-table__skeleton-fallback-row {\n @apply tw-px-4 tw-py-[10px];\n}\n</style>\n","<template>\n <div\n class=\"vc-data-table__body\"\n :role=\"items.length ? 'rowgroup' : 'presentation'\"\n @scroll=\"$emit('scroll', $event)\"\n >\n <!-- Empty state (wrapped as a single row/cell so it is valid inside role=\"table\";\n display:contents keeps the wrappers layout-transparent) -->\n <div\n v-if=\"items.length === 0 && !loading\"\n role=\"row\"\n style=\"display: contents\"\n >\n <div\n role=\"cell\"\n style=\"display: contents\"\n >\n <slot name=\"empty\">\n <TableEmpty\n :icon=\"emptyIcon\"\n :title=\"emptyTitle\"\n :description=\"emptyDescription\"\n :action-label=\"emptyActionLabel\"\n :action-handler=\"emptyActionHandler\"\n />\n </slot>\n </div>\n </div>\n\n <!-- Loading state — skeleton rows matching column layout -->\n <template v-else-if=\"loading && items.length === 0\">\n <slot name=\"loading\">\n <TableSkeletonRows\n :columns=\"columns\"\n :rows=\"skeletonRows\"\n :get-column-width=\"getColumnWidth\"\n :get-cell-style=\"getCellStyle\"\n :show-selection-cell=\"showSelectionCell\"\n />\n </slot>\n </template>\n\n <!-- Rows — single unified loop for both grouped and non-grouped modes -->\n <TransitionGroup\n v-else\n ref=\"rowsContainerRef\"\n tag=\"div\"\n role=\"presentation\"\n name=\"vc-table-row-swap\"\n class=\"vc-data-table__rows-container\"\n >\n <DataTableRow\n v-for=\"(item, index) in iterationItems\"\n :key=\"getItemKey(item, index)\"\n v-bind=\"getRowProps(item, getEffectiveIndex(item, index))\"\n :is-new-row=\"newRowIndices?.has(getEffectiveIndex(item, index))\"\n :grouping-enabled=\"groupingEnabled\"\n :group-key=\"groupingEnabled ? getGroupKey(item) : undefined\"\n :is-first-in-group=\"groupingEnabled ? isFirstInGroup(index) : false\"\n :is-last-in-group=\"groupingEnabled ? isLastInGroup(index) : false\"\n :group-count=\"groupingEnabled && isFirstInGroup(index) ? (groupCountMap?.get(getGroupKey(item)) ?? 0) : 0\"\n :expandable-row-groups=\"expandableRowGroups\"\n :is-group-row-expanded=\"groupingEnabled ? isGroupExpanded(getGroupKey(item)) : true\"\n @click=\"(e) => handleRowClick(item, getEffectiveIndex(item, index), e)\"\n @mouseenter=\"handleRowMouseEnter\"\n @mouseleave=\"handleRowMouseLeave\"\n @selection-change=\"() => handleRowSelectionChange(item)\"\n @expand-toggle=\"(e) => handleExpandToggle(item, getEffectiveIndex(item, index), e)\"\n @row-edit=\"() => handleRowEdit(item, getEffectiveIndex(item, index))\"\n @row-save=\"() => handleRowSave(item, getEffectiveIndex(item, index))\"\n @row-cancel=\"() => handleRowCancel(item, getEffectiveIndex(item, index))\"\n @edit-complete=\"(field, value) => handleEditComplete(item, field, getEffectiveIndex(item, index), value)\"\n @edit-cancel=\"(field) => handleEditCancel(item, field, getEffectiveIndex(item, index))\"\n @cell-value-change=\"(field, value) => handleCellValueChange(field, getEffectiveIndex(item, index), value)\"\n @cell-click=\"\n (col) => handleCellClick(item, col.props.field || col.props.id, getEffectiveIndex(item, index), col)\n \"\n @group-toggle=\"(e) => handleGroupToggle(getGroupKey(item), e)\"\n >\n <template #actions>\n <slot\n name=\"row-actions\"\n :item=\"item\"\n :index=\"getEffectiveIndex(item, index)\"\n />\n </template>\n <template #expansion>\n <slot\n name=\"expansion\"\n :data=\"item\"\n :index=\"getEffectiveIndex(item, index)\"\n />\n </template>\n <template #groupheader=\"slotProps\">\n <slot\n name=\"groupheader\"\n v-bind=\"slotProps\"\n />\n </template>\n <template #groupfooter=\"slotProps\">\n <slot\n name=\"groupfooter\"\n v-bind=\"slotProps\"\n />\n </template>\n </DataTableRow>\n </TransitionGroup>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * DataTableBody - Reusable body rendering component for VcDataTable\n *\n * Extracts body rendering logic from VcDataTable.vue to provide\n * a single, unified component for rendering table body content.\n *\n * Note: This is an internal sub-component of VcDataTable. It does NOT declare\n * its own generic — instead it uses Record<string, any> for item types.\n * Type safety is enforced at the VcDataTable level (which has generic=\"T\").\n * This avoids vue-tsc generic unification issues between parent and child.\n *\n * Features:\n * - Empty and loading states\n * - Unified row loop for both grouped and non-grouped modes\n * - Group context (header/footer) passed as props to DataTableRow\n * - Row click, selection, editing events\n * - Drag & drop for row reorder\n * - Slots for actions, expansion, group header/footer\n */\nimport { computed, ref, type ComponentPublicInstance } from \"vue\";\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\nimport type { VcColumnProps } from \"@ui/components/organisms/vc-data-table/types\";\nimport type { GroupedData } from \"@ui/components/organisms/vc-data-table/composables/useTableRowGrouping\";\nimport DataTableRow from \"@ui/components/organisms/vc-data-table/components/DataTableRow.vue\";\nimport TableEmpty from \"@ui/components/organisms/vc-data-table/components/TableEmpty.vue\";\nimport TableSkeletonRows from \"@ui/components/organisms/vc-data-table/components/_internal/TableSkeletonRows.vue\";\n\n/**\n * Base item type — actual generic enforcement happens in VcDataTable.\n * Uses `any` (not Record<string, any>) because TypeScript doesn't allow\n * Record<string, any> → T assignment even when T extends Record<string, any>.\n * This is safe: DataTableBody is an internal sub-component only used by VcDataTable.\n */\n\ntype Item = any;\n\n// Row props return type (mirrors getRowProps in VcDataTable)\n// This matches DataTableRow props exactly - exported for external use\nexport interface RowProps<T> {\n item: T;\n index: number;\n columns: ColumnInstance[];\n isSelected: boolean;\n isActive: boolean;\n isSelectable: boolean;\n selectionMode?: \"single\" | \"multiple\";\n showSelectionCell: boolean;\n reorderable: boolean;\n showDragHandle: boolean;\n expandable: boolean;\n isExpanded: boolean;\n expandedIcon: string;\n collapsedIcon: string;\n editingRowData: T; // DataTableRow requires T, not T | null\n isRowEditing: boolean;\n isInlineEditing: boolean;\n isCellEditing: (rowIndex: number, field: string) => boolean; // Match DataTableRow signature\n hasActions: boolean;\n actionsPosition: \"overlay\" | \"column\";\n getColumnWidth: (colProps: VcColumnProps) => string | undefined;\n getCellAlign: (colProps: VcColumnProps) => \"left\" | \"center\" | \"right\" | undefined;\n getCellStyle: (colProps: VcColumnProps) => Record<string, string> | object | undefined;\n rowClass?: string | Record<string, boolean> | (string | Record<string, boolean> | undefined)[];\n}\n\n// Props\nconst props = defineProps<{\n /** Items to render */\n items: Item[];\n /** Loading state */\n loading?: boolean;\n /** Empty state title */\n emptyTitle?: string;\n /** Empty state description */\n emptyDescription?: string;\n /** Empty state icon */\n emptyIcon?: string;\n /** Empty state action button label */\n emptyActionLabel?: string;\n /** Empty state action button handler */\n emptyActionHandler?: () => void;\n /** Loading text (kept for custom loading slot consumers) */\n loadingText?: string;\n /** Number of skeleton rows to show during loading */\n skeletonRows?: number;\n /** Visible columns (for skeleton rendering) */\n columns: ColumnInstance[];\n /** Column width resolver (for skeleton rendering) */\n getColumnWidth: (col: VcColumnProps) => string | undefined;\n /** Cell style resolver (for skeleton rendering) */\n getCellStyle: (col: VcColumnProps) => object | undefined;\n /** Whether selection cell (checkbox) is shown */\n showSelectionCell?: boolean;\n\n // === Grouping ===\n /** Whether grouping is enabled */\n groupingEnabled?: boolean;\n /** Grouped data */\n groupedData?: GroupedData<Item>[];\n /** Whether row groups are expandable */\n expandableRowGroups?: boolean;\n /** Function to check if group is expanded */\n isGroupExpanded: (key: string) => boolean;\n /** Function to get the group key for an item */\n getItemGroupKey?: (item: Item) => string;\n /** Function to get global index of an item */\n getGlobalIndex: (item: Item) => number;\n /** Function to get item key */\n getItemKey: (item: Item, index: number) => string | number;\n /** Function to build row props */\n getRowProps: (item: Item, index: number) => RowProps<Item>;\n /** Set of indices of newly added rows */\n newRowIndices?: Set<number>;\n}>();\n\n// Emits - matches DataTableRow emit signatures\nconst emit = defineEmits<{\n /** Scroll event from body container */\n scroll: [event: Event];\n /** Group expansion toggled */\n \"group-toggle\": [key: string, event?: Event];\n /** Row clicked */\n \"row-click\": [item: Item, index: number, event: MouseEvent];\n /** Row mouse enter (DataTableRow emits index) */\n \"row-mouseenter\": [index: number];\n /** Row mouse leave (DataTableRow emits nothing) */\n \"row-mouseleave\": [];\n /** Row selection changed */\n \"selection-change\": [item: Item];\n /** Row expand toggled */\n \"expand-toggle\": [item: Item, index: number, event?: Event];\n /** Row edit started */\n \"row-edit\": [item: Item, index: number];\n /** Row save */\n \"row-save\": [item: Item, index: number];\n /** Row cancel */\n \"row-cancel\": [item: Item, index: number];\n /** Cell edit completed */\n \"edit-complete\": [item: Item, field: string, index: number, value: unknown];\n /** Cell edit cancelled */\n \"edit-cancel\": [item: Item, field: string, index: number];\n /** Cell value changed */\n \"cell-value-change\": [field: string, index: number, value: unknown];\n /** Cell clicked */\n \"cell-click\": [item: Item, field: string, index: number, column: ColumnInstance];\n}>();\n\n// ============================================================================\n// Skeleton helpers\n// ============================================================================\n\nconst skeletonRows = computed(() => props.skeletonRows ?? 20);\n\n// ============================================================================\n// Grouping computed helpers\n// ============================================================================\n\n/** Flatten grouped data to maintain group ordering when grouping is enabled */\nconst iterationItems = computed<Item[]>(() => {\n if (props.groupingEnabled && props.groupedData?.length) {\n return props.groupedData.flatMap((g) => g.items);\n }\n return props.items;\n});\n\n/** Group count lookup map (groupKey -> count) */\nconst groupCountMap = computed<Map<string, number> | null>(() => {\n if (!props.groupedData) return null;\n const map = new Map<string, number>();\n for (const g of props.groupedData) {\n map.set(g.key, g.count);\n }\n return map;\n});\n\n/** Get the group key for an item */\nconst getGroupKey = (item: Item): string => props.getItemGroupKey?.(item) ?? \"\";\n\n/** Check if item at index is the first in its group (adjacent comparison) */\nconst isFirstInGroup = (index: number): boolean =>\n index === 0 || getGroupKey(iterationItems.value[index]) !== getGroupKey(iterationItems.value[index - 1]);\n\n/** Check if item at index is the last in its group (adjacent comparison) */\nconst isLastInGroup = (index: number): boolean =>\n index === iterationItems.value.length - 1 ||\n getGroupKey(iterationItems.value[index]) !== getGroupKey(iterationItems.value[index + 1]);\n\n/** Get the effective index for an item (global index for grouped, local index for non-grouped) */\nconst getEffectiveIndex = (item: Item, localIndex: number): number => {\n if (props.groupingEnabled) {\n return props.getGlobalIndex(item);\n }\n return localIndex;\n};\n\n// ============================================================================\n// Event handlers - delegate to parent (match DataTableRow signatures)\n// ============================================================================\n\nconst handleGroupToggle = (key: string, e?: Event) => emit(\"group-toggle\", key, e);\nconst handleRowClick = (item: Item, index: number, e: MouseEvent) => emit(\"row-click\", item, index, e);\nconst handleRowMouseEnter = (index: number) => emit(\"row-mouseenter\", index);\nconst handleRowMouseLeave = () => emit(\"row-mouseleave\");\nconst handleRowSelectionChange = (item: Item) => emit(\"selection-change\", item);\nconst handleExpandToggle = (item: Item, index: number, e?: Event) => emit(\"expand-toggle\", item, index, e);\nconst handleRowEdit = (item: Item, index: number) => emit(\"row-edit\", item, index);\nconst handleRowSave = (item: Item, index: number) => emit(\"row-save\", item, index);\nconst handleRowCancel = (item: Item, index: number) => emit(\"row-cancel\", item, index);\nconst handleEditComplete = (item: Item, field: string, index: number, value: unknown) =>\n emit(\"edit-complete\", item, field, index, value);\nconst handleEditCancel = (item: Item, field: string, index: number) => emit(\"edit-cancel\", item, field, index);\nconst handleCellValueChange = (field: string, index: number, value: unknown) =>\n emit(\"cell-value-change\", field, index, value);\nconst handleCellClick = (item: Item, field: string, index: number, column: ColumnInstance) =>\n emit(\"cell-click\", item, field, index, column);\n\n// ============================================================================\n// Rows container ref — exposed for SortableJS attachment\n// ============================================================================\n\nconst rowsContainerRef = ref<ComponentPublicInstance | null>(null);\nconst listEl = computed<HTMLElement | undefined>(() => {\n // The rows container is a <TransitionGroup tag=\"div\">; its rendered root <div> is `$el`.\n return (rowsContainerRef.value?.$el as HTMLElement) ?? undefined;\n});\n\n/**\n * Exposed for SortableJS attachment (row reorder). This is the live rows-container element.\n * Consumers MUST `watch` it (not read once) — the `<TransitionGroup>` is recreated when the\n * body toggles between rows/empty/loading states, so the element changes and SortableJS must\n * be re-attached. `useTableRowReorder` already handles this via a `watch(listEl, …)`.\n */\ndefineExpose({ listEl });\n</script>\n\n<style lang=\"scss\">\n.vc-data-table__body {\n @apply tw-flex tw-flex-col tw-overflow-y-auto tw-flex-auto tw-min-h-0;\n}\n\n.vc-data-table__rows-container {\n @apply tw-flex tw-flex-col;\n}\n\n.vc-data-table__group-label {\n @apply tw-font-medium;\n}\n\n.vc-data-table__group-count {\n @apply tw-ml-1 tw-text-neutrals-500;\n}\n\n.vc-data-table__group-footer {\n @apply tw-px-4 tw-py-2 tw-bg-neutrals-50;\n}\n\n/* Row swap animation */\n.vc-table-row-swap-move {\n transition: transform 0.3s ease;\n}\n</style>\n","<template>\n <VcTooltip\n class=\"vc-data-table__header-title\"\n :disabled=\"!isTruncated\"\n placement=\"top\"\n >\n <span\n ref=\"textEl\"\n class=\"vc-data-table__header-title-text\"\n >\n <span\n v-if=\"isEditing && required\"\n class=\"tw-text-danger-500 tw-mr-0.5\"\n aria-hidden=\"true\"\n >*</span\n >{{ title }}</span\n >\n <template #tooltip>\n {{ title }}\n </template>\n </VcTooltip>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * HeaderTitle - default column header title with a \"truncation tooltip\".\n *\n * The title text is clipped with an ellipsis when the column is too narrow.\n * To let users read the full name without widening the column, a styled\n * VcTooltip is shown on hover — but only while the text is actually truncated.\n *\n * Truncation is detected reactively via ResizeObserver (compares scrollWidth\n * vs clientWidth), so it stays correct as columns are resized. This avoids the\n * race that an on-hover check would have with VcTooltip's own mouseenter, which\n * reads the `disabled` prop synchronously.\n */\nimport { ref, watch } from \"vue\";\nimport { useResizeObserver } from \"@vueuse/core\";\nimport { VcTooltip } from \"@ui/components/atoms\";\n\nconst props = defineProps<{\n /** Column title text */\n title?: string;\n /** Whether the column is required (shows a `*` marker while editing) */\n required?: boolean;\n /** Whether the table is in inline editing mode */\n isEditing?: boolean;\n}>();\n\nconst textEl = ref<HTMLElement | null>(null);\nconst isTruncated = ref(false);\n\nconst checkTruncation = () => {\n const el = textEl.value;\n isTruncated.value = !!el && el.scrollWidth > el.clientWidth;\n};\n\n// Width changes (column resize) re-trigger the observer.\nuseResizeObserver(textEl, checkTruncation);\n// Content changes (title / required marker) don't always change the box size,\n// so re-check explicitly after the DOM updates.\nwatch(\n () => [props.title, props.required, props.isEditing],\n () => requestAnimationFrame(checkTruncation),\n);\n</script>\n\n<style lang=\"scss\">\n.vc-data-table__header-title {\n // VcTooltip root acts as the flex child of `.vc-data-table__header-content`.\n // min-width: 0 lets it shrink below content so the text can truncate.\n @apply tw-flex-1 tw-min-w-0;\n\n .vc-tooltip__trigger {\n @apply tw-block tw-min-w-0;\n }\n}\n\n.vc-data-table__header-title-text {\n @apply tw-block tw-truncate;\n}\n</style>\n","<template>\n <TableHeader>\n <TableRow\n variant=\"header\"\n :show-drag-handle=\"showDragHandle\"\n :actions-position=\"actionsPosition\"\n >\n <!-- Selection column (only if NOT defined via VcColumn) -->\n <TableHead\n v-if=\"showSelectionCell\"\n class=\"vc-data-table__selection-cell\"\n >\n <TableCheckbox\n v-if=\"selectionMode === 'multiple'\"\n :model-value=\"allSelected\"\n :indeterminate=\"someSelected\"\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.SELECT_ALL_ROWS')\"\n @update:model-value=\"handleSelectAllChange\"\n />\n </TableHead>\n\n <!-- Data columns from VcColumn -->\n <TableHead\n v-for=\"col in columns\"\n :ref=\"(el) => setHeaderRef(col.props.id, el as HTMLElement)\"\n :key=\"col.props.id\"\n :width=\"getColumnWidth(col.props)\"\n :align=\"getHeaderAlign(col.props)\"\n :sortable=\"col.props.sortable\"\n :sort-direction=\"getSortDirection(getSortField(col.props))\"\n :sort-index=\"getSortIndex(getSortField(col.props))\"\n :column-id=\"col.props.id\"\n :resizable=\"isColumnResizable(col.props)\"\n :reorderable=\"isColumnReorderable(col.props)\"\n :is-last-resizable=\"isLastResizable(col.props)\"\n :style=\"getHeaderStyle(col.props)\"\n @sort=\"handleSort(col.props, $event)\"\n @resize-start=\"handleResizeStart\"\n @reorder-drag-start=\"handleReorderDragStart\"\n @reorder-drag-over=\"handleReorderDragOver\"\n @reorder-drop=\"handleReorderDrop\"\n >\n <!-- Selection column header (checkbox for multiple) -->\n <template v-if=\"col.props.selectionMode\">\n <TableCheckbox\n v-if=\"col.props.selectionMode === 'multiple'\"\n :model-value=\"allSelected\"\n :indeterminate=\"someSelected\"\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.SELECT_ALL_ROWS')\"\n @update:model-value=\"handleSelectAllChange\"\n />\n </template>\n <!-- Expander/RowReorder column header (empty) -->\n <template v-else-if=\"col.props.expander || col.props.rowReorder\" />\n <!-- Custom header slot from VcColumn -->\n <template v-else-if=\"col.slots.header\">\n <SlotProxy\n :slot-fn=\"col.slots.header!\"\n :scope=\"{ column: col.props }\"\n />\n </template>\n <!-- Default header content -->\n <template v-else>\n <div class=\"vc-data-table__header-content\">\n <HeaderTitle\n :title=\"col.props.title\"\n :required=\"!!col.props.rules?.required\"\n :is-editing=\"isEditing\"\n />\n <ColumnFilter\n v-if=\"showFilter(col)\"\n :field=\"col.props.filterField || col.props.field || col.props.id\"\n :filter-type=\"getFilterType(col)\"\n :filter-options=\"getFilterOptions(col)\"\n :multiple=\"isFilterMultiple(col)\"\n :range-fields=\"getRangeFields(col)\"\n :placeholder=\"col.props.filterPlaceholder\"\n :model-value=\"getFilterValue(col)\"\n @apply=\"handleFilterApply(col, $event)\"\n @clear=\"handleFilterClear(col)\"\n >\n <template\n v-if=\"col.slots.filter\"\n #filter=\"{\n value,\n updateValue,\n startDate,\n updateStartDate,\n endDate,\n updateEndDate,\n applyFilter,\n clearFilter,\n }\"\n >\n <SlotProxy\n :slot-fn=\"col.slots.filter!\"\n :scope=\"{\n field: col.props.field,\n value,\n updateValue,\n startDate,\n updateStartDate,\n endDate,\n updateEndDate,\n applyFilter,\n clearFilter,\n }\"\n />\n </template>\n </ColumnFilter>\n </div>\n </template>\n </TableHead>\n <!-- Actions slot: provides spacer in column mode + column switcher when enabled -->\n <template\n v-if=\"showColumnSwitcher || actionsPosition === 'column'\"\n #actions\n >\n <div\n v-if=\"showColumnSwitcher\"\n class=\"vc-col-switcher-trigger\"\n :class=\"{ 'vc-col-switcher-trigger--active': columnSwitcherActive }\"\n role=\"button\"\n tabindex=\"0\"\n :aria-expanded=\"columnSwitcherActive\"\n :aria-label=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_SWITCHER.TITLE')\"\n @click.stop=\"emit('column-switcher-click')\"\n @keydown.enter.stop=\"emit('column-switcher-click')\"\n @keydown.space.prevent.stop=\"emit('column-switcher-click')\"\n >\n <span class=\"vc-col-switcher-trigger__chevron\">\n <VcIcon\n icon=\"lucide-chevron-left\"\n size=\"xs\"\n :use-container=\"false\"\n />\n </span>\n <VcTooltip placement=\"bottom\">\n <span\n ref=\"columnSwitcherBtnRef\"\n class=\"vc-col-switcher-trigger__action\"\n >\n <VcIcon\n icon=\"lucide-circle-plus\"\n size=\"s\"\n />\n </span>\n <template #tooltip>\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.COLUMN_SWITCHER.TITLE\") }}\n </template>\n </VcTooltip>\n </div>\n </template>\n </TableRow>\n </TableHeader>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * DataTableHeader - Reusable header rendering component for VcDataTable\n *\n * Extracts header rendering logic from VcDataTable.vue to provide\n * a single, unified component for rendering table headers.\n *\n * Features:\n * - Selection column (checkbox for select-all in multiple mode)\n * - Column headers with sort indicators\n * - Column filters\n * - Resize handles\n * - Reorder drag handles\n * - Custom header slots from VcColumn\n */\nimport { computed, ref } from \"vue\";\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\nimport type {\n VcColumnProps,\n FilterType,\n FilterOption,\n FilterValue,\n} from \"@ui/components/organisms/vc-data-table/types\";\nimport TableHeader from \"@ui/components/organisms/vc-data-table/components/TableHeader.vue\";\nimport TableRow from \"@ui/components/organisms/vc-data-table/components/TableRow.vue\";\nimport TableHead from \"@ui/components/organisms/vc-data-table/components/TableHead.vue\";\nimport TableCheckbox from \"@ui/components/organisms/vc-data-table/components/TableCheckbox.vue\";\nimport ColumnFilter from \"@ui/components/organisms/vc-data-table/components/ColumnFilter.vue\";\nimport HeaderTitle from \"@ui/components/organisms/vc-data-table/components/HeaderTitle.vue\";\nimport { VcIcon, VcTooltip } from \"@ui/components/atoms\";\nimport { SlotProxy } from \"@ui/components/organisms/vc-data-table/components/_internal/SlotProxy\";\n\n// Props interface\nconst _props = defineProps<{\n /** Column instances from ColumnCollector */\n columns: ColumnInstance[];\n\n // === Selection ===\n /** Whether to show selection cell (checkbox/radio) */\n showSelectionCell?: boolean;\n /** Selection mode: 'single' or 'multiple' */\n selectionMode?: \"single\" | \"multiple\";\n /** Whether all rows are selected */\n allSelected?: boolean;\n /** Whether some (but not all) rows are selected */\n someSelected?: boolean;\n\n // === Sort helpers ===\n /** Function to get sort direction for a field */\n getSortDirection: (field: string) => \"asc\" | \"desc\" | undefined;\n /** Function to get sort index for multi-sort */\n getSortIndex: (field: string) => number | undefined;\n\n // === Column helpers ===\n /** Function to get effective column width */\n getColumnWidth: (colProps: VcColumnProps) => string | undefined;\n /** Function to get header alignment */\n getHeaderAlign: (colProps: VcColumnProps) => \"left\" | \"center\" | \"right\" | undefined;\n /** Function to get header style */\n getHeaderStyle: (colProps: VcColumnProps) => Record<string, string> | object | undefined;\n /** Function to check if column is resizable */\n isColumnResizable: (colProps: VcColumnProps) => boolean;\n /** Function to check if column is reorderable */\n isColumnReorderable: (colProps: VcColumnProps) => boolean;\n /** Function to check if column is the last resizable one */\n isLastResizable: (colProps: VcColumnProps) => boolean;\n /** Function to get sort field for a column */\n getSortField: (colProps: VcColumnProps) => string;\n /** Function to set header ref for resize/reorder tracking */\n setHeaderRef: (columnId: string, el: HTMLElement | null) => void;\n\n // === Filter helpers ===\n /** Function to check if filter should be shown for column */\n showFilter: (col: ColumnInstance) => boolean;\n /** Function to get filter type for column */\n getFilterType: (col: ColumnInstance) => FilterType;\n /** Function to get filter options for column */\n getFilterOptions: (col: ColumnInstance) => FilterOption[] | undefined;\n /** Function to check if filter allows multiple selection */\n isFilterMultiple: (col: ColumnInstance) => boolean;\n /** Function to get range fields for dateRange filter */\n getRangeFields: (col: ColumnInstance) => [string, string] | undefined;\n /** Function to get current filter value for column */\n getFilterValue: (col: ColumnInstance) => FilterValue;\n\n // === Column switcher ===\n /** Whether the table is in inline editing mode */\n isEditing?: boolean;\n\n /** Whether to show drag handle spacer (aligns header with body rows that have drag handles) */\n showDragHandle?: boolean;\n\n /** Whether to show the column switcher icon in header row */\n showColumnSwitcher?: boolean;\n /** Whether the column switcher panel is currently open */\n columnSwitcherActive?: boolean;\n /** Position of row actions: 'overlay' (default) or 'column' (fixed right column) */\n actionsPosition?: \"overlay\" | \"column\";\n}>();\n\n// Emits\nconst emit = defineEmits<{\n /** Select all checkbox changed */\n \"select-all\": [value: boolean];\n /** Column sort requested */\n sort: [col: VcColumnProps, event?: MouseEvent];\n /** Column resize started */\n \"resize-start\": [columnId: string, event: MouseEvent];\n /** Column reorder drag started */\n \"reorder-start\": [columnId: string, event: DragEvent];\n /** Column reorder drag over */\n \"reorder-over\": [event: DragEvent];\n /** Column reorder drop */\n \"reorder-drop\": [columnId: string, event: DragEvent];\n /** Column filter applied */\n \"filter-apply\": [col: ColumnInstance, payload: Record<string, unknown>];\n /** Column filter cleared */\n \"filter-clear\": [col: ColumnInstance];\n /** Column switcher icon clicked */\n \"column-switcher-click\": [];\n}>();\n\n// Column switcher action ref (exposed for anchor positioning)\nconst columnSwitcherBtnRef = ref<HTMLElement | null>(null);\n\ndefineExpose({\n /** The column switcher action element (for dropdown anchor positioning) */\n columnSwitcherEl: computed(() => columnSwitcherBtnRef.value),\n});\n\n// Event handlers\n\nconst handleSelectAllChange = (value?: boolean) => {\n emit(\"select-all\", value ?? false);\n};\n\nconst handleSort = (colProps: VcColumnProps, event: Event) => {\n // TableHead emits Event, but header sort clicks are always MouseEvent in practice\n emit(\"sort\", colProps, event as MouseEvent);\n};\n\nconst handleResizeStart = (columnId: string | undefined, event: MouseEvent) => {\n if (columnId) {\n emit(\"resize-start\", columnId, event);\n }\n};\n\nconst handleReorderDragStart = (columnId: string | undefined, event: DragEvent) => {\n if (columnId) {\n emit(\"reorder-start\", columnId, event);\n }\n};\n\nconst handleReorderDragOver = (event: DragEvent) => {\n emit(\"reorder-over\", event);\n};\n\nconst handleReorderDrop = (columnId: string | undefined, event: DragEvent) => {\n if (columnId) {\n emit(\"reorder-drop\", columnId, event);\n }\n};\n\nconst handleFilterApply = (col: ColumnInstance, payload: Record<string, unknown>) => {\n emit(\"filter-apply\", col, payload);\n};\n\nconst handleFilterClear = (col: ColumnInstance) => {\n emit(\"filter-clear\", col);\n};\n</script>\n\n<style lang=\"scss\">\n.vc-col-switcher-trigger {\n position: absolute;\n right: 0;\n top: 50%;\n z-index: var(--z-local-header);\n\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 16px 0 0 16px;\n\n background: var(--neutrals-200);\n box-shadow: -4px 0 8px rgba(0, 0, 0, 0.1);\n cursor: pointer;\n\n // Idle: shifted right, ~14px visible — subtle peek\n transform: translateY(-50%) translateX(60%);\n transition:\n transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),\n background-color 0.2s ease;\n\n // Hover: slide fully in\n &:hover,\n &--active {\n transform: translateY(-50%) translateX(0);\n background: var(--primary-50);\n\n .vc-col-switcher-trigger__chevron {\n opacity: 0;\n pointer-events: none;\n }\n\n .vc-col-switcher-trigger__action {\n opacity: 1;\n pointer-events: auto;\n }\n }\n\n // Active state (panel open): stronger primary accent\n &--active {\n background: var(--primary-100);\n\n .vc-col-switcher-trigger__action {\n color: var(--primary-700);\n }\n }\n\n // Chevron icon (visible in idle)\n // Left-aligned with padding so it sits in the visible ~14px peek area\n &__chevron {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n padding-left: 3px;\n color: var(--neutrals-500);\n opacity: 1;\n transition: opacity 0.2s ease;\n pointer-events: none; // chevron is decorative, clicks go to container\n }\n\n // Action icon \"+\" (visible on hover/active)\n &__action {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--primary-100);\n color: var(--primary-600);\n opacity: 0;\n transition: opacity 0.2s ease;\n pointer-events: none; // hidden until hover\n }\n\n // Keyboard focus: reveal fully like hover\n &:focus-visible {\n outline: 2px solid var(--primary-500);\n outline-offset: 2px;\n transform: translateY(-50%) translateX(0);\n\n .vc-col-switcher-trigger__chevron {\n opacity: 0;\n }\n\n .vc-col-switcher-trigger__action {\n opacity: 1;\n pointer-events: auto;\n }\n }\n\n // Respect reduced motion preference\n @media (prefers-reduced-motion: reduce) {\n &,\n &__chevron,\n &__action {\n transition-duration: 0.01ms !important;\n }\n }\n}\n</style>\n","<template>\n <!-- Custom body slot from VcColumn (takes priority) -->\n <template v-if=\"config.column.slots.body || config.column.slots.default\">\n <SlotProxy\n :slot-fn=\"(config.column.slots.body || config.column.slots.default)!\"\n :scope=\"{\n data: item,\n field: fieldName,\n index,\n }\"\n />\n </template>\n\n <!-- Type-specific cell formatters -->\n <DynamicCellRenderer\n v-else\n :type=\"config.type || 'text'\"\n :value=\"cellValue\"\n :editable=\"isInlineEditing && config.column.props.editable\"\n :label=\"config.column.props.title || fieldName\"\n :field-name=\"uniqueFieldName\"\n :field-id=\"fieldName\"\n :rules=\"config.column.props.rules\"\n :row-index=\"index\"\n :currency=\"currency\"\n :format=\"config.column.props.format\"\n :variant=\"dateVariant\"\n :validate-on-mount=\"validateOnMount\"\n @update=\"$emit('update', $event)\"\n @blur=\"$emit('blur', $event)\"\n />\n</template>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\n/**\n * MobileCellRenderer - Renders cell content in mobile card view\n *\n * Simplified version of DataTableCellRenderer for mobile cards.\n * Does not support editing, selection, or special columns (those are handled separately).\n */\nimport { computed } from \"vue\";\nimport { get } from \"lodash-es\";\nimport type { MobileColumnConfig } from \"@ui/components/organisms/vc-data-table/types\";\nimport DynamicCellRenderer from \"@ui/components/organisms/vc-data-table/components/cells/DynamicCellRenderer.vue\";\nimport { SlotProxy } from \"@ui/components/organisms/vc-data-table/components/_internal/SlotProxy\";\n\nconst props = defineProps<{\n /** Mobile column configuration */\n config: MobileColumnConfig;\n /** Row data item */\n item: T;\n /** Row index */\n index: number;\n /** Whether inline editing is active */\n isInlineEditing?: boolean;\n /** Unique field name for VeeValidate */\n uniqueFieldName?: string;\n /** Whether to validate on mount */\n validateOnMount?: boolean;\n}>();\n\ndefineEmits<{\n (e: \"update\", payload: { field: string; value: unknown }): void;\n (e: \"blur\", payload: { row: number | undefined; field: string }): void;\n}>();\n\n// Field name from column\nconst fieldName = computed(() => props.config.field || props.config.id);\n\n// Get cell value using lodash _.get for nested fields\nconst cellValue = computed(() => {\n return get(props.item, fieldName.value || \"\");\n});\n\n// Currency for money cells\nconst currency = computed(() => {\n const field = props.config.column.props.currencyField || \"currency\";\n return ((props.item as Record<string, unknown>)[field] as string) || \"USD\";\n});\n\n// Date variant based on column type\nconst dateVariant = computed<\"date\" | \"time\" | \"date-time\">(() => {\n const type = props.config.type;\n if (type === \"time\") return \"time\";\n if (type === \"datetime\") return \"date-time\";\n return \"date\";\n});\n</script>\n","<template>\n <VcSidebar\n :model-value=\"open\"\n position=\"bottom\"\n size=\"sm\"\n draggable\n drag-handle\n :close-button=\"false\"\n :title=\"title\"\n :inset=\"false\"\n @update:model-value=\"!$event && handleClose()\"\n @close=\"handleClose\"\n >\n <!-- Actions list -->\n <div class=\"vc-mobile-action-sheet__actions\">\n <button\n v-for=\"action in actions\"\n :key=\"action.id\"\n class=\"vc-mobile-action-sheet__action\"\n :class=\"[\n `vc-mobile-action-sheet__action--${action.type || 'default'}`,\n { 'vc-mobile-action-sheet__action--disabled': action.disabled },\n ]\"\n :disabled=\"action.disabled\"\n @click=\"handleActionClick(action)\"\n >\n <VcIcon\n :icon=\"action.icon\"\n class=\"vc-mobile-action-sheet__action-icon\"\n />\n <span class=\"vc-mobile-action-sheet__action-title\">{{ action.title }}</span>\n </button>\n </div>\n\n <template #footer>\n <div class=\"vc-mobile-action-sheet__cancel\">\n <button\n class=\"vc-mobile-action-sheet__cancel-btn\"\n @click=\"handleClose\"\n >\n {{ cancelLabel }}\n </button>\n </div>\n </template>\n </VcSidebar>\n</template>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\n/**\n * MobileActionSheet - iOS-style bottom sheet for action overflow\n *\n * Thin wrapper around VcSidebar(position=\"bottom\") with swipe-to-dismiss.\n * Displays when there are more than 2 swipe actions on a mobile card.\n */\nimport { VcSidebar } from \"@ui/components/organisms/vc-sidebar\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\nimport type { MobileSwipeAction } from \"@ui/components/organisms/vc-data-table/types\";\n\nconst _props = withDefaults(\n defineProps<{\n /** Whether sheet is open */\n open: boolean;\n /** Sheet title */\n title?: string;\n /** Actions to display */\n actions: MobileSwipeAction<T>[];\n /** Cancel button label */\n cancelLabel?: string;\n }>(),\n {\n title: undefined,\n cancelLabel: \"Cancel\",\n },\n);\n\nconst emit = defineEmits<{\n /** Close the sheet */\n close: [];\n /** Action was clicked */\n action: [action: MobileSwipeAction<T>];\n}>();\n\nfunction handleClose() {\n emit(\"close\");\n}\n\nfunction handleActionClick(action: MobileSwipeAction<T>) {\n if (action.disabled) return;\n emit(\"action\", action);\n emit(\"close\");\n}\n</script>\n\n<style lang=\"scss\">\n:root {\n --action-sheet-border: var(--neutrals-200);\n --action-sheet-action-color: var(--primary-700);\n --action-sheet-action-hover: var(--neutrals-100);\n --action-sheet-action-danger: var(--danger-600);\n --action-sheet-action-success: var(--success-600);\n --action-sheet-action-warning: var(--warning-600);\n --action-sheet-cancel-bg: var(--additional-50);\n --action-sheet-cancel-color: var(--primary-600);\n}\n\n.vc-mobile-action-sheet {\n &__actions {\n @apply tw-border-t tw-border-[var(--action-sheet-border)];\n }\n\n &__action {\n @apply tw-w-full tw-flex tw-items-center tw-gap-3 tw-px-5 tw-py-4 tw-text-left\n tw-border-b tw-border-[var(--action-sheet-border)] tw-transition-colors tw-bg-transparent tw-border-x-0 tw-border-t-0 tw-cursor-pointer\n hover:tw-bg-[var(--action-sheet-action-hover)]\n active:tw-bg-[var(--action-sheet-action-hover)];\n\n &:last-child {\n @apply tw-border-b-0;\n }\n\n &--default {\n @apply tw-text-[var(--action-sheet-action-color)];\n }\n\n &--danger {\n @apply tw-text-[var(--action-sheet-action-danger)];\n }\n\n &--success {\n @apply tw-text-[var(--action-sheet-action-success)];\n }\n\n &--warning {\n @apply tw-text-[var(--action-sheet-action-warning)];\n }\n\n &--disabled {\n @apply tw-opacity-50 tw-cursor-not-allowed tw-pointer-events-none;\n }\n }\n\n &__action-icon {\n @apply tw-text-xl tw-flex-shrink-0;\n }\n\n &__action-title {\n @apply tw-text-base tw-font-medium;\n }\n\n &__cancel {\n @apply tw-p-3;\n }\n\n &__cancel-btn {\n @apply tw-w-full tw-py-4 tw-text-center tw-text-base tw-font-semibold tw-border-0\n tw-text-[var(--action-sheet-cancel-color)]\n tw-bg-[var(--action-sheet-cancel-bg)]\n tw-rounded-xl tw-transition-colors tw-cursor-pointer\n hover:tw-bg-[var(--action-sheet-action-hover)]\n active:tw-bg-[var(--action-sheet-action-hover)];\n }\n}\n</style>\n","import { ref, provide, inject, InjectionKey, Ref } from \"vue\";\n\ninterface TableSwipeContext {\n activeSwipeId: Ref<string | null>;\n setActiveSwipe: (id: string | null) => void;\n}\n\nconst TableSwipeKey = Symbol() as InjectionKey<TableSwipeContext>;\n\nexport function provideTableSwipe() {\n const activeSwipeId = ref<string | null>(null);\n\n function setActiveSwipe(id: string | null) {\n activeSwipeId.value = id;\n }\n\n const context = {\n activeSwipeId,\n setActiveSwipe,\n };\n\n provide(TableSwipeKey, context);\n return context;\n}\n\nexport function useTableSwipe() {\n const context = inject(TableSwipeKey);\n if (!context) {\n throw new Error(\"useTableSwipe must be used within a provider\");\n }\n return context;\n}\n","<template>\n <div\n ref=\"containerRef\"\n v-on-click-outside=\"reset\"\n class=\"vc-data-table-mobile-card\"\n :class=\"{\n 'vc-data-table-mobile-card--selected': isSelected,\n 'vc-data-table-mobile-card--even': index % 2 === 1,\n 'vc-data-table-mobile-card--long-press': isLongPressing,\n 'vc-data-table-mobile-card--reorderable': reorderable,\n }\"\n @click=\"handleClick\"\n @contextmenu.prevent\n @touchstart.passive=\"handleLongPressStart\"\n @touchend=\"handleLongPressEnd\"\n @touchcancel=\"handleLongPressEnd\"\n @touchmove.passive=\"handleLongPressEnd\"\n >\n <!-- Card content with swipe transform -->\n <div\n ref=\"cardRef\"\n class=\"vc-data-table-mobile-card__content\"\n :style=\"{ transform: `translateX(${translateX}px)` }\"\n >\n <!-- Drag handle (left) -->\n <div\n v-if=\"reorderable\"\n class=\"vc-data-table-mobile-card__drag-handle\"\n @click.stop\n @touchstart.stop\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"2\"\n y=\"4\"\n width=\"12\"\n height=\"1.5\"\n rx=\"0.75\"\n />\n <rect\n x=\"2\"\n y=\"7.25\"\n width=\"12\"\n height=\"1.5\"\n rx=\"0.75\"\n />\n <rect\n x=\"2\"\n y=\"10.5\"\n width=\"12\"\n height=\"1.5\"\n rx=\"0.75\"\n />\n </svg>\n </div>\n\n <!-- Selection checkbox -->\n <div\n v-if=\"showCheckbox\"\n class=\"vc-data-table-mobile-card__checkbox\"\n @click.stop=\"handleSelect\"\n >\n <VcCheckbox\n :model-value=\"isSelected\"\n :disabled=\"!isSelectable\"\n size=\"m\"\n />\n </div>\n\n <!-- Card body - Universal layout -->\n <div\n class=\"vc-data-table-mobile-card__body\"\n :class=\"{\n 'vc-data-table-mobile-card__body--with-checkbox': showCheckbox && !reorderable,\n 'vc-data-table-mobile-card__body--with-handle': reorderable && !showCheckbox,\n 'vc-data-table-mobile-card__body--with-handle-and-checkbox': reorderable && showCheckbox,\n }\"\n >\n <!-- Image (left side) -->\n <div\n v-if=\"layout.image\"\n class=\"vc-data-table-mobile-card__image\"\n >\n <MobileCellRenderer\n :config=\"layout.image\"\n :item=\"item\"\n :index=\"index\"\n :is-inline-editing=\"isInlineEditing\"\n :unique-field-name=\"`${layout.image.field || layout.image.id}_${index}`\"\n :validate-on-mount=\"isNewRow && layout.image.column.props.editable\"\n @update=\"handleCellUpdate(layout.image, $event)\"\n />\n </div>\n\n <!-- Main content area -->\n <div class=\"vc-data-table-mobile-card__main\">\n <!-- Title (full width, bold) -->\n <div\n v-if=\"layout.title\"\n class=\"vc-data-table-mobile-card__title\"\n >\n <MobileCellRenderer\n :config=\"layout.title\"\n :item=\"item\"\n :index=\"index\"\n :is-inline-editing=\"isInlineEditing\"\n :unique-field-name=\"`${layout.title.field || layout.title.id}_${index}`\"\n :validate-on-mount=\"isNewRow && layout.title.column.props.editable\"\n @update=\"handleCellUpdate(layout.title, $event)\"\n />\n </div>\n\n <!-- Fields (2-column grid with labels) -->\n <div\n v-if=\"layout.fields.length > 0\"\n class=\"vc-data-table-mobile-card__fields\"\n :class=\"{ 'vc-data-table-mobile-card__fields--editing': isInlineEditing }\"\n >\n <div\n v-for=\"field in layout.fields\"\n :key=\"field.id\"\n class=\"vc-data-table-mobile-card__field\"\n :class=\"{ 'vc-data-table-mobile-card__field--editing': isInlineEditing }\"\n >\n <span\n v-if=\"field.label\"\n class=\"vc-data-table-mobile-card__field-label\"\n >{{ field.label }}:</span\n >\n <span\n class=\"vc-data-table-mobile-card__field-value\"\n :class=\"{ 'vc-data-table-mobile-card__field-value--editing': isInlineEditing }\"\n >\n <MobileCellRenderer\n :config=\"field\"\n :item=\"item\"\n :index=\"index\"\n :is-inline-editing=\"isInlineEditing\"\n :unique-field-name=\"`${field.field || field.id}_${index}`\"\n :validate-on-mount=\"isNewRow && field.column.props.editable\"\n @update=\"handleCellUpdate(field, $event)\"\n />\n </span>\n </div>\n </div>\n\n <!-- Statuses (row of badges at bottom) -->\n <div\n v-if=\"layout.statuses.length > 0\"\n class=\"vc-data-table-mobile-card__statuses\"\n >\n <template\n v-for=\"status in layout.statuses\"\n :key=\"status.id\"\n >\n <MobileCellRenderer\n :config=\"status\"\n :item=\"item\"\n :index=\"index\"\n :is-inline-editing=\"isInlineEditing\"\n :unique-field-name=\"`${status.field || status.id}_${index}`\"\n :validate-on-mount=\"isNewRow && status.column.props.editable\"\n @update=\"handleCellUpdate(status, $event)\"\n />\n </template>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Swipe actions -->\n <div\n v-if=\"visibleActions.length > 0\"\n class=\"vc-data-table-mobile-card__actions\"\n :style=\"{ width: `${actionsWidth}px` }\"\n @touchstart.stop\n >\n <!-- More button (shown when 3+ actions) -->\n <button\n v-if=\"hasMoreActions\"\n class=\"vc-data-table-mobile-card__action vc-data-table-mobile-card__action--more\"\n @click.stop=\"handleMoreClick\"\n >\n <VcIcon icon=\"lucide-clock\" />\n <span class=\"vc-data-table-mobile-card__action-title\">{{ moreLabel }}</span>\n </button>\n\n <!-- First 2 actions -->\n <button\n v-for=\"action in displayActions\"\n :key=\"action.id\"\n class=\"vc-data-table-mobile-card__action\"\n :class=\"[\n `vc-data-table-mobile-card__action--${action.type || 'default'}`,\n { 'vc-data-table-mobile-card__action--disabled': action.disabled },\n ]\"\n :disabled=\"action.disabled\"\n @click.stop=\"handleActionClick(action)\"\n >\n <VcIcon\n :icon=\"action.icon\"\n size=\"s\"\n />\n <span class=\"vc-data-table-mobile-card__action-title\">{{ action.title }}</span>\n </button>\n </div>\n\n <!-- Action Sheet for overflow -->\n <MobileActionSheet\n :open=\"isActionSheetOpen\"\n :title=\"actionSheetTitle\"\n :actions=\"allActions\"\n :cancel-label=\"cancelLabel\"\n @close=\"isActionSheetOpen = false\"\n @action=\"handleSheetAction\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\n/**\n * DataTableMobileCard - Individual mobile card with iOS-style swipe\n *\n * Features:\n * - Spring physics animation for natural swipe feel\n * - Shows max 2 actions + \"More\" button for 3+\n * - Selection via long-press (checkboxes hidden by default, shown when selection active)\n * - Alternating row colors\n */\nimport { ref, computed, watch, onMounted, onBeforeUnmount } from \"vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport type {\n MobileCardLayout,\n MobileSwipeAction,\n MobileColumnConfig,\n} from \"@ui/components/organisms/vc-data-table/types\";\nimport { useTableSwipe } from \"@ui/components/organisms/vc-data-table/composables/useTableSwipe\";\nimport MobileCellRenderer from \"@ui/components/organisms/vc-data-table/components/mobile/MobileCellRenderer.vue\";\nimport MobileActionSheet from \"@ui/components/organisms/vc-data-table/components/mobile/MobileActionSheet.vue\";\nimport { VcCheckbox } from \"@ui/components/molecules/vc-checkbox\";\n\nconst props = withDefaults(\n defineProps<{\n /** Row data item */\n item: T;\n /** Row index */\n index: number;\n /** Card layout configuration */\n layout: MobileCardLayout;\n /** Whether row is selected */\n isSelected: boolean;\n /** Whether row is selectable */\n isSelectable: boolean;\n /** Swipe actions */\n actions?: MobileSwipeAction<T>[];\n /** Selection mode */\n selectionMode?: \"single\" | \"multiple\";\n /** Whether any items are currently selected (shows checkboxes) */\n anySelected?: boolean;\n /** Data key field for item identification */\n dataKey?: string;\n /** \"More\" button label */\n moreLabel?: string;\n /** Action sheet title */\n actionSheetTitle?: string;\n /** Cancel button label */\n cancelLabel?: string;\n /** Whether inline editing is active */\n isInlineEditing?: boolean;\n /** Whether this is a new row (for eager validation) */\n isNewRow?: boolean;\n /** Whether row reorder is enabled (shows the drag handle) */\n reorderable?: boolean;\n }>(),\n {\n actions: () => [],\n selectionMode: undefined,\n anySelected: false,\n isInlineEditing: false,\n isNewRow: false,\n dataKey: \"id\",\n moreLabel: \"More\",\n actionSheetTitle: \"Actions\",\n cancelLabel: \"Cancel\",\n reorderable: false,\n },\n);\n\nconst emit = defineEmits<{\n /** Row was clicked */\n click: [item: T, index: number];\n /** Row selection changed */\n select: [item: T, index: number];\n /** Action was triggered */\n action: [action: MobileSwipeAction<T>, item: T, index: number];\n /** Cell value changed during editing */\n \"cell-value-change\": [field: string, value: unknown];\n}>();\n\nfunction handleCellUpdate(config: MobileColumnConfig, payload: { field: string; value: unknown }) {\n emit(\"cell-value-change\", config.field || config.id, payload.value);\n}\n\n// Refs\nconst containerRef = ref<HTMLElement | null>(null);\nconst cardRef = ref<HTMLElement | null>(null);\n\n// Long press state for selection activation\nconst isLongPressing = ref(false);\nconst longPressTimeoutId = ref<ReturnType<typeof setTimeout> | null>(null);\n\n// Long press handler - activates selection mode\nfunction handleLongPressStart() {\n if (!props.selectionMode || translateX.value !== 0 || isAnimating.value) return;\n\n isLongPressing.value = true;\n longPressTimeoutId.value = setTimeout(() => {\n if (isLongPressing.value) {\n emit(\"select\", props.item, props.index);\n }\n isLongPressing.value = false;\n }, 500);\n}\n\nfunction handleLongPressEnd() {\n if (longPressTimeoutId.value) {\n clearTimeout(longPressTimeoutId.value);\n longPressTimeoutId.value = null;\n }\n isLongPressing.value = false;\n}\n\n// Swipe state\nconst translateX = ref(0);\nconst actionsWidth = ref(0);\nconst isAnimating = ref(false);\nconst isActionSheetOpen = ref(false);\nconst animationId = ref<number | null>(null);\n\n// Touch tracking\nconst startX = ref(0);\nconst startY = ref(0);\nconst startTranslateX = ref(0);\nconst velocity = ref(0);\nconst lastTime = ref(0);\nconst lastX = ref(0);\n// Direction lock: once determined, the gesture is either \"horizontal\" (swipe) or \"vertical\" (scroll).\n// null = undetermined, \"horizontal\" = swipe (we handle), \"vertical\" = scroll (browser handles).\nconst directionLock = ref<\"horizontal\" | \"vertical\" | null>(null);\nconst DIRECTION_LOCK_THRESHOLD = 8; // px — minimum movement to decide direction\n\n// Spring animation constants\nconst SPRING_STIFFNESS = 0.08;\nconst SPRING_DAMPING = 0.7;\nconst SPRING_MASS = 1;\n\n// Swipe context from provider\nconst { activeSwipeId, setActiveSwipe } = useTableSwipe();\n\n// Computed values\nconst itemId = computed(() => props.item[props.dataKey] ?? `item-${props.index}`);\n\n// Show checkbox only when selection mode is active AND there are selected items\n// This allows long-press to activate selection mode without permanent checkboxes\nconst showCheckbox = computed(() => {\n return props.anySelected && props.selectionMode !== undefined;\n});\n\nconst visibleActions = computed(() => {\n // Don't show swipe actions when items are selected\n if (props.anySelected) return [];\n return props.actions ?? [];\n});\n\nconst hasMoreActions = computed(() => visibleActions.value.length > 2);\n\nconst displayActions = computed(() => {\n return visibleActions.value.slice(0, 2);\n});\n\nconst allActions = computed((): MobileSwipeAction<T>[] => {\n return props.actions ?? [];\n});\n\nconst totalActionsWidth = computed(() => {\n const count = visibleActions.value.length;\n // Show max 3 slots: 2 actions + More, or just 2 if <= 2 actions\n const maxVisible = Math.min(count, count > 2 ? 3 : 2);\n return maxVisible * 70;\n});\n\n// Spring animation\nfunction springAnimation(targetValue: number, duration = 300) {\n if (animationId.value !== null) {\n cancelAnimationFrame(animationId.value);\n }\n\n const startValue = translateX.value;\n const startTime = performance.now();\n let springVelocity = velocity.value;\n let currentValue = startValue;\n\n isAnimating.value = true;\n\n function animate(time: number) {\n const elapsed = time - startTime;\n\n if (elapsed < duration) {\n const springForce = (targetValue - currentValue) * SPRING_STIFFNESS;\n const dampingForce = springVelocity * SPRING_DAMPING;\n const acceleration = (springForce - dampingForce) / SPRING_MASS;\n\n springVelocity += acceleration;\n currentValue += springVelocity;\n\n translateX.value = currentValue;\n actionsWidth.value = Math.abs(translateX.value);\n\n animationId.value = requestAnimationFrame(animate);\n } else {\n translateX.value = targetValue;\n actionsWidth.value = Math.abs(targetValue);\n isAnimating.value = false;\n animationId.value = null;\n }\n }\n\n animationId.value = requestAnimationFrame(animate);\n}\n\n// Touch handlers\nfunction handleTouchStart(e: TouchEvent) {\n if (isAnimating.value || visibleActions.value.length === 0) return;\n\n const touch = e.touches[0];\n startX.value = touch.clientX;\n startY.value = touch.clientY;\n startTranslateX.value = translateX.value;\n velocity.value = 0;\n lastTime.value = Date.now();\n lastX.value = touch.clientX;\n directionLock.value = null;\n\n setActiveSwipe(String(itemId.value));\n}\n\nfunction handleTouchMove(e: TouchEvent) {\n if (isAnimating.value || visibleActions.value.length === 0) return;\n if (activeSwipeId.value !== String(itemId.value)) return;\n\n const touch = e.touches[0];\n const currentX = touch.clientX;\n const deltaX = currentX - startX.value;\n const deltaY = touch.clientY - startY.value;\n\n // Determine direction lock on first significant movement\n if (directionLock.value === null) {\n const absDeltaX = Math.abs(deltaX);\n const absDeltaY = Math.abs(deltaY);\n if (absDeltaX >= DIRECTION_LOCK_THRESHOLD || absDeltaY >= DIRECTION_LOCK_THRESHOLD) {\n directionLock.value = absDeltaX > absDeltaY ? \"horizontal\" : \"vertical\";\n } else {\n return; // Not enough movement to decide yet\n }\n }\n\n // Vertical gesture → let browser handle scroll, don't interfere\n if (directionLock.value === \"vertical\") {\n return;\n }\n\n // Horizontal gesture → handle swipe, prevent scroll\n e.preventDefault();\n\n // Calculate velocity for inertia\n const now = Date.now();\n const dt = now - lastTime.value;\n if (dt > 0) {\n velocity.value = (currentX - lastX.value) / dt;\n }\n lastTime.value = now;\n lastX.value = currentX;\n\n // Calculate new position\n let newTranslateX = startTranslateX.value + deltaX;\n\n // Spring resistance for overscroll\n if (newTranslateX < -totalActionsWidth.value) {\n const overscroll = newTranslateX + totalActionsWidth.value;\n newTranslateX = -totalActionsWidth.value + overscroll * 0.3;\n }\n\n // Don't allow swipe past initial position\n if (newTranslateX > 0) {\n newTranslateX = 0;\n }\n\n translateX.value = newTranslateX;\n actionsWidth.value = Math.abs(newTranslateX);\n}\n\nfunction handleTouchEnd() {\n const wasVertical = directionLock.value === \"vertical\" || directionLock.value === null;\n directionLock.value = null;\n\n if (wasVertical) return; // Was a scroll gesture, not a swipe\n if (isAnimating.value || visibleActions.value.length === 0) return;\n if (activeSwipeId.value !== String(itemId.value)) return;\n\n const absVelocity = Math.abs(velocity.value);\n const direction = velocity.value < 0 ? -1 : 1;\n\n // Use velocity to determine open/close\n if (absVelocity > 0.5) {\n if (direction < 0) {\n springAnimation(-totalActionsWidth.value);\n } else {\n springAnimation(0);\n }\n } else {\n // Use position threshold (40%)\n const threshold = totalActionsWidth.value * 0.4;\n if (Math.abs(translateX.value) > threshold) {\n springAnimation(-totalActionsWidth.value);\n } else {\n springAnimation(0);\n }\n }\n}\n\n// Watch for other swipes\nwatch(\n activeSwipeId,\n (newVal) => {\n if ((!newVal || newVal !== String(itemId.value)) && translateX.value !== 0) {\n springAnimation(0);\n }\n },\n { immediate: true },\n);\n\n// Reset swipe state\nfunction reset() {\n if (isAnimating.value) return;\n springAnimation(0);\n\n if (activeSwipeId.value === String(itemId.value)) {\n setActiveSwipe(null);\n }\n}\n\n// Event handlers\nfunction handleClick() {\n if (translateX.value !== 0) {\n reset();\n return;\n }\n\n if (props.anySelected) {\n emit(\"select\", props.item, props.index);\n return;\n }\n\n emit(\"click\", props.item, props.index);\n}\n\nfunction handleSelect() {\n emit(\"select\", props.item, props.index);\n}\n\nfunction handleActionClick(action: MobileSwipeAction<T>) {\n if (action.disabled) return;\n reset();\n emit(\"action\", action, props.item, props.index);\n}\n\nfunction handleMoreClick() {\n reset();\n isActionSheetOpen.value = true;\n}\n\nfunction handleSheetAction(action: MobileSwipeAction<T>) {\n emit(\"action\", action, props.item, props.index);\n}\n\n// Lifecycle\nonMounted(() => {\n if (cardRef.value) {\n cardRef.value.addEventListener(\"touchstart\", handleTouchStart, { passive: true });\n cardRef.value.addEventListener(\"touchmove\", handleTouchMove, { passive: false });\n cardRef.value.addEventListener(\"touchend\", handleTouchEnd, { passive: true });\n }\n});\n\nonBeforeUnmount(() => {\n if (cardRef.value) {\n cardRef.value.removeEventListener(\"touchstart\", handleTouchStart);\n cardRef.value.removeEventListener(\"touchmove\", handleTouchMove);\n cardRef.value.removeEventListener(\"touchend\", handleTouchEnd);\n }\n\n if (animationId.value !== null) {\n cancelAnimationFrame(animationId.value);\n }\n\n // Clean up long press timeout\n if (longPressTimeoutId.value) {\n clearTimeout(longPressTimeoutId.value);\n }\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --mobile-card-bg: var(--additional-50);\n --mobile-card-bg-even: var(--neutrals-50);\n --mobile-card-bg-selected: var(--primary-100);\n --mobile-card-border: var(--neutrals-200);\n --mobile-card-text: var(--neutrals-800);\n --mobile-card-text-secondary: var(--neutrals-500);\n --mobile-card-action-bg: var(--secondary-400);\n --mobile-card-action-text: var(--additional-50);\n --mobile-card-action-danger: var(--danger-500);\n --mobile-card-action-success: var(--success-400);\n --mobile-card-action-warning: var(--warning-500);\n --mobile-card-action-more: var(--neutrals-400);\n}\n\n.vc-data-table-mobile-card {\n @apply tw-relative tw-overflow-hidden tw-select-none tw-mx-3 tw-mb-2 tw-rounded-lg;\n touch-action: pan-y;\n\n &:first-child {\n @apply tw-mt-3;\n }\n\n &--selected {\n @apply tw-ring-2 tw-ring-[var(--mobile-card-bg-selected)] #{!important};\n }\n\n // Visual feedback during long press\n &--long-press &__content {\n @apply tw-scale-[0.98] tw-shadow-lg;\n transition:\n transform 0.15s ease-out,\n box-shadow 0.15s ease-out;\n }\n\n &__content {\n @apply tw-relative tw-bg-[var(--mobile-card-bg)] tw-rounded-lg tw-border tw-border-[var(--mobile-card-border)] tw-shadow-sm;\n will-change: transform;\n }\n\n &--selected &__content {\n @apply tw-bg-[var(--mobile-card-bg-selected)];\n }\n\n &__checkbox {\n @apply tw-absolute tw-left-0 tw-top-0 tw-bottom-0 tw-flex tw-items-center tw-px-3 tw-z-[var(--z-local-sticky)];\n }\n\n // When a drag handle is present, the checkbox sits to the right of it.\n &--reorderable &__checkbox {\n left: 2.5rem;\n }\n\n &__drag-handle {\n @apply tw-absolute tw-left-0 tw-top-0 tw-bottom-0 tw-flex tw-items-center tw-justify-center tw-w-10 tw-z-[var(--z-local-sticky)];\n color: var(--table-drag-handle-color, var(--neutrals-400));\n cursor: grab;\n touch-action: none;\n\n &:active {\n cursor: grabbing;\n }\n }\n\n &__body {\n @apply tw-flex tw-items-stretch tw-p-4 tw-gap-3 tw-min-h-[72px];\n\n // Selection-only (non-reorderable) card: make room for the absolute checkbox.\n &--with-checkbox {\n @apply tw-pl-12;\n }\n }\n\n // Drag-handle offsets. Scoped under the root `--reorderable` modifier so the\n // higher specificity (0,2,0) reliably overrides the base `tw-p-4` padding\n // shorthand — an equal-specificity body modifier can lose to the shorthand,\n // leaving content to slide under the absolutely-positioned handle.\n &--reorderable &__body {\n @apply tw-pl-12; // 48px — clear the 40px handle\n }\n\n &--reorderable &__body--with-handle-and-checkbox {\n @apply tw-pl-20; // 80px — 40px handle + 40px checkbox\n }\n\n &__image {\n @apply tw-flex tw-items-center tw-justify-center tw-flex-shrink-0 tw-w-12 tw-h-12;\n\n // Image styling\n :deep(img) {\n @apply tw-w-full tw-h-full tw-object-cover tw-rounded;\n }\n }\n\n &__main {\n @apply tw-flex tw-flex-col tw-flex-1 tw-justify-center tw-gap-2 tw-min-w-0;\n }\n\n // Title - primary identifier (full width, bold)\n &__title {\n @apply tw-font-semibold tw-text-base tw-text-[var(--mobile-card-text)] tw-truncate;\n }\n\n // Fields - 2-column grid with labels\n &__fields {\n @apply tw-grid tw-grid-cols-2 tw-gap-x-4 tw-gap-y-1 tw-text-sm;\n\n // In editing mode, switch to single column for input + error space\n &--editing {\n @apply tw-grid-cols-1 tw-gap-y-3;\n }\n }\n\n &__field {\n @apply tw-flex tw-flex-wrap tw-items-baseline tw-gap-1 tw-min-w-0;\n\n // In editing mode, stack label above input\n &--editing {\n @apply tw-flex-col tw-items-stretch;\n }\n }\n\n &__field-label {\n @apply tw-text-[var(--mobile-card-text-secondary)] tw-flex-shrink-0;\n }\n\n &__field-value {\n @apply tw-font-medium tw-text-[var(--mobile-card-text)] tw-truncate;\n\n // In editing mode, allow overflow for error messages\n &--editing {\n @apply tw-overflow-visible tw-whitespace-normal;\n }\n }\n\n // Statuses - row of badges at bottom\n &__statuses {\n @apply tw-flex tw-flex-wrap tw-items-center tw-gap-2 tw-mt-1;\n }\n\n // Swipe actions\n &__actions {\n @apply tw-absolute tw-top-0 tw-bottom-0 tw-right-0 tw-flex tw-flex-row tw-rounded-r-lg tw-overflow-hidden;\n will-change: width;\n }\n\n &__action {\n @apply tw-flex tw-flex-col tw-justify-center tw-items-center tw-w-[70px]\n tw-text-[var(--mobile-card-action-text)] tw-bg-[var(--mobile-card-action-bg)]\n tw-border-none tw-outline-none tw-p-0 tw-transition-all tw-duration-150;\n\n // Round corners on last action button\n &:last-child {\n @apply tw-rounded-r-lg;\n }\n\n &:active {\n @apply tw-opacity-80 tw-scale-95;\n }\n\n &--default {\n @apply tw-bg-[var(--mobile-card-action-bg)];\n }\n\n &--danger {\n @apply tw-bg-[var(--mobile-card-action-danger)];\n }\n\n &--success {\n @apply tw-bg-[var(--mobile-card-action-success)];\n }\n\n &--warning {\n @apply tw-bg-[var(--mobile-card-action-warning)];\n }\n\n &--more {\n @apply tw-bg-[var(--mobile-card-action-more)];\n }\n\n &--disabled {\n @apply tw-opacity-50 tw-cursor-not-allowed tw-pointer-events-none;\n }\n }\n\n &__action-title {\n @apply tw-mt-1 tw-text-xs tw-text-center;\n }\n}\n</style>\n","import { computed, type Ref } from \"vue\";\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\nimport type {\n MobileCardLayout,\n MobileColumnConfig,\n MobileCardPosition,\n MobileCardRole,\n MobileFieldPosition,\n} from \"@ui/components/organisms/vc-data-table/types\";\n\n/** Field positions in order for auto-placement */\nconst FIELD_POSITIONS: MobileFieldPosition[] = [\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"];\n\n/** Maximum number of fields in 2x2 grid */\nconst MAX_FIELDS = 4;\n\n/** Types treated as statuses in default mobile layout */\nconst STATUS_TYPES = new Set([\"status\", \"status-icon\"]);\n\n/** Types preferred as title in default mobile layout */\nconst TITLE_PRIORITY_TYPES = new Set([\"text\", \"link\", \"html\"]);\n\nexport interface UseMobileCardLayoutOptions {\n /** Column instances from VcColumn */\n columns: Ref<ColumnInstance[]>;\n}\n\nexport interface UseMobileCardLayoutReturn {\n /** Computed mobile card layout */\n mobileLayout: Ref<MobileCardLayout>;\n /** Whether any columns are configured for mobile */\n hasMobileColumns: Ref<boolean>;\n /** Columns that are visible on mobile */\n mobileVisibleColumns: Ref<MobileColumnConfig[]>;\n}\n\n/**\n * Map legacy mobilePosition to mobileRole.\n * Used for backward compatibility when only mobilePosition is specified.\n */\nfunction mapPositionToRole(position: MobileCardPosition, isFirstTopLeft: boolean): MobileCardRole {\n switch (position) {\n case \"image\":\n return \"image\";\n case \"status\":\n return \"status\";\n case \"top-left\":\n // First top-left becomes title in legacy mode\n return isFirstTopLeft ? \"title\" : \"field\";\n case \"top-right\":\n case \"bottom-left\":\n case \"bottom-right\":\n return \"field\";\n default:\n return \"field\";\n }\n}\n\n/**\n * Create MobileColumnConfig from column instance.\n */\nfunction createColumnConfig(\n col: ColumnInstance,\n position: MobileCardPosition,\n isTitle: boolean = false,\n): MobileColumnConfig {\n return {\n id: col.props.id,\n field: col.props.field,\n type: col.props.type,\n position,\n label: col.props.title,\n isTitle,\n column: col,\n };\n}\n\n/**\n * Returns true for service-only columns that should not appear in fallback mobile cards.\n */\nfunction isServiceColumn(col: ColumnInstance): boolean {\n const { selectionMode, rowEditor, rowReorder, expander } = col.props;\n return Boolean(selectionMode || rowEditor || rowReorder || expander);\n}\n\n/**\n * Build a default mobile layout when no explicit mobile configuration is provided.\n * Strategy (legacy-friendly):\n * - First text-like column => title\n * - First image column => image block\n * - All status/status-icon columns => statuses row\n * - Next regular columns (up to 4) => fields grid\n */\nfunction createDefaultMobileConfigs(columns: ColumnInstance[]): MobileColumnConfig[] {\n const configs: MobileColumnConfig[] = [];\n const eligibleColumns = columns.filter(\n (col) => col.props.visible !== false && col.props.mobileVisible !== false && !isServiceColumn(col),\n );\n\n if (eligibleColumns.length === 0) {\n return configs;\n }\n\n const imageColumn = eligibleColumns.find((col) => col.props.type === \"image\");\n const statusColumns = eligibleColumns.filter((col) => STATUS_TYPES.has(col.props.type ?? \"\"));\n\n const regularColumns = eligibleColumns.filter((col) => col !== imageColumn && !statusColumns.includes(col));\n const titleColumn = regularColumns.find((col) => TITLE_PRIORITY_TYPES.has(col.props.type ?? \"\")) ?? regularColumns[0];\n\n if (titleColumn) {\n configs.push(createColumnConfig(titleColumn, \"top-left\", true));\n }\n\n if (imageColumn) {\n configs.push(createColumnConfig(imageColumn, \"image\"));\n }\n\n for (const statusColumn of statusColumns) {\n configs.push(createColumnConfig(statusColumn, \"status\"));\n }\n\n const fieldColumns = regularColumns.filter((col) => col !== titleColumn).slice(0, MAX_FIELDS);\n for (let i = 0; i < fieldColumns.length; i++) {\n configs.push(createColumnConfig(fieldColumns[i], FIELD_POSITIONS[i]));\n }\n\n return configs;\n}\n\n/**\n * Composable for computing mobile card layout from VcColumn definitions.\n *\n * Supports two APIs:\n * 1. **New API (recommended)**: Use `mobileRole` for semantic roles\n * - `title`: Primary identifier (full width, bold)\n * - `image`: Visual element (left side)\n * - `field`: Data with label (auto-distributed in 2x2 grid, max 4)\n * - `status`: Status badge (multiple allowed, bottom row)\n *\n * 2. **Legacy API**: Use `mobilePosition` (backward compatible)\n * - Automatically maps to roles: image→image, status→status,\n * first top-left→title, others→field\n *\n * Auto-placement for fields:\n * - Fields with explicit `mobilePosition` are placed there\n * - Fields without `mobilePosition` fill remaining grid positions in order\n * - Maximum 4 fields (2x2 grid), excess fields are hidden\n *\n * @example\n * ```vue\n * <!-- New API with mobileRole -->\n * <VcColumn id=\"name\" title=\"Name\" mobile-role=\"title\" />\n * <VcColumn id=\"price\" title=\"Price\" type=\"money\" mobile-role=\"field\" />\n * <VcColumn id=\"status\" type=\"status\" mobile-role=\"status\" />\n *\n * <!-- Legacy API with mobilePosition (still works) -->\n * <VcColumn id=\"name\" title=\"Name\" mobile-position=\"top-left\" />\n * ```\n */\nexport function useMobileCardLayout(options: UseMobileCardLayoutOptions): UseMobileCardLayoutReturn {\n const { columns } = options;\n\n /**\n * Process columns and determine their mobile configuration.\n * Priority: explicit mobileRole/mobilePosition > type-based fallback\n */\n const mobileVisibleColumns = computed<MobileColumnConfig[]>(() => {\n const configs: MobileColumnConfig[] = [];\n const fallbackColumns: ColumnInstance[] = [];\n let hasExplicitMobileConfig = false;\n\n // Track if we've seen first top-left for legacy mapping\n let firstTopLeftSeen = false;\n\n for (const col of columns.value) {\n const { mobileRole, mobilePosition } = col.props;\n const hasExplicitConfig = Boolean(mobileRole || mobilePosition);\n\n // Respect desktop/mobile visibility flags\n if (col.props.visible === false || col.props.mobileVisible === false) continue;\n\n // Only visible columns should switch layout to explicit mode.\n // Hidden explicit columns must not suppress fallback layout for visible data columns.\n if (hasExplicitConfig) {\n hasExplicitMobileConfig = true;\n }\n\n // Fallback candidates: columns without explicit mobile config\n if (!hasExplicitConfig) {\n fallbackColumns.push(col);\n continue;\n }\n\n // Determine the effective role\n let role: MobileCardRole;\n let position: MobileCardPosition;\n\n if (mobileRole) {\n // New API: mobileRole is specified\n role = mobileRole;\n // For fields, mobilePosition can override auto-placement\n position =\n mobileRole === \"field\" && mobilePosition\n ? mobilePosition\n : mobileRole === \"image\"\n ? \"image\"\n : mobileRole === \"status\"\n ? \"status\"\n : mobileRole === \"title\"\n ? \"top-left\" // Title uses top-left position internally\n : \"bottom-left\"; // Default for visible-only columns\n } else if (mobilePosition) {\n // Legacy API: only mobilePosition is specified\n const isFirstTopLeft = mobilePosition === \"top-left\" && !firstTopLeftSeen;\n if (isFirstTopLeft) firstTopLeftSeen = true;\n\n role = mapPositionToRole(mobilePosition, isFirstTopLeft);\n position = mobilePosition;\n } else {\n // mobileVisible: true without role/position - treat as hidden field\n continue;\n }\n\n configs.push({\n id: col.props.id,\n field: col.props.field,\n type: col.props.type,\n position,\n label: col.props.title,\n isTitle: role === \"title\",\n column: col,\n });\n }\n\n // Explicit config always wins (including intentional empty layout)\n if (hasExplicitMobileConfig) {\n return configs;\n }\n\n // No explicit mobile config -> build base layout from column types\n return createDefaultMobileConfigs(fallbackColumns);\n });\n\n /**\n * Whether any columns are configured for mobile display\n */\n const hasMobileColumns = computed(() => mobileVisibleColumns.value.length > 0);\n\n /**\n * Computed mobile card layout with columns distributed to positions.\n * Uses new universal layout structure (title, image, fields[], statuses[]).\n */\n const mobileLayout = computed<MobileCardLayout>(() => {\n const layout: MobileCardLayout = {\n title: undefined,\n image: undefined,\n fields: [],\n statuses: [],\n };\n\n // Separate columns by role\n const titleCols: MobileColumnConfig[] = [];\n const imageCols: MobileColumnConfig[] = [];\n const fieldCols: MobileColumnConfig[] = [];\n const statusCols: MobileColumnConfig[] = [];\n\n for (const col of mobileVisibleColumns.value) {\n if (col.isTitle) {\n titleCols.push(col);\n } else if (col.position === \"image\") {\n imageCols.push(col);\n } else if (col.position === \"status\") {\n statusCols.push(col);\n } else {\n // All position-based columns (top-left, top-right, bottom-left, bottom-right)\n fieldCols.push(col);\n }\n }\n\n // Assign single title (first one wins)\n if (titleCols.length > 0) {\n layout.title = titleCols[0];\n }\n\n // Assign single image (first one wins)\n if (imageCols.length > 0) {\n layout.image = imageCols[0];\n }\n\n // Assign multiple statuses (all allowed)\n layout.statuses = statusCols;\n\n // Auto-placement algorithm for fields\n // 1. Track which positions are explicitly occupied\n const occupiedPositions = new Set<MobileFieldPosition>();\n const explicitlyPlacedFields: MobileColumnConfig[] = [];\n const autoPlaceFields: MobileColumnConfig[] = [];\n\n for (const field of fieldCols) {\n const pos = field.position as MobileFieldPosition;\n if (FIELD_POSITIONS.includes(pos)) {\n // Field has explicit position\n occupiedPositions.add(pos);\n explicitlyPlacedFields.push(field);\n } else {\n // Field needs auto-placement\n autoPlaceFields.push(field);\n }\n }\n\n // 2. Add explicitly placed fields\n const allFields = [...explicitlyPlacedFields];\n\n // 3. Auto-place remaining fields in free positions\n const freePositions = FIELD_POSITIONS.filter((pos) => !occupiedPositions.has(pos));\n for (let i = 0; i < autoPlaceFields.length && i < freePositions.length; i++) {\n const field = autoPlaceFields[i];\n // Update position to the auto-assigned one\n allFields.push({\n ...field,\n position: freePositions[i],\n });\n }\n\n // 4. Limit to MAX_FIELDS (2x2 grid)\n layout.fields = allFields.slice(0, MAX_FIELDS);\n\n // Sort fields by position order for consistent rendering\n layout.fields.sort((a, b) => {\n const posA = FIELD_POSITIONS.indexOf(a.position as MobileFieldPosition);\n const posB = FIELD_POSITIONS.indexOf(b.position as MobileFieldPosition);\n return posA - posB;\n });\n\n return layout;\n });\n\n return {\n mobileLayout,\n hasMobileColumns,\n mobileVisibleColumns,\n };\n}\n\nexport default useMobileCardLayout;\n","<template>\n <div\n ref=\"containerRef\"\n class=\"vc-pull-to-refresh\"\n @touchstart.passive=\"onTouchStart\"\n @touchmove.passive=\"onTouchMove\"\n @touchend=\"onTouchEnd\"\n >\n <!-- Refresh indicator (hidden above content) -->\n <div\n class=\"vc-pull-to-refresh__indicator\"\n :style=\"indicatorStyle\"\n >\n <div class=\"vc-pull-to-refresh__indicator-content\">\n <VcIcon\n :icon=\"indicatorIcon\"\n class=\"vc-pull-to-refresh__icon\"\n :class=\"iconClasses\"\n />\n <span class=\"vc-pull-to-refresh__text\">{{ statusText }}</span>\n </div>\n </div>\n\n <!-- Content with spring animation -->\n <div\n class=\"vc-pull-to-refresh__content\"\n :style=\"contentStyle\"\n >\n <slot />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * PullToRefresh - Pull-to-refresh component with spring animation\n *\n * Provides iOS-like pull-to-refresh functionality for mobile views.\n * Uses spring physics animation for natural feel.\n *\n * Features:\n * - Spring physics animation (matching swipe actions)\n * - Icon rotates 180° when threshold passed\n * - Only active on mobile\n * - Disabled when content is scrolled down (scrollTop > 0)\n * - Disabled when refreshing=true\n */\nimport { ref, computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\nexport interface PullToRefreshProps {\n /** Enable/disable pull-to-refresh */\n enabled?: boolean;\n /** Distance threshold to trigger refresh (px) */\n threshold?: number;\n /** Loading state - parent controls when refresh is complete */\n refreshing?: boolean;\n /** Custom text for \"pull\" state (overrides i18n) */\n pullText?: string;\n /** Custom text for \"release\" state (overrides i18n) */\n releaseText?: string;\n /** Custom text for \"refreshing\" state (overrides i18n) */\n refreshingText?: string;\n}\n\nconst props = withDefaults(defineProps<PullToRefreshProps>(), {\n enabled: true,\n threshold: 60,\n refreshing: false,\n pullText: undefined,\n releaseText: undefined,\n refreshingText: undefined,\n});\n\n// i18n\nconst { t } = useI18n({ useScope: \"global\" });\n\nconst emit = defineEmits<{\n /** Triggered when user releases after passing threshold */\n refresh: [];\n}>();\n\n// Check if mobile via useResponsive composable\nconst { isMobile } = useResponsive();\n\n// Refs\nconst containerRef = ref<HTMLElement | null>(null);\n\n// Pull state\nconst pullDistance = ref(0);\nconst isPulling = ref(false);\nconst canRelease = ref(false);\nconst isAnimating = ref(false);\nconst animationId = ref<number | null>(null);\n\n// Touch tracking\nconst startY = ref(0);\nconst velocity = ref(0);\nconst lastTime = ref(0);\nconst lastY = ref(0);\n\n// Spring animation constants (matching swipe actions)\nconst SPRING_STIFFNESS = 0.08;\nconst SPRING_DAMPING = 0.7;\nconst SPRING_MASS = 1;\n\n// Indicator height\nconst INDICATOR_HEIGHT = 60;\n\n// Computed states\nconst isActive = computed(() => {\n return props.enabled && isMobile.value && !props.refreshing;\n});\n\nconst indicatorIcon = computed(() => {\n if (props.refreshing) {\n return \"lucide-refresh-cw\";\n }\n return \"lucide-arrow-down\";\n});\n\nconst iconClasses = computed(() => ({\n \"vc-pull-to-refresh__icon--rotate\": canRelease.value && !props.refreshing,\n \"vc-pull-to-refresh__icon--spin\": props.refreshing,\n}));\n\nconst statusText = computed(() => {\n if (props.refreshing) {\n return props.refreshingText ?? t(\"COMPONENTS.ORGANISMS.VC_TABLE.REFRESHING\");\n }\n if (canRelease.value) {\n return props.releaseText ?? t(\"COMPONENTS.ORGANISMS.VC_TABLE.RELEASE_TO_REFRESH\");\n }\n return props.pullText ?? t(\"COMPONENTS.ORGANISMS.VC_TABLE.PULL_TO_REFRESH\");\n});\n\nconst indicatorStyle = computed(() => {\n const offset = Math.min(pullDistance.value, INDICATOR_HEIGHT + 20);\n return {\n transform: `translateY(${offset - INDICATOR_HEIGHT}px)`,\n opacity: Math.min(pullDistance.value / props.threshold, 1),\n };\n});\n\nconst contentStyle = computed(() => {\n return {\n transform: `translateY(${pullDistance.value}px)`,\n };\n});\n\n// Check if container is scrolled to top\nfunction isAtTop(): boolean {\n if (!containerRef.value) return true;\n\n // Check if container or any scrollable parent is scrolled\n let element: HTMLElement | null = containerRef.value;\n while (element) {\n if (element.scrollTop > 0) {\n return false;\n }\n element = element.parentElement;\n }\n return true;\n}\n\n// Spring animation\nfunction springAnimation(targetValue: number, duration = 300) {\n if (animationId.value !== null) {\n cancelAnimationFrame(animationId.value);\n }\n\n const startValue = pullDistance.value;\n const startTime = performance.now();\n let springVelocity = velocity.value;\n let currentValue = startValue;\n\n isAnimating.value = true;\n\n function animate(time: number) {\n const elapsed = time - startTime;\n\n if (elapsed < duration) {\n const springForce = (targetValue - currentValue) * SPRING_STIFFNESS;\n const dampingForce = springVelocity * SPRING_DAMPING;\n const acceleration = (springForce - dampingForce) / SPRING_MASS;\n\n springVelocity += acceleration;\n currentValue += springVelocity;\n\n pullDistance.value = Math.max(0, currentValue);\n\n animationId.value = requestAnimationFrame(animate);\n } else {\n pullDistance.value = targetValue;\n isAnimating.value = false;\n animationId.value = null;\n }\n }\n\n animationId.value = requestAnimationFrame(animate);\n}\n\n// Touch handlers\nfunction onTouchStart(e: TouchEvent) {\n if (!isActive.value || isAnimating.value) return;\n if (!isAtTop()) return;\n\n const touch = e.touches[0];\n startY.value = touch.clientY;\n velocity.value = 0;\n lastTime.value = Date.now();\n lastY.value = touch.clientY;\n isPulling.value = true;\n}\n\nfunction onTouchMove(e: TouchEvent) {\n if (!isActive.value || !isPulling.value || isAnimating.value) return;\n\n const touch = e.touches[0];\n const currentY = touch.clientY;\n const deltaY = currentY - startY.value;\n\n // Only handle pull down\n if (deltaY < 0) {\n isPulling.value = false;\n pullDistance.value = 0;\n return;\n }\n\n // Calculate velocity for inertia\n const now = Date.now();\n const dt = now - lastTime.value;\n if (dt > 0) {\n velocity.value = (currentY - lastY.value) / dt;\n }\n lastTime.value = now;\n lastY.value = currentY;\n\n // Apply resistance as user pulls further\n const resistance = Math.max(0.4, 1 - deltaY / 300);\n let newPullDistance = deltaY * resistance;\n\n // Cap at max pull distance\n const maxPull = props.threshold * 2.5;\n newPullDistance = Math.min(newPullDistance, maxPull);\n\n pullDistance.value = newPullDistance;\n canRelease.value = newPullDistance >= props.threshold;\n}\n\nfunction onTouchEnd() {\n if (!isPulling.value) return;\n\n isPulling.value = false;\n\n if (canRelease.value && !props.refreshing) {\n // Trigger refresh\n emit(\"refresh\");\n // Animate to threshold height (show indicator while refreshing)\n springAnimation(INDICATOR_HEIGHT);\n } else {\n // Animate back to 0\n springAnimation(0);\n }\n\n canRelease.value = false;\n}\n\n// Watch for refreshing prop to animate back when done\nimport { watch } from \"vue\";\n\nwatch(\n () => props.refreshing,\n (newValue, oldValue) => {\n if (oldValue && !newValue) {\n // Refreshing finished, animate back to 0\n springAnimation(0);\n }\n },\n);\n\n// Cleanup on unmount\nimport { onUnmounted } from \"vue\";\n\nonUnmounted(() => {\n if (animationId.value !== null) {\n cancelAnimationFrame(animationId.value);\n }\n});\n\n// Expose for testing\ndefineExpose({\n pullDistance,\n canRelease,\n isPulling,\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --ptr-indicator-bg: var(--additional-50);\n --ptr-indicator-text: var(--neutrals-600);\n --ptr-indicator-icon: var(--primary-500);\n}\n\n.vc-pull-to-refresh {\n // overflow: clip (not hidden!) — clips the pull indicator visually\n // but does NOT create a scroll container. With `hidden`, touch scroll events\n // get trapped and never reach the parent overflow-y: auto element.\n @apply tw-relative;\n overflow: clip;\n // Fill the available height of the scroll container so the mobile card view\n // stretches to all free space instead of collapsing to content height.\n @apply tw-flex tw-flex-col tw-flex-1 tw-min-h-0;\n\n &__indicator {\n @apply tw-absolute tw-left-0 tw-right-0 tw-top-0 tw-flex tw-items-center tw-justify-center;\n @apply tw-bg-[var(--ptr-indicator-bg)] tw-text-[var(--ptr-indicator-text)];\n height: 60px;\n z-index: var(--z-local-sticky);\n }\n\n &__indicator-content {\n @apply tw-flex tw-items-center tw-gap-2;\n }\n\n &__icon {\n @apply tw-text-xl tw-text-[var(--ptr-indicator-icon)] tw-transition-transform tw-duration-200;\n\n &--rotate {\n transform: rotate(180deg);\n }\n\n &--spin {\n animation: ptr-spin 1s linear infinite;\n }\n }\n\n &__text {\n @apply tw-text-sm tw-font-medium;\n }\n\n &__content {\n @apply tw-relative tw-will-change-transform;\n // Fill height so the wrapped mobile card view can stretch.\n @apply tw-flex tw-flex-col tw-flex-1 tw-min-h-0;\n }\n}\n\n@keyframes ptr-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n","<template>\n <PullToRefresh\n :enabled=\"pullToRefresh\"\n :refreshing=\"loading\"\n :pull-text=\"pullToRefreshText?.pull\"\n :release-text=\"pullToRefreshText?.release\"\n :refreshing-text=\"pullToRefreshText?.refreshing\"\n @refresh=\"emit('refresh')\"\n >\n <div class=\"vc-data-table-mobile-view\">\n <!-- Empty state -->\n <div\n v-if=\"!loading && items.length === 0\"\n class=\"vc-data-table-mobile-view__empty\"\n >\n <slot name=\"empty\">\n <div class=\"vc-data-table-mobile-view__empty-content\">\n <VcIcon\n :icon=\"empty?.icon || 'lucide-inbox'\"\n class=\"vc-data-table-mobile-view__empty-icon\"\n />\n <p class=\"vc-data-table-mobile-view__empty-text\">\n {{ empty?.text || emptyText }}\n </p>\n <VcButton\n v-if=\"empty?.action\"\n variant=\"primary\"\n @click=\"empty?.clickHandler\"\n >\n {{ empty.action }}\n </VcButton>\n </div>\n </slot>\n </div>\n\n <!-- Cards list -->\n <div\n v-if=\"items.length > 0\"\n ref=\"listRef\"\n class=\"vc-data-table-mobile-view__list\"\n >\n <DataTableMobileCard\n v-for=\"(item, index) in items\"\n :key=\"getItemKey(item, index)\"\n :item=\"item\"\n :index=\"index\"\n :reorderable=\"reorderable\"\n :layout=\"mobileLayout\"\n :is-selected=\"isItemSelected(item)\"\n :is-selectable=\"isItemSelectable(item)\"\n :actions=\"getItemActions(item)\"\n :selection-mode=\"selectionMode\"\n :any-selected=\"hasSelection\"\n :data-key=\"dataKey\"\n :more-label=\"moreLabel\"\n :action-sheet-title=\"actionSheetTitle\"\n :cancel-label=\"cancelLabel\"\n :is-inline-editing=\"isInlineEditing\"\n :is-new-row=\"newRowIndices?.has(index)\"\n @click=\"handleRowClick\"\n @select=\"handleRowSelect\"\n @action=\"handleAction\"\n @cell-value-change=\"(field, value) => emit('cell-value-change', field, index, value)\"\n />\n </div>\n </div>\n </PullToRefresh>\n</template>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\n/**\n * DataTableMobileView - Mobile view container for VcDataTable\n *\n * Manages the list of mobile cards with:\n * - Swipe context provider\n * - Loading and empty states\n * - Selection management\n * - Action handling\n */\nimport { computed, ref, unref } from \"vue\";\nimport type {\n MobileSwipeAction,\n TableEmptyAction,\n ColumnInstance,\n TableAction,\n PullToRefreshTextConfig,\n} from \"@ui/components/organisms/vc-data-table/types\";\nimport { useMobileCardLayout } from \"@ui/components/organisms/vc-data-table/composables/useMobileCardLayout\";\nimport { provideTableSwipe } from \"@ui/components/organisms/vc-data-table/composables/useTableSwipe\";\nimport DataTableMobileCard from \"@ui/components/organisms/vc-data-table/components/mobile/DataTableMobileCard.vue\";\nimport PullToRefresh from \"@ui/components/organisms/vc-data-table/components/mobile/PullToRefresh.vue\";\nimport { VcButton } from \"@ui/components/atoms/vc-button\";\nimport { VcIcon } from \"@ui/components/atoms/vc-icon\";\n\nconst props = withDefaults(\n defineProps<{\n /** Data items to display */\n items: T[];\n /** Column instances from VcColumn */\n columns: ColumnInstance[];\n /** Currently selected items */\n selection?: T[];\n /** Selection mode */\n selectionMode?: \"single\" | \"multiple\";\n /** Function to check if row is selectable */\n isRowSelectable?: (data: T) => boolean;\n /** Function to generate row actions */\n rowActions?: (item: T) => TableAction[];\n /** Loading state */\n loading?: boolean;\n /** Data key field for item identification */\n dataKey?: string;\n /** Empty state configuration */\n empty?: TableEmptyAction;\n /** Empty text (fallback) */\n emptyText?: string;\n /** \"More\" button label */\n moreLabel?: string;\n /** Action sheet title */\n actionSheetTitle?: string;\n /** Cancel button label */\n cancelLabel?: string;\n /** Enable pull-to-refresh */\n pullToRefresh?: boolean;\n /** Custom text for pull-to-refresh states */\n pullToRefreshText?: PullToRefreshTextConfig;\n /** Whether inline editing is active */\n isInlineEditing?: boolean;\n /** Set of new row indices */\n newRowIndices?: Set<number>;\n /** Whether row reorder is enabled */\n reorderable?: boolean;\n }>(),\n {\n selection: () => [],\n selectionMode: undefined,\n isRowSelectable: () => true,\n rowActions: undefined,\n loading: false,\n dataKey: \"id\",\n empty: undefined,\n emptyText: \"No data available\",\n moreLabel: \"More\",\n actionSheetTitle: \"Actions\",\n cancelLabel: \"Cancel\",\n pullToRefresh: false,\n pullToRefreshText: undefined,\n isInlineEditing: false,\n newRowIndices: undefined,\n reorderable: false,\n },\n);\n\nconst emit = defineEmits<{\n /** Row was clicked */\n click: [item: T, index: number];\n /** Row selection changed */\n select: [item: T, index: number];\n /** Action was triggered */\n action: [action: MobileSwipeAction<T>, item: T, index: number];\n /** Pull-to-refresh triggered */\n refresh: [];\n /** Cell value changed during editing */\n \"cell-value-change\": [field: string, index: number, value: unknown];\n}>();\n\n// Provide swipe context for cards\nprovideTableSwipe();\n\n// Compute mobile layout from columns\nconst columnsRef = computed(() => props.columns);\nconst { mobileLayout, hasMobileColumns } = useMobileCardLayout({ columns: columnsRef });\n\n// Selection helpers\nconst hasSelection = computed(() => (props.selection?.length ?? 0) > 0);\n\nfunction isItemSelected(item: T): boolean {\n if (!props.selection) return false;\n const itemKey = item[props.dataKey];\n return props.selection.some((s) => s[props.dataKey] === itemKey);\n}\n\nfunction isItemSelectable(item: T): boolean {\n if (!props.isRowSelectable) return true;\n return props.isRowSelectable(item);\n}\n\n// Generate item key\nfunction getItemKey(item: T, index: number): string {\n return String(item[props.dataKey] ?? `item-${index}`);\n}\n\n// Convert TableAction to MobileSwipeAction\nfunction getItemActions(item: T): MobileSwipeAction<T>[] {\n if (!props.rowActions) return [];\n\n const actions = props.rowActions(item);\n if (!actions) return [];\n\n return actions.map((action) => ({\n id: action.id || String(unref(action.title)),\n title: String(unref(action.title)),\n icon: action.icon || \"lucide-ellipsis\",\n type: mapActionType(action.variant),\n disabled: action.disabled,\n clickHandler: (actionItem: T, index: number) => {\n action.clickHandler?.(actionItem, index);\n },\n }));\n}\n\nfunction mapActionType(variant?: string): \"danger\" | \"success\" | \"warning\" | \"default\" {\n switch (variant) {\n case \"danger\":\n return \"danger\";\n case \"success\":\n return \"success\";\n case \"warning\":\n return \"warning\";\n default:\n return \"default\";\n }\n}\n\n// Event handlers\nfunction handleRowClick(item: T, index: number) {\n emit(\"click\", item, index);\n}\n\nfunction handleRowSelect(item: T, index: number) {\n emit(\"select\", item, index);\n}\n\nfunction handleAction(action: MobileSwipeAction<T>, item: T, index: number) {\n emit(\"action\", action, item, index);\n}\n\nconst listRef = ref<HTMLElement | null>(null);\nconst listEl = computed<HTMLElement | undefined>(() => listRef.value ?? undefined);\n\n// Expose layout status for parent component\ndefineExpose({\n hasMobileColumns,\n mobileLayout,\n listEl,\n});\n</script>\n\n<style lang=\"scss\">\n:root {\n --mobile-view-bg: var(--additional-50);\n --mobile-view-empty-text: var(--neutrals-500);\n --mobile-view-empty-icon: var(--neutrals-300);\n}\n\n.vc-data-table-mobile-view {\n @apply tw-relative tw-min-h-[200px] tw-bg-[var(--mobile-view-bg)];\n // Stretch to fill the scroll container (PullToRefresh → content → here) so the\n // card list area occupies all free space rather than collapsing to content height.\n @apply tw-flex tw-flex-col tw-flex-1 tw-min-h-0;\n\n &__empty {\n @apply tw-flex tw-items-center tw-justify-center tw-min-h-[200px] tw-p-8;\n }\n\n &__empty-content {\n @apply tw-flex tw-flex-col tw-items-center tw-gap-4 tw-text-center;\n }\n\n &__empty-icon {\n @apply tw-text-6xl tw-text-[var(--mobile-view-empty-icon)];\n }\n\n &__empty-text {\n @apply tw-text-[var(--mobile-view-empty-text)] tw-m-0;\n }\n\n &__list {\n @apply tw-flex tw-flex-col;\n }\n}\n</style>\n","import { inject } from \"vue\";\r\nimport { TableContextKey, type TableContext } from \"@ui/components/organisms/vc-data-table/keys\";\r\n\r\n// Re-export for backward compatibility (TableContext now lives in keys.ts)\r\nexport type { TableContext };\r\n\r\n/**\r\n * Hook to access table context from child components\r\n * @returns Table context or null if not inside a Table component\r\n */\r\nexport function useTableContext<T = any>(): TableContext<T> | null {\r\n return inject(TableContextKey, null) as TableContext<T> | null;\r\n}\r\n","// useColumnWidthEngine.ts\n\n/**\n * Weight-based column width engine.\n *\n * Pure functions — no Vue reactivity. Fully deterministic:\n * same input always produces same output with exact integer sum.\n */\n\nexport interface ColumnSpec {\n weight: number;\n minPx: number;\n maxPx: number;\n}\n\nexport interface EngineInput {\n availableWidth: number;\n columns: { id: string; spec: ColumnSpec }[];\n mode: \"fit\" | \"gap\";\n}\n\nexport interface EngineOutput {\n widths: Record<string, number>;\n fillerWidth: number;\n}\n\nexport type ParsedWidth =\n | { type: \"px\"; desiredPx: number }\n | { type: \"percent\"; desiredPx: number }\n | { type: \"auto\"; desiredPx: null };\n\n/**\n * Default minimum column width in pixels when VcColumn.minWidth is not set.\n * Shared between engine, resize composable, and watcher init paths.\n */\nexport const DEFAULT_MIN_COLUMN_PX = 40;\n\n// ============================================================================\n// Core engine\n// ============================================================================\n\nexport function computeColumnWidths(input: EngineInput): EngineOutput {\n const { availableWidth, columns, mode } = input;\n\n // Edge cases\n if (availableWidth <= 0 || columns.length === 0) {\n const widths: Record<string, number> = {};\n for (const col of columns) widths[col.id] = 0;\n return { widths, fillerWidth: columns.length === 0 ? Math.max(0, availableWidth) : 0 };\n }\n\n // Step 1: Desired px from weights\n const desired = columns.map((col) => col.spec.weight * availableWidth);\n\n // Step 2: Clamp pass\n const clamped = columns.map((col, i) => Math.max(col.spec.minPx, Math.min(desired[i], col.spec.maxPx)));\n\n // Step 3: Delta\n let delta = availableWidth - clamped.reduce((s, w) => s + w, 0);\n\n // Step 4: Gap mode — positive delta becomes filler\n if (mode === \"gap\" && delta >= 0) {\n return finalize(columns, clamped, delta, availableWidth);\n }\n\n // Step 5: Grow pass (fit mode, delta > 0)\n if (delta > 0) {\n distributeGrow(columns, clamped, delta);\n delta = availableWidth - clamped.reduce((s, w) => s + w, 0);\n }\n\n // Step 6: Shrink pass (delta < 0)\n if (delta < 0) {\n distributeShrink(columns, clamped, delta);\n delta = availableWidth - clamped.reduce((s, w) => s + w, 0);\n }\n\n // Step 7: Crisis — sum(minPx) > available\n if (delta < -0.5) {\n crisisSqueeze(columns, clamped, availableWidth);\n delta = 0;\n }\n\n return finalize(columns, clamped, 0, availableWidth);\n}\n\nfunction distributeGrow(columns: EngineInput[\"columns\"], clamped: number[], surplus: number): void {\n let remaining = surplus;\n const maxIters = columns.length;\n\n for (let iter = 0; iter < maxIters && remaining > 0.5; iter++) {\n // Eligible: columns not yet at maxPx\n const eligible: number[] = [];\n let totalCapacity = 0;\n\n for (let i = 0; i < columns.length; i++) {\n const capacity = columns[i].spec.maxPx - clamped[i];\n if (capacity > 0.5) {\n eligible.push(i);\n totalCapacity += capacity;\n }\n }\n\n if (eligible.length === 0 || totalCapacity <= 0) break;\n\n const hasInfinite = !isFinite(totalCapacity);\n let distributed = 0;\n\n if (hasInfinite) {\n // When some columns have infinite capacity, distribute by weight\n const totalWeight = eligible.reduce((s, idx) => s + columns[idx].spec.weight, 0) || eligible.length;\n for (const idx of eligible) {\n const w = totalWeight > 0 ? columns[idx].spec.weight / totalWeight : 1 / eligible.length;\n const share = w * remaining;\n const capacity = columns[idx].spec.maxPx - clamped[idx];\n const actual = Math.min(share, capacity);\n clamped[idx] += actual;\n distributed += actual;\n }\n } else {\n for (const idx of eligible) {\n const capacity = columns[idx].spec.maxPx - clamped[idx];\n const share = (capacity / totalCapacity) * remaining;\n const actual = Math.min(share, capacity);\n clamped[idx] += actual;\n distributed += actual;\n }\n }\n remaining -= distributed;\n }\n}\n\nfunction distributeShrink(columns: EngineInput[\"columns\"], clamped: number[], deficit: number): void {\n let remaining = Math.abs(deficit);\n const maxIters = columns.length;\n\n for (let iter = 0; iter < maxIters && remaining > 0.5; iter++) {\n const eligible: number[] = [];\n let totalCapacity = 0;\n\n for (let i = 0; i < columns.length; i++) {\n const capacity = clamped[i] - columns[i].spec.minPx;\n if (capacity > 0.5) {\n eligible.push(i);\n totalCapacity += capacity;\n }\n }\n\n if (eligible.length === 0 || totalCapacity <= 0) break;\n\n let distributed = 0;\n for (const idx of eligible) {\n const capacity = clamped[idx] - columns[idx].spec.minPx;\n const share = (capacity / totalCapacity) * remaining;\n const actual = Math.min(share, capacity);\n clamped[idx] -= actual;\n distributed += actual;\n }\n remaining -= distributed;\n }\n}\n\nfunction crisisSqueeze(columns: EngineInput[\"columns\"], clamped: number[], availableWidth: number): void {\n console.warn(\n `[VcDataTable] Column width crisis: sum(minPx)=${columns.reduce((s, c) => s + c.spec.minPx, 0)}px > availableWidth=${availableWidth}px. Columns will be squeezed below their minimum widths.`,\n );\n\n // Proportional distribution of available space, ignoring minPx\n const totalWeight = columns.reduce((s, c) => s + c.spec.weight, 0) || columns.length;\n for (let i = 0; i < columns.length; i++) {\n const w = totalWeight > 0 ? columns[i].spec.weight / totalWeight : 1 / columns.length;\n clamped[i] = Math.max(0, w * availableWidth);\n }\n}\n\n/**\n * Integer rounding via largest-remainder method.\n * Deterministic tie-break by column order index (lower index wins).\n */\nfunction finalize(\n columns: EngineInput[\"columns\"],\n floats: number[],\n fillerFloat: number,\n availableWidth: number,\n): EngineOutput {\n const widths: Record<string, number> = {};\n\n // Floor all values\n const floored = floats.map((f) => Math.floor(f));\n const remainders = floats.map((f, i) => f - floored[i]);\n const flooredFiller = Math.floor(fillerFloat);\n\n const total = floored.reduce((s, w) => s + w, 0) + flooredFiller;\n let shortage = availableWidth - total;\n\n // Build priority list: highest remainder first, ties broken by index (stable)\n const indices = floats.map((_, i) => i);\n indices.sort((a, b) => remainders[b] - remainders[a] || a - b);\n\n // Also consider filler remainder\n const fillerRemainder = fillerFloat - flooredFiller;\n let fillerWidth = flooredFiller;\n\n // Distribute remaining pixels, respecting maxPx\n let idxPointer = 0;\n while (shortage > 0) {\n let assigned = false;\n // Try columns in remainder-priority order\n while (idxPointer < indices.length) {\n const ci = indices[idxPointer];\n if (fillerRemainder > remainders[ci] && fillerFloat > 0) break; // filler has higher priority\n // Skip if adding 1px would exceed maxPx\n if (floored[ci] + 1 > columns[ci].spec.maxPx) {\n idxPointer++;\n continue;\n }\n floored[ci] += 1;\n idxPointer++;\n assigned = true;\n break;\n }\n if (!assigned) {\n fillerWidth += 1;\n }\n shortage--;\n }\n\n for (let i = 0; i < columns.length; i++) {\n widths[columns[i].id] = floored[i];\n }\n\n return { widths, fillerWidth };\n}\n\n// ============================================================================\n// Initialization helpers\n// ============================================================================\n\nexport function parseColumnWidth(value: string | number | undefined, availableWidth: number): ParsedWidth {\n if (value === undefined || value === null || value === \"\") {\n return { type: \"auto\", desiredPx: null };\n }\n\n if (typeof value === \"number\") {\n return { type: \"px\", desiredPx: value };\n }\n\n const trimmed = value.trim();\n\n // Percentage: \"20%\"\n if (trimmed.endsWith(\"%\")) {\n const pct = parseFloat(trimmed) / 100;\n return { type: \"percent\", desiredPx: pct * availableWidth };\n }\n\n // Pixel: \"200px\" or \"200\"\n const pxMatch = trimmed.match(/^(\\d+(?:\\.\\d+)?)(px)?$/);\n if (pxMatch) {\n return { type: \"px\", desiredPx: parseFloat(pxMatch[1]) };\n }\n\n // Unrecognized CSS value (e.g. \"10rem\") — treat as auto.\n // Only px and % are supported; other units are ignored.\n warnUnsupportedWidthOnce(value);\n return { type: \"auto\", desiredPx: null };\n}\n\n// Module-level set to avoid spamming console during re-renders.\nconst warnedWidthValues = new Set<string>();\nfunction warnUnsupportedWidthOnce(value: string): void {\n if (typeof process === \"undefined\" || process.env?.NODE_ENV === \"production\") return;\n if (warnedWidthValues.has(value)) return;\n warnedWidthValues.add(value);\n\n console.warn(\n `[VcDataTable] Unsupported width value \"${value}\". Only px (number, \"200\", \"200px\") and % (\"20%\") are supported. Treating as auto.`,\n );\n}\n\nexport function buildInitialWeights(\n parsed: { id: string; parsed: ParsedWidth }[],\n availableWidth: number,\n): Record<string, number> {\n if (availableWidth <= 0 || parsed.length === 0) {\n const weights: Record<string, number> = {};\n const equal = parsed.length > 0 ? 1 / parsed.length : 0;\n for (const p of parsed) weights[p.id] = equal;\n return weights;\n }\n\n // Compute desired px for each column\n let fixedSum = 0;\n const autoIds: string[] = [];\n const desiredMap: Record<string, number> = {};\n\n for (const { id, parsed: p } of parsed) {\n if (p.desiredPx !== null) {\n desiredMap[id] = p.desiredPx;\n fixedSum += p.desiredPx;\n } else {\n autoIds.push(id);\n }\n }\n\n // Auto columns split the remaining space equally\n const remaining = Math.max(0, availableWidth - fixedSum);\n const autoShare = autoIds.length > 0 ? remaining / autoIds.length : 0;\n for (const id of autoIds) {\n desiredMap[id] = autoShare;\n }\n\n // Convert to weights (normalize to sum=1)\n const total = Object.values(desiredMap).reduce((s, v) => s + v, 0);\n const weights: Record<string, number> = {};\n for (const { id } of parsed) {\n weights[id] = total > 0 ? desiredMap[id] / total : 1 / parsed.length;\n }\n\n return weights;\n}\n\nexport function normalizeWeights(specs: Record<string, ColumnSpec>, visibleIds: string[]): void {\n const total = visibleIds.reduce((s, id) => s + (specs[id]?.weight ?? 0), 0);\n if (total <= 0) {\n const equal = 1 / visibleIds.length;\n for (const id of visibleIds) {\n if (specs[id]) specs[id].weight = equal;\n }\n return;\n }\n for (const id of visibleIds) {\n if (specs[id]) specs[id].weight = specs[id].weight / total;\n }\n}\n","import { ref, watch, type Ref, onBeforeUnmount } from \"vue\";\nimport type { ColumnState, ColumnSpec } from \"../types\";\nimport { DEFAULT_MIN_COLUMN_PX, type EngineOutput } from \"./useColumnWidthEngine\";\n\nexport interface UseTableColumnsResizeOptions {\n columnState: Ref<ColumnState>;\n engineOutput: Ref<EngineOutput>;\n /** Re-runs the width engine with current weights and measured availableWidth. */\n recompute: () => void;\n /** Returns net available width for data columns (measured from DOM wrapper). */\n getAvailableWidth: () => number;\n /** Floor for both user-drag clamp and iterative right-neighbor distribution. */\n minColumnWidth?: number;\n /** Returns ids of currently-visible regular (non-special) columns in display order. */\n getVisibleRegularColumnIds?: () => string[];\n onResizeEnd?: () => void;\n containerEl?: Ref<HTMLElement | null>;\n}\n\n/**\n * Column resizing via weight manipulation.\n *\n * On drag start, snapshots current weights.\n * During drag, converts pixel delta to weight delta and redistributes\n * among right neighbors. On end, commits to columnState.\n * Container resize calls recompute() immediately on the first tick, then rAF-throttled.\n */\nexport function useTableColumnsResize(options: UseTableColumnsResizeOptions) {\n const {\n columnState,\n engineOutput,\n recompute,\n getAvailableWidth,\n minColumnWidth = DEFAULT_MIN_COLUMN_PX,\n getVisibleRegularColumnIds,\n onResizeEnd,\n containerEl,\n } = options;\n\n const isResizing = ref(false);\n\n let startX = 0;\n let rafId = 0;\n let initialSpecs: Record<string, ColumnSpec> = {};\n let draggedId = \"\";\n let rightNeighborIds: string[] = [];\n\n const cloneSpecs = (specs: Record<string, ColumnSpec>): Record<string, ColumnSpec> => {\n const cloned: Record<string, ColumnSpec> = {};\n for (const [id, spec] of Object.entries(specs)) {\n cloned[id] = { ...spec };\n }\n return cloned;\n };\n\n const getActiveOrder = (): string[] => {\n const visibleRegular = getVisibleRegularColumnIds?.() ?? [];\n if (visibleRegular.length > 0) {\n return visibleRegular.filter((id) => !!columnState.value.specs[id]);\n }\n\n const renderedIds = new Set(Object.keys(engineOutput.value.widths));\n if (renderedIds.size === 0) {\n return columnState.value.order.filter((id) => !!columnState.value.specs[id]);\n }\n return columnState.value.order.filter((id) => renderedIds.has(id) && !!columnState.value.specs[id]);\n };\n\n // ── Explicit resize lifecycle (input-source agnostic; the tested seam) ──\n // start → update(deltaPx) → end. The pointer wiring below (handleResize*)\n // is one driver of this lifecycle; tests can drive it directly without\n // simulating document events.\n\n /** Snapshot specs + right neighbors for `columnId`. Returns false if not resizable. */\n const start = (columnId: string): boolean => {\n const activeOrder = getActiveOrder();\n const idx = activeOrder.indexOf(columnId);\n if (idx < 0) return false;\n\n draggedId = columnId;\n initialSpecs = cloneSpecs(columnState.value.specs);\n // Find right neighbors in order\n rightNeighborIds = activeOrder.slice(idx + 1).filter((id) => !!initialSpecs[id]);\n isResizing.value = true;\n return true;\n };\n\n /** Apply a pixel delta (relative to the drag start) to the active column. */\n const update = (rawDeltaPx: number) => {\n if (!isResizing.value || !draggedId) return;\n applyResize(rawDeltaPx);\n };\n\n /** Commit and reset the drag state. */\n const end = () => {\n isResizing.value = false;\n draggedId = \"\";\n initialSpecs = {};\n rightNeighborIds = [];\n };\n\n const handleResizeStart = (columnId: string, event: MouseEvent) => {\n if (!start(columnId)) return;\n\n startX = event.pageX;\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n document.addEventListener(\"mousemove\", handleResizeMove);\n document.addEventListener(\"mouseup\", handleResizeEnd);\n };\n\n const applyResize = (rawDelta: number) => {\n const available = getAvailableWidth();\n if (available <= 0) return;\n\n const activeOrder = getActiveOrder();\n if (activeOrder.length === 0 || !activeOrder.includes(draggedId)) return;\n\n // --- Work in pixels, same as the old system ---\n // Compute initial pixel widths from weights\n const initialPx: Record<string, number> = {};\n for (const id of activeOrder) {\n if (initialSpecs[id]) {\n initialPx[id] = initialSpecs[id].weight * available;\n }\n }\n\n // Max growth = right neighbors' shrink capacity + filler space (gap mode)\n let maxGrowthPx = 0;\n for (const id of rightNeighborIds) {\n const min = initialSpecs[id]?.minPx ?? minColumnWidth;\n maxGrowthPx += Math.max(0, initialPx[id] - min);\n }\n // In gap mode, filler space can also be consumed by growing columns\n const totalInitialPx = activeOrder.reduce((s, id) => s + (initialPx[id] ?? 0), 0);\n const fillerPx = Math.max(0, available - totalInitialPx);\n maxGrowthPx += fillerPx;\n\n // Max shrink = dragged column down to its minPx\n const draggedMin = initialSpecs[draggedId]?.minPx ?? minColumnWidth;\n const maxShrinkPx = Math.max(0, initialPx[draggedId] - draggedMin);\n\n // Clamp: can't grow more than right neighbors can give, can't shrink below min\n const clampedDelta = Math.max(-maxShrinkPx, Math.min(rawDelta, maxGrowthPx));\n if (Math.abs(clampedDelta) < 0.5) return;\n\n // Build new pixel widths starting from initial values\n const newPx: Record<string, number> = { ...initialPx };\n\n // Apply clamped delta to dragged column\n newPx[draggedId] = initialPx[draggedId] + clampedDelta;\n\n // Distribute inverse delta across right neighbors (iterative, same as old system)\n if (rightNeighborIds.length > 0) {\n for (const id of rightNeighborIds) {\n newPx[id] = initialPx[id];\n }\n let remaining = clampedDelta;\n const active = [...rightNeighborIds];\n\n while (Math.abs(remaining) > 0.5 && active.length > 0) {\n const share = remaining / active.length;\n const next: string[] = [];\n let applied = 0;\n\n for (const id of active) {\n const min = initialSpecs[id]?.minPx ?? minColumnWidth;\n const current = newPx[id];\n const target = current - share;\n const clamped = Math.max(min, target);\n const actualChange = current - clamped;\n applied += actualChange;\n newPx[id] = clamped;\n\n if (clamped > min || share < 0) {\n next.push(id);\n }\n }\n\n remaining -= applied;\n if (Math.abs(applied) < 0.5) break;\n active.length = 0;\n active.push(...next);\n }\n }\n\n // Convert px back to weights using available as denominator.\n // This preserves filler: if user shrinks a column, sum(weights) < 1.0\n // and the filler absorbs the freed space. User can then grow back into it.\n const newSpecs = cloneSpecs(initialSpecs);\n const visibleIds = activeOrder.filter((id) => !!newSpecs[id]);\n for (const id of visibleIds) {\n if (newSpecs[id] && newPx[id] !== undefined) {\n newSpecs[id].weight = newPx[id] / available;\n }\n }\n\n // Commit specs; recompute() re-runs the engine (in useTableColumns).\n columnState.value = { ...columnState.value, specs: newSpecs };\n recompute();\n };\n\n const handleResizeMove = (event: MouseEvent) => {\n if (!isResizing.value || !draggedId) return;\n const rawDelta = event.pageX - startX;\n if (rafId) cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => {\n update(rawDelta);\n rafId = 0;\n });\n };\n\n const handleResizeEnd = () => {\n if (!isResizing.value) return;\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n end();\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n document.removeEventListener(\"mousemove\", handleResizeMove);\n document.removeEventListener(\"mouseup\", handleResizeEnd);\n onResizeEnd?.();\n };\n\n const getResizeHeadProps = (columnId: string, index: number) => ({\n resizable: true,\n columnId,\n isLastResizable: index === columnState.value.order.length - 1,\n onResizeStart: (id: string | undefined, e: MouseEvent) => {\n if (id) handleResizeStart(id, e);\n },\n });\n\n // --- Container ResizeObserver: recompute on container resize ---\n //\n // Flow:\n // 1. First tick (mount / blade-open): compute immediately so exact px widths\n // land on the first frame. The proportional CSS fallback in\n // getEffectiveColumnWidth makes the initial paint correct; this just locks\n // in exact px values without any artificial delay.\n // 2. Subsequent ticks → rAF-throttled to at most one recompute per frame.\n // Prevents layout thrash during continuous animations (blade open/close\n // takes ~300ms, ~18 ticks).\n //\n // `recompute()` queries DOM (getBoundingClientRect) and runs the engine;\n // calling it on every tick after the first would cause visible jank.\n\n let resizeObserver: ResizeObserver | null = null;\n let settled = false;\n let rafRecomputeId = 0;\n\n const scheduleRecompute = () => {\n if (rafRecomputeId) return;\n rafRecomputeId = requestAnimationFrame(() => {\n rafRecomputeId = 0;\n if (!isResizing.value) recompute();\n });\n };\n\n const setupResizeObserver = () => {\n if (!containerEl?.value || typeof ResizeObserver === \"undefined\") return;\n\n settled = false;\n\n resizeObserver = new ResizeObserver(() => {\n if (isResizing.value) return;\n if (!settled) {\n // First observed tick: compute immediately so exact px widths land on the\n // first frame. The proportional CSS fallback in getEffectiveColumnWidth\n // already makes the initial paint correct; computing now just locks exact\n // px without the previous 100ms delay. Weights are proportional, so even a\n // mid-animation width scales correctly and refines on subsequent ticks.\n settled = true;\n recompute();\n return;\n }\n // Post-settle: rAF-throttle to avoid layout thrash during animations.\n // Weights stay as-is — engine scales everything proportionally.\n scheduleRecompute();\n });\n resizeObserver.observe(containerEl.value);\n };\n\n if (containerEl) {\n watch(\n containerEl,\n (el) => {\n resizeObserver?.disconnect();\n if (el) setupResizeObserver();\n },\n { immediate: true },\n );\n }\n\n onBeforeUnmount(() => {\n if (rafRecomputeId) cancelAnimationFrame(rafRecomputeId);\n resizeObserver?.disconnect();\n if (isResizing.value) {\n if (rafId) cancelAnimationFrame(rafId);\n document.removeEventListener(\"mousemove\", handleResizeMove);\n document.removeEventListener(\"mouseup\", handleResizeEnd);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n isResizing.value = false;\n }\n });\n\n return {\n isResizing,\n handleResizeStart,\n getResizeHeadProps,\n // Explicit resize lifecycle (input-source agnostic; the tested seam)\n start,\n update,\n end,\n };\n}\n","import { ref, type Ref, onBeforeUnmount } from \"vue\";\nimport type { ColumnState } from \"../types\";\n\nexport interface UseTableColumnsReorderOptions {\n columnState: Ref<ColumnState>;\n onReorderEnd?: () => void;\n}\n\n/**\n * Composable for table column reordering with drag & drop\n * Features:\n * - Live reordering (columns swap during drag)\n * - 50% threshold (swap only when crossing middle of target column)\n * - Smooth transitions\n * - Throttling for performance\n */\nexport function useTableColumnsReorder(options: UseTableColumnsReorderOptions) {\n const { columnState, onReorderEnd } = options;\n\n const isDragging = ref(false);\n let draggedColumnId: string | null = null;\n let dragThrottleTimer: number | null = null;\n\n const handleDragStart = (columnId: string, event: DragEvent) => {\n if (!event.dataTransfer) return;\n\n draggedColumnId = columnId;\n isDragging.value = true;\n\n event.dataTransfer.effectAllowed = \"move\";\n event.dataTransfer.setData(\"text/plain\", columnId);\n\n // Disable default ghost image - use transparent 1x1 pixel\n const transparentPixel = document.createElement(\"img\");\n transparentPixel.src = \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n transparentPixel.style.position = \"absolute\";\n transparentPixel.style.top = \"-9999px\";\n document.body.appendChild(transparentPixel);\n event.dataTransfer.setDragImage(transparentPixel, 0, 0);\n\n // Clean up the temporary image after drag starts\n setTimeout(() => transparentPixel.remove(), 0);\n\n // Add dragging class to header being dragged\n const dragElement = (event.target as HTMLElement).closest(\".vc-table-composition__head\") as HTMLElement;\n if (dragElement) {\n dragElement.classList.add(\"vc-table-composition__head--dragging\");\n // dragend fires on the source element when drag ends for ANY reason\n // (successful drop, cancel, or drop outside valid targets).\n // This is the safety net — without it, dropping outside a column header\n // leaves the --dragging class stuck because `drop` never fires.\n dragElement.addEventListener(\"dragend\", cleanupDrag, { once: true });\n }\n };\n\n const handleDragOver = (event: DragEvent) => {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = \"move\";\n }\n\n if (!draggedColumnId) return;\n\n // Throttle the reorder to avoid too frequent updates (50ms)\n if (dragThrottleTimer) return;\n\n dragThrottleTimer = window.setTimeout(() => {\n dragThrottleTimer = null;\n }, 50);\n\n // Get the column being hovered\n const target = event.target as HTMLElement;\n const header = target.closest(\".vc-table-composition__head\") as HTMLElement;\n if (!header) return;\n\n // Get column ID from data attribute (more reliable than DOM index)\n const hoveredColumnId = header.getAttribute(\"data-column-id\");\n if (!hoveredColumnId || hoveredColumnId === draggedColumnId) return;\n\n // Check if cursor crossed the middle of the hovered column (50% threshold)\n const rect = (header as HTMLElement).getBoundingClientRect();\n const middleX = rect.left + rect.width / 2;\n const mouseX = event.clientX;\n\n const order = columnState.value.order;\n const dragIndex = order.indexOf(draggedColumnId);\n const dropIndex = order.indexOf(hoveredColumnId);\n\n // Only swap if:\n // 1. Moving left and cursor is past the left half of target\n // 2. Moving right and cursor is past the right half of target\n const movingLeft = dragIndex > dropIndex;\n const movingRight = dragIndex < dropIndex;\n\n const shouldSwap = (movingLeft && mouseX < middleX) || (movingRight && mouseX > middleX);\n\n if (shouldSwap && dragIndex !== -1 && dropIndex !== -1 && dragIndex !== dropIndex) {\n const newOrder = [...order];\n const [movedId] = newOrder.splice(dragIndex, 1);\n newOrder.splice(dropIndex, 0, movedId);\n columnState.value = { ...columnState.value, order: newOrder };\n }\n };\n\n const handleDrop = (event: DragEvent) => {\n event.preventDefault();\n cleanupDrag();\n };\n\n const cleanupDrag = () => {\n // Guard: both `drop` and `dragend` call this — only run once\n if (!isDragging.value) return;\n\n // Remove dragging class from all headers\n document.querySelectorAll(\".vc-table-composition__head--dragging\").forEach((el) => {\n el.classList.remove(\"vc-table-composition__head--dragging\");\n });\n\n isDragging.value = false;\n draggedColumnId = null;\n if (dragThrottleTimer) {\n clearTimeout(dragThrottleTimer);\n dragThrottleTimer = null;\n }\n\n // Callback\n if (onReorderEnd) {\n onReorderEnd();\n }\n };\n\n // Cleanup on dragend event\n const handleDragEnd = () => {\n cleanupDrag();\n };\n\n /**\n * Returns props to spread onto a `<TableHead>` for drag-and-drop reordering.\n *\n * Usage: `<TableHead v-bind=\"reorder.getReorderHeadProps(col.id)\" />`\n */\n const getReorderHeadProps = (columnId: string) => ({\n reorderable: true,\n columnId,\n onReorderDragStart: (id: string | undefined, e: DragEvent) => handleDragStart(id!, e),\n onReorderDragOver: (e: DragEvent) => handleDragOver(e),\n onReorderDrop: (id: string | undefined, e: DragEvent) => {\n handleDrop(e);\n },\n onReorderDragEnd: () => handleDragEnd(),\n });\n\n // Cleanup: if component unmounts mid-drag, clear timer and state\n onBeforeUnmount(() => {\n if (dragThrottleTimer) {\n clearTimeout(dragThrottleTimer);\n dragThrottleTimer = null;\n }\n isDragging.value = false;\n draggedColumnId = null;\n });\n\n return {\n isDragging,\n handleDragStart,\n handleDragOver,\n handleDrop,\n handleDragEnd,\n getReorderHeadProps,\n };\n}\n","import { ref, Ref, watch, onBeforeUnmount } from \"vue\";\nimport Sortable from \"sortablejs\";\nimport { TableItem } from \"@ui/components/organisms/vc-data-table/types\";\n\ninterface UseTableRowReorderOptions<T> {\n /** When true, dragging is disabled (SortableJS `disabled` option). */\n disabled: Ref<boolean>;\n /** CSS selector for the drag handle element(s). */\n handle: string;\n /** Called after a committed reorder. Payload matches the public `@row-reorder` contract. */\n onReorder: (args: { dragIndex: number; dropIndex: number; value: T[] }) => void;\n}\n\n/**\n * Row reordering for VcDataTable, powered by SortableJS.\n *\n * Works on both desktop rows and mobile cards (touch + mouse) because SortableJS\n * runs in fallback mode (`forceFallback: true`). Dragging is restricted to the\n * `handle` selector so row click, swipe and long-press gestures are preserved.\n *\n * The composable keeps an internal `reorderedItems` copy. On drop it commits\n * optimistically into that copy (so the consuming table can render the new order\n * immediately and stay the single source of DOM truth — this also hides\n * SortableJS's raw DOM mutation), then calls `onReorder`. When the parent later\n * updates `items`, the watcher resyncs and clears `pendingReorder`.\n */\nexport function useTableRowReorder<T extends TableItem | string>(\n listEl: Ref<HTMLElement | undefined>,\n items: Ref<T[]>,\n options: UseTableRowReorderOptions<T>,\n) {\n const reorderedItems = ref<T[]>([...items.value]) as Ref<T[]>;\n const isDragging = ref(false);\n // Keeps reorderedItems visible after drop until the parent updates items.\n const pendingReorder = ref(false);\n\n let sortableInstance: Sortable | null = null;\n\n function destroySortable() {\n if (sortableInstance) {\n sortableInstance.destroy();\n sortableInstance = null;\n }\n }\n\n function createSortable(el: HTMLElement) {\n destroySortable();\n sortableInstance = Sortable.create(el, {\n handle: options.handle,\n animation: 200,\n forceFallback: true,\n fallbackTolerance: 3,\n // `ghostClass` styles the in-list drop placeholder (stays within the reorder\n // track). `fallbackClass` styles the floating clone that follows the pointer —\n // we hide it (see CSS) so the drag can't roam the screen; feedback is the\n // placeholder + live row shifting, matching the column reorder behaviour.\n ghostClass: \"vc-data-table__row-reorder-ghost\",\n fallbackClass: \"vc-data-table__row-reorder-fallback\",\n disabled: options.disabled.value,\n onStart: () => {\n isDragging.value = true;\n // Snapshot current order into the internal copy.\n reorderedItems.value = [...items.value];\n },\n onEnd: (evt) => {\n isDragging.value = false;\n const oldIndex = evt.oldIndex;\n const newIndex = evt.newIndex;\n if (oldIndex == null || newIndex == null || oldIndex === newIndex) return;\n\n // SortableJS mutates the DOM directly. Undo that move so the real DOM\n // matches the order Vue last rendered — otherwise Vue's keyed patch and\n // SortableJS's mutation desync and the rows snap back to their original\n // positions (the reactive `items` update is correct, only the DOM is wrong).\n // Vue then re-renders the new order from a known baseline. (vuedraggable pattern.)\n const parent = evt.from;\n const dragged = evt.item;\n if (parent && dragged && dragged.parentElement === parent) {\n parent.removeChild(dragged);\n parent.insertBefore(dragged, parent.children[oldIndex] ?? null);\n }\n\n const arr = [...items.value];\n const [moved] = arr.splice(oldIndex, 1);\n arr.splice(newIndex, 0, moved);\n\n reorderedItems.value = arr;\n pendingReorder.value = true;\n options.onReorder({ dragIndex: oldIndex, dropIndex: newIndex, value: [...arr] });\n },\n });\n }\n\n // Create/destroy when the list element appears/disappears (v-if / view switch).\n watch(\n listEl,\n (el) => {\n if (el) createSortable(el);\n else destroySortable();\n },\n { immediate: true },\n );\n\n // Reactively toggle the disabled option.\n watch(options.disabled, (val) => {\n if (sortableInstance) sortableInstance.option(\"disabled\", val);\n });\n\n // Resync internal copy with the source when not dragging.\n watch(\n items,\n (newVal) => {\n if (!isDragging.value) {\n reorderedItems.value = [...newVal];\n pendingReorder.value = false;\n }\n },\n { deep: true },\n );\n\n onBeforeUnmount(destroySortable);\n\n return {\n isDragging,\n reorderedItems,\n pendingReorder,\n };\n}\n","import { ref, computed, Ref, toRaw, inject } from \"vue\";\nimport { useForm, PublicFormContextKey } from \"vee-validate\";\n\n/**\n * Safe deep clone that handles Date objects and other non-serializable types.\n * Falls back to JSON serialization with Date support when structuredClone fails.\n */\nfunction safeClone<T>(obj: T): T {\n try {\n return structuredClone(toRaw(obj));\n } catch {\n // Fallback: deep clone with Date support\n return JSON.parse(\n JSON.stringify(obj, (_key, value) => {\n if (value instanceof Date) {\n return { __type: \"Date\", value: value.toISOString() };\n }\n return value;\n }),\n (_key, value) => {\n if (value && typeof value === \"object\" && value.__type === \"Date\") {\n return new Date(value.value);\n }\n return value;\n },\n );\n }\n}\n\nexport interface EditChange<T> {\n rowIndex: number;\n row: T;\n field: string;\n oldValue: unknown;\n newValue: unknown;\n}\n\nexport interface UseTableInlineEditOptions<T extends Record<string, any>> {\n /** Reactive array of table items */\n items: Ref<T[]>;\n /** Validation rules: field → validator function returning error string or `true` */\n rules?: Record<string, (value: unknown, row: T) => string | true>;\n /** Called on every cell update */\n onCellUpdate?: (rowIndex: number, field: string, value: unknown, row: T) => void;\n /** Called when user commits changes */\n onSave?: (changes: EditChange<T>[]) => void | Promise<void>;\n /** Called when user cancels editing */\n onCancel?: () => void;\n}\n\n/**\n * Composable for inline table editing.\n *\n * Uses VeeValidate's useForm for reliable dirty/valid state tracking and error management.\n * Provides `getCellEditProps()` to eliminate boilerplate when binding\n * editable cell formatters (`CellDefault`, `CellNumber`, `CellMoney`).\n *\n * @example\n * ```ts\n * const inlineEdit = useTableInlineEdit({ items: tableItems });\n *\n * // In template:\n * // <CellMoney v-bind=\"inlineEdit.getCellEditProps(index, 'price', { required: true })\" />\n * ```\n */\nexport function useTableInlineEdit<T extends Record<string, any>>(options: UseTableInlineEditOptions<T>) {\n const { items, rules: _rules, onCellUpdate, onSave, onCancel } = options;\n\n const isEditing = ref(false);\n\n // Snapshot of original values before editing started (deep clone)\n let snapshot: T[] = [];\n\n // VeeValidate form context:\n // If a parent form exists (e.g. blade's useForm), reuse it so <Field>\n // components register with the parent — blade.meta.valid then reflects\n // table cell errors. Only create own form when no parent exists.\n // Use inject() with a default instead of useFormContext() to avoid\n // Vue \"injection not found\" warning when no parent form exists.\n const parentForm = inject(PublicFormContextKey, undefined);\n const ownForm = parentForm ? undefined : useForm();\n const activeForm = (parentForm ?? ownForm)!;\n const { meta, setFieldValue, errors: veeErrors, validate } = activeForm;\n\n // resetForm is only safe on our own form — resetting the parent\n // would wipe non-table fields (blade inputs, etc.).\n const safeResetForm = () => {\n if (ownForm) {\n ownForm.resetForm();\n }\n };\n\n // Track which cells have been modified (for pendingChanges calculation)\n const modifiedCells = ref<Map<string, unknown>>(new Map());\n\n // Track indices of newly added rows (for eager validation on mount)\n const newRowIndices = ref<Set<number>>(new Set());\n\n const clearNewRowFlag = (rowIndex: number) => {\n if (newRowIndices.value.has(rowIndex)) {\n const next = new Set(newRowIndices.value);\n next.delete(rowIndex);\n newRowIndices.value = next;\n }\n };\n\n const cellKey = (rowIndex: number, field: string) => `${rowIndex}:${field}`;\n\n // --- Lifecycle ---\n\n const startEditing = () => {\n snapshot = items.value.map((item) => safeClone(item));\n // Reset VeeValidate form state - this clears dirty, errors, and resets to initial state\n safeResetForm();\n // Clear modified cells tracking\n modifiedCells.value = new Map();\n isEditing.value = true;\n };\n\n const cancelEditing = () => {\n // Restore original values\n items.value.splice(0, items.value.length, ...snapshot.map((s) => safeClone(s)));\n // Reset VeeValidate form state\n safeResetForm();\n modifiedCells.value = new Map();\n isEditing.value = false;\n onCancel?.();\n };\n\n const saveChanges = async () => {\n // Run all validations via VeeValidate form context\n const { valid } = await validate();\n if (!valid) return;\n\n if (onSave) {\n await onSave(pendingChanges.value);\n }\n\n // Commit: clear dirty state, update snapshot\n snapshot = items.value.map((item) => safeClone(item));\n safeResetForm();\n modifiedCells.value = new Map();\n isEditing.value = false;\n };\n\n // --- Cell operations ---\n\n const updateCell = (rowIndex: number, field: string, value: unknown) => {\n if (rowIndex < 0 || rowIndex >= items.value.length) return;\n\n const key = cellKey(rowIndex, field);\n const row = items.value[rowIndex];\n\n // Update value in items array\n (row as any)[field] = value;\n\n // Track modified cell for pendingChanges\n const newModified = new Map(modifiedCells.value);\n newModified.set(key, value);\n modifiedCells.value = newModified;\n\n // Update VeeValidate field to trigger dirty tracking\n // This marks the form as dirty via VeeValidate's internal mechanism\n setFieldValue(key, value);\n\n onCellUpdate?.(rowIndex, field, value, row);\n };\n\n const getCellValue = (rowIndex: number, field: string): unknown => {\n if (rowIndex < 0 || rowIndex >= items.value.length) return undefined;\n return items.value[rowIndex][field];\n };\n\n const isCellDirty = (rowIndex: number, field: string): boolean => {\n return modifiedCells.value.has(cellKey(rowIndex, field));\n };\n\n // --- Validation ---\n\n // Use VeeValidate's meta.valid for validation state\n const isValid = computed(() => meta.value.valid);\n\n // --- Computed changes ---\n\n const pendingChanges = computed<EditChange<T>[]>(() => {\n const changes: EditChange<T>[] = [];\n for (const [key, newValue] of modifiedCells.value.entries()) {\n const [rowStr, field] = key.split(\":\");\n const rowIndex = parseInt(rowStr, 10);\n const oldValue = snapshot[rowIndex]?.[field];\n if (oldValue !== newValue) {\n changes.push({\n rowIndex,\n row: items.value[rowIndex],\n field,\n oldValue,\n newValue,\n });\n }\n }\n return changes;\n });\n\n // isDirty based on actual changes (comparing with snapshot)\n // This is more reliable than VeeValidate's meta.dirty because:\n // 1. VeeValidate tracks all setFieldValue calls, but we don't set initial values\n // 2. Our snapshot comparison accurately reflects what the user has actually changed\n const isDirty = computed(() => pendingChanges.value.length > 0);\n\n // --- Row operations ---\n\n const addRow = (defaults?: Partial<T>) => {\n const newRow = (defaults ?? {}) as T;\n items.value.push(newRow);\n\n const newIndex = items.value.length - 1;\n const next = new Set(newRowIndices.value);\n next.add(newIndex);\n newRowIndices.value = next;\n };\n\n const removeRow = (rowIndex: number) => {\n if (rowIndex < 0 || rowIndex >= items.value.length) return;\n items.value.splice(rowIndex, 1);\n\n // Clean up modified cells — rebuild keys above removed index\n const newModified = new Map<string, unknown>();\n for (const [key, val] of modifiedCells.value.entries()) {\n const [rowStr, field] = key.split(\":\");\n const idx = parseInt(rowStr, 10);\n if (idx === rowIndex) continue; // removed\n const newIdx = idx > rowIndex ? idx - 1 : idx;\n newModified.set(cellKey(newIdx, field), val);\n }\n modifiedCells.value = newModified;\n\n // Rebuild newRowIndices — shift indices above removed row\n const newNewRowIndices = new Set<number>();\n for (const idx of newRowIndices.value) {\n if (idx === rowIndex) continue;\n newNewRowIndices.add(idx > rowIndex ? idx - 1 : idx);\n }\n newRowIndices.value = newNewRowIndices;\n };\n\n // --- Head props helper ---\n\n /**\n * Returns props to spread onto an editable cell formatter (`CellDefault`, `CellNumber`, `CellMoney`).\n *\n * Eliminates boilerplate for editable cells:\n * ```vue\n * <CellMoney v-bind=\"inlineEdit.getCellEditProps(index, 'price', { required: true })\" />\n * ```\n */\n const getCellEditProps = (rowIndex: number, field: string, cellRules?: Record<string, unknown>) => ({\n editable: isEditing.value,\n fieldId: field,\n fieldName: `${field}_${rowIndex}`,\n label: field,\n rowIndex,\n rules: cellRules,\n onUpdate: (payload: { field: string; value: unknown }) => {\n updateCell(rowIndex, payload.field, payload.value);\n },\n onBlur: (_payload: { row: number | undefined; field: string }) => {\n // No manual validation needed — Field handles it\n },\n });\n\n return {\n isEditing,\n startEditing,\n cancelEditing,\n saveChanges,\n updateCell,\n getCellValue,\n isCellDirty,\n isDirty,\n errors: veeErrors,\n isValid,\n pendingChanges,\n addRow,\n removeRow,\n getCellEditProps,\n newRowIndices,\n clearNewRowFlag,\n };\n}\n","import { ref, computed, watch, onMounted, onBeforeUnmount, type Ref, type ComputedRef } from \"vue\";\r\n\r\nexport interface VirtualScrollOptions<T> {\r\n /** The items array to virtualize */\r\n items: Ref<T[]> | ComputedRef<T[]>;\r\n /** Height of each row in pixels (required for virtualization) */\r\n itemSize: number;\r\n /** Reference to the scroll container element */\r\n containerRef: Ref<HTMLElement | null>;\r\n /** Number of buffer items above/below viewport (default: 5) */\r\n numToleratedItems?: number;\r\n /** Debounce delay for scroll events in ms (default: 0) */\r\n delay?: number;\r\n /** Enable lazy loading mode */\r\n lazy?: boolean;\r\n /** Callback when virtual scroll position changes */\r\n onScroll?: (event: { first: number; last: number }) => void;\r\n /** Callback for lazy loading when new items need to be fetched */\r\n onLazyLoad?: (event: { first: number; last: number }) => void;\r\n}\r\n\r\nexport interface VirtualScrollItem<T> {\r\n item: T;\r\n index: number;\r\n}\r\n\r\nexport interface VirtualScrollReturn<T> {\r\n /** Currently visible items with their original indices */\r\n visibleItems: ComputedRef<VirtualScrollItem<T>[]>;\r\n /** Total height of the content in pixels */\r\n totalHeight: ComputedRef<number>;\r\n /** Offset Y for positioning visible rows */\r\n offsetY: ComputedRef<number>;\r\n /** Current visible range (start and end indices) */\r\n visibleRange: ComputedRef<{ start: number; end: number }>;\r\n /** Current scroll position */\r\n scrollTop: Ref<number>;\r\n /** Container height */\r\n containerHeight: Ref<number>;\r\n /** Handle scroll events */\r\n onScroll: (event: Event) => void;\r\n /** Whether virtual scroll is currently loading (for lazy mode) */\r\n isLoading: Ref<boolean>;\r\n /** Scroll to a specific index */\r\n scrollToIndex: (index: number, behavior?: ScrollBehavior) => void;\r\n /** Scroll to top */\r\n scrollToTop: (behavior?: ScrollBehavior) => void;\r\n /** Scroll to bottom */\r\n scrollToBottom: (behavior?: ScrollBehavior) => void;\r\n}\r\n\r\n/**\r\n * Composable for virtual scrolling / windowing of large lists\r\n *\r\n * Virtual scrolling renders only the visible items plus a buffer,\r\n * dramatically improving performance for large datasets.\r\n *\r\n * @example\r\n * ```ts\r\n * const items = ref(generateLargeDataset(10000));\r\n * const containerRef = ref<HTMLElement | null>(null);\r\n *\r\n * const {\r\n * visibleItems,\r\n * totalHeight,\r\n * offsetY,\r\n * onScroll,\r\n * } = useVirtualScroll({\r\n * items,\r\n * itemSize: 48, // row height in pixels\r\n * containerRef,\r\n * numToleratedItems: 5,\r\n * });\r\n * ```\r\n */\r\nexport function useVirtualScroll<T>(options: VirtualScrollOptions<T>): VirtualScrollReturn<T> {\r\n const {\r\n items,\r\n itemSize,\r\n containerRef,\r\n numToleratedItems = 5,\r\n delay = 0,\r\n lazy = false,\r\n onScroll: onScrollCallback,\r\n onLazyLoad,\r\n } = options;\r\n\r\n // Internal state\r\n const scrollTop = ref(0);\r\n const containerHeight = ref(0);\r\n const isLoading = ref(false);\r\n let scrollTimeout: ReturnType<typeof setTimeout> | null = null;\r\n let lastLazyLoadRange = { start: -1, end: -1 };\r\n\r\n /**\r\n * Calculate the visible range of items based on scroll position\r\n */\r\n const visibleRange = computed(() => {\r\n const buffer = numToleratedItems;\r\n const itemCount = items.value.length;\r\n\r\n if (itemCount === 0 || containerHeight.value === 0) {\r\n return { start: 0, end: 0 };\r\n }\r\n\r\n // Calculate start index (first visible item minus buffer)\r\n const firstVisibleIndex = Math.floor(scrollTop.value / itemSize);\r\n const start = Math.max(0, firstVisibleIndex - buffer);\r\n\r\n // Calculate how many items fit in the viewport\r\n const visibleCount = Math.ceil(containerHeight.value / itemSize);\r\n\r\n // Calculate end index (last visible item plus buffer)\r\n const end = Math.min(itemCount, firstVisibleIndex + visibleCount + buffer * 2);\r\n\r\n return { start, end };\r\n });\r\n\r\n /**\r\n * Get the visible items with their original indices\r\n */\r\n const visibleItems = computed<VirtualScrollItem<T>[]>(() => {\r\n const { start, end } = visibleRange.value;\r\n const itemsArray = items.value;\r\n\r\n return itemsArray.slice(start, end).map((item, localIndex) => ({\r\n item,\r\n index: start + localIndex,\r\n }));\r\n });\r\n\r\n /**\r\n * Calculate total height for the spacer element\r\n */\r\n const totalHeight = computed(() => {\r\n return items.value.length * itemSize;\r\n });\r\n\r\n /**\r\n * Calculate offset for positioning visible rows\r\n */\r\n const offsetY = computed(() => {\r\n return visibleRange.value.start * itemSize;\r\n });\r\n\r\n /**\r\n * Handle scroll events with optional debouncing\r\n */\r\n const handleScroll = (event: Event) => {\r\n const target = event.target as HTMLElement;\r\n if (!target) return;\r\n\r\n const updateScroll = () => {\r\n scrollTop.value = target.scrollTop;\r\n containerHeight.value = target.clientHeight;\r\n\r\n const range = visibleRange.value;\r\n\r\n // Emit scroll event callback\r\n if (onScrollCallback) {\r\n onScrollCallback({ first: range.start, last: range.end });\r\n }\r\n\r\n // Handle lazy loading\r\n if (lazy && onLazyLoad) {\r\n // Only trigger lazy load if range has changed significantly\r\n if (range.start !== lastLazyLoadRange.start || range.end !== lastLazyLoadRange.end) {\r\n lastLazyLoadRange = { ...range };\r\n isLoading.value = true;\r\n onLazyLoad({ first: range.start, last: range.end });\r\n }\r\n }\r\n };\r\n\r\n if (delay > 0) {\r\n if (scrollTimeout) {\r\n clearTimeout(scrollTimeout);\r\n }\r\n scrollTimeout = setTimeout(updateScroll, delay);\r\n } else {\r\n updateScroll();\r\n }\r\n };\r\n\r\n /**\r\n * Scroll to a specific item index\r\n */\r\n const scrollToIndex = (index: number, behavior: ScrollBehavior = \"auto\") => {\r\n if (!containerRef.value) return;\r\n\r\n const targetScrollTop = index * itemSize;\r\n containerRef.value.scrollTo({\r\n top: targetScrollTop,\r\n behavior,\r\n });\r\n };\r\n\r\n /**\r\n * Scroll to the top of the list\r\n */\r\n const scrollToTop = (behavior: ScrollBehavior = \"auto\") => {\r\n if (!containerRef.value) return;\r\n containerRef.value.scrollTo({ top: 0, behavior });\r\n };\r\n\r\n /**\r\n * Scroll to the bottom of the list\r\n */\r\n const scrollToBottom = (behavior: ScrollBehavior = \"auto\") => {\r\n if (!containerRef.value) return;\r\n const maxScroll = totalHeight.value - containerHeight.value;\r\n containerRef.value.scrollTo({ top: Math.max(0, maxScroll), behavior });\r\n };\r\n\r\n /**\r\n * Initialize container dimensions on mount\r\n */\r\n const initializeContainer = () => {\r\n if (containerRef.value) {\r\n containerHeight.value = containerRef.value.clientHeight;\r\n scrollTop.value = containerRef.value.scrollTop;\r\n }\r\n };\r\n\r\n /**\r\n * Handle window resize to update container height\r\n */\r\n const handleResize = () => {\r\n initializeContainer();\r\n };\r\n\r\n // Watch for container ref changes\r\n watch(\r\n containerRef,\r\n (newRef) => {\r\n if (newRef) {\r\n initializeContainer();\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n // Watch for items changes - reset scroll if items change significantly\r\n watch(\r\n () => items.value.length,\r\n (newLength, oldLength) => {\r\n // If items array is replaced entirely (e.g., new search results)\r\n // we might want to scroll to top\r\n if (oldLength > 0 && newLength !== oldLength) {\r\n // Reset lazy load tracking\r\n lastLazyLoadRange = { start: -1, end: -1 };\r\n }\r\n },\r\n );\r\n\r\n // Setup resize observer\r\n onMounted(() => {\r\n initializeContainer();\r\n window.addEventListener(\"resize\", handleResize);\r\n });\r\n\r\n // Cleanup\r\n onBeforeUnmount(() => {\r\n window.removeEventListener(\"resize\", handleResize);\r\n if (scrollTimeout) {\r\n clearTimeout(scrollTimeout);\r\n }\r\n });\r\n\r\n return {\r\n visibleItems,\r\n totalHeight,\r\n offsetY,\r\n visibleRange,\r\n scrollTop,\r\n containerHeight,\r\n onScroll: handleScroll,\r\n isLoading,\r\n scrollToIndex,\r\n scrollToTop,\r\n scrollToBottom,\r\n };\r\n}\r\n","import { ref, computed, watch, type Ref, type ComputedRef } from \"vue\";\r\nimport * as _ from \"lodash-es\";\r\n\r\nexport interface RowGroupingOptions<T> {\r\n /**\r\n * Items to group\r\n */\r\n items: Ref<T[]> | ComputedRef<T[]>;\r\n /**\r\n * Field(s) to group rows by\r\n */\r\n groupRowsBy: Ref<string | string[] | undefined>;\r\n /**\r\n * How to display groups: 'subheader' shows a header row for each group\r\n */\r\n rowGroupMode?: Ref<\"subheader\" | \"rowspan\">;\r\n /**\r\n * Whether groups can be expanded/collapsed\r\n */\r\n expandableRowGroups?: Ref<boolean | undefined>;\r\n /**\r\n * Initial/controlled expanded group keys\r\n */\r\n expandedRowGroups?: Ref<string[] | undefined>;\r\n /**\r\n * Callback when expanded groups change\r\n */\r\n onExpandedRowGroupsChange?: (groups: string[]) => void;\r\n /**\r\n * Callback when a group is expanded\r\n */\r\n onRowGroupExpand?: (event: { data: string; originalEvent: Event }) => void;\r\n /**\r\n * Callback when a group is collapsed\r\n */\r\n onRowGroupCollapse?: (event: { data: string; originalEvent: Event }) => void;\r\n}\r\n\r\nexport interface GroupedData<T> {\r\n /**\r\n * Group key (value of the grouping field)\r\n */\r\n key: string;\r\n /**\r\n * Items in this group\r\n */\r\n items: T[];\r\n /**\r\n * First item in the group (for slot context)\r\n */\r\n firstItem: T;\r\n /**\r\n * Number of items in the group\r\n */\r\n count: number;\r\n}\r\n\r\nexport interface UseTableRowGroupingReturn<T> {\r\n /**\r\n * Grouped items as a Map (groupKey -> items)\r\n */\r\n groupedItems: ComputedRef<Map<string, T[]> | null>;\r\n /**\r\n * Grouped data as array for easier template iteration\r\n */\r\n groupedData: ComputedRef<GroupedData<T>[]>;\r\n /**\r\n * Whether row grouping is enabled\r\n */\r\n isGroupingEnabled: ComputedRef<boolean>;\r\n /**\r\n * Internal expanded groups state\r\n */\r\n internalExpandedRowGroups: Ref<string[]>;\r\n /**\r\n * Check if a group is expanded\r\n */\r\n isGroupExpanded: (groupKey: string) => boolean;\r\n /**\r\n * Toggle group expansion\r\n */\r\n toggleGroupExpansion: (groupKey: string, event: Event) => void;\r\n /**\r\n * Expand a specific group\r\n */\r\n expandGroup: (groupKey: string) => void;\r\n /**\r\n * Collapse a specific group\r\n */\r\n collapseGroup: (groupKey: string) => void;\r\n /**\r\n * Expand all groups\r\n */\r\n expandAllGroups: () => void;\r\n /**\r\n * Collapse all groups\r\n */\r\n collapseAllGroups: () => void;\r\n /**\r\n * Get visible items (respecting collapsed groups)\r\n */\r\n visibleItems: ComputedRef<T[]>;\r\n /**\r\n * Get the group key for an item\r\n */\r\n getItemGroupKey: (item: T) => string;\r\n}\r\n\r\n/**\r\n * Composable for managing row grouping in tables\r\n *\r\n * @example\r\n * ```ts\r\n * const { groupedData, isGroupExpanded, toggleGroupExpansion } = useTableRowGrouping({\r\n * items: computed(() => props.items),\r\n * groupRowsBy: computed(() => props.groupRowsBy),\r\n * expandableRowGroups: computed(() => props.expandableRowGroups),\r\n * expandedRowGroups: computed(() => props.expandedRowGroups),\r\n * onExpandedRowGroupsChange: (groups) => emit('update:expandedRowGroups', groups),\r\n * onRowGroupExpand: (event) => emit('rowgroup-expand', event),\r\n * onRowGroupCollapse: (event) => emit('rowgroup-collapse', event),\r\n * });\r\n * ```\r\n */\r\nexport function useTableRowGrouping<T extends Record<string, any>>(\r\n options: RowGroupingOptions<T>,\r\n): UseTableRowGroupingReturn<T> {\r\n const {\r\n items,\r\n groupRowsBy,\r\n rowGroupMode: _rowGroupMode = ref(\"subheader\"),\r\n expandableRowGroups = ref(false),\r\n expandedRowGroups,\r\n onExpandedRowGroupsChange,\r\n onRowGroupExpand,\r\n onRowGroupCollapse,\r\n } = options;\r\n\r\n // Internal expanded groups state\r\n const internalExpandedRowGroups = ref<string[]>([]);\r\n\r\n // Sync with props when controlled\r\n watch(\r\n () => expandedRowGroups?.value,\r\n (newVal) => {\r\n if (newVal !== undefined) {\r\n internalExpandedRowGroups.value = [...newVal];\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n // Check if grouping is enabled\r\n const isGroupingEnabled = computed(() => {\r\n return !!groupRowsBy.value;\r\n });\r\n\r\n // Get the primary grouping field\r\n const primaryGroupField = computed(() => {\r\n if (!groupRowsBy.value) return null;\r\n return Array.isArray(groupRowsBy.value) ? groupRowsBy.value[0] : groupRowsBy.value;\r\n });\r\n\r\n // Get the group key for an item\r\n const getItemGroupKey = (item: T): string => {\r\n if (!primaryGroupField.value) return \"\";\r\n const value = _.get(item, primaryGroupField.value);\r\n return String(value ?? \"undefined\");\r\n };\r\n\r\n // Compute grouped items as a Map\r\n const groupedItems = computed<Map<string, T[]> | null>(() => {\r\n if (!isGroupingEnabled.value || !primaryGroupField.value) {\r\n return null;\r\n }\r\n\r\n const groups = new Map<string, T[]>();\r\n\r\n for (const item of items.value) {\r\n const key = getItemGroupKey(item);\r\n if (!groups.has(key)) {\r\n groups.set(key, []);\r\n }\r\n groups.get(key)!.push(item);\r\n }\r\n\r\n return groups;\r\n });\r\n\r\n // Compute grouped data as array for easier iteration\r\n const groupedData = computed<GroupedData<T>[]>(() => {\r\n if (!groupedItems.value) {\r\n return [];\r\n }\r\n\r\n const result: GroupedData<T>[] = [];\r\n\r\n groupedItems.value.forEach((groupItems, key) => {\r\n result.push({\r\n key,\r\n items: groupItems,\r\n firstItem: groupItems[0],\r\n count: groupItems.length,\r\n });\r\n });\r\n\r\n return result;\r\n });\r\n\r\n // Check if a group is expanded\r\n const isGroupExpanded = (groupKey: string): boolean => {\r\n // If not expandable, all groups are always expanded\r\n if (!expandableRowGroups?.value) {\r\n return true;\r\n }\r\n return internalExpandedRowGroups.value.includes(groupKey);\r\n };\r\n\r\n // Toggle group expansion\r\n const toggleGroupExpansion = (groupKey: string, event: Event): void => {\r\n if (!expandableRowGroups?.value) {\r\n return;\r\n }\r\n\r\n const isExpanded = isGroupExpanded(groupKey);\r\n\r\n if (isExpanded) {\r\n // Collapse\r\n internalExpandedRowGroups.value = internalExpandedRowGroups.value.filter((k) => k !== groupKey);\r\n onRowGroupCollapse?.({ data: groupKey, originalEvent: event });\r\n } else {\r\n // Expand\r\n internalExpandedRowGroups.value = [...internalExpandedRowGroups.value, groupKey];\r\n onRowGroupExpand?.({ data: groupKey, originalEvent: event });\r\n }\r\n\r\n onExpandedRowGroupsChange?.(internalExpandedRowGroups.value);\r\n };\r\n\r\n // Expand a specific group\r\n const expandGroup = (groupKey: string): void => {\r\n if (!expandableRowGroups?.value || isGroupExpanded(groupKey)) {\r\n return;\r\n }\r\n internalExpandedRowGroups.value = [...internalExpandedRowGroups.value, groupKey];\r\n onExpandedRowGroupsChange?.(internalExpandedRowGroups.value);\r\n };\r\n\r\n // Collapse a specific group\r\n const collapseGroup = (groupKey: string): void => {\r\n if (!expandableRowGroups?.value || !isGroupExpanded(groupKey)) {\r\n return;\r\n }\r\n internalExpandedRowGroups.value = internalExpandedRowGroups.value.filter((k) => k !== groupKey);\r\n onExpandedRowGroupsChange?.(internalExpandedRowGroups.value);\r\n };\r\n\r\n // Expand all groups\r\n const expandAllGroups = (): void => {\r\n if (!expandableRowGroups?.value || !groupedItems.value) {\r\n return;\r\n }\r\n const keys: string[] = [];\r\n groupedItems.value.forEach((_, key) => keys.push(key));\r\n internalExpandedRowGroups.value = keys;\r\n onExpandedRowGroupsChange?.(internalExpandedRowGroups.value);\r\n };\r\n\r\n // Collapse all groups\r\n const collapseAllGroups = (): void => {\r\n if (!expandableRowGroups?.value) {\r\n return;\r\n }\r\n internalExpandedRowGroups.value = [];\r\n onExpandedRowGroupsChange?.(internalExpandedRowGroups.value);\r\n };\r\n\r\n // Get visible items (respecting collapsed groups)\r\n const visibleItems = computed<T[]>(() => {\r\n if (!isGroupingEnabled.value) {\r\n return items.value;\r\n }\r\n\r\n // If not expandable, all items are visible\r\n if (!expandableRowGroups?.value) {\r\n return items.value;\r\n }\r\n\r\n // Filter items to only include those from expanded groups\r\n return items.value.filter((item) => {\r\n const groupKey = getItemGroupKey(item);\r\n return isGroupExpanded(groupKey);\r\n });\r\n });\r\n\r\n return {\r\n groupedItems,\r\n groupedData,\r\n isGroupingEnabled,\r\n internalExpandedRowGroups,\r\n isGroupExpanded,\r\n toggleGroupExpansion,\r\n expandGroup,\r\n collapseGroup,\r\n expandAllGroups,\r\n collapseAllGroups,\r\n visibleItems,\r\n getItemGroupKey,\r\n };\r\n}\r\n","import { ref, computed } from \"vue\";\r\nimport type { FilterValue } from \"@ui/components/organisms/vc-data-table/types\";\r\n\r\nexport interface UseFilterStateOptions {\r\n /** Called whenever a filter is applied/cleared with a flat payload for the backend */\r\n onFilterChange?: (payload: Record<string, unknown>) => void;\r\n}\r\n\r\n/**\r\n * Simple filter state composable for backend-driven filtering.\r\n *\r\n * Collects filter values and emits flat payloads for the backend to handle.\r\n */\r\nexport function useFilterState(options: UseFilterStateOptions = {}) {\r\n const filterValues = ref<Record<string, FilterValue>>({});\r\n\r\n const isValueEmpty = (val: unknown): boolean => {\r\n if (val === null || val === undefined || val === \"\") return true;\r\n if (Array.isArray(val) && val.length === 0) return true;\r\n return false;\r\n };\r\n\r\n const updateFilter = (field: string, value: FilterValue) => {\r\n filterValues.value = {\r\n ...filterValues.value,\r\n [field]: value,\r\n };\r\n notifyChange();\r\n };\r\n\r\n const updateRangeFilter = (rangeFields: [string, string], value: { start?: string; end?: string }) => {\r\n // Store as composite key for internal tracking\r\n const key = `__range__${rangeFields[0]}__${rangeFields[1]}`;\r\n filterValues.value = {\r\n ...filterValues.value,\r\n [key]: value as FilterValue,\r\n };\r\n notifyChange();\r\n };\r\n\r\n const clearFilter = (field: string) => {\r\n const newValues = { ...filterValues.value };\r\n delete newValues[field];\r\n // Also check for range keys containing this field\r\n for (const key of Object.keys(newValues)) {\r\n if (key.startsWith(\"__range__\") && key.includes(field)) {\r\n delete newValues[key];\r\n }\r\n }\r\n filterValues.value = newValues;\r\n notifyChange();\r\n };\r\n\r\n const clearAllFilters = () => {\r\n filterValues.value = {};\r\n notifyChange();\r\n };\r\n\r\n /**\r\n * Build flat payload for backend.\r\n * Expands dateRange composite keys to separate fields.\r\n */\r\n function buildPayload(): Record<string, unknown> {\r\n const payload: Record<string, unknown> = {};\r\n\r\n for (const [key, value] of Object.entries(filterValues.value)) {\r\n if (key.startsWith(\"__range__\")) {\r\n // Expand range to separate fields\r\n const rangeVal = value as { start?: string; end?: string } | null;\r\n if (rangeVal) {\r\n const parts = key.replace(\"__range__\", \"\").split(\"__\");\r\n if (parts[0] && rangeVal.start) {\r\n payload[parts[0]] = rangeVal.start;\r\n }\r\n if (parts[1] && rangeVal.end) {\r\n payload[parts[1]] = rangeVal.end;\r\n }\r\n }\r\n } else if (!isValueEmpty(value)) {\r\n payload[key] = value;\r\n }\r\n }\r\n\r\n return payload;\r\n }\r\n\r\n function notifyChange() {\r\n if (options.onFilterChange) {\r\n options.onFilterChange(buildPayload());\r\n }\r\n }\r\n\r\n const isObjectWithValues = (val: unknown): boolean => {\r\n if (typeof val !== \"object\" || val === null || Array.isArray(val)) return false;\r\n return Object.values(val).some((v) => v !== null && v !== undefined && v !== \"\");\r\n };\r\n\r\n const hasActiveFilters = computed(() => {\r\n return Object.values(filterValues.value).some((val) => {\r\n if (typeof val === \"object\" && val !== null && !Array.isArray(val)) {\r\n return isObjectWithValues(val);\r\n }\r\n return !isValueEmpty(val);\r\n });\r\n });\r\n\r\n const activeFilterCount = computed(() => {\r\n let count = 0;\r\n for (const val of Object.values(filterValues.value)) {\r\n if (typeof val === \"object\" && val !== null && !Array.isArray(val)) {\r\n if (isObjectWithValues(val)) count++;\r\n } else if (!isValueEmpty(val)) {\r\n count++;\r\n }\r\n }\r\n return count;\r\n });\r\n\r\n return {\r\n filterValues,\r\n updateFilter,\r\n updateRangeFilter,\r\n clearFilter,\r\n clearAllFilters,\r\n buildPayload,\r\n hasActiveFilters,\r\n activeFilterCount,\r\n };\r\n}\r\n\r\nexport type UseFilterStateReturn = ReturnType<typeof useFilterState>;\r\n","/**\r\n * useTableSort - Composable for table sorting functionality\r\n *\r\n * Handles single and multi-sort modes with removable sort support.\r\n * Extracted from VcDataTable.vue for better modularity.\r\n *\r\n * Inspired by PrimeVue DataTable sorting patterns.\r\n */\r\nimport { ref, watch, type Ref } from \"vue\";\r\nimport type { SortMeta } from \"@ui/components/organisms/vc-data-table/types\";\r\n\r\nexport interface UseTableSortOptions {\r\n /** Current sort field (for single sort mode) */\r\n sortField: Ref<string | undefined>;\r\n /** Current sort order: 1 = asc, -1 = desc, 0 = none */\r\n sortOrder: Ref<number>;\r\n /** Sort mode: single or multiple */\r\n sortMode: Ref<\"single\" | \"multiple\">;\r\n /** Multi-sort metadata array */\r\n multiSortMeta: Ref<SortMeta[]>;\r\n /** Allow removing sort by cycling through asc -> desc -> none */\r\n removableSort: Ref<boolean>;\r\n /** Callback when sort changes */\r\n onSort?: (event: SortEvent) => void;\r\n}\r\n\r\nexport interface SortEvent {\r\n sortField?: string;\r\n sortOrder?: number;\r\n multiSortMeta?: SortMeta[];\r\n}\r\n\r\nexport interface UseTableSortReturn {\r\n /** Handle sort click on column header */\r\n handleSort: (field: string, event?: Event) => void;\r\n /** Get sort direction for a field */\r\n getSortDirection: (field: string) => \"asc\" | \"desc\" | undefined;\r\n /** Get sort index for multi-sort (1-based for display) */\r\n getSortIndex: (field: string) => number | undefined;\r\n /** Check if field is currently sorted */\r\n isSorted: (field: string) => boolean;\r\n /** Internal sort field state */\r\n internalSortField: Ref<string | undefined>;\r\n /** Internal sort order state */\r\n internalSortOrder: Ref<number>;\r\n /** Internal multi-sort meta state */\r\n internalMultiSortMeta: Ref<SortMeta[]>;\r\n}\r\n\r\nexport function useTableSort(options: UseTableSortOptions): UseTableSortReturn {\r\n const { sortField, sortOrder, sortMode, multiSortMeta, removableSort, onSort } = options;\r\n\r\n // Internal state (initialized from props, kept in sync via watchers below)\r\n const internalSortField = ref<string | undefined>(sortField.value);\r\n const internalSortOrder = ref<number>(sortOrder.value ?? 0);\r\n const internalMultiSortMeta = ref<SortMeta[]>([...(multiSortMeta.value || [])]);\r\n\r\n // Sync internal state when props change from the parent.\r\n // This is critical for adapter/controlled usage where the parent manages\r\n // the sort cycle independently (e.g. VcTableAdapter + legacy onHeaderClick).\r\n // Without these watchers, VcDataTable's internal sort state drifts from the\r\n // parent's props since both advance their own cycle on each click.\r\n watch(\r\n () => [sortField.value, sortOrder.value, multiSortMeta.value] as const,\r\n ([field, order, meta]) => {\r\n internalSortField.value = field;\r\n internalSortOrder.value = order ?? 0;\r\n internalMultiSortMeta.value = [...(meta || [])];\r\n },\r\n );\r\n\r\n /**\r\n * Handle sort click on column header\r\n */\r\n const handleSort = (field: string, event?: Event): void => {\r\n if (sortMode.value === \"multiple\") {\r\n handleMultiSort(field, event);\r\n } else {\r\n handleSingleSort(field);\r\n }\r\n };\r\n\r\n /**\r\n * Handle single sort mode\r\n */\r\n const handleSingleSort = (field: string): void => {\r\n let newOrder: 1 | -1 | 0 = 1;\r\n\r\n if (internalSortField.value === field) {\r\n if (internalSortOrder.value === 1) {\r\n newOrder = -1;\r\n } else if (internalSortOrder.value === -1) {\r\n newOrder = removableSort.value ? 0 : 1;\r\n }\r\n }\r\n\r\n internalSortField.value = newOrder === 0 ? undefined : field;\r\n internalSortOrder.value = newOrder;\r\n\r\n onSort?.({\r\n sortField: newOrder === 0 ? undefined : field,\r\n sortOrder: newOrder,\r\n });\r\n };\r\n\r\n /**\r\n * Handle multi-sort mode\r\n */\r\n const handleMultiSort = (field: string, event?: Event): void => {\r\n const currentMeta = [...internalMultiSortMeta.value];\r\n const existingIndex = currentMeta.findIndex((m) => m.field === field);\r\n const isCtrlClick =\r\n (event as MouseEvent | KeyboardEvent | undefined)?.ctrlKey ||\r\n (event as MouseEvent | KeyboardEvent | undefined)?.metaKey;\r\n\r\n if (isCtrlClick) {\r\n // Ctrl+click: add to or toggle existing sort\r\n if (existingIndex >= 0) {\r\n const existing = currentMeta[existingIndex];\r\n if (existing.order === 1) {\r\n existing.order = -1;\r\n } else if (existing.order === -1) {\r\n if (removableSort.value) {\r\n // Remove from sort\r\n currentMeta.splice(existingIndex, 1);\r\n } else {\r\n existing.order = 1;\r\n }\r\n }\r\n } else {\r\n // Add new sort field\r\n currentMeta.push({ field, order: 1 });\r\n }\r\n } else {\r\n // Regular click: replace all sorts with this column\r\n if (existingIndex >= 0 && currentMeta.length === 1) {\r\n // Toggle existing single sort\r\n const existing = currentMeta[0];\r\n if (existing.order === 1) {\r\n existing.order = -1;\r\n } else if (existing.order === -1) {\r\n if (removableSort.value) {\r\n currentMeta.splice(0, 1);\r\n } else {\r\n existing.order = 1;\r\n }\r\n }\r\n } else {\r\n // Replace with new single sort\r\n currentMeta.length = 0;\r\n currentMeta.push({ field, order: 1 });\r\n }\r\n }\r\n\r\n internalMultiSortMeta.value = currentMeta;\r\n\r\n onSort?.({\r\n multiSortMeta: currentMeta,\r\n });\r\n };\r\n\r\n /**\r\n * Get sort direction for a field\r\n */\r\n const getSortDirection = (field: string): \"asc\" | \"desc\" | undefined => {\r\n if (sortMode.value === \"multiple\") {\r\n const meta = internalMultiSortMeta.value.find((m) => m.field === field);\r\n if (meta) {\r\n return meta.order === 1 ? \"asc\" : meta.order === -1 ? \"desc\" : undefined;\r\n }\r\n return undefined;\r\n }\r\n\r\n // Single sort mode\r\n if (internalSortField.value === field) {\r\n return internalSortOrder.value === 1 ? \"asc\" : internalSortOrder.value === -1 ? \"desc\" : undefined;\r\n }\r\n return undefined;\r\n };\r\n\r\n /**\r\n * Get sort index for multi-sort (1-based for display)\r\n */\r\n const getSortIndex = (field: string): number | undefined => {\r\n if (sortMode.value !== \"multiple\") return undefined;\r\n\r\n const meta = internalMultiSortMeta.value;\r\n if (meta.length <= 1) return undefined;\r\n\r\n const index = meta.findIndex((m) => m.field === field);\r\n return index >= 0 ? index + 1 : undefined;\r\n };\r\n\r\n /**\r\n * Check if field is currently sorted\r\n */\r\n const isSorted = (field: string): boolean => {\r\n return getSortDirection(field) !== undefined;\r\n };\r\n\r\n return {\r\n handleSort,\r\n getSortDirection,\r\n getSortIndex,\r\n isSorted,\r\n internalSortField,\r\n internalSortOrder,\r\n internalMultiSortMeta,\r\n };\r\n}\r\n\r\nexport default useTableSort;\r\n","/**\r\n * useTableEditing - Composable for cell and row editing (PrimeVue-style)\r\n *\r\n * Supports two editing modes:\r\n * - cell: Click on a cell to edit it inline\r\n * - row: Edit/Save/Cancel buttons per row\r\n *\r\n * This is different from useTableInlineEdit which handles bulk editing mode.\r\n * Extracted from VcDataTable.vue for better modularity.\r\n *\r\n * Inspired by PrimeVue DataTable editMode patterns.\r\n */\r\nimport { ref, watch, toRaw, type Ref } from \"vue\";\r\n\r\n/**\r\n * Safe deep clone that handles Date objects and other non-serializable types.\r\n * Falls back to JSON serialization with Date support when structuredClone fails.\r\n */\r\nfunction safeClone<T>(obj: T): T {\r\n try {\r\n return structuredClone(toRaw(obj));\r\n } catch {\r\n // Fallback: deep clone with Date support\r\n return JSON.parse(\r\n JSON.stringify(obj, (_key, value) => {\r\n if (value instanceof Date) {\r\n return { __type: \"Date\", value: value.toISOString() };\r\n }\r\n return value;\r\n }),\r\n (_key, value) => {\r\n if (value && typeof value === \"object\" && value.__type === \"Date\") {\r\n return new Date(value.value);\r\n }\r\n return value;\r\n },\r\n );\r\n }\r\n}\r\n\r\nexport interface UseTableEditingOptions<T> {\r\n /** Editing mode: cell or row */\r\n editMode: Ref<\"cell\" | \"row\" | undefined>;\r\n /** External editing rows (v-model:editingRows) */\r\n editingRows?: Ref<T[] | undefined>;\r\n /** Data key field for item identification */\r\n dataKey: string;\r\n /** Function to get unique key for an item */\r\n getItemKey: (item: T, index: number) => string;\r\n}\r\n\r\nexport interface CellEditEvent<T> {\r\n data: T;\r\n field: string;\r\n index: number;\r\n}\r\n\r\nexport interface CellEditCompleteEvent<T> extends CellEditEvent<T> {\r\n newValue: unknown;\r\n}\r\n\r\nexport interface RowEditEvent<T> {\r\n data: T;\r\n index: number;\r\n}\r\n\r\nexport interface RowEditSaveEvent<T> extends RowEditEvent<T> {\r\n newData: T;\r\n}\r\n\r\n/** Editing metadata for a row - stores copy of data being edited */\r\nexport interface EditingMeta<T> {\r\n data: T;\r\n fields: string[];\r\n}\r\n\r\nexport interface UseTableEditingReturn<T> {\r\n // State\r\n /** Currently editing cell (for cell mode) */\r\n editingCell: Ref<{ rowIndex: number; field: string } | null>;\r\n /** Internal array of rows being edited (for row mode) */\r\n internalEditingRows: Ref<T[]>;\r\n /** Snapshot of row data before editing (for cancel) */\r\n editingRowSnapshot: Ref<Map<string, T>>;\r\n /** Editing metadata - stores copies of rows being edited (PrimeVue-style) */\r\n editingMeta: Ref<Record<number, EditingMeta<T>>>;\r\n\r\n // Cell editing methods\r\n /** Check if a specific cell is being edited */\r\n isCellEditing: (rowIndex: number, field: string) => boolean;\r\n /** Start editing a cell */\r\n startCellEdit: (item: T, field: string, rowIndex: number) => CellEditEvent<T>;\r\n /** Complete cell editing with new value */\r\n completeCellEdit: (item: T, field: string, rowIndex: number, newValue: unknown) => CellEditCompleteEvent<T>;\r\n /** Cancel cell editing */\r\n cancelCellEdit: (item: T, field: string, rowIndex: number) => CellEditEvent<T>;\r\n /** Get the editing data for a row (copy that user edits) */\r\n getEditingRowData: (item: T, rowIndex: number) => T;\r\n\r\n // Row editing methods\r\n /** Check if a specific row is being edited */\r\n isRowEditing: (item: T) => boolean;\r\n /** Start editing a row */\r\n startRowEdit: (item: T, rowIndex: number) => RowEditEvent<T>;\r\n /** Save row editing */\r\n saveRowEdit: (item: T, rowIndex: number) => RowEditSaveEvent<T>;\r\n /** Cancel row editing (restores original data) */\r\n cancelRowEdit: (item: T, rowIndex: number) => RowEditEvent<T>;\r\n}\r\n\r\nexport function useTableEditing<T extends Record<string, any>>(\r\n options: UseTableEditingOptions<T>,\r\n): UseTableEditingReturn<T> {\r\n const { editMode, editingRows, getItemKey } = options;\r\n\r\n // ============================================================================\r\n // Cell Editing State\r\n // ============================================================================\r\n\r\n /** Currently editing cell: { rowIndex, field } */\r\n const editingCell = ref<{ rowIndex: number; field: string } | null>(null);\r\n\r\n /**\r\n * Editing metadata - stores copies of rows being edited.\r\n * Key is rowIndex, value is { data: copy of row, fields: array of fields being edited }\r\n * This prevents re-renders when user types - they edit the copy, not the original.\r\n */\r\n const editingMeta = ref<Record<number, EditingMeta<T>>>({}) as Ref<Record<number, EditingMeta<T>>>;\r\n\r\n // ============================================================================\r\n // Row Editing State\r\n // ============================================================================\r\n\r\n /** Internal array of rows currently being edited */\r\n const internalEditingRows = ref<T[]>([]) as Ref<T[]>;\r\n\r\n /** Snapshot of row data before editing (for cancel/restore) */\r\n const editingRowSnapshot = ref<Map<string, T>>(new Map()) as Ref<Map<string, T>>;\r\n\r\n // Sync editingRows with external prop\r\n watch(\r\n () => editingRows?.value,\r\n (newVal) => {\r\n if (newVal !== undefined) {\r\n internalEditingRows.value = [...newVal];\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n // ============================================================================\r\n // Cell Editing Methods\r\n // ============================================================================\r\n\r\n /**\r\n * Check if a specific cell is being edited\r\n */\r\n const isCellEditing = (rowIndex: number, field: string): boolean => {\r\n if (editMode.value === \"cell\") {\r\n return editingCell.value?.rowIndex === rowIndex && editingCell.value?.field === field;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Start editing a cell - creates a copy of the row data in editingMeta\r\n */\r\n const startCellEdit = (item: T, field: string, rowIndex: number): CellEditEvent<T> => {\r\n if (editMode.value !== \"cell\") {\r\n return { data: item, field, index: rowIndex };\r\n }\r\n\r\n editingCell.value = { rowIndex, field };\r\n\r\n // Create or update editingMeta for this row (PrimeVue pattern)\r\n const meta = editingMeta.value[rowIndex];\r\n if (!meta) {\r\n // Create a copy of the row data - user will edit this copy\r\n editingMeta.value = {\r\n ...editingMeta.value,\r\n [rowIndex]: {\r\n data: safeClone(item),\r\n fields: [field],\r\n },\r\n };\r\n } else {\r\n // Add field to existing meta\r\n if (!meta.fields.includes(field)) {\r\n meta.fields.push(field);\r\n }\r\n }\r\n\r\n return { data: item, field, index: rowIndex };\r\n };\r\n\r\n /**\r\n * Get the editing data for a row.\r\n * Returns the copy from editingMeta if editing, otherwise the original item.\r\n * This is what should be passed to editor slot - edits go to the copy, not the original.\r\n */\r\n const getEditingRowData = (item: T, rowIndex: number): T => {\r\n const meta = editingMeta.value[rowIndex];\r\n return meta ? meta.data : item;\r\n };\r\n\r\n /**\r\n * Complete cell editing with new value.\r\n * Clears editingMeta for this row - the new value should be applied by the parent.\r\n */\r\n const completeCellEdit = (item: T, field: string, rowIndex: number, newValue: unknown): CellEditCompleteEvent<T> => {\r\n if (editMode.value !== \"cell\") {\r\n return { data: item, field, newValue, index: rowIndex };\r\n }\r\n\r\n // Get the edited data from meta before clearing\r\n const meta = editingMeta.value[rowIndex];\r\n const editedData = meta?.data;\r\n\r\n // Clear editing state\r\n editingCell.value = null;\r\n\r\n // Clean up editingMeta\r\n if (meta) {\r\n const fields = meta.fields.filter((f) => f !== field);\r\n if (fields.length === 0) {\r\n const newMeta = { ...editingMeta.value };\r\n delete newMeta[rowIndex];\r\n editingMeta.value = newMeta;\r\n } else {\r\n editingMeta.value = {\r\n ...editingMeta.value,\r\n [rowIndex]: { ...meta, fields },\r\n };\r\n }\r\n }\r\n\r\n // Return event with both original and new value\r\n // newValue comes from editingMeta if available\r\n const finalNewValue = editedData ? (editedData as Record<string, unknown>)[field] : newValue;\r\n return { data: item, field, newValue: finalNewValue, index: rowIndex };\r\n };\r\n\r\n /**\r\n * Cancel cell editing - discards the copy in editingMeta\r\n */\r\n const cancelCellEdit = (item: T, field: string, rowIndex: number): CellEditEvent<T> => {\r\n if (editMode.value !== \"cell\") {\r\n return { data: item, field, index: rowIndex };\r\n }\r\n\r\n // Clear editing state\r\n editingCell.value = null;\r\n\r\n // Clean up editingMeta (discard the copy)\r\n const meta = editingMeta.value[rowIndex];\r\n if (meta) {\r\n const fields = meta.fields.filter((f) => f !== field);\r\n if (fields.length === 0) {\r\n const newMeta = { ...editingMeta.value };\r\n delete newMeta[rowIndex];\r\n editingMeta.value = newMeta;\r\n } else {\r\n editingMeta.value = {\r\n ...editingMeta.value,\r\n [rowIndex]: { ...meta, fields },\r\n };\r\n }\r\n }\r\n\r\n return { data: item, field, index: rowIndex };\r\n };\r\n\r\n // ============================================================================\r\n // Row Editing Methods\r\n // ============================================================================\r\n\r\n /**\r\n * Check if a specific row is being edited\r\n */\r\n const isRowEditing = (item: T): boolean => {\r\n const key = getItemKey(item, -1);\r\n return internalEditingRows.value.some((row) => getItemKey(row, -1) === key);\r\n };\r\n\r\n /**\r\n * Start editing a row\r\n */\r\n const startRowEdit = (item: T, rowIndex: number): RowEditEvent<T> => {\r\n if (editMode.value !== \"row\") {\r\n return { data: item, index: rowIndex };\r\n }\r\n\r\n const key = getItemKey(item, rowIndex);\r\n\r\n // Store snapshot for cancel\r\n editingRowSnapshot.value.set(key, safeClone(item));\r\n\r\n // Add to editing rows\r\n internalEditingRows.value = [...internalEditingRows.value, item];\r\n\r\n return { data: item, index: rowIndex };\r\n };\r\n\r\n /**\r\n * Save row editing\r\n */\r\n const saveRowEdit = (item: T, rowIndex: number): RowEditSaveEvent<T> => {\r\n if (editMode.value !== \"row\") {\r\n return { data: item, newData: item, index: rowIndex };\r\n }\r\n\r\n const key = getItemKey(item, rowIndex);\r\n const originalData = editingRowSnapshot.value.get(key);\r\n\r\n // Remove from editing\r\n internalEditingRows.value = internalEditingRows.value.filter((row) => getItemKey(row, -1) !== key);\r\n editingRowSnapshot.value.delete(key);\r\n\r\n return {\r\n data: originalData || item,\r\n newData: item,\r\n index: rowIndex,\r\n };\r\n };\r\n\r\n /**\r\n * Cancel row editing (restores original data)\r\n */\r\n const cancelRowEdit = (item: T, rowIndex: number): RowEditEvent<T> => {\r\n if (editMode.value !== \"row\") {\r\n return { data: item, index: rowIndex };\r\n }\r\n\r\n const key = getItemKey(item, rowIndex);\r\n const originalData = editingRowSnapshot.value.get(key);\r\n\r\n // Restore original data\r\n if (originalData) {\r\n Object.assign(item, originalData);\r\n }\r\n\r\n // Remove from editing\r\n internalEditingRows.value = internalEditingRows.value.filter((row) => getItemKey(row, -1) !== key);\r\n editingRowSnapshot.value.delete(key);\r\n\r\n return { data: item, index: rowIndex };\r\n };\r\n\r\n return {\r\n // State\r\n editingCell,\r\n internalEditingRows,\r\n editingRowSnapshot,\r\n editingMeta,\r\n\r\n // Cell editing\r\n isCellEditing,\r\n startCellEdit,\r\n completeCellEdit,\r\n cancelCellEdit,\r\n getEditingRowData,\r\n\r\n // Row editing\r\n isRowEditing,\r\n startRowEdit,\r\n saveRowEdit,\r\n cancelRowEdit,\r\n };\r\n}\r\n\r\nexport default useTableEditing;\r\n","/**\r\n * useTableExpansion - Composable for expandable rows functionality\r\n *\r\n * Handles row expansion/collapse with efficient key-based lookup.\r\n * Extracted from VcDataTable.vue for better modularity.\r\n *\r\n * Inspired by PrimeVue DataTable expandableRows patterns.\r\n */\r\nimport { ref, computed, watch, type Ref, type ComputedRef } from \"vue\";\r\n\r\nexport interface UseTableExpansionOptions<T> {\r\n /** External expanded rows (v-model:expandedRows) */\r\n expandedRows?: Ref<T[] | undefined>;\r\n /** Function to get unique key for an item */\r\n getItemKey: (item: T, index: number) => string;\r\n /** Per-row callback to disable expansion. When omitted, all rows are expandable. */\r\n isRowExpandable?: (item: T) => boolean;\r\n}\r\n\r\nexport interface RowExpandEvent<T> {\r\n data: T;\r\n originalEvent: Event;\r\n}\r\n\r\nexport interface UseTableExpansionReturn<T> {\r\n /** Internal array of expanded rows */\r\n internalExpandedRows: Ref<T[]>;\r\n /** Set of expanded row keys for O(1) lookup */\r\n expandedRowKeys: ComputedRef<Set<string>>;\r\n /** Check if a row is allowed to expand (based on isRowExpandable callback) */\r\n canExpand: (item: T) => boolean;\r\n /** Check if a specific row is expanded */\r\n isRowExpanded: (item: T, index: number) => boolean;\r\n /** Toggle row expansion state */\r\n toggleRowExpansion: (item: T, index: number, event: Event) => RowExpandEvent<T> | null;\r\n /** Expand a row */\r\n expandRow: (item: T, index: number, event?: Event) => RowExpandEvent<T> | null;\r\n /** Collapse a row */\r\n collapseRow: (item: T, index: number, event?: Event) => RowExpandEvent<T>;\r\n /** Expand all rows */\r\n expandAll: (items: T[]) => void;\r\n /** Collapse all rows */\r\n collapseAll: () => void;\r\n}\r\n\r\nexport function useTableExpansion<T extends Record<string, any>>(\r\n options: UseTableExpansionOptions<T>,\r\n): UseTableExpansionReturn<T> {\r\n const { expandedRows, getItemKey, isRowExpandable } = options;\r\n\r\n // ============================================================================\r\n // State\r\n // ============================================================================\r\n\r\n /** Internal array of expanded rows */\r\n const internalExpandedRows = ref<T[]>([]) as Ref<T[]>;\r\n\r\n // Sync expandedRows with external prop\r\n watch(\r\n () => expandedRows?.value,\r\n (newVal) => {\r\n if (newVal !== undefined) {\r\n internalExpandedRows.value = [...newVal];\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n /**\r\n * Set of expanded row keys for O(1) lookup\r\n * Uses getItemKey with index=0 - the key should be based on dataKey field, not array index\r\n */\r\n const expandedRowKeys = computed<Set<string>>(() => {\r\n return new Set(internalExpandedRows.value.map((item) => getItemKey(item, 0)));\r\n });\r\n\r\n // ============================================================================\r\n // Methods\r\n // ============================================================================\r\n\r\n /**\r\n * Check if a row is allowed to expand (based on isRowExpandable callback)\r\n */\r\n const canExpand = (item: T): boolean => {\r\n if (!isRowExpandable) return true;\r\n return isRowExpandable(item);\r\n };\r\n\r\n /**\r\n * Check if a specific row is expanded\r\n * Note: Uses index=0 for key generation to match expandedRowKeys computation\r\n * The key should be based on dataKey field, not array index\r\n */\r\n const isRowExpanded = (item: T, _index: number): boolean => {\r\n // Use 0 as index because expandedRowKeys also uses 0\r\n // This ensures keys match when dataKey field doesn't exist (fallback to row-0)\r\n const key = getItemKey(item, 0);\r\n const result = expandedRowKeys.value.has(key);\r\n return result;\r\n };\r\n\r\n /**\r\n * Expand a row\r\n */\r\n const expandRow = (item: T, index: number, event?: Event): RowExpandEvent<T> | null => {\r\n if (!canExpand(item)) return null;\r\n\r\n if (!isRowExpanded(item, index)) {\r\n internalExpandedRows.value = [...internalExpandedRows.value, item];\r\n }\r\n return {\r\n data: item,\r\n originalEvent: event || new Event(\"expand\"),\r\n };\r\n };\r\n\r\n /**\r\n * Collapse a row\r\n */\r\n const collapseRow = (item: T, index: number, event?: Event): RowExpandEvent<T> => {\r\n // Use getItemKey with 0 as index to match expandedRowKeys computation\r\n const key = getItemKey(item, 0);\r\n internalExpandedRows.value = internalExpandedRows.value.filter((r) => getItemKey(r, 0) !== key);\r\n return {\r\n data: item,\r\n originalEvent: event || new Event(\"collapse\"),\r\n };\r\n };\r\n\r\n /**\r\n * Toggle row expansion state\r\n */\r\n const toggleRowExpansion = (item: T, index: number, event: Event): RowExpandEvent<T> | null => {\r\n event.stopPropagation();\r\n\r\n if (!canExpand(item)) return null;\r\n\r\n if (isRowExpanded(item, index)) {\r\n return collapseRow(item, index, event);\r\n } else {\r\n return expandRow(item, index, event);\r\n }\r\n };\r\n\r\n /**\r\n * Expand all rows\r\n */\r\n const expandAll = (items: T[]): void => {\r\n internalExpandedRows.value = isRowExpandable ? items.filter(isRowExpandable) : [...items];\r\n };\r\n\r\n /**\r\n * Collapse all rows\r\n */\r\n const collapseAll = (): void => {\r\n internalExpandedRows.value = [];\r\n };\r\n\r\n return {\r\n internalExpandedRows,\r\n expandedRowKeys,\r\n canExpand,\r\n isRowExpanded,\r\n toggleRowExpansion,\r\n expandRow,\r\n collapseRow,\r\n expandAll,\r\n collapseAll,\r\n };\r\n}\r\n\r\nexport default useTableExpansion;\r\n","/**\r\n * useTableSelectionV2 - Enhanced selection composable for VcDataTable\r\n *\r\n * Features:\r\n * - Single and multiple selection modes\r\n * - isRowSelectable callback for disabling selection on specific rows\r\n * - Efficient Set-based lookup for O(1) selection checks\r\n * - Select all with selectability filtering\r\n *\r\n * This is an enhanced version for VcDataTable.\r\n * The original useTableSelection is kept for VcTableComposition compatibility.\r\n *\r\n * Inspired by PrimeVue DataTable selection patterns.\r\n */\r\nimport { ref, computed, watch, type Ref, type ComputedRef } from \"vue\";\r\n\r\nexport interface UseTableSelectionV2Options<T> {\r\n /** Source data items */\r\n items: Ref<T[]>;\r\n /** External selection value (v-model:selection) */\r\n selection?: Ref<T | T[] | undefined>;\r\n /** Selection mode: single or multiple */\r\n selectionMode: Ref<\"single\" | \"multiple\" | undefined>;\r\n /** Callback to determine if a row can be selected */\r\n isRowSelectable?: (item: T) => boolean;\r\n /** Data key field for item identification */\r\n dataKey: string;\r\n /** Function to get unique key for an item */\r\n getItemKey: (item: T, index: number) => string;\r\n /** Total count of items (for pagination - used by \"select all\" feature) */\r\n totalCount?: Ref<number | undefined>;\r\n /** External \"select all\" state (v-model:selectAllActive) */\r\n selectAllActive?: Ref<boolean | undefined>;\r\n /**\r\n * Whether the consumer opted into the cross-page \"select all\" feature.\r\n * When falsy, the \"Select all N items\" choice banner stays hidden even if\r\n * all visible rows are selected and more items exist.\r\n */\r\n selectAllEnabled?: Ref<boolean | undefined>;\r\n /** Callback when \"select all\" mode changes */\r\n onSelectAllChange?: (active: boolean) => void;\r\n}\r\n\r\nexport interface RowSelectEvent<T> {\r\n data: T;\r\n originalEvent: Event;\r\n}\r\n\r\nexport interface RowSelectAllEvent<T> {\r\n data: T[];\r\n originalEvent: Event;\r\n}\r\n\r\n/** Selection state info for display */\r\nexport interface SelectionInfo {\r\n /** Number of selected items */\r\n count: number;\r\n /** Whether \"select all\" mode is active (includes non-visible items) */\r\n isSelectAll: boolean;\r\n /** Total count of items (from totalCount prop) */\r\n totalCount?: number;\r\n}\r\n\r\nexport interface UseTableSelectionV2Return<T> {\r\n /** Internal selection array */\r\n internalSelection: Ref<T[]>;\r\n /** Set of selected item keys for O(1) lookup */\r\n selectionKeys: ComputedRef<Set<string>>;\r\n /** All selectable items are selected */\r\n allSelected: ComputedRef<boolean>;\r\n /** Some but not all selectable items are selected (indeterminate state) */\r\n someSelected: ComputedRef<boolean>;\r\n /** Whether \"select all\" mode is active (includes non-visible items) */\r\n isSelectAllActive: Ref<boolean>;\r\n /** Whether to show \"select all\" choice (when all visible items selected and more exist) */\r\n showSelectAllChoice: ComputedRef<boolean>;\r\n /** Selection info for display */\r\n selectionInfo: ComputedRef<SelectionInfo>;\r\n /** Check if an item is selected */\r\n isSelected: (item: T) => boolean;\r\n /** Check if an item can be selected */\r\n canSelect: (item: T) => boolean;\r\n /** Handle row selection change (click or checkbox) */\r\n handleRowSelectionChange: (item: T, event?: Event | boolean) => RowSelectEvent<T> | null;\r\n /** Handle select all checkbox change */\r\n handleSelectAllChange: (value: boolean, event?: Event) => RowSelectAllEvent<T>;\r\n /** Select a specific item */\r\n selectItem: (item: T, event?: Event) => RowSelectEvent<T> | null;\r\n /** Unselect a specific item */\r\n unselectItem: (item: T, event?: Event) => RowSelectEvent<T> | null;\r\n /** Clear all selections */\r\n clearSelection: () => void;\r\n /** Select all items (marks mode, emits event for parent to handle) */\r\n selectAll: () => void;\r\n /** Clear \"select all\" mode */\r\n clearSelectAll: () => void;\r\n /** Get selection state for bulk operations */\r\n getSelectionState: () => { selected: T[]; isSelectAll: boolean; count: number };\r\n}\r\n\r\nexport function useTableSelectionV2<T extends Record<string, any>>(\r\n options: UseTableSelectionV2Options<T>,\r\n): UseTableSelectionV2Return<T> {\r\n const {\r\n items,\r\n selection,\r\n selectionMode,\r\n isRowSelectable,\r\n getItemKey,\r\n totalCount,\r\n selectAllActive,\r\n selectAllEnabled,\r\n onSelectAllChange,\r\n } = options;\r\n\r\n // ============================================================================\r\n // State\r\n // ============================================================================\r\n\r\n /** Internal selection array */\r\n const internalSelection = ref<T[]>([]) as Ref<T[]>;\r\n\r\n /** Internal \"select all\" mode state */\r\n const isSelectAllActive = ref<boolean>(false);\r\n\r\n // Sync selection with external prop\r\n watch(\r\n () => selection?.value,\r\n (newVal) => {\r\n if (newVal !== undefined) {\r\n internalSelection.value = Array.isArray(newVal) ? newVal : [newVal];\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n // Sync selectAllActive with external prop\r\n watch(\r\n () => selectAllActive?.value,\r\n (newVal) => {\r\n if (newVal !== undefined) {\r\n isSelectAllActive.value = newVal;\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n /**\r\n * Set of selected item keys for O(1) lookup\r\n */\r\n const selectionKeys = computed<Set<string>>(() => {\r\n return new Set(internalSelection.value.map((item) => getItemKey(item, -1)));\r\n });\r\n\r\n // ============================================================================\r\n // Computed Properties\r\n // ============================================================================\r\n\r\n /**\r\n * Get all selectable items (filtered by isRowSelectable)\r\n */\r\n const selectableItems = computed<T[]>(() => {\r\n if (!isRowSelectable) return items.value;\r\n return items.value.filter(isRowSelectable);\r\n });\r\n\r\n /**\r\n * All selectable items are selected\r\n */\r\n const allSelected = computed<boolean>(() => {\r\n if (!items.value || items.value.length === 0) return false;\r\n if (selectableItems.value.length === 0) return false;\r\n return selectableItems.value.every((item) => isSelected(item));\r\n });\r\n\r\n /**\r\n * Some but not all selectable items are selected (indeterminate state)\r\n */\r\n const someSelected = computed<boolean>(() => {\r\n if (!items.value || items.value.length === 0) return false;\r\n if (selectableItems.value.length === 0) return false;\r\n const selectedCount = selectableItems.value.filter((item) => isSelected(item)).length;\r\n return selectedCount > 0 && selectedCount < selectableItems.value.length;\r\n });\r\n\r\n /**\r\n * Whether to show \"select all\" choice banner\r\n * Shows when all visible items are selected and more items exist (totalCount > items.length)\r\n */\r\n const showSelectAllChoice = computed<boolean>(() => {\r\n if (!selectAllEnabled?.value) return false; // Consumer did not opt into cross-page select all\r\n if (!totalCount?.value) return false;\r\n if (isSelectAllActive.value) return false; // Already in select all mode\r\n return allSelected.value && totalCount.value > items.value.length;\r\n });\r\n\r\n /**\r\n * Selection info for display\r\n */\r\n const selectionInfo = computed<SelectionInfo>(() => ({\r\n count: isSelectAllActive.value\r\n ? (totalCount?.value ?? internalSelection.value.length)\r\n : internalSelection.value.length,\r\n isSelectAll: isSelectAllActive.value,\r\n totalCount: totalCount?.value,\r\n }));\r\n\r\n // ============================================================================\r\n // Methods\r\n // ============================================================================\r\n\r\n /**\r\n * Check if an item is selected\r\n */\r\n const isSelected = (item: T): boolean => {\r\n const key = getItemKey(item, -1);\r\n return selectionKeys.value.has(key);\r\n };\r\n\r\n /**\r\n * Check if an item can be selected\r\n */\r\n const canSelect = (item: T): boolean => {\r\n if (!isRowSelectable) return true;\r\n return isRowSelectable(item);\r\n };\r\n\r\n /**\r\n * Select a specific item\r\n */\r\n const selectItem = (item: T, event?: Event): RowSelectEvent<T> | null => {\r\n if (!canSelect(item)) return null;\r\n\r\n const mode = selectionMode.value;\r\n const key = getItemKey(item, -1);\r\n\r\n if (mode === \"single\") {\r\n internalSelection.value = [item];\r\n } else {\r\n if (!selectionKeys.value.has(key)) {\r\n internalSelection.value = [...internalSelection.value, item];\r\n }\r\n }\r\n\r\n return {\r\n data: item,\r\n originalEvent: event || new Event(\"select\"),\r\n };\r\n };\r\n\r\n /**\r\n * Unselect a specific item\r\n */\r\n const unselectItem = (item: T, event?: Event): RowSelectEvent<T> | null => {\r\n const key = getItemKey(item, -1);\r\n\r\n internalSelection.value = internalSelection.value.filter((selected) => getItemKey(selected, -1) !== key);\r\n\r\n return {\r\n data: item,\r\n originalEvent: event || new Event(\"unselect\"),\r\n };\r\n };\r\n\r\n /**\r\n * Handle row selection change (click or checkbox)\r\n */\r\n const handleRowSelectionChange = (item: T, eventOrValue?: Event | boolean): RowSelectEvent<T> | null => {\r\n // Check if row is selectable\r\n if (!canSelect(item)) {\r\n return null;\r\n }\r\n\r\n const isCurrentlySelected = isSelected(item);\r\n const originalEvent = eventOrValue instanceof Event ? eventOrValue : new Event(\"change\");\r\n\r\n if (isCurrentlySelected) {\r\n return unselectItem(item, originalEvent);\r\n } else {\r\n return selectItem(item, originalEvent);\r\n }\r\n };\r\n\r\n /**\r\n * Handle select all checkbox change\r\n */\r\n const handleSelectAllChange = (value: boolean, event?: Event): RowSelectAllEvent<T> => {\r\n const originalEvent = event || new Event(\"change\");\r\n\r\n if (value) {\r\n // Select all selectable items\r\n internalSelection.value = [...selectableItems.value];\r\n return {\r\n data: selectableItems.value,\r\n originalEvent,\r\n };\r\n } else {\r\n // Clear selection\r\n internalSelection.value = [];\r\n return {\r\n data: [],\r\n originalEvent,\r\n };\r\n }\r\n };\r\n\r\n /**\r\n * Clear all selections\r\n */\r\n const clearSelection = (): void => {\r\n internalSelection.value = [];\r\n isSelectAllActive.value = false;\r\n onSelectAllChange?.(false);\r\n };\r\n\r\n /**\r\n * Select all items (marks mode, parent should handle loading all IDs)\r\n * This sets the \"select all\" flag - parent component decides how to handle bulk operations\r\n */\r\n const selectAll = (): void => {\r\n // First select all visible items\r\n internalSelection.value = [...selectableItems.value];\r\n // Then activate \"select all\" mode for non-visible items\r\n isSelectAllActive.value = true;\r\n onSelectAllChange?.(true);\r\n };\r\n\r\n /**\r\n * Clear \"select all\" mode (but keep visible selections)\r\n */\r\n const clearSelectAll = (): void => {\r\n isSelectAllActive.value = false;\r\n onSelectAllChange?.(false);\r\n };\r\n\r\n /**\r\n * Get selection state for bulk operations\r\n * Parent can use this to determine whether to operate on selected items or all items\r\n */\r\n const getSelectionState = (): { selected: T[]; isSelectAll: boolean; count: number } => {\r\n return {\r\n selected: [...internalSelection.value],\r\n isSelectAll: isSelectAllActive.value,\r\n count: isSelectAllActive.value\r\n ? (totalCount?.value ?? internalSelection.value.length)\r\n : internalSelection.value.length,\r\n };\r\n };\r\n\r\n // Clear select all mode when selection changes manually (e.g., uncheck an item)\r\n watch(\r\n () => internalSelection.value.length,\r\n (newLength, oldLength) => {\r\n // If user deselects an item while in \"select all\" mode, exit that mode\r\n if (isSelectAllActive.value && newLength < oldLength) {\r\n isSelectAllActive.value = false;\r\n onSelectAllChange?.(false);\r\n }\r\n },\r\n );\r\n\r\n return {\r\n internalSelection,\r\n selectionKeys,\r\n allSelected,\r\n someSelected,\r\n isSelectAllActive,\r\n showSelectAllChoice,\r\n selectionInfo,\r\n isSelected,\r\n canSelect,\r\n handleRowSelectionChange,\r\n handleSelectAllChange,\r\n selectItem,\r\n unselectItem,\r\n clearSelection,\r\n selectAll,\r\n clearSelectAll,\r\n getSelectionState,\r\n };\r\n}\r\n\r\nexport default useTableSelectionV2;\r\n","import { computed, type ComputedRef } from \"vue\";\nimport type { useTableSelectionV2 } from \"@ui/components/organisms/vc-data-table/composables/useTableSelectionV2\";\n\n/** @internal Raw selection composable instance — hidden behind {@link TableSelectionFacade}. */\nexport type SelectionImpl<T extends Record<string, unknown>> = ReturnType<typeof useTableSelectionV2<T>>;\n\n/** Emit-owning handlers the facade exposes as `onRowSelect` / `onSelectAll`. */\nexport interface TableSelectionHandlers<T extends Record<string, unknown>> {\n /** Toggle a row's selection; emits row-select / row-unselect. */\n onRowSelect: (item: T, eventOrValue?: Event | boolean) => void;\n /** Toggle select-all; emits row-select-all / row-unselect-all + update:selectAll. */\n onSelectAll: (value: boolean) => void;\n}\n\n/**\n * Deep, intention-revealing surface for row selection. Wraps the raw\n * `useTableSelectionV2` instance (hidden implementation) plus the two\n * emit-owning handlers, so VcDataTable's template and children consume a single\n * `selection` object instead of the 17-member composable and loose handlers.\n * Members map 1:1 to the implementation; behaviour is unchanged.\n */\nexport interface TableSelectionFacade<T extends Record<string, unknown>> {\n /** Currently selected items (loaded rows). Maps `internalSelection`. */\n selected: ComputedRef<T[]>;\n /** All loaded rows are selected. Maps `allSelected`. */\n isAllSelected: SelectionImpl<T>[\"allSelected\"];\n /** Some, but not all, loaded rows are selected. Maps `someSelected`. */\n isPartiallySelected: SelectionImpl<T>[\"someSelected\"];\n /** \"Select all across pages/total\" mode is active. Maps `isSelectAllActive`. */\n isSelectAllAcrossPages: SelectionImpl<T>[\"isSelectAllActive\"];\n /** Whether to show the \"select all N\" prompt. Maps `showSelectAllChoice`. */\n showSelectAllPrompt: SelectionImpl<T>[\"showSelectAllChoice\"];\n /** Selection summary ({ count, isSelectAll }). Maps `selectionInfo`. */\n info: SelectionImpl<T>[\"selectionInfo\"];\n /** Predicate: is this item selected. */\n isSelected: SelectionImpl<T>[\"isSelected\"];\n /** Predicate: can this item be selected. */\n canSelect: SelectionImpl<T>[\"canSelect\"];\n /** Snapshot of the current selection state. Maps `getSelectionState`. */\n getState: SelectionImpl<T>[\"getSelectionState\"];\n /** Select all selectable rows. */\n selectAll: SelectionImpl<T>[\"selectAll\"];\n /** Clear the selection. Maps `clearSelection`. */\n clear: SelectionImpl<T>[\"clearSelection\"];\n /** Toggle a row's selection; emits row-select / row-unselect. */\n onRowSelect: TableSelectionHandlers<T>[\"onRowSelect\"];\n /** Toggle select-all; emits row-select-all / row-unselect-all + update:selectAll. */\n onSelectAll: TableSelectionHandlers<T>[\"onSelectAll\"];\n}\n\n/**\n * Assemble the {@link TableSelectionFacade} from a raw selection instance and\n * its emit-owning handlers. Pure aliasing — reactivity identity is preserved,\n * so no behaviour changes versus reading the raw members directly.\n */\nexport function createTableSelectionFacade<T extends Record<string, unknown>>(\n selection: SelectionImpl<T>,\n handlers: TableSelectionHandlers<T>,\n): TableSelectionFacade<T> {\n return {\n selected: computed(() => selection.internalSelection.value),\n isAllSelected: selection.allSelected,\n isPartiallySelected: selection.someSelected,\n isSelectAllAcrossPages: selection.isSelectAllActive,\n showSelectAllPrompt: selection.showSelectAllChoice,\n info: selection.selectionInfo,\n isSelected: selection.isSelected,\n canSelect: selection.canSelect,\n getState: selection.getSelectionState,\n selectAll: selection.selectAll,\n clear: selection.clearSelection,\n onRowSelect: handlers.onRowSelect,\n onSelectAll: handlers.onSelectAll,\n };\n}\n","/**\n * Pure helper functions for VcColumn props.\n *\n * Extracted into a standalone module so they can be imported from anywhere\n * without creating composable init-order dependencies.\n */\nimport type { VcColumnProps } from \"@ui/components/organisms/vc-data-table/types\";\n\n/**\n * A \"special\" column is one that's infrastructural (selection checkbox,\n * row reorder handle, row expander, row editor) rather than a data column.\n *\n * Special columns have hardcoded widths and are NOT part of the width engine.\n */\nexport function isSpecialColumn(col: VcColumnProps): boolean {\n return !!(col.selectionMode || col.rowReorder || col.expander || col.rowEditor);\n}\n\n/**\n * Hardcoded pixel widths for special columns.\n * These are rendered by VcColumn with fixed styles set in\n * useTableColumns.getHeaderStyle / getCellStyle.\n */\nexport const SPECIAL_COLUMN_WIDTHS = {\n selection: 40,\n rowReorder: 50,\n expander: 50,\n rowEditor: 100,\n} as const;\n\n/**\n * Returns the fixed pixel width of a special column, or 0 if not special.\n */\nexport function getSpecialColumnWidth(col: VcColumnProps): number {\n if (col.selectionMode) return SPECIAL_COLUMN_WIDTHS.selection;\n if (col.rowReorder) return SPECIAL_COLUMN_WIDTHS.rowReorder;\n if (col.expander) return SPECIAL_COLUMN_WIDTHS.expander;\n if (col.rowEditor) return SPECIAL_COLUMN_WIDTHS.rowEditor;\n return 0;\n}\n","/**\n * useTableColumns - Composable for column-related logic\n *\n * Uses the weight-based column width engine for deterministic\n * width computation: sum(widths) + filler === availableWidth.\n *\n * Available width is measured directly from the DOM transition-wrapper\n * element — no hardcoded constants for row padding, drag handles, etc.\n */\nimport { ref, computed, watch, type Ref, type ComputedRef } from \"vue\";\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\nimport { isSpecialColumn, SPECIAL_COLUMN_WIDTHS } from \"@ui/components/organisms/vc-data-table/utils/columnHelpers\";\nimport type {\n VcColumnProps,\n ColumnState,\n ColumnSpec,\n TableFitMode,\n} from \"@ui/components/organisms/vc-data-table/types\";\nimport {\n computeColumnWidths,\n parseColumnWidth,\n buildInitialWeights,\n normalizeWeights,\n DEFAULT_MIN_COLUMN_PX,\n type EngineOutput,\n} from \"./useColumnWidthEngine\";\n\nexport interface UseTableColumnsOptions {\n visibleColumns: Ref<ColumnInstance[]> | ComputedRef<ColumnInstance[]>;\n resizableColumns?: boolean;\n reorderableColumns?: boolean;\n fitMode?: TableFitMode;\n /**\n * Measures the pixel width available for data columns directly from DOM.\n * Should return the transition-wrapper width (already excludes row padding,\n * drag handles, selection cells, etc.) or 0 if not yet rendered.\n */\n getAvailableWidth: () => number;\n}\n\nexport interface UseTableColumnsReturn {\n // State\n columnState: Ref<ColumnState>;\n engineOutput: Ref<EngineOutput>;\n headerRefs: Map<string, HTMLElement>;\n\n // Methods\n setHeaderRef: (id: string, el: unknown) => void;\n recompute: () => void;\n resetFromProps: () => void;\n /**\n * Cancels a pending deferred re-init from declared props.\n * Called by the orchestrator after persistence restores ColumnState — the\n * restored weights take precedence over declared VcColumn widths.\n */\n markStateRestored: () => void;\n\n // Computed\n orderedVisibleColumns: ComputedRef<ColumnInstance[]>;\n totalColumns: ComputedRef<number>;\n\n // Helpers\n isSpecialColumn: (col: VcColumnProps) => boolean;\n isColumnResizable: (col: VcColumnProps) => boolean;\n isColumnReorderable: (col: VcColumnProps) => boolean;\n isLastResizableColumn: (col: VcColumnProps) => boolean;\n getEffectiveColumnWidth: (col: VcColumnProps) => string | undefined;\n getHeaderAlign: (col: VcColumnProps) => \"left\" | \"center\" | \"right\" | undefined;\n getCellAlign: (col: VcColumnProps) => \"left\" | \"center\" | \"right\" | undefined;\n getHeaderStyle: (col: VcColumnProps) => object | undefined;\n getCellStyle: (col: VcColumnProps) => object | undefined;\n getSortField: (col: VcColumnProps) => string;\n}\n\nexport function useTableColumns(options: UseTableColumnsOptions): UseTableColumnsReturn {\n const { visibleColumns, resizableColumns = true, reorderableColumns = false, fitMode = \"gap\" } = options;\n\n // ============================================================================\n // State\n // ============================================================================\n\n const columnState = ref<ColumnState>({ order: [], specs: {} });\n const engineOutput = ref<EngineOutput>({ widths: {}, fillerWidth: 0 });\n const headerRefs = new Map<string, HTMLElement>();\n\n // ============================================================================\n // Helpers\n // ============================================================================\n\n const isColumnResizable = (col: VcColumnProps): boolean => {\n if (isSpecialColumn(col)) return false;\n return resizableColumns;\n };\n\n const isColumnReorderable = (col: VcColumnProps): boolean => {\n if (isSpecialColumn(col)) return false;\n return reorderableColumns;\n };\n\n const getEffectiveColumnWidth = (col: VcColumnProps): string | undefined => {\n if (col.selectionMode) return `${SPECIAL_COLUMN_WIDTHS.selection}px`;\n if (col.rowReorder) return `${SPECIAL_COLUMN_WIDTHS.rowReorder}px`;\n if (col.expander) return `${SPECIAL_COLUMN_WIDTHS.expander}px`;\n if (col.rowEditor) return `${SPECIAL_COLUMN_WIDTHS.rowEditor}px`;\n const w = engineOutput.value.widths[col.id];\n if (w !== undefined && w > 0) return `${w}px`;\n // Engine hasn't computed yet (first paint — availableWidth not measurable).\n // Fall back to the column's DECLARED width so the first frame already matches\n // the engine's fixed/auto layout: TableHead renders `flex: 0 0 <declared>` for\n // fixed/percent columns and `flex: 1 1 0` for auto columns. For px/auto this is\n // identical to the engine's result; for percent columns it can differ by a few\n // px on the first frame (CSS resolves % against the wrapper width, which still\n // includes special cells, vs the engine's special-cell-excluded availableWidth),\n // corrected on the first recompute. This eliminates the equal-distribution flash.\n const declared = parseColumnWidth(col.width, 0);\n if (declared.type === \"px\") return `${declared.desiredPx}px`;\n if (declared.type === \"percent\" && typeof col.width === \"string\") return col.width.trim();\n return undefined;\n };\n\n const getHeaderAlign = (col: VcColumnProps): \"left\" | \"center\" | \"right\" | undefined => {\n if (isSpecialColumn(col)) return \"center\";\n const align = col.headerAlign || col.align;\n if (!align) return undefined;\n if (align === \"start\") return \"left\";\n if (align === \"end\") return \"right\";\n return align;\n };\n\n const getCellAlign = (col: VcColumnProps): \"left\" | \"center\" | \"right\" | undefined => {\n if (isSpecialColumn(col)) return \"center\";\n if (!col.align) return undefined;\n if (col.align === \"start\") return \"left\";\n if (col.align === \"end\") return \"right\";\n return col.align;\n };\n\n const getHeaderStyle = (col: VcColumnProps): object | undefined => {\n if (col.selectionMode) {\n return {\n textAlign: \"center\",\n justifyContent: \"center\",\n minWidth: `${SPECIAL_COLUMN_WIDTHS.selection}px`,\n maxWidth: `${SPECIAL_COLUMN_WIDTHS.selection}px`,\n };\n }\n if (col.rowReorder || col.expander) {\n const px = col.rowReorder ? SPECIAL_COLUMN_WIDTHS.rowReorder : SPECIAL_COLUMN_WIDTHS.expander;\n return { textAlign: \"center\", justifyContent: \"center\", minWidth: `${px}px`, maxWidth: `${px}px` };\n }\n return undefined;\n };\n\n const getCellStyle = (col: VcColumnProps): object | undefined => getHeaderStyle(col);\n\n const getSortField = (col: VcColumnProps): string => col.sortField || col.field || col.id;\n\n // ============================================================================\n // Refs\n // ============================================================================\n\n const setHeaderRef = (id: string, el: unknown) => {\n const domEl =\n el && typeof el === \"object\" && \"$el\" in el ? (el as { $el: HTMLElement }).$el : (el as HTMLElement | null);\n if (domEl) headerRefs.set(id, domEl);\n else headerRefs.delete(id);\n };\n\n // ============================================================================\n // Column Ordering\n // ============================================================================\n\n const orderedVisibleColumns = computed<ColumnInstance[]>(() => {\n const validColumns = visibleColumns.value.filter(\n (col): col is ColumnInstance => col != null && col.props != null && col.props.id != null,\n );\n\n if (!reorderableColumns || columnState.value.order.length === 0) {\n return validColumns;\n }\n\n const orderMap = new Map(columnState.value.order.map((id, i) => [id, i]));\n const specialCols = validColumns.filter((col) => isSpecialColumn(col.props));\n const dataCols = validColumns\n .filter((col) => !isSpecialColumn(col.props))\n .sort((a, b) => (orderMap.get(a.props.id) ?? 0) - (orderMap.get(b.props.id) ?? 0));\n\n const selectionCol = specialCols.filter((c) => c.props.selectionMode);\n const expanderCol = specialCols.filter((c) => c.props.expander);\n const reorderCol = specialCols.filter((c) => c.props.rowReorder);\n const editorCol = specialCols.filter((c) => c.props.rowEditor);\n\n return [...selectionCol, ...expanderCol, ...reorderCol, ...dataCols, ...editorCol];\n });\n\n const isLastResizableColumn = (col: VcColumnProps): boolean => {\n if (!isColumnResizable(col)) return false;\n const resizableCols = orderedVisibleColumns.value.filter((c) => isColumnResizable(c.props));\n return resizableCols.length > 0 && resizableCols[resizableCols.length - 1].props.id === col.id;\n };\n\n const totalColumns = computed(() => visibleColumns.value.length);\n\n // ============================================================================\n // Initialization from VcColumn props\n // ============================================================================\n\n /**\n * Build a ColumnSpec for one column from its declared props.\n * Uses `availableWidth` to resolve percentage values.\n */\n function buildSpec(col: VcColumnProps, availableWidth: number, fallbackWeight: number): ColumnSpec {\n const minParsed = parseColumnWidth(col.minWidth, availableWidth);\n const maxParsed = parseColumnWidth(col.maxWidth, availableWidth);\n return {\n weight: fallbackWeight,\n minPx: minParsed.desiredPx ?? DEFAULT_MIN_COLUMN_PX,\n maxPx: maxParsed.desiredPx ?? Infinity,\n };\n }\n\n /**\n * Initialize weights and specs for all currently-visible regular columns\n * from their declared props (`width`, `minWidth`, `maxWidth`).\n * Safe to call with availableWidth=0 — percentages resolve to 0 in that case,\n * so `needsPropsReinit` will remain true until a real width is available.\n */\n function applyInitFromProps(availableWidth: number): void {\n const regularCols = visibleColumns.value.filter((c) => !isSpecialColumn(c.props));\n if (regularCols.length === 0) return;\n\n const parsed = regularCols.map((col) => ({\n id: col.props.id,\n parsed: parseColumnWidth(col.props.width, availableWidth),\n }));\n const weights = buildInitialWeights(parsed, availableWidth);\n\n const order = [...columnState.value.order];\n // Ensure all regular columns are in order\n const orderSet = new Set(order);\n for (const col of regularCols) {\n if (!orderSet.has(col.props.id)) order.push(col.props.id);\n }\n\n const specs: Record<string, ColumnSpec> = { ...columnState.value.specs };\n for (const col of regularCols) {\n const fallbackWeight = weights[col.props.id] ?? 1 / regularCols.length;\n specs[col.props.id] = buildSpec(col.props, availableWidth, fallbackWeight);\n }\n\n columnState.value = { order, specs };\n }\n\n /**\n * Cancel any pending deferred re-init from declared props.\n * When persistence restores weights, those take precedence over declared\n * VcColumn widths — so `needsPropsReinit` must be cleared to prevent\n * recompute() from overwriting restored weights with parsed props.\n */\n const markStateRestored = (): void => {\n needsPropsReinit = false;\n };\n\n /**\n * Reset: rebuild ColumnState from declared props, discarding persisted state.\n * Called by handleTableReset in the orchestrator. Also clears engineOutput\n * so callers don't see stale widths between reset and the next recompute.\n */\n const resetFromProps = (): void => {\n columnState.value = { order: [], specs: {} };\n engineOutput.value = { widths: {}, fillerWidth: 0 };\n needsPropsReinit = true;\n const available = options.getAvailableWidth();\n if (available > 0) {\n applyInitFromProps(available);\n needsPropsReinit = false;\n recompute();\n }\n };\n\n // ============================================================================\n // Engine recomputation\n // ============================================================================\n\n // When true, the next recompute with a positive availableWidth will re-parse\n // declared VcColumn props (handles the initial-mount case where DOM was empty).\n let needsPropsReinit = false;\n\n const recompute = () => {\n const availableWidth = options.getAvailableWidth();\n if (availableWidth <= 0) return;\n\n // Deferred initial-props parsing: the first watcher run (immediate, pre-mount)\n // has no DOM to measure. Once DOM is ready and we have a real width, parse\n // declared props to honor <VcColumn :width=\"200\" min-width=\"100\" />.\n if (needsPropsReinit) {\n applyInitFromProps(availableWidth);\n needsPropsReinit = false;\n }\n\n const visibleRegular = orderedVisibleColumns.value.filter((c) => !isSpecialColumn(c.props)).map((c) => c.props.id);\n\n const cols = visibleRegular\n .filter((id) => columnState.value.specs[id])\n .map((id) => ({ id, spec: columnState.value.specs[id] }));\n\n if (cols.length === 0) return;\n engineOutput.value = computeColumnWidths({ availableWidth, columns: cols, mode: fitMode });\n };\n\n // ============================================================================\n // Watch for column changes\n // ============================================================================\n\n let prevVisibleIdSet = new Set<string>();\n let isFirstRun = true;\n\n watch(\n visibleColumns,\n () => {\n const regularCols = visibleColumns.value.filter((c) => !isSpecialColumn(c.props));\n const newIds = regularCols.map((c) => c.props.id);\n const newIdSet = new Set(newIds);\n const trackedIds = new Set(columnState.value.order);\n\n const brandNewIds = newIds.filter((id) => !trackedIds.has(id));\n // On first run (immediate), skip show/hide detection — all columns appear\n // \"just shown\" but their weights may have been restored from persistence.\n const justShownIds = isFirstRun ? [] : newIds.filter((id) => trackedIds.has(id) && !prevVisibleIdSet.has(id));\n const justHiddenIds = isFirstRun ? [] : [...prevVisibleIdSet].filter((id) => !newIdSet.has(id));\n const visibleSetChanged = brandNewIds.length > 0 || justShownIds.length > 0 || justHiddenIds.length > 0;\n\n const isInitialEmpty = columnState.value.order.length === 0;\n const available = options.getAvailableWidth();\n\n if (isInitialEmpty || brandNewIds.length > 0) {\n // Brand-new or initial columns need specs.\n if (isInitialEmpty && available > 0) {\n // Best case: DOM is ready and we can parse declared props immediately.\n applyInitFromProps(available);\n needsPropsReinit = false;\n } else {\n // Fallback: DOM not ready OR we're adding columns to an existing set.\n // Give new columns a reasonable default weight; if available=0, mark\n // for a proper props re-init on first recompute() with real width.\n const state = { ...columnState.value };\n state.order = [...state.order];\n state.specs = { ...state.specs };\n\n const existingVisible = newIds.filter((id) => state.specs[id] && !brandNewIds.includes(id));\n const avgWeight =\n existingVisible.length > 0\n ? existingVisible.reduce((s, id) => s + state.specs[id].weight, 0) / existingVisible.length\n : 1 / newIds.length;\n\n for (const col of regularCols) {\n if (!trackedIds.has(col.props.id)) {\n state.order.push(col.props.id);\n state.specs[col.props.id] = buildSpec(col.props, available, avgWeight);\n }\n }\n\n const visibleRegular = newIds.filter((id) => state.specs[id]);\n normalizeWeights(state.specs, visibleRegular);\n columnState.value = state;\n\n if (isInitialEmpty && available <= 0) needsPropsReinit = true;\n }\n } else if (justShownIds.length > 0) {\n // Previously hidden columns became visible. Give them average weight of\n // currently visible columns, then renormalize. Preserves proportions.\n const state = { ...columnState.value };\n state.specs = { ...state.specs };\n\n const existingVisible = newIds.filter((id) => state.specs[id] && !justShownIds.includes(id));\n const avgWeight =\n existingVisible.length > 0\n ? existingVisible.reduce((s, id) => s + state.specs[id].weight, 0) / existingVisible.length\n : 1 / newIds.length;\n\n for (const id of justShownIds) {\n if (state.specs[id]) state.specs[id] = { ...state.specs[id], weight: avgWeight };\n }\n\n normalizeWeights(\n state.specs,\n newIds.filter((id) => state.specs[id]),\n );\n columnState.value = state;\n } else if (justHiddenIds.length > 0) {\n // Columns were hidden. Renormalize remaining visible so they fill space.\n const state = { ...columnState.value };\n state.specs = { ...state.specs };\n normalizeWeights(\n state.specs,\n newIds.filter((id) => state.specs[id]),\n );\n columnState.value = state;\n }\n\n prevVisibleIdSet = newIdSet;\n isFirstRun = false;\n\n if (visibleSetChanged) recompute();\n },\n { immediate: true },\n );\n\n return {\n columnState,\n engineOutput,\n headerRefs,\n setHeaderRef,\n recompute,\n resetFromProps,\n markStateRestored,\n orderedVisibleColumns,\n totalColumns,\n isSpecialColumn,\n isColumnResizable,\n isColumnReorderable,\n isLastResizableColumn,\n getEffectiveColumnWidth,\n getHeaderAlign,\n getCellAlign,\n getHeaderStyle,\n getCellStyle,\n getSortField,\n };\n}\n","import { type Ref, type ComputedRef, watch, nextTick, onBeforeUnmount } from \"vue\";\nimport type { ColumnState, ColumnSpec, PersistedStateV2 } from \"../types\";\n\n/** Legacy v1 persisted state shape (for migration) */\nexport interface DataTablePersistedState {\n /** Schema version — bump when adding/renaming/removing fields. */\n v: 1;\n columnWidths?: Record<string, number>;\n columnOrder?: string[];\n hiddenColumnIds?: string[];\n shownColumnIds?: string[];\n}\n\nexport interface UseDataTableStateOptions {\n stateKey: Ref<string | undefined>;\n stateStorage: Ref<\"local\" | \"session\"> | ComputedRef<\"local\" | \"session\">;\n columnState: Ref<ColumnState>;\n hiddenColumnIds: Ref<Set<string>>;\n shownColumnIds?: Ref<Set<string>>;\n getAvailableWidth?: () => number;\n /** Called after state is saved (for `state-save` emit). */\n onStateSave?: (state: PersistedStateV2) => void;\n /** Called after state is restored (for `state-restore` emit). */\n onStateRestore?: (state: PersistedStateV2) => void;\n}\n\nexport interface UseDataTableStateReturn {\n saveState: () => void;\n clearState: () => void;\n resetState: () => void;\n}\n\nconst DEBOUNCE_MS = 150;\nconst SCHEMA_VERSION = 2;\n\nfunction migrateV1toV2(state: DataTablePersistedState): PersistedStateV2 | null {\n if (state.v !== 1 || !state.columnWidths) return null;\n const entries = Object.entries(state.columnWidths as Record<string, number>);\n const pxValues = entries.filter(([, w]) => (w as number) > 0);\n const totalPx = pxValues.reduce((s, [, w]) => s + (w as number), 0);\n\n if (totalPx <= 0) return null; // corrupted — discard\n\n const weights: Record<string, number> = {};\n for (const [id, px] of entries) {\n weights[id] = (px as number) > 0 ? (px as number) / totalPx : 0;\n }\n\n return {\n v: 2,\n order: state.columnOrder ?? Object.keys(state.columnWidths),\n weights,\n hiddenColumnIds: state.hiddenColumnIds,\n shownColumnIds: state.shownColumnIds,\n };\n}\n\nexport function useDataTableState(options: UseDataTableStateOptions): UseDataTableStateReturn {\n const {\n stateKey,\n stateStorage,\n columnState,\n hiddenColumnIds,\n shownColumnIds,\n getAvailableWidth,\n onStateSave,\n onStateRestore,\n } = options;\n\n // Counter instead of boolean: multiple restore paths run concurrently during\n // setup and each schedules its own nextTick to decrement. A boolean would let\n // the first nextTick unblock saves while the second restore is still in flight.\n let restoringCount = 0;\n let debounceTimer: ReturnType<typeof setTimeout> | undefined;\n\n function getStorageKey(): string | null {\n const key = stateKey.value;\n return key ? `VC_DATATABLE_${key.toUpperCase()}` : null;\n }\n\n function getStorage(): Storage | null {\n try {\n return stateStorage.value === \"session\" ? sessionStorage : localStorage;\n } catch {\n return null;\n }\n }\n\n function readPersistedState(): PersistedStateV2 | null {\n const storageKey = getStorageKey();\n if (!storageKey) return null;\n\n const storage = getStorage();\n if (!storage) return null;\n\n let raw: string | null;\n try {\n raw = storage.getItem(storageKey);\n } catch {\n return null;\n }\n\n if (!raw) return null;\n\n try {\n const state = JSON.parse(raw) as unknown;\n if (typeof state !== \"object\" || state === null) return null;\n const s = state as { v?: number };\n\n // v2 — direct use\n if (s.v === SCHEMA_VERSION) {\n const v2 = state as PersistedStateV2;\n // Minimal shape validation\n if (!Array.isArray(v2.order)) return null;\n if (typeof v2.weights !== \"object\" || v2.weights === null) return null;\n if (v2.hiddenColumnIds !== undefined && !Array.isArray(v2.hiddenColumnIds)) return null;\n if (v2.shownColumnIds !== undefined && !Array.isArray(v2.shownColumnIds)) return null;\n return v2;\n }\n\n // v1 — migrate\n if (s.v === 1) {\n return migrateV1toV2(state as DataTablePersistedState);\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n // Read persisted state eagerly — before watchers activate.\n let pendingState = readPersistedState();\n\n // Pending column weight/order data — applied when useTableColumns finishes\n // initializing columnState (i.e., when columns are registered).\n let pendingColumnRestore: { weights: Record<string, number>; order: string[] } | null =\n pendingState?.weights && pendingState?.order ? { weights: pendingState.weights, order: pendingState.order } : null;\n\n function buildState(): PersistedStateV2 {\n const state: PersistedStateV2 = {\n v: 2,\n order: columnState.value.order,\n weights: Object.fromEntries(Object.entries(columnState.value.specs).map(([id, s]) => [id, s.weight])),\n };\n state.hiddenColumnIds = [...hiddenColumnIds.value];\n if (shownColumnIds) {\n state.shownColumnIds = [...shownColumnIds.value];\n }\n return state;\n }\n\n function saveState(): void {\n if (restoringCount > 0) return;\n\n const storageKey = getStorageKey();\n if (!storageKey) return;\n\n const storage = getStorage();\n if (!storage) return;\n\n const state = buildState();\n\n try {\n storage.setItem(storageKey, JSON.stringify(state));\n onStateSave?.(state);\n } catch {\n // Quota exceeded or other storage error — silently ignore\n }\n }\n\n function clearState(): void {\n // Cancel any pending debounced save to prevent re-persisting after clear\n if (debounceTimer != null) {\n clearTimeout(debounceTimer);\n debounceTimer = undefined;\n }\n\n const storageKey = getStorageKey();\n if (!storageKey) return;\n\n const storage = getStorage();\n if (!storage) return;\n\n try {\n storage.removeItem(storageKey);\n } catch {\n // Silently ignore\n }\n }\n\n function resetState(): void {\n // Cancel pending saves\n if (debounceTimer != null) {\n clearTimeout(debounceTimer);\n debounceTimer = undefined;\n }\n\n // Clear persisted state\n clearState();\n\n // Reset runtime state\n restoringCount++;\n columnState.value = { order: [], specs: {} };\n hiddenColumnIds.value = new Set();\n if (shownColumnIds) {\n shownColumnIds.value = new Set();\n }\n\n void nextTick(() => {\n restoringCount--;\n });\n }\n\n function applyColumnRestore(\n currentState: ColumnState,\n pending: { weights: Record<string, number>; order: string[] },\n ): void {\n restoringCount++;\n\n const { weights, order } = pending;\n const newOrder: string[] = [];\n const newSpecs: Record<string, ColumnSpec> = {};\n\n // Rebuild from persisted order\n for (const id of order) {\n if (weights[id] !== undefined) {\n newOrder.push(id);\n newSpecs[id] = {\n weight: weights[id],\n minPx: currentState.specs[id]?.minPx ?? 40,\n maxPx: currentState.specs[id]?.maxPx ?? Infinity,\n };\n }\n }\n\n // Append new columns not in saved state\n for (const id of currentState.order) {\n if (!newSpecs[id]) {\n newOrder.push(id);\n newSpecs[id] = currentState.specs[id] ?? { weight: 0, minPx: 40, maxPx: Infinity };\n }\n }\n\n // Don't normalize here — weights were saved already normalized for visible\n // columns. Normalizing across ALL columns (including hidden) would dilute\n // visible weights. The engine only sees visible columns and handles their\n // proportions correctly.\n columnState.value = { order: newOrder, specs: newSpecs };\n\n void nextTick(() => {\n restoringCount--;\n });\n }\n\n // Column state is typically available by now (slot-based extraction is sync).\n // If not yet (inject/provide path), a watcher picks them up.\n if (pendingColumnRestore) {\n if (columnState.value.order.length > 0) {\n // Columns are already available (slot-based extraction) — apply immediately\n applyColumnRestore(columnState.value, pendingColumnRestore);\n pendingColumnRestore = null;\n } else {\n // Columns not yet registered (inject/provide path) — wait via watcher\n const stopColumnWatch = watch(\n columnState,\n (currentState) => {\n if (!pendingColumnRestore) return;\n if (currentState.order.length === 0) return;\n\n applyColumnRestore(currentState, pendingColumnRestore!);\n pendingColumnRestore = null;\n\n void nextTick(() => {\n restoringCount--;\n stopColumnWatch();\n });\n },\n { deep: true },\n );\n }\n }\n\n // Hidden/shown column IDs — apply sync to avoid race with data-discovered columns watcher\n if (pendingState) {\n const state = pendingState;\n pendingState = null;\n\n restoringCount++;\n\n // Hidden columns\n if (state.hiddenColumnIds) {\n hiddenColumnIds.value = new Set(state.hiddenColumnIds);\n }\n if (shownColumnIds && state.shownColumnIds) {\n shownColumnIds.value = new Set(state.shownColumnIds);\n }\n\n onStateRestore?.(state);\n\n void nextTick(() => {\n restoringCount--;\n });\n }\n\n // Guards shared by the scheduling check and the deferred save, so a restore\n // starting (or stateKey/width changing) DURING the debounce window can't let a\n // stale save slip through.\n function canPersist(): boolean {\n if (restoringCount > 0) return false;\n if (!stateKey.value) return false;\n // Don't save while columns haven't been restored yet\n if (pendingColumnRestore) return false;\n // Don't save when container has no width yet\n if (getAvailableWidth && getAvailableWidth() <= 0) return false;\n return true;\n }\n\n function debouncedSave(): void {\n if (!canPersist()) return;\n\n if (debounceTimer != null) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(() => {\n debounceTimer = undefined;\n // Re-check: the debounce window may have started a restore or cleared the key.\n if (!canPersist()) return;\n saveState();\n }, DEBOUNCE_MS);\n }\n\n // Watch only column-related persisted sources\n const watchedSources = shownColumnIds\n ? [columnState, hiddenColumnIds, shownColumnIds]\n : [columnState, hiddenColumnIds];\n watch(watchedSources, debouncedSave, { deep: true });\n\n onBeforeUnmount(() => {\n if (debounceTimer != null) {\n clearTimeout(debounceTimer);\n debounceTimer = undefined;\n // Flush the save synchronously\n if (stateKey.value) {\n saveState();\n }\n }\n });\n\n return {\n saveState,\n clearState,\n resetState,\n };\n}\n","/**\n * @internal\n * Wires all VcDataTable sub-composables together.\n *\n * This composable owns:\n * - All sub-composable calls (selection, sort, editing, expansion, row grouping,\n * inline edit, state persistence, columns, resize, reorder, row reorder, filters)\n * - Inter-composable watchers\n * - Derived computed properties (displayItems, effectiveSelectionMode, etc.)\n * - Event handlers (handleSort, handleSelectAllChange, handleRowSelectionChange,\n * handleRowClick, handleAddRow, handleRemoveRow, handleColumnVisibilityChange)\n *\n * VcDataTable.vue retains: template, props/emits, defineSlots, slot extraction,\n * all provide() calls, DOM refs, and UI-state refs (showGlobalFiltersPanel, etc.).\n */\n\nimport { ref, computed, watch, toRef, type Ref, type ComputedRef } from \"vue\";\nimport {\n useTableRowReorder,\n useTableColumnsResize,\n useTableColumnsReorder,\n useFilterState,\n useColumnFilter,\n useTableSort,\n useTableEditing,\n useTableExpansion,\n useTableSelectionV2,\n useTableColumns,\n useTableRowGrouping,\n useTableInlineEdit,\n useDataTableState,\n createTableSelectionFacade,\n} from \"@ui/components/organisms/vc-data-table/composables\";\nimport type { TableSelectionFacade } from \"@ui/components/organisms/vc-data-table/composables\";\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\nimport { isSpecialColumn } from \"@ui/components/organisms/vc-data-table/utils/columnHelpers\";\nimport { DEFAULT_MIN_COLUMN_PX } from \"@ui/components/organisms/vc-data-table/composables/useColumnWidthEngine\";\nimport type {\n VcColumnProps,\n FilterValue,\n EditChange,\n TableAction,\n SortMeta,\n MobileSwipeAction,\n VcDataTableExtendedProps,\n TableFitMode,\n PersistedStateV2,\n} from \"@ui/components/organisms/vc-data-table/types\";\n\n// ============================================================================\n// Orchestrator input/output interfaces\n// ============================================================================\n\n/**\n * @internal\n * Reactive props subset passed from VcDataTable into the orchestrator.\n * All values must be reactive (Ref/ComputedRef) so the orchestrator\n * correctly tracks changes throughout the component's lifetime.\n */\nexport interface VcDataTableOrchestratorOptions<T extends Record<string, unknown>> {\n props: VcDataTableExtendedProps<T> & { fitMode?: TableFitMode };\n emit: VcDataTableOrchestratorEmit<T>;\n visibleColumns: ComputedRef<ColumnInstance[]>;\n declaredColumns: ComputedRef<ColumnInstance[]>;\n hiddenColumnIds: Ref<Set<string>>;\n shownDataDiscoveredColumnIds: Ref<Set<string>>;\n dataDiscoveredColumns: ComputedRef<ColumnInstance[]>;\n getItemKey: (item: T, index: number) => string;\n /**\n * Ref to the tableContainerRef DOM element.\n * Required by useTableColumnsResize to query cell elements.\n */\n tableContainerRef: Ref<HTMLElement | null>;\n}\n\n/**\n * @internal\n * Emit signature expected by the orchestrator (subset of VcDataTable emits\n * that are consumed by the extracted event handlers and watchers).\n */\nexport type VcDataTableOrchestratorEmit<T> = {\n (event: \"update:selection\", value: T | T[]): void;\n (event: \"update:selectAll\", value: boolean): void;\n (event: \"row-select\", payload: { data: T; originalEvent: Event }): void;\n (event: \"row-unselect\", payload: { data: T; originalEvent: Event }): void;\n (event: \"row-select-all\", payload: { data: T[]; originalEvent: Event }): void;\n (event: \"row-unselect-all\", payload: { data: T[]; originalEvent: Event }): void;\n (event: \"select-all\", payload: { selected: boolean }): void;\n (event: \"update:selectAllActive\", value: boolean): void;\n (event: \"update:editingRows\", value: T[]): void;\n (event: \"cell-edit-init\", payload: { data: T; field: string; index: number }): void;\n (event: \"cell-edit-complete\", payload: { data: T; field: string; newValue: unknown; index: number }): void;\n (event: \"cell-edit-cancel\", payload: { data: T; field: string; index: number }): void;\n (event: \"row-edit-init\", payload: { data: T; index: number }): void;\n (event: \"row-edit-save\", payload: { data: T; newData: T; index: number }): void;\n (event: \"row-edit-cancel\", payload: { data: T; index: number }): void;\n (event: \"edit-save\", payload: { changes: EditChange<T>[] }): void;\n (event: \"edit-cancel\"): void;\n (event: \"row-add\", payload: { defaults: Record<string, unknown>; cancel: () => void }): void;\n (event: \"row-remove\", payload: { data: T; index: number; cancel: () => void }): void;\n (event: \"update:sortField\", value: string): void;\n (event: \"update:sortOrder\", value: number): void;\n (event: \"update:multiSortMeta\", value: SortMeta[]): void;\n (event: \"sort\", payload: { sortField?: string; sortOrder?: number; multiSortMeta?: SortMeta[] }): void;\n (event: \"filter\", payload: { filters: Record<string, unknown>; filteredValue: T[] }): void;\n (event: \"update:activeItemId\", value: string | undefined): void;\n (event: \"row-click\", payload: { data: T; index: number; originalEvent: Event }): void;\n (event: \"row-action\", payload: { action: TableAction | MobileSwipeAction<T>; item: T; index: number }): void;\n (event: \"row-reorder\", payload: { dragIndex: number; dropIndex: number; value: T[] }): void;\n (event: \"column-resize-end\", payload: { columns: { id: string; width: number }[] }): void;\n (event: \"column-reorder\", payload: { columns: { id: string; [key: string]: unknown }[] }): void;\n (event: \"state-save\", state: PersistedStateV2): void;\n (event: \"state-restore\", state: PersistedStateV2): void;\n (event: \"update:expandedRows\", value: T[]): void;\n (event: \"row-expand\", payload: { data: T; originalEvent: Event }): void;\n (event: \"row-collapse\", payload: { data: T; originalEvent: Event }): void;\n (event: \"update:expandedRowGroups\", value: string[]): void;\n (event: \"rowgroup-expand\", payload: { data: string; originalEvent: Event }): void;\n (event: \"rowgroup-collapse\", payload: { data: string; originalEvent: Event }): void;\n};\n\n/**\n * @internal\n * All reactive state and handlers returned by the orchestrator for use in\n * VcDataTable's template and provide() calls.\n */\nexport interface VcDataTableOrchestratorReturn<T extends Record<string, unknown>> {\n // Row selection facade (hides the raw useTableSelectionV2 instance)\n selection: TableSelectionFacade<T>;\n sort: ReturnType<typeof useTableSort>;\n editing: ReturnType<typeof useTableEditing<T>>;\n expansion: ReturnType<typeof useTableExpansion<T>>;\n rowGrouping: ReturnType<typeof useTableRowGrouping<T>>;\n inlineEdit: ReturnType<typeof useTableInlineEdit<T>>;\n cols: ReturnType<typeof useTableColumns>;\n statePersistence: ReturnType<typeof useDataTableState>;\n\n // Column filter helpers (returned from useColumnFilter / useFilterState)\n colFilter: ReturnType<typeof useColumnFilter>;\n filterValues: Ref<Record<string, FilterValue>>;\n updateFilter: (field: string, value: FilterValue) => void;\n updateRangeFilter: (fields: [string, string], value: { start?: string; end?: string }) => void;\n clearFilter: (field: string) => void;\n clearAllFilters: () => void;\n buildPayload: () => Record<string, unknown>;\n hasActiveFilters: ComputedRef<boolean>;\n activeFilterCount: ComputedRef<number>;\n\n // Column filter template helpers\n showColumnFilter: (col: ColumnInstance) => boolean;\n getColumnFilterType: (col: ColumnInstance) => ReturnType<ReturnType<typeof useColumnFilter>[\"getFilterType\"]>;\n getColumnFilterOptions: (col: ColumnInstance) => ReturnType<ReturnType<typeof useColumnFilter>[\"getFilterOptions\"]>;\n isColumnFilterMultiple: (col: ColumnInstance) => boolean;\n getColumnRangeFields: (col: ColumnInstance) => ReturnType<ReturnType<typeof useColumnFilter>[\"getRangeFields\"]>;\n getColumnFilterValue: (col: ColumnInstance) => FilterValue;\n handleColumnFilterApply: (col: ColumnInstance, payload: Record<string, unknown>) => void;\n handleColumnFilterClear: (col: ColumnInstance) => void;\n emitFilterPayload: () => void;\n\n // Global filter (owned by component UI state but wired here)\n globalFilterPayload: Ref<Record<string, unknown> | null>;\n\n // Resize / reorder handlers (from useTableColumnsResize / useTableColumnsReorder)\n handleResizeStart: ReturnType<typeof useTableColumnsResize>[\"handleResizeStart\"];\n isColumnReordering: Ref<boolean>;\n handleColumnDragStart: ReturnType<typeof useTableColumnsReorder>[\"handleDragStart\"];\n handleColumnDragOver: ReturnType<typeof useTableColumnsReorder>[\"handleDragOver\"];\n handleColumnDrop: ReturnType<typeof useTableColumnsReorder>[\"handleDrop\"];\n\n // Row reorder state\n reorderedItems: Ref<T[]>;\n pendingReorder: Ref<boolean>;\n isRowReorderEnabled: ComputedRef<boolean>;\n showRowDragHandle: ComputedRef<boolean>;\n rowReorderListRef: Ref<HTMLElement | undefined>;\n\n // Derived computeds\n displayItems: ComputedRef<T[]>;\n getGlobalIndex: (item: T) => number;\n effectiveSelectionMode: ComputedRef<\"single\" | \"multiple\" | undefined>;\n selectionColumn: ComputedRef<ColumnInstance | null>;\n hasSelectionColumn: ComputedRef<boolean>;\n isSelectionViaColumn: ComputedRef<boolean>;\n expanderColumn: ComputedRef<ColumnInstance | null>;\n hasExpanderColumn: ComputedRef<boolean>;\n computedVariant: ComputedRef<\"striped\" | \"bordered\" | \"default\">;\n switcherColumns: ComputedRef<{ id: string; label: string; visible: boolean; defaultVisible: boolean }[]>;\n switcherVisibleColumnIds: ComputedRef<string[]>;\n safeColumns: ComputedRef<ColumnInstance[]>;\n isInlineEditing: ComputedRef<boolean>;\n\n // Expansion helper\n isRowExpanded: (item: T) => boolean;\n canExpand: (item: T) => boolean;\n expandedKeysArray: Ref<string[]>;\n\n // Data-discovered IDs watcher stable ref\n dataDiscoveredIds: Ref<Set<string>>;\n\n // Event handlers (selection handlers live on the `selection` facade)\n handleSort: (col: VcColumnProps, event?: MouseEvent) => void;\n handleRowClick: (item: T, index: number, event: Event) => void;\n handleAddRow: (defaults?: Partial<T>) => void;\n handleRemoveRow: (rowIndex: number) => void;\n handleColumnVisibilityChange: (visibleIds: string[]) => void;\n handleTableReset: () => void;\n handleCellClick: (item: T, field: string, rowIndex: number, col: ColumnInstance) => void;\n handleCellEditComplete: (item: T, field: string, rowIndex: number, newValue: unknown) => void;\n handleCellEditCancel: (item: T, field: string, rowIndex: number) => void;\n handleCellValueChange: (field: string, rowIndex: number, newValue: unknown) => void;\n handleExpandToggle: (item: T, index: number, event: Event) => void;\n handleStartRowEdit: (item: T, index: number) => void;\n handleSaveRowEdit: (item: T, index: number) => void;\n handleCancelRowEdit: (item: T, index: number) => void;\n handleRowAction: (action: TableAction, item: T, index: number) => void;\n handleMobileRowClick: (item: T, index: number) => void;\n handleMobileRowSelect: (item: T, index: number) => void;\n handleMobileRowAction: (action: MobileSwipeAction<T>, item: T, index: number) => void;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * @internal\n * Wires all VcDataTable sub-composables together.\n *\n * Called once in VcDataTable's `<script setup>`. Receives reactive inputs from\n * the component and returns all the reactive state and handlers the template\n * needs. The component itself retains provide() calls, DOM refs, and UI state.\n */\n/** SortableJS `handle` selector matching the desktop row and mobile card drag handles. */\nconst ROW_REORDER_HANDLE_SELECTOR = \".vc-table-composition__row-drag-handle, .vc-data-table-mobile-card__drag-handle\";\n\nexport function useDataTableOrchestrator<T extends Record<string, unknown>>(\n options: VcDataTableOrchestratorOptions<T>,\n): VcDataTableOrchestratorReturn<T> {\n const {\n props,\n emit,\n visibleColumns,\n declaredColumns,\n hiddenColumnIds,\n shownDataDiscoveredColumnIds,\n dataDiscoveredColumns,\n getItemKey,\n tableContainerRef,\n } = options;\n\n // ============================================================================\n // Derived computeds (needed early — used as inputs to sub-composables below)\n // ============================================================================\n\n const selectionColumn = computed<ColumnInstance | null>(() => {\n return visibleColumns.value.find((col) => col.props.selectionMode !== undefined) || null;\n });\n\n const hasSelectionColumn = computed(() => props.selectionMode !== undefined || selectionColumn.value !== null);\n\n const effectiveSelectionMode = computed<\"single\" | \"multiple\" | undefined>(() => {\n if (props.selectionMode) return props.selectionMode;\n return selectionColumn.value?.props.selectionMode;\n });\n\n const isSelectionViaColumn = computed(() => selectionColumn.value !== null);\n\n const computedVariant = computed(() => {\n if (props.striped) return \"striped\";\n if (props.bordered) return \"bordered\";\n return props.variant ?? \"default\";\n });\n\n // ============================================================================\n // Selection Composable\n // ============================================================================\n\n // The cross-page \"select all\" banner is opt-in: it appears only when the\n // consumer wires the feature up by binding `selectAllActive` (one-way or via\n // v-model). Its default is `undefined`, so a table that passes `totalCount`\n // purely for pagination never surfaces a \"Select all N items\" prompt nobody handles.\n const selectAllEnabled = computed(() => props.selectAllActive !== undefined);\n\n const selection = useTableSelectionV2<T>({\n items: toRef(props, \"items\") as Ref<T[]>,\n selection: toRef(props, \"selection\") as Ref<T | T[] | undefined>,\n selectionMode: computed(() => effectiveSelectionMode.value),\n isRowSelectable: (item: T) => (props.isRowSelectable ? props.isRowSelectable(item) : true),\n dataKey: props.dataKey ?? \"id\",\n getItemKey,\n totalCount: toRef(props, \"totalCount\") as Ref<number | undefined>,\n selectAllActive: toRef(props, \"selectAllActive\") as Ref<boolean | undefined>,\n selectAllEnabled,\n onSelectAllChange: (active: boolean) => {\n emit(\"update:selectAllActive\", active);\n emit(\"select-all\", { selected: active });\n },\n });\n\n // Watch for selection changes and emit\n watch(\n () => selection.internalSelection.value,\n (newSelection) => {\n emit(\"update:selection\", effectiveSelectionMode.value === \"single\" ? newSelection[0] : newSelection);\n },\n { deep: true },\n );\n\n // ============================================================================\n // Sort Composable\n // ============================================================================\n\n const sort = useTableSort({\n sortField: toRef(props, \"sortField\") as Ref<string | undefined>,\n sortOrder: toRef(props, \"sortOrder\") as Ref<number>,\n sortMode: toRef(props, \"sortMode\") as Ref<\"single\" | \"multiple\">,\n multiSortMeta: toRef(props, \"multiSortMeta\") as Ref<SortMeta[]>,\n removableSort: toRef(props, \"removableSort\") as Ref<boolean>,\n onSort: (event) => {\n if (event.sortField !== undefined) emit(\"update:sortField\", event.sortField);\n if (event.sortOrder !== undefined) emit(\"update:sortOrder\", event.sortOrder);\n if (event.multiSortMeta !== undefined) emit(\"update:multiSortMeta\", event.multiSortMeta);\n emit(\"sort\", event);\n },\n });\n\n // ============================================================================\n // Editing Composable\n // ============================================================================\n\n const editing = useTableEditing<T>({\n editMode: toRef(props, \"editMode\") as Ref<\"cell\" | \"row\" | undefined>,\n editingRows: toRef(props, \"editingRows\") as Ref<T[] | undefined>,\n dataKey: props.dataKey ?? \"id\",\n getItemKey,\n });\n\n // ============================================================================\n // Expansion Composable\n // ============================================================================\n\n const expansion = useTableExpansion<T>({\n expandedRows: toRef(props, \"expandedRows\") as Ref<T[]>,\n getItemKey,\n isRowExpandable: (item: T) => (props.isRowExpandable ? props.isRowExpandable(item) : true),\n });\n\n // Use a regular ref with array of keys for proper reactivity\n const expandedKeysArray = ref<string[]>([]);\n\n // Watch for expansion changes, update local ref and emit\n watch(\n () => expansion.internalExpandedRows.value,\n (newExpanded) => {\n // Update array of expanded keys\n const newKeys = newExpanded.map((item) => getItemKey(item as T, 0));\n\n // Only update if keys actually changed (prevent infinite loop)\n const currentKeys = expandedKeysArray.value.join(\",\");\n const newKeysStr = newKeys.join(\",\");\n if (currentKeys !== newKeysStr) {\n expandedKeysArray.value = newKeys;\n emit(\"update:expandedRows\", newExpanded as T[]);\n }\n },\n { deep: true, immediate: true },\n );\n\n // Helper to check if row is expanded\n const isRowExpanded = (item: T): boolean => {\n const key = getItemKey(item, 0);\n return expandedKeysArray.value.includes(key);\n };\n\n // Helper to check if row can be expanded\n const canExpand = (item: T): boolean => {\n return expansion.canExpand(item);\n };\n\n // ============================================================================\n // Row Grouping Composable\n // ============================================================================\n\n const rowGrouping = useTableRowGrouping<T>({\n items: toRef(props, \"items\") as Ref<T[]>,\n groupRowsBy: toRef(props, \"groupRowsBy\") as Ref<string | undefined>,\n rowGroupMode: toRef(props, \"rowGroupMode\") as Ref<\"subheader\" | \"rowspan\">,\n expandableRowGroups: toRef(props, \"expandableRowGroups\") as Ref<boolean>,\n expandedRowGroups: toRef(props, \"expandedRowGroups\") as Ref<string[] | undefined>,\n onExpandedRowGroupsChange: (groups) => emit(\"update:expandedRowGroups\", groups),\n onRowGroupExpand: (event) => emit(\"rowgroup-expand\", event),\n onRowGroupCollapse: (event) => emit(\"rowgroup-collapse\", event),\n });\n\n // ============================================================================\n // Inline Edit Composable (Row CRUD)\n // ============================================================================\n\n const inlineEdit = useTableInlineEdit<T>({\n items: toRef(props, \"items\") as Ref<T[]>,\n rules: props.validationRules as Record<string, (value: unknown, row: T) => string | true> | undefined,\n onSave: (changes) => {\n emit(\"edit-save\", { changes: changes as EditChange<T>[] });\n },\n onCancel: () => {\n emit(\"edit-cancel\");\n },\n });\n\n // Computed for inline editing state (for use in template)\n // editMode=\"inline\" makes all editable cells always active (legacy compatibility)\n const isInlineEditing = computed(() => inlineEdit.isEditing.value || props.editMode === \"inline\");\n\n // ============================================================================\n // Column Helpers (via composable)\n // ============================================================================\n\n // Cached transition-wrapper element — updated lazily on measurement.\n // Avoids a querySelector call on every ResizeObserver tick.\n let cachedWrapper: HTMLElement | null = null;\n\n /**\n * Measures available width for data columns directly from the DOM.\n *\n * Reads the transition-wrapper width (already excludes row padding,\n * drag handles, row-level gap) and subtracts special cells rendered\n * inside the wrapper (implicit selection checkbox, VcColumn-based\n * selection/expander/rowReorder/rowEditor). No hardcoded pixel constants.\n *\n * When wrapper is not mounted yet, returns 0 — callers treat this as\n * \"defer until DOM is ready\" to avoid a first-frame column jump.\n */\n const measureAvailableWidth = (): number => {\n if (!cachedWrapper || !cachedWrapper.isConnected) {\n cachedWrapper = (tableContainerRef.value?.querySelector(\".vc-table-composition__row-transition-wrapper\") ??\n null) as HTMLElement | null;\n }\n if (!cachedWrapper || cachedWrapper.clientWidth <= 0) return 0;\n\n // Subtract special cells inside the wrapper.\n let specialWidth = 0;\n // 1. Implicit selection cells (not a VcColumn — no data-column-id).\n const implicitCells = cachedWrapper.querySelectorAll(\".vc-data-table__selection-cell\");\n for (const cell of implicitCells) {\n specialWidth += (cell as HTMLElement).getBoundingClientRect().width;\n }\n // 2. Special VcColumn cells (selectionMode, expander, rowReorder, rowEditor).\n for (const col of visibleColumns.value) {\n if (isSpecialColumn(col.props)) {\n const el = cols.headerRefs.get(col.props.id);\n if (el) specialWidth += el.getBoundingClientRect().width;\n }\n }\n return Math.max(0, cachedWrapper.clientWidth - specialWidth);\n };\n\n const cols = useTableColumns({\n visibleColumns,\n resizableColumns: props.resizableColumns ?? true,\n reorderableColumns: props.reorderableColumns ?? true,\n fitMode: props.fitMode ?? \"gap\",\n getAvailableWidth: measureAvailableWidth,\n });\n\n // ============================================================================\n // Column Switcher\n // ============================================================================\n\n // Stable set of data-discovered column IDs.\n // Uses a string key watcher so the Set is only re-created when actual IDs change\n // (avoids false triggers from new array references in the computed source).\n const dataDiscoveredIds = ref<Set<string>>(new Set());\n watch(\n () => dataDiscoveredColumns.value.map((c) => c.props.id).join(\",\"),\n () => {\n dataDiscoveredIds.value = new Set(dataDiscoveredColumns.value.map((c) => c.props.id));\n },\n { immediate: true },\n );\n\n const switcherColumns = computed(() => {\n // Declared columns (excluding statically hidden and special columns)\n const declared = declaredColumns.value\n .filter((col) => col.props.visible !== false)\n .filter((col) => !isSpecialColumn(col.props))\n .map((col) => ({\n id: col.props.id,\n label: col.props.title || col.props.field || col.props.id,\n visible: !hiddenColumnIds.value.has(col.props.id),\n defaultVisible: true,\n }));\n\n // Data-discovered columns (from items keys, default hidden)\n const discovered = dataDiscoveredColumns.value.map((col) => ({\n id: col.props.id,\n label: col.props.title || col.props.id,\n visible: !hiddenColumnIds.value.has(col.props.id),\n defaultVisible: false,\n }));\n\n return [...declared, ...discovered];\n });\n\n const switcherVisibleColumnIds = computed(() => {\n return switcherColumns.value.filter((c) => c.visible).map((c) => c.id);\n });\n\n // ============================================================================\n // State Persistence\n // ============================================================================\n\n const statePersistence = useDataTableState({\n stateKey: toRef(props, \"stateKey\") as Ref<string | undefined>,\n stateStorage: computed(() => props.stateStorage ?? \"local\"),\n columnState: cols.columnState,\n hiddenColumnIds,\n shownColumnIds: shownDataDiscoveredColumnIds,\n getAvailableWidth: measureAvailableWidth,\n onStateSave: (state) => emit(\"state-save\", state),\n onStateRestore: (state) => {\n // Persistence has restored weights — cancel any pending deferred\n // re-init from declared VcColumn props so recompute() doesn't overwrite\n // the user's saved column widths with the declarative defaults.\n cols.markStateRestored();\n emit(\"state-restore\", state);\n },\n });\n\n // Initialize hiddenColumnIds with data-discovered columns (they start hidden).\n // Keep hidden IDs for columns that temporarily disappear between different\n // datasets/views (e.g. products vs catalog). This preserves per-view visibility.\n watch(\n dataDiscoveredIds,\n (newIds, oldIds) => {\n const updatedHidden = new Set(hiddenColumnIds.value);\n const updatedShown = new Set(shownDataDiscoveredColumnIds.value);\n let hiddenChanged = false;\n let shownChanged = false;\n\n // Newly discovered auto columns are hidden by default, unless user\n // explicitly enabled them earlier (persisted in shownDataDiscoveredColumnIds).\n for (const id of newIds) {\n if ((!oldIds || !oldIds.has(id)) && !updatedHidden.has(id) && !updatedShown.has(id)) {\n updatedHidden.add(id);\n hiddenChanged = true;\n }\n }\n\n // If a key becomes a declared column (no longer auto-discovered), drop it\n // from auto-column state sets. Do not remove IDs that simply disappeared\n // due to switching datasets/views.\n if (oldIds) {\n const declaredIds = new Set(declaredColumns.value.map((col) => col.props.id));\n for (const id of oldIds) {\n if (!newIds.has(id) && declaredIds.has(id)) {\n if (updatedHidden.delete(id)) {\n hiddenChanged = true;\n }\n if (updatedShown.delete(id)) {\n shownChanged = true;\n }\n }\n }\n }\n\n if (hiddenChanged) {\n hiddenColumnIds.value = updatedHidden;\n }\n if (shownChanged) {\n shownDataDiscoveredColumnIds.value = updatedShown;\n }\n },\n { immediate: true },\n );\n\n // ============================================================================\n // Row Reorder\n // ============================================================================\n\n const rowReorderColumn = computed<ColumnInstance | null>(() => {\n return visibleColumns.value.find((col) => col.props.rowReorder === true) || null;\n });\n\n const isRowReorderEnabled = computed(() => props.reorderableRows || rowReorderColumn.value !== null);\n // Handle is shown whenever reorder is enabled (the handle is the only drag affordance now).\n const showRowDragHandle = computed(() => isRowReorderEnabled.value);\n\n // Element of the active view's rows container; bound by VcDataTable.\n const rowReorderListRef = ref<HTMLElement>();\n\n const { reorderedItems, pendingReorder } = useTableRowReorder(rowReorderListRef, toRef(props, \"items\") as Ref<T[]>, {\n disabled: computed(() => !isRowReorderEnabled.value),\n handle: ROW_REORDER_HANDLE_SELECTOR,\n onReorder: (event) => emit(\"row-reorder\", event),\n });\n\n // ============================================================================\n // Expander Column Detection\n // ============================================================================\n\n const expanderColumn = computed<ColumnInstance | null>(() => {\n return visibleColumns.value.find((col) => col.props.expander === true) || null;\n });\n\n const hasExpanderColumn = computed(() => expanderColumn.value !== null);\n\n // ============================================================================\n // Filtering\n // ============================================================================\n\n // Column filter helpers (declarative `filter` prop API)\n const colFilter = useColumnFilter();\n\n const {\n filterValues,\n updateFilter,\n updateRangeFilter,\n clearFilter,\n clearAllFilters,\n buildPayload,\n hasActiveFilters,\n activeFilterCount,\n } = useFilterState({\n onFilterChange: (payload) => {\n emit(\"filter\", { filters: payload, filteredValue: props.items });\n },\n });\n\n // Template helpers that bridge VcColumn instances → ColumnFilter props\n const showColumnFilter = (col: ColumnInstance): boolean => {\n return colFilter.hasFilter(col.props.filter);\n };\n\n const getColumnFilterField = (col: ColumnInstance): string => {\n return col.props.filterField || colFilter.getFilterField(col.props.id, col.props.filter);\n };\n\n const getColumnFilterType = (col: ColumnInstance) => {\n return colFilter.getFilterType(col.props.filter);\n };\n\n const getColumnFilterOptions = (col: ColumnInstance) => {\n return colFilter.getFilterOptions(col.props.filter);\n };\n\n const isColumnFilterMultiple = (col: ColumnInstance): boolean => {\n return colFilter.isMultipleSelect(col.props.filter);\n };\n\n const getColumnRangeFields = (col: ColumnInstance) => {\n return colFilter.getRangeFields(col.props.filter);\n };\n\n const getColumnFilterValue = (col: ColumnInstance): FilterValue => {\n const field = getColumnFilterField(col);\n // For dateRange, reconstruct { start, end } from range key\n if (getColumnFilterType(col) === \"dateRange\") {\n const rangeFields = getColumnRangeFields(col);\n if (rangeFields) {\n const key = `__range__${rangeFields[0]}__${rangeFields[1]}`;\n return filterValues.value[key] ?? null;\n }\n }\n return filterValues.value[field] ?? null;\n };\n\n // Global filter payload (passed back so component can merge it in emitFilterPayload)\n const globalFilterPayload = ref<Record<string, unknown> | null>(null);\n\n /** Emit the combined column + global filter payload */\n const emitFilterPayload = () => {\n const payload = buildPayload();\n // Merge global filter payload (if any)\n if (globalFilterPayload.value) {\n Object.assign(payload, globalFilterPayload.value);\n }\n emit(\"filter\", { filters: payload, filteredValue: props.items });\n };\n\n const handleColumnFilterApply = (col: ColumnInstance, payload: Record<string, unknown>) => {\n const filterType = getColumnFilterType(col);\n const field = getColumnFilterField(col);\n\n if (filterType === \"dateRange\") {\n const rangeFields = getColumnRangeFields(col);\n if (rangeFields) {\n const start = payload[rangeFields[0]] as string | undefined;\n const end = payload[rangeFields[1]] as string | undefined;\n updateRangeFilter(rangeFields, { start, end });\n }\n } else {\n const value = payload[field];\n updateFilter(field, value as FilterValue);\n }\n\n // Emit combined payload\n emitFilterPayload();\n };\n\n const handleColumnFilterClear = (col: ColumnInstance) => {\n const field = getColumnFilterField(col);\n const filterType = getColumnFilterType(col);\n\n if (filterType === \"dateRange\") {\n const rangeFields = getColumnRangeFields(col);\n if (rangeFields) {\n const key = `__range__${rangeFields[0]}__${rangeFields[1]}`;\n clearFilter(key);\n }\n } else {\n clearFilter(field);\n }\n\n // Emit combined payload\n emitFilterPayload();\n };\n\n // ============================================================================\n // Display Items\n // ============================================================================\n\n // Display items: items come pre-filtered from the backend\n // Only row-reorder dragging changes display order locally\n const displayItems = computed<T[]>(() => {\n // During drag or waiting for parent to update items after drop\n if (pendingReorder.value && isRowReorderEnabled.value) {\n return [...(reorderedItems.value as T[])];\n }\n\n return props.items ?? [];\n });\n\n // Helper to get global index of an item (for grouped mode)\n const getGlobalIndex = (item: T): number => {\n return displayItems.value.indexOf(item);\n };\n\n // ============================================================================\n // Safe Columns (null-check protected)\n // ============================================================================\n\n const safeColumns = computed(() => {\n return cols.orderedVisibleColumns.value.filter(\n (col): col is ColumnInstance => col != null && col.props != null && col.props.id != null,\n );\n });\n\n // ============================================================================\n // Resize + Reorder Composables\n // ============================================================================\n\n const { handleResizeStart } = useTableColumnsResize({\n columnState: cols.columnState,\n engineOutput: cols.engineOutput,\n recompute: cols.recompute,\n getAvailableWidth: measureAvailableWidth,\n minColumnWidth: DEFAULT_MIN_COLUMN_PX,\n getVisibleRegularColumnIds: () =>\n cols.orderedVisibleColumns.value.filter((col) => !isSpecialColumn(col.props)).map((col) => col.props.id),\n onResizeEnd: () => emit(\"column-resize-end\", { columns: [] }),\n containerEl: tableContainerRef,\n });\n\n const {\n isDragging: isColumnReordering,\n handleDragStart: handleColumnDragStart,\n handleDragOver: handleColumnDragOver,\n handleDrop: handleColumnDrop,\n } = useTableColumnsReorder({\n columnState: cols.columnState,\n onReorderEnd: () => emit(\"column-reorder\", { columns: [] }),\n });\n\n // ============================================================================\n // Event Handlers\n // ============================================================================\n\n const handleSort = (col: VcColumnProps, event?: MouseEvent) => {\n sort.handleSort(cols.getSortField(col), event);\n };\n\n const handleSelectAllChange = (value: boolean) => {\n const result = selection.handleSelectAllChange(value);\n if (value) emit(\"row-select-all\", result);\n else emit(\"row-unselect-all\", result);\n emit(\"update:selectAll\", value);\n };\n\n const handleRowSelectionChange = (item: T, eventOrValue?: Event | boolean) => {\n const wasSelected = selection.isSelected(item);\n const result = selection.handleRowSelectionChange(item, eventOrValue);\n if (result) {\n if (wasSelected) emit(\"row-unselect\", result);\n else emit(\"row-select\", result);\n }\n };\n\n // Row selection facade — the single, intention-revealing surface the\n // component consumes. Wraps the raw `selection` instance (hidden impl) and\n // the two emit-owning handlers above.\n const selectionFacade: TableSelectionFacade<T> = createTableSelectionFacade(selection, {\n onRowSelect: handleRowSelectionChange,\n onSelectAll: handleSelectAllChange,\n });\n\n const handleRowClick = (item: T, index: number, event: Event) => {\n const itemKey = getItemKey(item, index);\n const isSameItem = props.activeItemId != null && itemKey === String(props.activeItemId);\n emit(\"update:activeItemId\", isSameItem ? undefined : itemKey);\n emit(\"row-click\", { data: item, index, originalEvent: event });\n const target = event.target as HTMLElement;\n const isCheckboxClick = target.tagName === \"INPUT\" && target.getAttribute(\"type\") === \"checkbox\";\n if (effectiveSelectionMode.value === \"single\" && !isCheckboxClick) {\n handleRowSelectionChange(item, event);\n }\n };\n\n const handleCellClick = (item: T, field: string, rowIndex: number, col: ColumnInstance) => {\n if (\n props.editMode === \"cell\" &&\n (col.slots.editor || col.props.editable) &&\n !editing.isCellEditing(rowIndex, field)\n ) {\n const event = editing.startCellEdit(item, field, rowIndex);\n emit(\"cell-edit-init\", event);\n }\n };\n\n const handleCellEditComplete = (item: T, field: string, rowIndex: number, newValue: unknown) => {\n // Close the editor and emit the event\n // This is called from focusout on the editor wrapper or Enter key\n const event = editing.completeCellEdit(item, field, rowIndex, newValue);\n emit(\"cell-edit-complete\", { data: item, field, newValue: event.newValue, index: rowIndex });\n\n // If inline editing is active, also update the inlineEdit composable\n if (inlineEdit.isEditing.value) {\n inlineEdit.updateCell(rowIndex, field, newValue);\n }\n };\n\n const handleCellEditCancel = (item: T, field: string, rowIndex: number) => {\n // Cancel editing - discard changes\n editing.cancelCellEdit(item, field, rowIndex);\n emit(\"cell-edit-cancel\", { data: item, field, index: rowIndex });\n };\n\n /**\n * Handle cell value change during editing (for inline edit dirty tracking).\n * Called on every keystroke/input change, not just on blur.\n */\n const handleCellValueChange = (field: string, rowIndex: number, newValue: unknown) => {\n // Clear new row flag on first interaction\n inlineEdit.clearNewRowFlag(rowIndex);\n\n // Use isInlineEditing (not inlineEdit.isEditing) to cover editMode=\"inline\" without startEditing()\n if (isInlineEditing.value) {\n inlineEdit.updateCell(rowIndex, field, newValue);\n }\n\n // In editMode=\"inline\", also emit cell-edit-complete so parent pages\n // that listen to @cell-edit-complete get notified. Mobile view has no\n // blur/complete cycle, so this is the only way values propagate.\n if (props.editMode === \"inline\") {\n const item = props.items[rowIndex];\n if (item) {\n emit(\"cell-edit-complete\", { data: item, field, newValue, index: rowIndex });\n }\n }\n };\n\n const handleExpandToggle = (item: T, index: number, event: Event) => {\n const wasExpanded = expansion.isRowExpanded(item, index);\n const result = expansion.toggleRowExpansion(item, index, event);\n if (!result) return;\n if (wasExpanded) emit(\"row-collapse\", result);\n else emit(\"row-expand\", result);\n };\n\n const handleStartRowEdit = (item: T, index: number) => {\n const event = editing.startRowEdit(item, index);\n emit(\"update:editingRows\", editing.internalEditingRows.value as T[]);\n emit(\"row-edit-init\", event);\n };\n\n const handleSaveRowEdit = (item: T, index: number) => {\n const event = editing.saveRowEdit(item, index);\n emit(\"update:editingRows\", editing.internalEditingRows.value as T[]);\n emit(\"row-edit-save\", event);\n };\n\n const handleCancelRowEdit = (item: T, index: number) => {\n const event = editing.cancelRowEdit(item, index);\n emit(\"update:editingRows\", editing.internalEditingRows.value as T[]);\n emit(\"row-edit-cancel\", event);\n };\n\n const handleRowAction = (action: TableAction, item: T, index: number) => {\n // Call the action's click handler with item and index (matching legacy vc-table behavior)\n action.clickHandler?.(item, index);\n emit(\"row-action\", { action, item, index });\n };\n\n const handleAddRow = (defaults?: Partial<T>) => {\n let cancelled = false;\n const event = {\n defaults: (defaults ?? {}) as Record<string, unknown>,\n cancel: () => {\n cancelled = true;\n },\n };\n emit(\"row-add\", event);\n if (!cancelled) {\n inlineEdit.addRow(event.defaults as Partial<T>);\n }\n };\n\n const handleRemoveRow = (rowIndex: number) => {\n if (rowIndex < 0 || rowIndex >= props.items.length) return;\n let cancelled = false;\n const event = {\n data: props.items[rowIndex],\n index: rowIndex,\n cancel: () => {\n cancelled = true;\n },\n };\n emit(\"row-remove\", event);\n if (!cancelled) {\n inlineEdit.removeRow(rowIndex);\n }\n };\n\n const handleColumnVisibilityChange = (visibleIds: string[]) => {\n const visibleSet = new Set(visibleIds);\n const allToggleableIds = switcherColumns.value.map((c) => c.id);\n const discoveredToggleableIds = switcherColumns.value.filter((c) => c.defaultVisible === false).map((c) => c.id);\n\n // Preserve hidden IDs that are not part of the current switcher view.\n // This prevents losing hidden preferences when switching datasets/views.\n const toggleableSet = new Set(allToggleableIds);\n const discoveredSet = new Set(discoveredToggleableIds);\n const newHidden = new Set<string>([...hiddenColumnIds.value].filter((id) => !toggleableSet.has(id)));\n const newShown = new Set<string>([...shownDataDiscoveredColumnIds.value].filter((id) => !discoveredSet.has(id)));\n\n for (const id of allToggleableIds) {\n if (!visibleSet.has(id)) {\n newHidden.add(id);\n }\n }\n\n for (const id of discoveredToggleableIds) {\n if (visibleSet.has(id)) {\n newShown.add(id);\n }\n }\n\n hiddenColumnIds.value = newHidden;\n shownDataDiscoveredColumnIds.value = newShown;\n };\n\n const handleTableReset = () => {\n // 1. Reset persisted state (clears storage + runtime refs including columnState, hiddenColumnIds, etc.)\n statePersistence.resetState();\n\n // 2. Re-hide data-discovered columns (they default to hidden).\n // The dataDiscoveredIds watcher won't re-fire because the IDs haven't changed,\n // but resetState() cleared hiddenColumnIds — so we must re-populate manually.\n if (dataDiscoveredIds.value.size > 0) {\n hiddenColumnIds.value = new Set(dataDiscoveredIds.value);\n }\n\n // 3. Re-init from declared VcColumn props (discards any runtime state).\n cols.resetFromProps();\n cols.recompute();\n };\n\n // ============================================================================\n // Mobile View Event Handlers\n // ============================================================================\n\n const handleMobileRowClick = (item: T, index: number) => {\n emit(\"row-click\", { data: item, index, originalEvent: new Event(\"click\") });\n };\n\n const handleMobileRowSelect = (item: T, _index: number) => {\n handleRowSelectionChange(item);\n };\n\n const handleMobileRowAction = (action: MobileSwipeAction<T>, item: T, index: number) => {\n // Execute the action's click handler if provided\n if (action.clickHandler) {\n action.clickHandler(item, index);\n }\n // Also emit the row-action event for parent components\n emit(\"row-action\", { action, item, index });\n };\n\n // ============================================================================\n // Return\n // ============================================================================\n\n return {\n // Row selection facade (hides raw useTableSelectionV2 + emit handlers)\n selection: selectionFacade,\n // Sub-composable instances\n sort,\n editing,\n expansion,\n rowGrouping,\n inlineEdit,\n cols,\n statePersistence,\n\n // Column filter helpers\n colFilter,\n filterValues,\n updateFilter,\n updateRangeFilter,\n clearFilter,\n clearAllFilters,\n buildPayload,\n hasActiveFilters,\n activeFilterCount,\n\n // Column filter template helpers\n showColumnFilter,\n getColumnFilterType,\n getColumnFilterOptions,\n isColumnFilterMultiple,\n getColumnRangeFields,\n getColumnFilterValue,\n handleColumnFilterApply,\n handleColumnFilterClear,\n emitFilterPayload,\n\n // Global filter\n globalFilterPayload,\n\n // Resize / reorder\n handleResizeStart,\n isColumnReordering,\n handleColumnDragStart,\n handleColumnDragOver,\n handleColumnDrop,\n\n // Row reorder\n reorderedItems: reorderedItems as Ref<T[]>,\n pendingReorder,\n isRowReorderEnabled,\n showRowDragHandle,\n rowReorderListRef,\n\n // Derived computeds\n displayItems,\n getGlobalIndex,\n effectiveSelectionMode,\n selectionColumn,\n hasSelectionColumn,\n isSelectionViaColumn,\n expanderColumn,\n hasExpanderColumn,\n computedVariant,\n switcherColumns,\n switcherVisibleColumnIds,\n safeColumns,\n isInlineEditing,\n\n // Expansion helper\n isRowExpanded,\n canExpand,\n expandedKeysArray,\n\n // Data-discovered IDs stable ref\n dataDiscoveredIds,\n\n // Event handlers (selection handlers are on the `selection` facade)\n handleSort,\n handleRowClick,\n handleAddRow,\n handleRemoveRow,\n handleColumnVisibilityChange,\n handleTableReset,\n handleCellClick,\n handleCellEditComplete,\n handleCellEditCancel,\n handleCellValueChange,\n handleExpandToggle,\n handleStartRowEdit,\n handleSaveRowEdit,\n handleCancelRowEdit,\n handleRowAction,\n handleMobileRowClick,\n handleMobileRowSelect,\n handleMobileRowAction,\n };\n}\n","/**\r\n * ColumnCollector - Utility for collecting VcColumn instances from slots\r\n *\r\n * This is inspired by PrimeVue's HelperSet pattern.\r\n * VcColumn components register themselves via inject/provide when mounted.\r\n *\r\n * Usage in VcDataTable:\r\n * ```ts\r\n * const columnCollector = new ColumnCollector();\r\n * provide('$columns', columnCollector);\r\n *\r\n * // Get collected columns\r\n * const columns = computed(() => columnCollector.getColumns());\r\n * ```\r\n */\r\n\r\nimport type { ComponentInternalInstance, Slots, VNode } from \"vue\";\r\nimport type { ColumnInstance } from \"@ui/components/organisms/vc-data-table/types\";\r\n\r\n// Re-export for backward compatibility (ColumnInstance now lives in types.ts)\r\nexport type { ColumnInstance };\r\n\r\nexport class ColumnCollector {\r\n private columns: Map<ComponentInternalInstance, ColumnInstance> = new Map();\r\n private updateCallback: (() => void) | null = null;\r\n\r\n /**\r\n * Set a callback to be called when columns change\r\n */\r\n onUpdate(callback: () => void): void {\r\n this.updateCallback = callback;\r\n }\r\n\r\n /**\r\n * Add a column instance\r\n */\r\n add(column: ColumnInstance): void {\r\n this.columns.set(column.instance, column);\r\n this.triggerUpdate();\r\n }\r\n\r\n /**\r\n * Delete a column instance\r\n */\r\n delete(instance: ComponentInternalInstance): void {\r\n this.columns.delete(instance);\r\n this.triggerUpdate();\r\n }\r\n\r\n /**\r\n * Clear all columns\r\n */\r\n clear(): void {\r\n this.columns.clear();\r\n this.triggerUpdate();\r\n }\r\n\r\n /**\r\n * Get all column instances as array\r\n */\r\n getAll(): ColumnInstance[] {\r\n return Array.from(this.columns.values());\r\n }\r\n\r\n /**\r\n * Get columns sorted by their order in the DOM (vnode order)\r\n * This ensures columns appear in the order they are declared in template\r\n */\r\n getColumns(): ColumnInstance[] {\r\n // Sort by vnode.key or index to maintain declaration order\r\n const columns = this.getAll();\r\n\r\n // Filter out any invalid columns and sort by component uid\r\n return columns\r\n .filter(\r\n (col): col is ColumnInstance =>\r\n col != null && col.instance != null && col.props != null && col.props.id != null,\r\n )\r\n .sort((a, b) => {\r\n return a.instance.uid - b.instance.uid;\r\n });\r\n }\r\n\r\n /**\r\n * Get visible columns only\r\n */\r\n getVisibleColumns(): ColumnInstance[] {\r\n return this.getColumns().filter((col) => col.props.visible !== false);\r\n }\r\n\r\n /**\r\n * Get column by id\r\n */\r\n getColumnById(id: string): ColumnInstance | undefined {\r\n return this.getAll().find((col) => col.props.id === id);\r\n }\r\n\r\n /**\r\n * Get size of collection\r\n */\r\n get size(): number {\r\n return this.columns.size;\r\n }\r\n\r\n /**\r\n * Extract columns from VNode tree (alternative approach for slot parsing)\r\n * This recursively finds VcColumn vnodes in the default slot\r\n */\r\n static extractFromSlots(slots: Slots): VNode[] {\r\n const defaultSlot = slots.default?.();\r\n if (!defaultSlot) return [];\r\n\r\n const columnVNodes: VNode[] = [];\r\n\r\n const processVNode = (vnode: VNode) => {\r\n // Check if this is a VcColumn\r\n if (typeof vnode.type === \"object\" && (vnode.type as any).name === \"VcColumn\") {\r\n columnVNodes.push(vnode);\r\n }\r\n // Check for Fragment with children\r\n else if (Array.isArray(vnode.children)) {\r\n (vnode.children as VNode[]).forEach(processVNode);\r\n }\r\n };\r\n\r\n defaultSlot.forEach(processVNode);\r\n return columnVNodes;\r\n }\r\n\r\n private triggerUpdate(): void {\r\n this.updateCallback?.();\r\n }\r\n}\r\n\r\nexport default ColumnCollector;\r\n","import { Directive, DirectiveBinding } from \"vue\";\r\n\r\nexport const autofocus = {\r\n mounted(el: HTMLElement, binding: DirectiveBinding): void {\r\n if (binding.value) {\r\n el.focus();\r\n }\r\n },\r\n} as Directive;\r\n","<template>\n <div\n ref=\"tableRootRef\"\n v-loading:49=\"(loading || bladeLoading) && !showSkeleton\"\n class=\"vc-data-table\"\n :aria-busy=\"loading || bladeLoading || undefined\"\n >\n <!-- Header slot -->\n <div\n v-if=\"$slots.header\"\n class=\"vc-data-table__header\"\n >\n <slot name=\"header\" />\n </div>\n\n <!-- Search bar + Global Filters + Column Switcher (combined toolbar) -->\n <TableSearchHeader\n v-if=\"searchable || globalFilters?.length || $slots['search-header-actions']\"\n :searchable=\"searchable\"\n :model-value=\"internalSearchValue\"\n :placeholder=\"searchPlaceholder\"\n @update:model-value=\"handleSearchInput\"\n >\n <template #actions>\n <GlobalFiltersButton\n v-if=\"globalFilters?.length\"\n ref=\"globalFiltersButtonRef\"\n :active-count=\"globalActiveFilterCount\"\n @click=\"showGlobalFiltersPanel = !showGlobalFiltersPanel\"\n />\n <!-- Custom actions from parent (e.g. adapter's filter button) -->\n <slot name=\"search-header-actions\" />\n </template>\n </TableSearchHeader>\n\n <!-- Global Filters Panel (separate, teleported to body) -->\n <GlobalFiltersPanel\n v-if=\"globalFilters?.length\"\n :filters=\"globalFilters\"\n :model-value=\"globalFilterValues\"\n :show=\"showGlobalFiltersPanel\"\n :anchor-ref=\"globalFiltersButtonEl\"\n @update:model-value=\"globalFilterValues = $event\"\n @update:show=\"showGlobalFiltersPanel = $event\"\n @apply=\"handleGlobalFilterApply\"\n @clear=\"handleGlobalFilterClear\"\n />\n\n <!-- Column Switcher Panel (separate, teleported to body) -->\n <TableColumnSwitcher\n v-if=\"columnSwitcher\"\n :columns=\"switcherColumns\"\n :visible-columns=\"switcherVisibleColumnIds\"\n :show=\"showColumnSwitcherPanel\"\n :anchor-ref=\"columnSwitcherButtonEl\"\n @update:visible-columns=\"handleColumnVisibilityChange\"\n @update:show=\"showColumnSwitcherPanel = $event\"\n @reset=\"handleTableReset\"\n />\n\n <!-- Add Row Button (header position) -->\n <TableAddRowButton\n v-if=\"showAddRowButton && addRowPosition === 'header'\"\n :label=\"addRowLabel\"\n :icon=\"addRowIcon\"\n @add=\"handleAddRow()\"\n />\n\n <!-- Selection Banner -->\n <slot\n name=\"selection-banner\"\n :count=\"selection.selected.value.length\"\n :total-count=\"props.totalCount\"\n :is-select-all=\"selection.isSelectAllAcrossPages.value\"\n :select-all=\"selection.selectAll\"\n :clear-selection=\"selection.clear\"\n >\n <TableSelectAllBar\n v-if=\"effectiveSelectionMode === 'multiple'\"\n :selection-count=\"selection.selected.value.length\"\n :total-count=\"props.totalCount ?? 0\"\n :all-selected=\"selection.isSelectAllAcrossPages.value\"\n :show-select-all-prompt=\"selection.showSelectAllPrompt.value\"\n @select-all=\"selection.selectAll\"\n @cancel=\"selection.clear\"\n />\n </slot>\n\n <!-- Desktop: Main table content -->\n <div\n v-if=\"!isMobileView\"\n ref=\"tableContainerRef\"\n class=\"vc-data-table__content\"\n :style=\"scrollHeight ? { height: scrollHeight } : undefined\"\n >\n <Table :variant=\"computedVariant\">\n <DataTableHeader\n ref=\"dataTableHeaderRef\"\n :columns=\"safeColumns\"\n :show-drag-handle=\"showRowDragHandle\"\n :show-selection-cell=\"hasSelectionColumn && !isSelectionViaColumn\"\n :selection-mode=\"effectiveSelectionMode\"\n :all-selected=\"selection.isAllSelected.value\"\n :some-selected=\"selection.isPartiallySelected.value\"\n :get-sort-direction=\"sort.getSortDirection\"\n :get-sort-index=\"sort.getSortIndex\"\n :get-column-width=\"cols.getEffectiveColumnWidth\"\n :get-header-align=\"cols.getHeaderAlign\"\n :get-header-style=\"cols.getHeaderStyle\"\n :is-column-resizable=\"cols.isColumnResizable\"\n :is-column-reorderable=\"cols.isColumnReorderable\"\n :is-last-resizable=\"cols.isLastResizableColumn\"\n :get-sort-field=\"cols.getSortField\"\n :set-header-ref=\"cols.setHeaderRef\"\n :show-filter=\"showColumnFilter\"\n :get-filter-type=\"getColumnFilterType\"\n :get-filter-options=\"getColumnFilterOptions\"\n :is-filter-multiple=\"isColumnFilterMultiple\"\n :get-range-fields=\"getColumnRangeFields\"\n :get-filter-value=\"getColumnFilterValue\"\n :is-editing=\"isInlineEditing\"\n :show-column-switcher=\"!!columnSwitcher\"\n :column-switcher-active=\"showColumnSwitcherPanel\"\n :actions-position=\"rowActionsPosition\"\n @select-all=\"selection.onSelectAll\"\n @sort=\"handleSort\"\n @resize-start=\"handleResizeStart\"\n @reorder-start=\"handleColumnDragStart\"\n @reorder-over=\"handleColumnDragOver\"\n @reorder-drop=\"(_, event) => handleColumnDrop(event)\"\n @filter-apply=\"handleColumnFilterApply\"\n @filter-clear=\"handleColumnFilterClear\"\n @column-switcher-click=\"showColumnSwitcherPanel = !showColumnSwitcherPanel\"\n />\n\n <!-- Body -->\n <DataTableBody\n ref=\"desktopBodyRef\"\n :items=\"displayItems\"\n :loading=\"loading || bladeLoading\"\n :skeleton-rows=\"props.skeletonRows\"\n :columns=\"safeColumns\"\n :get-column-width=\"cols.getEffectiveColumnWidth\"\n :get-cell-style=\"cols.getCellStyle\"\n :show-selection-cell=\"hasSelectionColumn && !isSelectionViaColumn\"\n :empty-icon=\"resolvedEmptyIcon\"\n :empty-title=\"resolvedEmptyTitle\"\n :empty-description=\"resolvedEmptyDescription\"\n :empty-action-label=\"resolvedEmptyActionLabel\"\n :empty-action-handler=\"resolvedEmptyActionHandler\"\n :loading-text=\"loadingText\"\n :grouping-enabled=\"rowGrouping.isGroupingEnabled.value\"\n :grouped-data=\"rowGrouping.groupedData.value\"\n :expandable-row-groups=\"expandableRowGroups\"\n :is-group-expanded=\"rowGrouping.isGroupExpanded\"\n :get-item-group-key=\"rowGrouping.getItemGroupKey\"\n :get-global-index=\"getGlobalIndex\"\n :get-item-key=\"getItemKey\"\n :new-row-indices=\"inlineEdit.newRowIndices.value\"\n :get-row-props=\"getRowProps as any\"\n @scroll=\"handleContentScroll\"\n @group-toggle=\"(key, e) => rowGrouping.toggleGroupExpansion(key, e!)\"\n @row-click=\"handleRowClick\"\n @row-mouseenter=\"handleRowMouseEnter\"\n @row-mouseleave=\"handleRowMouseLeave\"\n @selection-change=\"selection.onRowSelect\"\n @expand-toggle=\"(item, index, e) => handleExpandToggle(item, index, e!)\"\n @row-edit=\"handleStartRowEdit\"\n @row-save=\"handleSaveRowEdit\"\n @row-cancel=\"handleCancelRowEdit\"\n @edit-complete=\"handleCellEditComplete\"\n @edit-cancel=\"handleCellEditCancel\"\n @cell-value-change=\"handleCellValueChange\"\n @cell-click=\"handleCellClick\"\n >\n <template #row-actions=\"{ item, index }\">\n <TableRowActions\n v-if=\"rowActions\"\n :actions=\"rowActions(item)\"\n :row-index=\"index\"\n :mode=\"rowActionsMode\"\n :position=\"rowActionsPosition\"\n :max-quick-actions=\"maxQuickActions\"\n @action=\"(action) => handleRowAction(action, item, index)\"\n />\n </template>\n <template #expansion=\"{ data, index }\">\n <slot\n name=\"expansion\"\n :data=\"data\"\n :index=\"index\"\n />\n </template>\n <template\n v-if=\"$slots['not-found'] || $slots.empty\"\n #empty\n >\n <slot\n v-if=\"isNotFoundState && $slots['not-found']\"\n name=\"not-found\"\n />\n <slot\n v-else\n name=\"empty\"\n />\n </template>\n <template\n v-if=\"$slots.loading\"\n #loading\n >\n <slot name=\"loading\" />\n </template>\n <template\n v-if=\"$slots.groupheader\"\n #groupheader=\"{ data, index }\"\n >\n <slot\n name=\"groupheader\"\n :data=\"data\"\n :index=\"index\"\n />\n </template>\n <template\n v-if=\"$slots.groupfooter\"\n #groupfooter=\"{ data, index }\"\n >\n <slot\n name=\"groupfooter\"\n :data=\"data\"\n :index=\"index\"\n />\n </template>\n </DataTableBody>\n\n <!-- Footer -->\n <TableFooter v-if=\"$slots.footer && items && items.length\">\n <slot name=\"footer\" />\n </TableFooter>\n\n <!-- Add Row Button (footer position) -->\n <TableAddRowButton\n v-if=\"showAddRowButton && addRowPosition === 'footer'\"\n :label=\"addRowLabel\"\n :icon=\"addRowIcon\"\n @add=\"handleAddRow()\"\n />\n </Table>\n </div>\n\n <!-- Mobile: Card view with swipe actions (wrapped for scroll + pagination pinning) -->\n <div\n v-else\n class=\"vc-data-table__content\"\n >\n <!-- Mobile: Select all toolbar (appears when selection is active) -->\n <div\n v-if=\"\n effectiveSelectionMode === 'multiple' &&\n (selection.isPartiallySelected.value || selection.isAllSelected.value)\n \"\n class=\"vc-data-table__mobile-select-toolbar\"\n >\n <TableCheckbox\n :model-value=\"selection.isAllSelected.value\"\n :indeterminate=\"selection.isPartiallySelected.value && !selection.isAllSelected.value\"\n @change=\"selection.onSelectAll\"\n />\n <span class=\"vc-data-table__mobile-select-toolbar-text\">\n {{ $t(\"COMPONENTS.ORGANISMS.VC_TABLE.SELECTED\", \"Selected\") }}: {{ selection.selected.value.length }}\n </span>\n </div>\n\n <DataTableMobileView\n ref=\"mobileViewRef\"\n :items=\"displayItems\"\n :reorderable=\"isRowReorderEnabled\"\n :columns=\"visibleColumns\"\n :selection=\"selection.selected.value\"\n :selection-mode=\"effectiveSelectionMode\"\n :is-row-selectable=\"props.isRowSelectable\"\n :row-actions=\"rowActions\"\n :loading=\"loading\"\n :data-key=\"dataKey\"\n :pull-to-refresh=\"pullToRefresh\"\n :pull-to-refresh-text=\"pullToRefreshText\"\n :is-inline-editing=\"isInlineEditing\"\n :new-row-indices=\"inlineEdit.newRowIndices.value\"\n @click=\"handleMobileRowClick\"\n @select=\"handleMobileRowSelect\"\n @action=\"handleMobileRowAction\"\n @refresh=\"emit('pull-refresh')\"\n @cell-value-change=\"(field, index, value) => handleCellValueChange(field, index, value)\"\n >\n <template #empty>\n <slot\n v-if=\"isNotFoundState && $slots['not-found']\"\n name=\"not-found\"\n />\n <slot\n v-else-if=\"$slots.empty\"\n name=\"empty\"\n />\n <TableEmpty\n v-else\n :icon=\"resolvedEmptyIcon\"\n :title=\"resolvedEmptyTitle\"\n :description=\"resolvedEmptyDescription\"\n :action-label=\"resolvedEmptyActionLabel\"\n :action-handler=\"resolvedEmptyActionHandler\"\n />\n </template>\n </DataTableMobileView>\n\n <!-- Add Row Button (mobile) -->\n <TableAddRowButton\n v-if=\"showAddRowButton\"\n :label=\"addRowLabel\"\n :icon=\"addRowIcon\"\n @add=\"handleAddRow()\"\n />\n </div>\n\n <!-- Pagination / Total counter (outside scroll area, works for both desktop and mobile) -->\n <div\n v-if=\"props.pagination && props.pagination.pages > 0\"\n ref=\"paginationRef\"\n class=\"vc-data-table__pagination\"\n >\n <span class=\"vc-data-table__page-info\">{{ paginationRangeText }}</span>\n <!-- Pagination controls -->\n <slot\n name=\"pagination\"\n :pages=\"props.pagination.pages\"\n :current-page=\"props.pagination.currentPage\"\n :on-page-click=\"handlePaginationClick\"\n >\n <VcPagination\n :pages=\"props.pagination.pages\"\n :current-page=\"props.pagination.currentPage\"\n :variant=\"props.pagination.variant\"\n :max-pages=\"paginationMaxPages\"\n :show-first-last=\"paginationShowFirstLast\"\n @item-click=\"handlePaginationClick\"\n />\n </slot>\n </div>\n\n <!-- VcColumn renderless components (they register themselves via inject) -->\n <slot />\n </div>\n</template>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\n/**\n * VcDataTable - Declarative DataTable component with VcColumn support\n *\n * Refactored to use composables for better code organization.\n * Inspired by PrimeVue DataTable architecture.\n *\n * Orchestration logic (sub-composable wiring, watchers, event handlers, derived\n * computeds) is extracted into useDataTableOrchestrator for independent testability.\n */\nimport { ref, computed, provide, watch, watchEffect, onBeforeUnmount, useSlots, type VNode } from \"vue\";\nimport { useElementSize } from \"@vueuse/core\";\nimport { useI18n } from \"vue-i18n\";\nimport {\n Table,\n TableFooter,\n TableEmpty,\n TableRowActions,\n DataTableHeader,\n DataTableBody,\n GlobalFiltersButton,\n GlobalFiltersPanel,\n TableColumnSwitcher,\n DataTableMobileView,\n TableAddRowButton,\n TableSearchHeader,\n TableSelectAllBar,\n TableCheckbox,\n} from \"@ui/components/organisms/vc-data-table/components\";\nimport { VcPagination } from \"@ui/components/molecules\";\nimport { useDataTableOrchestrator } from \"@ui/components/organisms/vc-data-table/composables/useDataTableOrchestrator\";\nimport { ColumnCollector, type ColumnInstance } from \"@ui/components/organisms/vc-data-table/utils/ColumnCollector\";\nimport {\n ColumnCollectorKey,\n FilterContextKey,\n FillerWidthKey,\n IsColumnReorderingKey,\n} from \"@ui/components/organisms/vc-data-table/keys\";\nimport { useResponsive } from \"@framework/core/composables/useResponsive\";\nimport { useBladeLoading } from \"@ui/composables/useBladeLoading\";\nimport type {\n VcColumnProps,\n VcDataTableExtendedProps,\n EditChange,\n TableAction,\n SortMeta,\n MobileSwipeAction,\n TableFitMode,\n} from \"@ui/components/organisms/vc-data-table/types\";\nimport type { PersistedStateV2 } from \"@ui/components/organisms/vc-data-table/types\";\nimport { vLoading } from \"@core/directives\";\nimport type { VirtualElement } from \"@floating-ui/vue\";\n\nconst props = withDefaults(defineProps<VcDataTableExtendedProps<T> & { fitMode?: TableFitMode }>(), {\n fitMode: \"gap\",\n items: () => [],\n dataKey: \"id\",\n selectionMode: undefined,\n isRowSelectable: undefined,\n selectAll: false,\n editMode: undefined,\n sortField: undefined,\n sortOrder: 0,\n sortMode: \"single\",\n multiSortMeta: () => [],\n removableSort: true,\n striped: false,\n bordered: false,\n showGridlines: false,\n rowHover: true,\n size: \"normal\",\n variant: \"default\",\n resizableColumns: true,\n reorderableColumns: true,\n reorderableRows: false,\n showAllColumns: true,\n scrollable: false,\n scrollHeight: undefined,\n loading: false,\n expandedRows: () => [],\n expandedRowIcon: \"lucide-chevron-down\",\n collapsedRowIcon: \"lucide-chevron-right\",\n groupRowsBy: undefined,\n rowGroupMode: \"subheader\",\n expandableRowGroups: false,\n expandedRowGroups: undefined,\n rowActionsMode: \"inline\",\n rowActionsPosition: \"overlay\",\n maxQuickActions: 4,\n pullToRefresh: false,\n pullToRefreshText: undefined,\n totalCount: undefined,\n totalLabel: undefined,\n selectAllActive: undefined,\n addRow: undefined,\n validationRules: undefined,\n pagination: undefined,\n infiniteScroll: false,\n infiniteScrollDistance: 100,\n globalFilters: undefined,\n columnSwitcher: true,\n stateStorage: \"local\",\n searchable: false,\n searchValue: undefined,\n searchPlaceholder: \"Search...\",\n emptyState: undefined,\n notFoundState: undefined,\n searchDebounce: 300,\n activeItemId: undefined,\n});\n\n// Emits\nconst emit = defineEmits<{\n // === Selection ===\n /** v-model update for selected item(s) */\n \"update:selection\": [value: T | T[]];\n /** v-model update for the \"select all\" checkbox state */\n \"update:selectAll\": [value: boolean];\n /** Emitted when a row is selected (click or checkbox) */\n \"row-select\": [event: { data: T; originalEvent: Event }];\n /** Emitted when a row is deselected */\n \"row-unselect\": [event: { data: T; originalEvent: Event }];\n /** Emitted when \"select all\" selects all visible rows */\n \"row-select-all\": [event: { data: T[]; originalEvent: Event }];\n /** Emitted when \"select all\" deselects all visible rows */\n \"row-unselect-all\": [event: { data: T[]; originalEvent: Event }];\n /** Emitted when the \"select all\" banner mode changes */\n \"select-all\": [event: { selected: boolean }];\n /** v-model update for \"select all\" active state (includes non-visible items) */\n \"update:selectAllActive\": [value: boolean];\n\n // === Editing ===\n /** v-model update for currently editing rows */\n \"update:editingRows\": [value: T[]];\n /** Emitted when a cell enters edit mode */\n \"cell-edit-init\": [event: { data: T; field: string; index: number }];\n /** Emitted when a cell edit is completed (value committed) */\n \"cell-edit-complete\": [event: { data: T; field: string; newValue: unknown; index: number }];\n /** Emitted when a cell edit is cancelled */\n \"cell-edit-cancel\": [event: { data: T; field: string; index: number }];\n /** Emitted when row edit mode is initiated */\n \"row-edit-init\": [event: { data: T; index: number }];\n /** Emitted when row edits are saved */\n \"row-edit-save\": [event: { data: T; newData: T; index: number }];\n /** Emitted when row edits are cancelled */\n \"row-edit-cancel\": [event: { data: T; index: number }];\n\n // === Inline Edit (bulk editing mode) ===\n /** Emitted when inline edit changes are saved */\n \"edit-save\": [event: { changes: EditChange<T>[] }];\n /** Emitted when inline editing is cancelled */\n \"edit-cancel\": [];\n /** Emitted when a new row is being added via inline edit */\n \"row-add\": [event: { defaults: Record<string, unknown>; cancel: () => void }];\n /** Emitted when a row is being removed via inline edit */\n \"row-remove\": [event: { data: T; index: number; cancel: () => void }];\n\n // === Sorting ===\n /** v-model update for the sorted field name */\n \"update:sortField\": [value: string];\n /** v-model update for the sort direction */\n \"update:sortOrder\": [value: number];\n /** v-model update for multi-sort metadata */\n \"update:multiSortMeta\": [value: SortMeta[]];\n /** Emitted when sort changes — use for backend sorting */\n sort: [event: { sortField?: string; sortOrder?: number; multiSortMeta?: SortMeta[] }];\n\n // === Filtering ===\n /** Emitted when filter values change — flat payload ready for backend API */\n filter: [event: { filters: Record<string, unknown>; filteredValue: T[] }];\n\n // === Row Interactions ===\n /** v-model update for active (highlighted) row ID */\n \"update:activeItemId\": [value: string | undefined];\n /** Emitted when a row is clicked */\n \"row-click\": [event: { data: T; index: number; originalEvent: Event }];\n /** Emitted when a row action button/menu item is activated */\n \"row-action\": [event: { action: TableAction | MobileSwipeAction<T>; item: T; index: number }];\n\n // === Reorder ===\n /** Emitted when rows are reordered via drag-and-drop */\n \"row-reorder\": [event: { dragIndex: number; dropIndex: number; value: T[] }];\n /** Emitted when a column resize operation ends */\n \"column-resize-end\": [event: { columns: { id: string; width: number }[] }];\n /** Emitted when columns are reordered via drag-and-drop */\n \"column-reorder\": [event: { columns: { id: string; [key: string]: unknown }[] }];\n\n // === State ===\n /** Emitted when table state is saved to storage */\n \"state-save\": [state: PersistedStateV2];\n /** Emitted when table state is restored from storage */\n \"state-restore\": [state: PersistedStateV2];\n\n // === Expandable Rows ===\n /** v-model update for currently expanded rows */\n \"update:expandedRows\": [value: T[]];\n /** Emitted when a row is expanded */\n \"row-expand\": [event: { data: T; originalEvent: Event }];\n /** Emitted when a row is collapsed */\n \"row-collapse\": [event: { data: T; originalEvent: Event }];\n\n // === Row Grouping ===\n /** v-model update for currently expanded row groups */\n \"update:expandedRowGroups\": [value: string[]];\n /** Emitted when a row group is expanded */\n \"rowgroup-expand\": [event: { data: string; originalEvent: Event }];\n /** Emitted when a row group is collapsed */\n \"rowgroup-collapse\": [event: { data: string; originalEvent: Event }];\n\n // === Pull-to-Refresh ===\n /** Emitted when user triggers pull-to-refresh on mobile */\n \"pull-refresh\": [];\n\n // === Infinite Scroll ===\n /** Emitted when user scrolls near the bottom of the table */\n \"load-more\": [];\n\n // === Pagination ===\n /** Emitted when a page button is clicked in the built-in pagination */\n \"pagination-click\": [page: number];\n\n // === Search ===\n /** v-model update for search input value */\n \"update:searchValue\": [value: string];\n /** Emitted (debounced) when search value changes — use for backend filtering */\n search: [value: string];\n}>();\n\ndefineOptions({ inheritAttrs: false });\n\ndefineSlots<{\n /** Default slot for VcColumn declarations */\n default?: () => VNode[];\n /** Custom header content above the table */\n header?: () => VNode[];\n /** Extra action buttons in the search header toolbar */\n \"search-header-actions\"?: () => VNode[];\n /** Custom selection banner replacing the default TableSelectAllBar */\n \"selection-banner\"?: (props: {\n count: number;\n totalCount: number | undefined;\n isSelectAll: boolean;\n selectAll: () => void;\n clearSelection: () => void;\n }) => VNode[];\n /** Custom content for expanded rows */\n expansion?: (props: { data: T; index: number }) => VNode[];\n /** Custom not-found state content (shown when search yields no results) */\n \"not-found\"?: () => VNode[];\n /** Custom empty state content */\n empty?: () => VNode[];\n /** Custom loading state content */\n loading?: () => VNode[];\n /** Custom row group header */\n groupheader?: (props: { data: T; index: number }) => VNode[];\n /** Custom row group footer */\n groupfooter?: (props: { data: T; index: number }) => VNode[];\n /** Custom footer content below the table body */\n footer?: () => VNode[];\n /** Custom pagination replacing the default VcPagination */\n pagination?: (props: { pages: number; currentPage: number; onPageClick: (page: number) => void }) => VNode[];\n}>();\n\n// ============================================================================\n// Internationalization\n// ============================================================================\n\nconst { t } = useI18n({ useScope: \"global\" });\n\nconst emptyTitle = computed(() => t(\"COMPONENTS.ORGANISMS.VC_TABLE.EMPTY_TITLE\"));\nconst emptyDescription = computed(() => t(\"COMPONENTS.ORGANISMS.VC_TABLE.EMPTY_DESCRIPTION\"));\nconst notFoundTitle = computed(() => t(\"COMPONENTS.ORGANISMS.VC_TABLE.NOT_FOUND_TITLE\"));\nconst notFoundDescription = computed(() => t(\"COMPONENTS.ORGANISMS.VC_TABLE.NOT_FOUND_DESCRIPTION\"));\n\n/** Detect not-found state: items empty + active search or filters */\nconst isNotFoundState = computed(\n () =>\n displayItems.value.length === 0 && !props.loading && (internalSearchValue.value !== \"\" || hasActiveFilters.value),\n);\n\n/** Resolved title/description/icon/action for the current empty-like state */\nconst resolvedEmptyIcon = computed(() => (isNotFoundState.value ? props.notFoundState?.icon : props.emptyState?.icon));\nconst resolvedEmptyTitle = computed(() =>\n isNotFoundState.value\n ? (props.notFoundState?.title ?? notFoundTitle.value)\n : (props.emptyState?.title ?? emptyTitle.value),\n);\nconst resolvedEmptyDescription = computed(() =>\n isNotFoundState.value\n ? (props.notFoundState?.description ?? notFoundDescription.value)\n : (props.emptyState?.description ?? emptyDescription.value),\n);\nconst resolvedEmptyActionLabel = computed(() =>\n isNotFoundState.value ? props.notFoundState?.actionLabel : props.emptyState?.actionLabel,\n);\nconst resolvedEmptyActionHandler = computed(() =>\n isNotFoundState.value ? props.notFoundState?.actionHandler : props.emptyState?.actionHandler,\n);\nconst loadingText = computed(() => t(\"COMPONENTS.ORGANISMS.VC_TABLE.LOADING\"));\n\n/** Track whether data has ever been loaded — distinguishes initial load from refresh */\nconst hasLoadedOnce = ref(false);\nwatch(\n () => props.items,\n (items) => {\n if (items && items.length > 0) hasLoadedOnce.value = true;\n },\n { immediate: true },\n);\n\n/** Blade-level loading state (skeleton mode from parent VcBlade) */\nconst bladeLoading = useBladeLoading();\n\n/** True when skeleton should show instead of spinner overlay */\nconst showSkeleton = computed(() => (props.loading || bladeLoading.value) && !hasLoadedOnce.value);\n\nconst paginationRangeText = computed(() => {\n const p = props.pagination;\n if (!p) return \"\";\n const total = props.totalCount;\n if (total != null && p.pages > 0) {\n const pageSize = Math.ceil(total / p.pages);\n const start = (p.currentPage - 1) * pageSize + 1;\n const end = Math.min(start + props.items.length - 1, total);\n return `${start}\\u2013${end} ${t(\"COMPONENTS.ORGANISMS.VC_TABLE.OF\", {}, \"of\")} ${total}`;\n }\n return `${t(\"COMPONENTS.ORGANISMS.VC_TABLE.PAGE\", {}, \"Page\")} ${p.currentPage} ${t(\"COMPONENTS.ORGANISMS.VC_TABLE.OF\", {}, \"of\")} ${p.pages}`;\n});\n\n// ============================================================================\n// Mobile Responsive Detection\n// ============================================================================\n\nconst { isMobile } = useResponsive();\nconst isMobileView = computed(() => isMobile.value);\n\n// ============================================================================\n// Column Collection (Hybrid approach: slots + inject/provide)\n// ============================================================================\n\nconst slots = useSlots();\n\n// Extract columns from slot VNodes (PrimeVue-like approach)\n// Convert kebab-case to camelCase for props normalization\nconst kebabToCamel = (str: string): string => {\n return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\n};\n\n// Boolean props that should be converted from \"\" to true\nconst BOOLEAN_PROPS = new Set([\n \"sortable\",\n \"editable\",\n \"visible\",\n \"alwaysVisible\",\n \"filter\",\n \"selectionMode\",\n \"rowEditor\",\n \"rowReorder\",\n \"expander\",\n \"mobileVisible\",\n]);\n\n// Normalize VNode props from kebab-case to camelCase\n// Also handles boolean attributes (e.g., `editable` becomes `editable: \"\"` in Vue, should be `true`)\nconst normalizeProps = (props: Record<string, unknown>): VcColumnProps => {\n const normalized: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n const camelKey = kebabToCamel(key);\n let value = props[key];\n\n // Handle boolean attributes: empty string \"\" means true in Vue templates\n if (BOOLEAN_PROPS.has(camelKey) && value === \"\") {\n value = true;\n }\n\n normalized[camelKey] = value;\n }\n return normalized as unknown as VcColumnProps;\n};\n\nconst extractColumnsFromSlots = (): ColumnInstance[] => {\n const defaultSlot = slots.default?.();\n if (!defaultSlot) return [];\n\n const columns: ColumnInstance[] = [];\n\n const processVNode = (vnode: VNode) => {\n // Check if this is a VcColumn component\n const type = vnode.type as any;\n if (type && (type.name === \"VcColumn\" || type.__name === \"VcColumn\")) {\n // Normalize props from kebab-case to camelCase\n const rawProps = (vnode.props || {}) as Record<string, unknown>;\n const props = normalizeProps(rawProps);\n // Ensure id exists\n if (props.id) {\n columns.push({\n instance: null as any, // Not needed for slot-based approach\n props: props,\n slots: (vnode.children || {}) as any,\n });\n }\n }\n // Check Fragment or array children\n if (Array.isArray(vnode.children)) {\n (vnode.children as VNode[]).forEach(processVNode);\n }\n };\n\n defaultSlot.forEach(processVNode);\n return columns;\n};\n\n// Also keep inject/provide for backward compatibility\nconst columnCollector = new ColumnCollector();\nprovide(ColumnCollectorKey, columnCollector);\n\nconst columnsVersion = ref(0);\ncolumnCollector.onUpdate(() => {\n columnsVersion.value++;\n});\n\n// All declared columns (before visibility filtering) — from slots or collector\nconst declaredColumns = computed<ColumnInstance[]>(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n columnsVersion.value;\n const slotCols = extractColumnsFromSlots();\n if (slotCols.length > 0) return slotCols;\n return columnCollector.getColumns();\n});\n\n// Column IDs hidden by user via TableColumnSwitcher (runtime toggle)\nconst hiddenColumnIds = ref<Set<string>>(new Set());\n// Data-discovered columns explicitly shown by user.\n// Needed to persist \"Show all\" for auto columns across reloads.\nconst shownDataDiscoveredColumnIds = ref<Set<string>>(new Set());\n\n// Auto-discovered columns from items keys (for columnSwitcher 'auto' mode)\n// These are keys in items[0] that don't have a matching declared VcColumn.\n// They start hidden and can be toggled on via the switcher.\nconst dataDiscoveredColumns = computed<ColumnInstance[]>(() => {\n const mode = props.columnSwitcher;\n if (!mode || mode === \"defined\") return [];\n\n const items = props.items;\n if (!items || items.length === 0) return [];\n\n const declaredIds = new Set(declaredColumns.value.map((col) => col.props.id));\n const firstItem = items[0] as Record<string, unknown>;\n const itemKeys = Object.keys(firstItem);\n\n return itemKeys\n .filter((key) => !declaredIds.has(key))\n .map((key) => ({\n instance: null as any,\n props: {\n id: key,\n field: key,\n title: key.replace(/([A-Z])/g, \" $1\").replace(/^./, (s) => s.toUpperCase()),\n } as VcColumnProps,\n slots: {} as any,\n }));\n});\n\n// Use slot-based extraction as primary, fallback to inject\n// Reuse declaredColumns instead of re-extracting from slots to avoid creating duplicate objects\nconst visibleColumns = computed<ColumnInstance[]>(() => {\n const baseCols = declaredColumns.value;\n\n const declared = baseCols.filter((col) => {\n if (col.props.visible === false) return false;\n if (hiddenColumnIds.value.size > 0 && hiddenColumnIds.value.has(col.props.id)) return false;\n // When showAllColumns=false, only show alwaysVisible columns (e.g. second blade opened)\n if (!props.showAllColumns) return !!col.props.alwaysVisible;\n return true;\n });\n\n // Data-discovered columns — only those explicitly enabled by user (not in hiddenColumnIds)\n const discovered = dataDiscoveredColumns.value.filter((col) => !hiddenColumnIds.value.has(col.props.id));\n\n return [...declared, ...discovered];\n});\n\n// ============================================================================\n// Helper: Get Item Key\n// ============================================================================\n\nconst getItemKey = (item: T, index: number): string => {\n const key = (item as Record<string, unknown>)[props.dataKey];\n return key?.toString() || `row-${index}`;\n};\n\n// ============================================================================\n// DOM Refs (declared early — passed to orchestrator for column resize)\n// ============================================================================\n\nconst tableRootRef = ref<HTMLElement | null>(null);\nconst tableContainerRef = ref<HTMLElement | null>(null);\nconst paginationRef = ref<HTMLElement | null>(null);\n\n// ============================================================================\n// Orchestrator — wires all sub-composables, watchers, and event handlers\n// ============================================================================\n\nconst {\n // Sub-composable instances\n selection,\n sort,\n editing,\n expansion: _expansion,\n rowGrouping,\n inlineEdit,\n cols,\n statePersistence,\n\n // Column filter helpers\n filterValues,\n updateFilter,\n clearFilter,\n clearAllFilters,\n hasActiveFilters,\n activeFilterCount,\n\n // Column filter template helpers\n showColumnFilter,\n getColumnFilterType,\n getColumnFilterOptions,\n isColumnFilterMultiple,\n getColumnRangeFields,\n getColumnFilterValue,\n handleColumnFilterApply,\n handleColumnFilterClear,\n emitFilterPayload,\n\n // Global filter payload (owned by component UI state; orchestrator wires it)\n globalFilterPayload,\n\n // Resize / reorder\n handleResizeStart,\n isColumnReordering,\n handleColumnDragStart,\n handleColumnDragOver,\n handleColumnDrop,\n\n // Row reorder state\n rowReorderListRef,\n\n // Derived computeds\n displayItems,\n getGlobalIndex,\n effectiveSelectionMode,\n hasSelectionColumn,\n isSelectionViaColumn,\n isRowReorderEnabled,\n showRowDragHandle,\n hasExpanderColumn,\n computedVariant,\n switcherColumns,\n switcherVisibleColumnIds,\n safeColumns,\n isInlineEditing,\n\n // Expansion helper\n isRowExpanded,\n canExpand,\n\n // Event handlers\n handleSort,\n handleRowClick,\n handleAddRow,\n handleRemoveRow,\n handleColumnVisibilityChange,\n handleTableReset,\n handleCellClick,\n handleCellEditComplete,\n handleCellEditCancel,\n handleCellValueChange,\n handleExpandToggle,\n handleStartRowEdit,\n handleSaveRowEdit,\n handleCancelRowEdit,\n handleRowAction,\n handleMobileRowClick,\n handleMobileRowSelect,\n handleMobileRowAction,\n} = useDataTableOrchestrator<T>({\n props,\n emit: emit as any,\n visibleColumns,\n declaredColumns,\n hiddenColumnIds,\n shownDataDiscoveredColumnIds,\n dataDiscoveredColumns,\n getItemKey,\n tableContainerRef,\n});\n\n// Template refs for the active view's rows container.\n// These are declared after the orchestrator so rowReorderListRef (from the\n// orchestrator) is already in scope when watchEffect runs.\nconst desktopBodyRef = ref<{ listEl?: HTMLElement } | null>(null);\nconst mobileViewRef = ref<{ listEl?: HTMLElement } | null>(null);\n\n// Feed the active view's rows container into the orchestrator-owned reorder composable.\n// Only one view is mounted at a time; the composable recreates SortableJS when the element changes.\nwatchEffect(() => {\n rowReorderListRef.value = isMobileView.value ? mobileViewRef.value?.listEl : desktopBodyRef.value?.listEl;\n});\n\n// Provide filter context (values returned by orchestrator, provide() here per plan rules)\nprovide(FilterContextKey, {\n filterValues,\n updateFilter,\n clearFilter,\n clearAllFilters,\n hasActiveFilters,\n activeFilterCount,\n});\n\n// Provide engine-controlled filler width for TableRow\nprovide(\n FillerWidthKey,\n computed(() => cols.engineOutput.value.fillerWidth),\n);\n\n// Provide column reordering state so TableRow enables FLIP animation only during drag\nprovide(IsColumnReorderingKey, isColumnReordering);\n\n// ============================================================================\n// Pagination handler (UI-level, stays in component)\n// ============================================================================\n\nconst handlePaginationClick = (page: number) => {\n emit(\"pagination-click\", page);\n};\n\n// ============================================================================\n// Search (UI state stays in component)\n// ============================================================================\n\nconst internalSearchValue = ref(props.searchValue ?? \"\");\nlet searchTimer: ReturnType<typeof setTimeout> | null = null;\n\nconst handleSearchInput = (value: string) => {\n internalSearchValue.value = value;\n emit(\"update:searchValue\", value);\n\n if (searchTimer) clearTimeout(searchTimer);\n searchTimer = setTimeout(() => {\n emit(\"search\", value);\n }, props.searchDebounce ?? 300);\n};\n\n// Watch for external changes (controlled mode)\nwatch(\n () => props.searchValue,\n (newVal) => {\n if (newVal !== undefined && newVal !== internalSearchValue.value) {\n internalSearchValue.value = newVal;\n }\n },\n);\n\n// Infinite scroll handler\nconst handleContentScroll = (e: Event) => {\n if (!props.infiniteScroll || props.loading) return;\n const el = e.target as HTMLElement;\n const threshold = props.infiniteScrollDistance ?? 100;\n if (el.scrollHeight - el.scrollTop - el.clientHeight < threshold) {\n emit(\"load-more\");\n }\n};\n\n// Dev warning: totalCount > items.length without pagination\nif (import.meta.env.DEV) {\n watch(\n () => [props.totalCount, props.items.length, props.pagination] as const,\n ([total, length, pagination]) => {\n if (!pagination && total && total > length) {\n console.warn(\n '[VcDataTable] totalCount > items.length but no \"pagination\" prop provided. ' +\n 'Add :pagination=\"{ currentPage, pages }\" to enable pagination.',\n );\n }\n },\n { immediate: true },\n );\n}\n\n// Add row config\nconst showAddRowButton = computed(() => props.addRow?.enabled === true);\nconst addRowPosition = computed(() => props.addRow?.position ?? \"footer\");\nconst addRowLabel = computed(() => props.addRow?.label ?? \"Add row\");\nconst addRowIcon = computed(() => props.addRow?.icon ?? \"lucide-plus\");\n\n// ============================================================================\n// Row Hover for Actions\n// ============================================================================\n// Note: Row hover state for action visibility is managed by Table.vue's own\n// tableContext provide (selectedRowIndex + setSelectedRowIndex). TableRow.vue\n// calls setSelectedRowIndex on mouseenter/mouseleave, and TableRowActions.vue\n// injects from the same context. No duplicate provide needed here.\n\n// Handlers kept as no-ops to satisfy template bindings from DataTableBody.\n// The actual hover state flows through Table.vue → TableRow → TableRowActions.\nconst handleRowMouseEnter = (_index: number) => {};\nconst handleRowMouseLeave = () => {};\n\n// ============================================================================\n// Global Filter UI State (UI-level state, component-owned)\n// ============================================================================\n\nconst showGlobalFiltersPanel = ref(false);\nconst globalFilterValues = ref<Record<string, unknown>>({});\nconst globalFiltersButtonRef = ref<InstanceType<typeof GlobalFiltersButton> | null>(null);\n\n// Wrap the component ref as a floating-ui VirtualElement so the anchor is resolved\n// lazily on every position update. `$el` of a Vue component instance is NOT reactive —\n// when `VcButton`'s inner `v-if=\"!bladeLoading\"` swaps the DOM root after the blade\n// finishes loading, a plain `computed(() => ref.value?.$el)` keeps a stale detached\n// node. Reading `$el` inside `getBoundingClientRect()` (called per autoUpdate frame)\n// always picks up the live element instead.\nconst globalFiltersButtonEl = computed<VirtualElement | null>(() => {\n const inst = globalFiltersButtonRef.value;\n if (!inst) return null;\n return {\n getBoundingClientRect: () =>\n (inst as unknown as { $el?: HTMLElement }).$el?.getBoundingClientRect() ?? new DOMRect(),\n get contextElement() {\n return (inst as unknown as { $el?: HTMLElement }).$el;\n },\n };\n});\n\n// Column switcher state\nconst showColumnSwitcherPanel = ref(false);\nconst dataTableHeaderRef = ref<InstanceType<typeof DataTableHeader> | null>(null);\n\nconst columnSwitcherButtonEl = computed<VirtualElement | null>(() => {\n const header = dataTableHeaderRef.value;\n if (!header) return null;\n return {\n getBoundingClientRect: () => (header.columnSwitcherEl ?? null)?.getBoundingClientRect() ?? new DOMRect(),\n get contextElement() {\n return header.columnSwitcherEl ?? undefined;\n },\n };\n});\n\n// Computed: count of active global filters\nconst globalActiveFilterCount = computed(() => {\n let count = 0;\n for (const val of Object.values(globalFilterValues.value)) {\n if (val === null || val === undefined || val === \"\") continue;\n if (Array.isArray(val) && val.length === 0) continue;\n if (typeof val === \"object\" && !Array.isArray(val)) {\n const range = val as { start?: string; end?: string };\n if (range.start || range.end) count++;\n continue;\n }\n count++;\n }\n return count;\n});\n\nconst handleGlobalFilterApply = (payload: Record<string, unknown>) => {\n globalFilterPayload.value = payload;\n emitFilterPayload();\n};\n\nconst handleGlobalFilterClear = () => {\n globalFilterPayload.value = null;\n globalFilterValues.value = {};\n emitFilterPayload();\n};\n\n// ============================================================================\n// Row Props Builder (for DataTableRow component)\n// Uses orchestrator outputs + DOM refs + UI state — stays in component\n// ============================================================================\n\n/**\n * Builds the props object for DataTableRow component.\n * This centralizes all row-related prop computation in one place.\n */\nconst getRowProps = (item: T, index: number) => ({\n item,\n index,\n columns: safeColumns.value,\n\n // Selection\n isSelected: selection.isSelected(item),\n isActive: props.activeItemId != null && getItemKey(item, index) === String(props.activeItemId),\n isSelectable: selection.canSelect(item),\n selectionMode: effectiveSelectionMode.value,\n showSelectionCell: hasSelectionColumn.value && !isSelectionViaColumn.value,\n\n // Reorder\n reorderable: isRowReorderEnabled.value,\n showDragHandle: showRowDragHandle.value,\n\n // Expansion\n expandable: hasExpanderColumn.value && canExpand(item),\n isExpanded: isRowExpanded(item),\n expandedIcon: props.expandedRowIcon,\n collapsedIcon: props.collapsedRowIcon,\n\n // Editing\n editingRowData: editing.getEditingRowData(item, index),\n isRowEditing: editing.isRowEditing(item),\n isInlineEditing: isInlineEditing.value,\n isCellEditing: editing.isCellEditing,\n\n // Actions\n hasActions: !!props.rowActions,\n actionsPosition: props.rowActionsPosition ?? \"overlay\",\n\n // Column helpers\n getColumnWidth: cols.getEffectiveColumnWidth,\n getCellAlign: cols.getCellAlign,\n getCellStyle: cols.getCellStyle,\n\n // Custom class\n rowClass: props.rowClass?.(item),\n});\n\n// ============================================================================\n// Adaptive Pagination\n// ============================================================================\n\nconst { width: paginationWidth } = useElementSize(paginationRef);\n\n/** Pagination item width (29px) + gap (8px) = 37px per button */\nconst PAGINATION_ITEM_SLOT = 37;\n/** Approximate width of the page-info text + padding */\nconst PAGINATION_BASE_WIDTH = 140;\n\nconst paginationMaxPages = computed(() => {\n if (!props.pagination || paginationWidth.value === 0) return 5;\n const available = paginationWidth.value - PAGINATION_BASE_WIDTH;\n // prev + next buttons always shown = 2 slots\n const slotsForPages = Math.floor((available - 2 * PAGINATION_ITEM_SLOT) / PAGINATION_ITEM_SLOT);\n if (slotsForPages >= 7) return 5; // enough room for 5 pages + first/last\n if (slotsForPages >= 3) return slotsForPages;\n return 0;\n});\n\nconst paginationShowFirstLast = computed(() => {\n if (!props.pagination || paginationWidth.value === 0) return true;\n const available = paginationWidth.value - PAGINATION_BASE_WIDTH;\n // Need room for: first + prev + at least 1 page + next + last = 5 slots minimum\n return available >= 5 * PAGINATION_ITEM_SLOT;\n});\n\n// Note: Click-outside handling is done via focusout on the editor wrapper in DataTableCellRenderer.\n// No need for a separate mousedown listener - focusout covers all cases.\n\n// ============================================================================\n// Expose API\n// ============================================================================\n\ndefineExpose({\n // Selection API (public keys unchanged; sourced from the selection facade)\n selectAll: selection.selectAll,\n clearSelection: selection.clear,\n getSelectionState: selection.getState,\n isSelectAllActive: selection.isSelectAllAcrossPages,\n showSelectAllChoice: selection.showSelectAllPrompt,\n selectionInfo: selection.info,\n\n // Row CRUD API\n addRow: handleAddRow,\n removeRow: handleRemoveRow,\n\n // Inline editing API\n startEditing: inlineEdit.startEditing,\n cancelEditing: inlineEdit.cancelEditing,\n saveChanges: inlineEdit.saveChanges,\n isEditing: inlineEdit.isEditing,\n isValid: inlineEdit.isValid,\n isDirty: inlineEdit.isDirty,\n pendingChanges: inlineEdit.pendingChanges,\n\n // State persistence API\n clearState: statePersistence.clearState,\n saveState: statePersistence.saveState,\n});\n\nonBeforeUnmount(() => {\n columnCollector.clear();\n if (searchTimer) clearTimeout(searchTimer);\n});\n</script>\n\n<style lang=\"scss\">\n// Table CSS variables are defined in Table.vue on .vc-table-composition.\n// No :root fallback needed — all sub-components render inside <Table>.\n.vc-data-table {\n // Note: overflow-visible allows absolutely positioned elements like row actions\n // to escape the container bounds. The inner __content element handles scrolling.\n @apply tw-relative tw-flex tw-flex-col tw-grow tw-basis-0 tw-flex-auto tw-h-full tw-overflow-visible;\n\n // Break the content-inflation feedback loop. The table measures its own inner\n // wrapper to size columns; if that wrapper is ever wider than its allotted box,\n // the engine bakes oversized column widths, which keeps the wrapper wide — a\n // self-reinforcing loop that never recovers (the ResizeObserver sees no further\n // size change). It happens because every flex ancestor up to the nearest scroll\n // viewport defaults to `min-width: auto`, so a momentarily-unconstrained table\n // (long cell content, no column widths yet on a cold mount / view switch / reset)\n // stretches the whole subtree — including ancestors the framework doesn't own.\n //\n // `contain: inline-size` makes this element's width independent of its content,\n // so the subtree can never push past its allotted width and the wrapper\n // measurement is always correct. It is size containment only (not layout/paint),\n // so it does NOT establish a containing block for the absolutely positioned row\n // actions above, and it constrains the inline axis only — block height/scrolling\n // are untouched.\n contain: inline-size;\n\n &__header {\n @apply tw-flex-shrink-0 tw-px-4 tw-py-2;\n }\n\n &__content {\n // flex-basis: 0 (tw-basis-0) is critical: with `auto` basis the element sizes to content\n // first, so overflow-y never activates on mobile touch devices.\n // basis-0 forces height from flex allocation → content overflows → scroll works.\n @apply tw-relative tw-box-border tw-w-full tw-flex tw-flex-col tw-grow tw-shrink tw-min-h-0;\n // Vertical scroll only — horizontal overflow is hidden to prevent scrollbar flash\n // during animated container resize (blade expand/collapse).\n // Columns use flex-shrink to fit within available width.\n overflow-x: hidden;\n overflow-y: auto;\n // Enable momentum scrolling on iOS\n -webkit-overflow-scrolling: touch;\n }\n\n &__loading {\n @apply tw-flex tw-items-center tw-justify-center tw-p-8 tw-text-neutrals-500;\n }\n\n // Hide spinner overlay when skeleton is showing (initial load)\n &--skeleton-active .vc-loading-overlay {\n display: none !important;\n }\n\n &__expansion-row {\n @apply tw-bg-neutrals-50 tw-w-full tw-border-b tw-border-[color:var(--table-border-color)];\n }\n\n &__expansion-content {\n @apply tw-p-4;\n }\n\n &__global-filters {\n @apply tw-flex tw-items-center tw-px-3 tw-py-2;\n border-bottom: 1px solid var(--table-border-color, #e5e7eb);\n }\n\n &__header-content {\n @apply tw-flex tw-items-center tw-justify-between tw-gap-2 tw-w-full;\n }\n\n // &__header-title / &__header-title-text styles live in HeaderTitle.vue,\n // which owns the truncation + tooltip behavior for the default header.\n\n &__group-label {\n @apply tw-font-semibold tw-text-sm;\n color: var(--neutrals-900);\n }\n\n &__group-count {\n @apply tw-text-sm tw-ml-2;\n color: var(--neutrals-500);\n }\n\n &__group-footer {\n @apply tw-bg-neutrals-50 tw-px-4 tw-py-2 tw-border-b;\n border-color: var(--table-border-color);\n font-size: 0.875rem;\n color: var(--neutrals-600);\n }\n\n &__rows-container {\n @apply tw-flex tw-flex-col;\n }\n\n &__mobile-select-toolbar {\n @apply tw-flex tw-items-center tw-gap-3 tw-px-4 tw-py-2.5;\n background-color: var(--table-select-bar-bg, var(--additional-50));\n border-bottom: 1px solid var(--table-border-color, var(--neutrals-200));\n }\n\n &__mobile-select-toolbar-text {\n @apply tw-text-sm tw-font-medium;\n color: var(--neutrals-700);\n }\n\n &__selection-cell {\n text-align: center;\n justify-content: center;\n min-width: 40px;\n max-width: 40px;\n width: 40px;\n // Override overflow:hidden from TableHead/TableCell so checkbox\n // focus ring (box-shadow 3px) is fully visible within the 40px cell\n &,\n .vc-table-composition__cell-content {\n overflow: visible;\n // Don't let cell-content grow — keep it intrinsic-sized so that\n // justify-content: center on the parent actually centers the checkbox/skeleton\n flex: 0 0 auto;\n }\n }\n\n &__pagination {\n @apply tw-flex-shrink-0 tw-flex tw-justify-between tw-items-center tw-px-4 tw-py-[11px] tw-border-t;\n border-color: var(--table-border-color, var(--neutrals-200));\n }\n\n &__page-info {\n @apply tw-text-sm;\n color: var(--neutrals-600);\n }\n}\n\n/* SortableJS reorder feedback (applies to the dragged row wrapper / mobile card) */\n// In-list drop-slot placeholder — marks where the row/card will land, staying\n// within its reorder track. This is the primary drag feedback.\n.vc-data-table__row-reorder-ghost {\n opacity: 0.6;\n background: var(--primary-50) !important;\n outline: 1px dashed var(--primary-300);\n outline-offset: -1px;\n}\n\n// SortableJS's floating clone follows the pointer across the whole screen in\n// fallback mode. Hide it so the drag stays constrained to the list — feedback\n// comes from the placeholder above plus the live row shifting (same effect the\n// column reorder achieves with a transparent drag image).\n.vc-data-table__row-reorder-fallback {\n opacity: 0 !important;\n}\n\n/* FLIP move animation for row reorder */\n.vc-table-row-swap-move {\n transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1) !important;\n}\n\n/* Disable transitions on enter/leave so only moves animate */\n.vc-table-row-swap-enter-active,\n.vc-table-row-swap-leave-active {\n transition: none !important;\n}\n</style>\n","<template>\n <div class=\"vc-table-adapter\">\n <VcDataTable\n :items=\"props.items\"\n :sort-field=\"sortFieldValue\"\n :sort-order=\"sortOrderValue\"\n :removable-sort=\"true\"\n :selection-mode=\"selectionMode\"\n :selection=\"internalSelection\"\n :is-row-selectable=\"rowSelectable\"\n :row-actions=\"effectiveRowActions\"\n :active-item-id=\"selectedItemId ? toValue(selectedItemId) : undefined\"\n :loading=\"loadingValue\"\n :resizable-columns=\"props.resizableColumns\"\n :reorderable-columns=\"props.reorderableColumns\"\n :reorderable-rows=\"props.reorderableRows\"\n :state-key=\"props.stateKey\"\n :pull-to-refresh=\"props.pullToReload\"\n :column-switcher=\"columnSwitcherValue\"\n :edit-mode=\"editModeValue\"\n :show-all-columns=\"expanded\"\n :select-all=\"props.selectAll\"\n :total-count=\"props.totalCount\"\n :total-label=\"props.totalLabel\"\n :searchable=\"showSearch\"\n :search-value=\"props.searchValue\"\n :search-placeholder=\"props.searchPlaceholder\"\n :pagination=\"paginationConfig\"\n :add-row=\"addRowConfig\"\n :variant=\"props.variant\"\n :empty-state=\"mappedEmptyState\"\n :not-found-state=\"mappedNotFoundState\"\n @sort=\"handleSort\"\n @update:selection=\"handleSelectionUpdate\"\n @row-click=\"handleRowClick\"\n @row-reorder=\"handleRowReorder\"\n @cell-edit-complete=\"handleCellEditComplete\"\n @pull-refresh=\"handlePullRefresh\"\n @update:select-all=\"handleSelectAll\"\n @pagination-click=\"handlePaginationClick\"\n @search=\"handleSearchChange\"\n @update:search-value=\"handleSearchChange\"\n @row-add=\"handleAddRow\"\n >\n <!-- Dynamic VcColumn generation from columns[] prop -->\n <VcColumn\n v-for=\"col in effectiveColumns\"\n :id=\"col.id\"\n :key=\"col.id\"\n :field=\"col.field || col.id\"\n :title=\"toValue(col.title)\"\n :width=\"col.width\"\n :type=\"mapColumnType(col.type)\"\n :sortable=\"col.sortable\"\n :editable=\"col.editable\"\n :align=\"mapColumnAlign(col.align)\"\n :always-visible=\"col.alwaysVisible\"\n :currency-field=\"col.currencyField\"\n :rules=\"col.rules\"\n :filter=\"col.filter\"\n :mobile-role=\"mapMobileRole(col.mobilePosition)\"\n :mobile-position=\"mapMobilePosition(col.mobilePosition)\"\n :mobile-visible=\"col.mobileVisible\"\n >\n <!-- Forward item_{colId} → VcColumn #body -->\n <template\n v-if=\"$slots[`item_${col.id}`]\"\n #body=\"{ data, index }\"\n >\n <slot\n :name=\"`item_${col.id}`\"\n :item=\"data\"\n :cell=\"col\"\n :index=\"index\"\n />\n </template>\n <!-- Forward header_{colId} → VcColumn #header -->\n <template\n v-if=\"$slots[`header_${col.id}`]\"\n #header\n >\n <slot :name=\"`header_${col.id}`\" />\n </template>\n </VcColumn>\n\n <!-- Legacy header + filters → toolbar-actions -->\n <template\n v-if=\"$slots.filters || $slots.header\"\n #search-header-actions\n >\n <GlobalFiltersButton\n v-if=\"$slots.filters\"\n ref=\"legacyFiltersButtonRef\"\n :active-count=\"props.activeFilterCount ?? 0\"\n :disabled=\"props.disableFilter\"\n @click=\"showLegacyFiltersPanel = !showLegacyFiltersPanel\"\n />\n <slot name=\"search-header-actions\"></slot>\n </template>\n\n <!-- Header -->\n <template\n v-if=\"$slots.header\"\n #header\n >\n <slot\n name=\"header\"\n :header=\"() => null\"\n />\n </template>\n\n <!-- Empty / NotFound — delegate rendering to VcDataTable via props, passthrough custom slots -->\n <template\n v-if=\"$slots.notfound\"\n #not-found\n >\n <slot name=\"notfound\" />\n </template>\n <template\n v-if=\"$slots.empty\"\n #empty\n >\n <slot name=\"empty\" />\n </template>\n\n <!-- Loading -->\n <template\n v-if=\"$slots.loading\"\n #loading\n >\n <slot name=\"loading\" />\n </template>\n\n <!-- Footer -->\n <template\n v-if=\"$slots.footer\"\n #footer\n >\n <slot name=\"footer\" />\n </template>\n </VcDataTable>\n\n <!-- Legacy Filters Panel (reuses VcDropdownPanel for consistent styling) -->\n <VcDropdownPanel\n :show=\"showLegacyFiltersPanel && !!$slots.filters\"\n :anchor-ref=\"legacyFiltersButtonEl\"\n :title=\"$t('COMPONENTS.ORGANISMS.VC_TABLE.GLOBAL_FILTERS.TITLE')\"\n width=\"280px\"\n max-width=\"400px\"\n @update:show=\"showLegacyFiltersPanel = $event\"\n >\n <div class=\"vc-global-filters-panel__content\">\n <slot\n name=\"filters\"\n :close-panel=\"closeLegacyFiltersPanel\"\n />\n </div>\n </VcDropdownPanel>\n </div>\n</template>\n\n<!-- eslint-disable @typescript-eslint/no-explicit-any -->\n<script lang=\"ts\" setup generic=\"T extends Record<string, any>\">\nimport { computed, ref, toValue, watch } from \"vue\";\nimport type { Ref, MaybeRef } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport VcDataTable from \"@ui/components/organisms/vc-data-table/VcDataTable.vue\";\nimport VcColumn from \"@ui/components/organisms/vc-data-table/components/VcColumn.vue\";\nimport { GlobalFiltersButton } from \"@ui/components/organisms/vc-data-table/components\";\nimport { VcDropdownPanel } from \"@ui/components/molecules\";\nimport type {\n TableAction,\n TableEmptyAction,\n DataTablePagination,\n AddRowConfig,\n TableStateConfig,\n} from \"@ui/components/organisms/vc-data-table/types\";\nimport type { ITableColumns, IActionBuilderResult } from \"@core/types\";\nimport type { VirtualElement } from \"@floating-ui/vue\";\n\n// ============================================================================\n// Props — mirrors old VcTable (TableProps) interface\n// ============================================================================\n\nconst props = withDefaults(\n defineProps<{\n columns: ITableColumns[];\n items?: T[];\n itemActionBuilder?: (item: T) => IActionBuilderResult<T>[] | undefined;\n sort?: string;\n multiselect?: boolean;\n disableItemCheckbox?: (item: T) => boolean;\n expanded?: boolean;\n totalLabel?: string;\n totalCount?: number;\n pages?: number;\n currentPage?: number;\n searchPlaceholder?: string;\n searchValue?: string;\n loading?: MaybeRef<boolean>;\n empty?: TableEmptyAction;\n notfound?: TableEmptyAction;\n header?: boolean;\n footer?: boolean;\n activeFilterCount?: number;\n selectedItemId?: MaybeRef<string>;\n pullToReload?: boolean;\n resizableColumns?: boolean;\n reorderableColumns?: boolean;\n reorderableRows?: boolean;\n stateKey: string;\n selectAll?: boolean;\n enableItemActions?: boolean;\n paginationVariant?: \"default\" | \"minimal\";\n selectionItems?: T[];\n disableFilter?: boolean;\n columnSelector?: \"auto\" | \"defined\" | Ref<ITableColumns[]> | ITableColumns[] | (() => ITableColumns[]);\n noHeaderCheckbox?: boolean;\n variant?: \"default\" | \"striped\" | \"bordered\";\n editing?: boolean;\n addNewRowButton?: { show: boolean; title: string };\n }>(),\n {\n items: () => [] as any,\n sort: undefined,\n multiselect: false,\n disableItemCheckbox: undefined,\n expanded: true,\n totalLabel: undefined,\n totalCount: undefined,\n pages: undefined,\n currentPage: 1,\n searchPlaceholder: undefined,\n searchValue: undefined,\n loading: false,\n empty: undefined,\n notfound: undefined,\n header: true,\n footer: true,\n activeFilterCount: 0,\n selectedItemId: undefined,\n pullToReload: false,\n resizableColumns: true,\n reorderableColumns: true,\n reorderableRows: false,\n selectAll: false,\n enableItemActions: true,\n paginationVariant: \"default\",\n selectionItems: undefined,\n disableFilter: false,\n columnSelector: \"auto\",\n noHeaderCheckbox: false,\n variant: \"default\",\n editing: false,\n addNewRowButton: undefined,\n itemActionBuilder: undefined,\n },\n);\n\n// ============================================================================\n// Emits — mirrors old VcTable emit signatures\n// ============================================================================\n\nconst emit = defineEmits<{\n (e: \"paginationClick\", page: number): void;\n (e: \"selectionChanged\", values: T[]): void;\n (e: \"search:change\", value: string | undefined): void;\n (e: \"headerClick\", item: ITableColumns): void;\n (e: \"itemClick\", item: T): void;\n (e: \"scroll:ptr\"): void;\n (e: \"row:reorder\", args: { dragIndex: number; dropIndex: number; value: T[] }): void;\n (e: \"select:all\", values: boolean): void;\n (e: \"onEditComplete\", args: { event: { field: string; value: string | number }; index: number }): void;\n (e: \"onAddNewRow\"): void;\n /** Emitted after cell edit completes (alongside onEditComplete), for blur-based recalculations. */\n (e: \"onCellBlur\", args: { row: number | undefined; field: string }): void;\n}>();\n\n// Slots — includes mobile-item for backward compatibility (VcDataTable handles mobile internally)\ndefineSlots<{\n header?: (props: { header: () => null }) => any;\n filters?: (props: { closePanel: () => void }) => any;\n \"mobile-item\"?: (props: { item: T }) => any;\n [key: `header_${string}`]: (props: any) => any;\n [key: `item_${string}`]: (props: { item: T; cell: ITableColumns; index: number }) => any;\n notfound?: (props: any) => any;\n empty?: (props: any) => any;\n footer?: (props: any) => any;\n loading?: (props: any) => any;\n \"search-header-actions\"?: (props: any) => any;\n}>();\n\n// ============================================================================\n// Internationalization\n// ============================================================================\n\nconst { t: $t } = useI18n({ useScope: \"global\" });\n\n// ============================================================================\n// Internal state\n// ============================================================================\n\nconst internalSelection = ref(props.selectionItems ?? []) as Ref<T[]>;\n\n// ============================================================================\n// Legacy Filters Panel (dropdown, teleported to body)\n// ============================================================================\n\nconst showLegacyFiltersPanel = ref(false);\nconst legacyFiltersButtonRef = ref<InstanceType<typeof GlobalFiltersButton> | null>(null);\n\n// VirtualElement wrapper — resolves $el lazily on every floating-ui update so the\n// inner `v-if=\"!bladeLoading\"` swap in VcButton can't leave a stale detached anchor.\n// See VcDataTable.vue for the rationale.\nconst legacyFiltersButtonEl = computed<VirtualElement | null>(() => {\n const inst = legacyFiltersButtonRef.value;\n if (!inst) return null;\n return {\n getBoundingClientRect: () =>\n (inst as unknown as { $el?: HTMLElement }).$el?.getBoundingClientRect() ?? new DOMRect(),\n get contextElement() {\n return (inst as unknown as { $el?: HTMLElement }).$el;\n },\n };\n});\n\nconst closeLegacyFiltersPanel = () => {\n showLegacyFiltersPanel.value = false;\n};\n\n// Sync internalSelection when parent updates selectionItems\nwatch(\n () => props.selectionItems,\n (newVal) => {\n if (newVal) {\n internalSelection.value = [...newVal];\n }\n },\n);\n\n// ============================================================================\n// Computed: Prop mapping (old → new)\n// ============================================================================\n\n// Sort: \"field:DESC\" → sortField + sortOrder\nconst sortFieldValue = computed(() => props.sort?.split(\":\")[0] || undefined);\nconst sortOrderValue = computed<1 | -1 | 0>(() => {\n const dir = props.sort?.split(\":\")[1];\n if (dir === \"ASC\") return 1;\n if (dir === \"DESC\") return -1;\n return 0;\n});\n// Track last known sort field for fallback during sort removal (3rd click).\n// Needed because props.sort may not be bound (parent uses `:sort-expression`\n// which doesn't match the adapter's `sort` prop), so sortFieldValue can be\n// undefined even when a column was actively sorted.\nconst lastSortField = ref<string>();\n\n// Selection\nconst selectionMode = computed<\"single\" | \"multiple\" | undefined>(() => (props.multiselect ? \"multiple\" : undefined));\nconst rowSelectable = computed(() =>\n props.disableItemCheckbox ? (item: T) => !props.disableItemCheckbox!(item) : undefined,\n);\n\n// Row Actions: IActionBuilderResult → TableAction (TableAction extends IActionBuilderResult)\nconst effectiveRowActions = computed<((item: T) => TableAction<T>[]) | undefined>(() => {\n if (!props.enableItemActions || !props.itemActionBuilder) return undefined;\n return (item: T) => (props.itemActionBuilder!(item) ?? []) as TableAction<T>[];\n});\n\n// Pagination\nconst paginationConfig = computed<DataTablePagination | undefined>(() => {\n if (props.footer === false || !props.pages) return undefined;\n return {\n currentPage: props.currentPage ?? 1,\n pages: props.pages,\n variant: props.paginationVariant,\n };\n});\n\n// Columns: filter only by explicit visibility.\n// The expanded/alwaysVisible filtering is handled exclusively by VcDataTable\n// via the showAllColumns prop. Keeping all VcColumn elements mounted ensures\n// that state persistence (column widths/order) is never lost during blade collapse.\nconst effectiveColumns = computed(() => props.columns.filter((col) => col.visible !== false));\n\n// NotFound state detection\nconst _isNotFoundState = computed(\n () => props.items.length === 0 && (!!props.searchValue || (props.activeFilterCount ?? 0) > 0),\n);\n\n/** Map legacy TableEmptyAction → TableStateConfig for VcDataTable */\nconst mappedEmptyState = computed<TableStateConfig | undefined>(() => {\n if (!props.empty) return undefined;\n return {\n icon: props.empty.icon,\n title: typeof props.empty.text === \"string\" ? props.empty.text : toValue(props.empty.text),\n actionLabel: props.empty.action\n ? typeof props.empty.action === \"string\"\n ? props.empty.action\n : toValue(props.empty.action)\n : undefined,\n actionHandler: props.empty.clickHandler,\n };\n});\n\nconst mappedNotFoundState = computed<TableStateConfig | undefined>(() => {\n if (!props.notfound) return undefined;\n return {\n icon: props.notfound.icon,\n title: typeof props.notfound.text === \"string\" ? props.notfound.text : toValue(props.notfound.text),\n actionLabel: props.notfound.action\n ? typeof props.notfound.action === \"string\"\n ? props.notfound.action\n : toValue(props.notfound.action)\n : undefined,\n actionHandler: props.notfound.clickHandler,\n };\n});\n\n// Loading: unwrap MaybeRef\nconst loadingValue = computed(() => toValue(props.loading) ?? false);\n\n// Add row\nconst addRowConfig = computed<AddRowConfig | undefined>(() => {\n if (!props.addNewRowButton?.show) return undefined;\n return {\n enabled: true,\n label: props.addNewRowButton.title,\n position: \"footer\" as const,\n };\n});\n\n// Edit mode: legacy editing=true → all editable cells are always inputs (inline mode)\nconst editModeValue = computed<\"inline\" | undefined>(() => (props.editing ? \"inline\" : undefined));\n\n// Search: show search bar when header is true\nconst showSearch = computed(() => props.header !== false);\n\n// Column switcher mapping\nconst columnSwitcherValue = computed<boolean | \"auto\" | \"defined\">(() => {\n if (props.columnSelector === \"auto\") return \"auto\";\n if (props.columnSelector === \"defined\") return \"defined\";\n // Other types (Ref<ITableColumns[]>, ITableColumns[], fn) — just enable auto mode\n if (props.columnSelector) return \"auto\";\n return false;\n});\n\n// ============================================================================\n// Type mappers (old column types → new VcColumn types)\n// ============================================================================\n\ntype VcColumnCellType =\n | \"text\"\n | \"number\"\n | \"money\"\n | \"date\"\n | \"date-ago\"\n | \"time\"\n | \"datetime\"\n | \"image\"\n | \"link\"\n | \"html\"\n | \"status\"\n | \"status-icon\";\n\nfunction mapColumnType(type: string | undefined): VcColumnCellType | undefined {\n if (!type) return undefined;\n // Old ITableColumnsBase uses \"date-time\", VcColumn uses \"datetime\"\n if (type === \"date-time\") return \"datetime\";\n return type as VcColumnCellType;\n}\n\nfunction mapColumnAlign(align: string | undefined): \"start\" | \"center\" | \"end\" | undefined {\n if (!align) return undefined;\n // Old type has extra values like \"between\" | \"around\" | \"evenly\" — not supported in VcColumn\n if (align === \"start\" || align === \"center\" || align === \"end\") return align;\n return undefined;\n}\n\n// Legacy mobilePosition includes \"image\" | \"status\" which are now separate mobileRole values\nfunction mapMobileRole(mobilePosition: string | undefined): \"image\" | \"status\" | \"field\" | \"title\" | undefined {\n if (mobilePosition === \"image\") return \"image\";\n if (mobilePosition === \"status\") return \"status\";\n if (mobilePosition === \"top-left\") return \"title\";\n // Grid positions (\"top-left\", etc.) map to \"field\" role\n if (mobilePosition) return \"field\";\n return undefined;\n}\n\nfunction mapMobilePosition(\n mobilePosition: string | undefined,\n): \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\" | undefined {\n if (\n mobilePosition === \"top-left\" ||\n mobilePosition === \"top-right\" ||\n mobilePosition === \"bottom-left\" ||\n mobilePosition === \"bottom-right\"\n ) {\n return mobilePosition;\n }\n return undefined;\n}\n\n// ============================================================================\n// Event Handlers\n// ============================================================================\n\n// Sort → headerClick: find the column, emit legacy event.\n// When sort is removed (3rd click), event.sortField is undefined — fall back to\n// the current prop value which still holds the previously sorted column (parent\n// hasn't updated yet). This lets the parent advance its own asc→desc→none cycle.\n//\n// IMPORTANT: We encode VcDataTable's sort direction into the column ID so the\n// parent's handleSortChange receives e.g. \"name:DESC\" and sets the direction\n// directly instead of independently cycling its own asc→desc→none state.\n// Without this, both VcDataTable and the parent advance their sort cycles\n// independently on each click, causing a one-step misalignment between the\n// displayed sort icon and the actual data sort order.\nfunction handleSort(event: { sortField?: string; sortOrder?: number }) {\n // Remember the last sorted field so we can identify it during sort removal\n // (when event.sortField is undefined on the 3rd click).\n if (event.sortField) {\n lastSortField.value = event.sortField;\n }\n\n const field = event.sortField ?? lastSortField.value ?? sortFieldValue.value;\n if (field) {\n const col = props.columns.find((c) => (c.field || c.id) === field);\n if (col) {\n // Encode direction so parent sets it directly (no independent cycling)\n let sortId = col.id;\n if (event.sortOrder === 1) sortId = `${col.id}:ASC`;\n else if (event.sortOrder === -1) sortId = `${col.id}:DESC`;\n // sortOrder=0 (removal) → bare ID → parent cycles from DESC to clear\n emit(\"headerClick\", { ...col, id: sortId });\n }\n }\n\n // Clear tracked field after sort removal so it doesn't leak to future sorts\n if (event.sortOrder === 0) {\n lastSortField.value = undefined;\n }\n}\n\n// Selection → selectionChanged\nfunction handleSelectionUpdate(items: T | T[]) {\n const arr = Array.isArray(items) ? items : [items];\n internalSelection.value = arr;\n emit(\"selectionChanged\", arr);\n}\n\n// Row click → itemClick\nfunction handleRowClick(event: { data: T }) {\n emit(\"itemClick\", event.data);\n}\n\n// Pagination → paginationClick\nfunction handlePaginationClick(page: number) {\n emit(\"paginationClick\", page);\n}\n\n// Search → search:change (used for both @search and @update:search-value)\nfunction handleSearchChange(value: string) {\n emit(\"search:change\", value || undefined);\n}\n\n// Row reorder → row:reorder\nfunction handleRowReorder(event: { dragIndex: number; dropIndex: number; value: T[] }) {\n emit(\"row:reorder\", event);\n}\n\n// Pull refresh → scroll:ptr\nfunction handlePullRefresh() {\n emit(\"scroll:ptr\");\n}\n\n// Cell edit → onEditComplete + onCellBlur\nfunction handleCellEditComplete(event: { data: T; field: string; newValue: unknown; index: number }) {\n emit(\"onEditComplete\", {\n event: { field: event.field, value: event.newValue as string | number },\n index: event.index,\n });\n emit(\"onCellBlur\", { row: event.index, field: event.field });\n}\n\n// Select all → select:all\nfunction handleSelectAll(value: boolean) {\n emit(\"select:all\", value);\n}\n\n// Add row → onAddNewRow\n// Cancel VcDataTable's internal inlineEdit.addRow() because the parent manages items directly.\nfunction handleAddRow(event: { defaults: Record<string, unknown>; cancel: () => void }) {\n event.cancel();\n emit(\"onAddNewRow\");\n}\n</script>\n\n<style lang=\"scss\">\n.vc-table-adapter {\n @apply tw-flex tw-flex-col tw-grow tw-basis-0 tw-overflow-hidden;\n}\n</style>\n"],"names":["LOCALE_SHORTCUTS","TOKEN_MAP","convertMomentFormat","momentFormat","result","moment","dateFns","pattern","replacement","localeCache","enUS","resolveLocale","localeCode","mod","dateFnsKey","locale","base","resolveLocaleSync","toDate","value","d","formatDateRelative","date","formatDistanceToNow","formatDateWithPattern","momentFormatStr","dateFnsFormat","format","formatBadgeCount","num","getThumbnailUrl","url","size","lastSlash","queryIndex","dotIndex","extensionDot","rest","getBestThumbnailSize","displaySize","SEVERITY_TIMEOUTS","NotificationContextKey","EXCLUDED_NOTIFICATION_TYPES","resolveSeverity","toast","msg","resolveToastKey","config","type","groupValue","defaultIsComplete","createToastController","activeToasts","handle","message","severity","handleAuto","handleProgress","timeout","notification","toastConfig","key","active","completedType","toastId","logger","createLogger","createNotificationStore","options","registry","history","ref","realtime","subscribers","subscriberCounter","broadcastFilter","toastHandle","notificationsClient","PushNotificationClient","unreadCount","computed","n","hasUnread","registerType","ingest","opts","effectiveIsNew","existingIdx","x","existing","existingRtIdx","existingRt","sub","markAsRead","inHistory","inRealtime","markAllAsRead","e","loadHistory","take","criteria","subscribe","id","getByType","setBroadcastFilter","fn","clearBroadcastFilter","_singleton","useNotificationStore","getCurrentInstance","injected","inject","NotificationStoreKey","createBladeMessaging","bladeStack","_exposedMethods","exposeToChildren","bladeId","methods","callParent","callerBladeId","method","args","callerBlade","parentMethods","cleanup","useBladeMessaging","messaging","BladeMessagingKey","__registerBladeConfig","name","getBladeConfig","getAllBladeConfigs","TableQueryStateKey","encodeQueryState","ns","patch","out","SORT_RE","decodeQueryState","query","res","sort","search","pageRaw","DEBOUNCE_MS","normalizeSegment","createBladeQueryState","deps","descriptor","router","syncUrlReplace","createUrlSync","pending","timer","resolveNs","tableKey","read","decoded","write","namespace","p","_createElementBlock","__props","_createElementVNode","navigateToMainRoute","params","routes","mainRoute","r","mainRouteAlias","BladeRegistryKey","isValidBladeComponent","component","createBladeRegistry","app","registeredBladesInternal","shallowRef","_routeIndex","_normalizeRoute","route","registerBlade","registrationData","allowOverwrite","isWorkspace","routable","permissions","menuItem","newMap","existingGlobalComponent","mergedData","addMenuItem","getBlade","getBladeComponent","registration","globalComponent","error","getBladeByRoute","normalized","data","useBladeRegistry","ErrorInterceptor","_Interceptor","props","emit","__emit","bladeRegistry","maximized","banners","bladeInstanceRef","bladeComponent","provide","BladeDescriptorKey","BladeRenderingStateKey","BladeMaximizedKey","BladeBannersKey","BladeBackButtonKey","useRouter","useBladeStack","watch","instance","onBeforeUnmount","onCloseBlade","onParentCall","onExpand","onCollapse","_createBlock","_unref","_withCtx","resetInterceptor","_withDirectives","_openBlock","_resolveDynamicComponent","ButtonGroupKey","toRef","groupClass","_renderSlot","_ctx","resolvedTitle","toValue","onClick","_normalizeClass","VcIcon","_hoisted_1","_hoisted_2","measureNaturalWidth","element","originalFlexShrink","styles","width","readContainerGap","container","gap","useAdaptiveItems","containerRef","items","getItemKey","moreButtonFallbackWidth","calculationStrategy","initialItemWidth","containerWidth","useElementSize","itemSizes","measuredMoreWidth","containerGap","visibleItems","hiddenItems","showMoreButton","elementsObserver","observedElements","getMoreButtonWidth","measureMoreButton","el","getItemWidth","item","distributeItems","itemsToCheck","availableWidth","currentWidth","visible","hidden","itemWidth","gapBefore","calculateVisibleItems","effectiveMoreWidth","gapBeforeMore","measureElementSizes","cleanupSizeCache","currentKeys","setupElementsObserver","entries","hasChanges","entry","borderBoxWidth","nextTick","elements","newElements","debouncedCalculate","useDebounceFn","prevWidth","onMounted","useCollapsible","collapsedHeight","maxExpandedHeight","contentRef","contentHeight","isExpanded","hasOverflow","hasScroll","wrapperStyle","toggle","useResizeObserver","useTableSort","currentSortProperty","currentSortDirection","currentSort","newState","sortExpression","sortParam","newSortProperty","newSortDirection","parts","dir","useTableSelection","idField","getItemId","selectedItems","allSelected","selectedIds","selectionCount","hasSelection","selectedIdSet","selected","ids","idsToRemove","directionToOrder","orderToDirection","order","useDataTableSort","initialField","initialOrder","sortField","sortOrder","service","restored","field","useDataTablePagination","pageSize","currentPage","pages","skip","totalCount","goToPage","page","setPage","reset","reactive","useTableSearch","searchValue","stateKey","panelId","isMobile","useResponsive","referenceEl","floatingEl","focusedIndex","teleportTarget","useTeleportTarget","shouldTeleport","isOpen","y","resolvedPlacement","resolvedStrategy","useFloatingPosition","panelClasses","panelStyle","normalizedMaxHeight","itemRole","activeDescendantId","itemId","outsideClickBinding","closeByReason","syncFocusedIndex","activeIndex","index","open","close","reason","selectItem","moveFocus","nextIndex","total","normalizedIndex","onPanelKeydown","event","onDocumentEscapeKeydown","opened","$slots","_Teleport","_createVNode","_Transition","_normalizeStyle","_hoisted_3","_Fragment","_renderList","$event","_createTextVNode","_toDisplayString","_hoisted_5","MORE_BUTTON_WIDTH","INITIAL_ITEM_WIDTH","showBreadcrumbs","adaptive","recalculate","toggleBreadcrumbs","onItemClick","$t","VcDropdown","_cache","isActive","VcButton","click","VcDropdownItem","i","_hoisted_4","VcBreadcrumbsItem","_mergeProps","buttonRef","onLongPress","hideBreadcrumbs","VcBreadcrumbs","OnLongPress","useBreadcrumbs","trimAfter","push","breadcrumb","wrapped","existingIndex","updated","remove","t","useI18n","breadcrumbs","blades","activeBlade","hasBlades","bladeCount","b","aiAgentService","AiAgentServiceKey","isAiPanelExpanded","visibleBladesCount","isBladeVisible","watchDebounced","newVal","bc","visibleIndex","targetBlade","prevented","onClose","mobileBackButtonFor","h","VcMobileBackButton","blade","VcBladeSlot","RouterView","PopupPluginKey","popupPluginInstance","createBackendRegistry","impl","setPopupPluginInstance","createKeyedBackendRegistry","registerPopupPreset","preset","getPopupPreset","popupTitleId","pendingDismissReason","variantMeta","isVisible","canCloseOnOverlay","canCloseOnEscape","icon","iconStyle","isMobileView","emitClose","closeFromAction","handleEscapeKeydown","handleDialogDismiss","TransitionRoot","Dialog","TransitionChild","DialogPanel","DialogTitle","getPopupPlugin","popupPlugin","sanitizeHtml","html","DOMPurify","popup","slot","VcPopupContainer","_PopupContainer","usePopupInternal","usePopup","popupInstance","rawPopup","createInstance","unref","destroy","confirmation","popupInstanceInternal","resolveInstance","customInstance","pushInstance","instanceToClose","showSimplePopup","title","showConfirmation","warningComponent","resolve","showError","errorComponent","showInfo","infoComponent","createComponent","slots","slotName","slotContent","markRaw","renderingState","tooltipVisible","tooltipIconRef","tooltipRef","floatingStyle","shift","VcSkeleton","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","customPositionStyle","bladeLoading","useBladeLoading","cardBodyId","useId","isCollapsedInternal","onHeaderClick","$attrs","VcCard","_Card","VcContainer","_Container","ensureHttps","urlObject","thumbnailSrc","useFallback","resolvedSrc","img","imageHandler","secureUrl","onClickFn","VcLink","_Link","VcLoading","_Loading","clampedValue","VcProgress","_Progress","sandbox","extra","VcLabel","truncateCount","VcBadge","VcWidget","_Widget","useSlots","normalizeVariant","variant","normalizedVariant","hasTitle","hasContent","isTitleOnly","showTrigger","isCollapsed","resolveVisibility","bladeInstance","isRef","resolveReactiveBoolean","resolveTitle","resolveIcon","isItemDisabled","getStaggerStyle","openMenu","closeMenu","handlePrimaryClick","handleItemClick","isWaiting","isDisabled","resolvedIcon","handleClick","isMenuOpen","toolbarContentRef","updateObserver","ToolbarBaseButton","languageToCountryMap","PROP_ITEM_ID_PREFIX","useToolbarRegistration","hasAccess","usePermissions","registerToolbarItem","unregisterToolbarItem","getToolbarItems","updateToolbarItem","useToolbar","currentBladeId","useBlade","FALLBACK_BLADE_ID","registeredItemIds","registrationBladeId","convertToToolbarItem","activeBladeId","updateItems","nextRegisteredIds","toolbarItem","clearToolbarItems","targetBladeId","a","priorityA","newBladeId","oldBladeId","ToolbarMobile","ToolbarDesktop","useBladeError","hasError","shortErrorMessage","err","errorDetails","copyError","text","ERROR_BANNER_ID","MODIFIED_BANNER_ID","BannerRenderSlot","defineComponent","bannersRef","BladeStackKey","errorContentRef","isErrorExpanded","errorWrapperStyle","toggleError","copied","errorDetailsText","handleCopy","has","idx","VARIANT_PRIORITY","sortedBanners","variantIcon","dismissBanner","banner","_TransitionGroup","_withModifiers","useWidgets","WidgetServiceKey","InjectionError","widgetService","WidgetScopeKey","trigger","useHeadlessWidgetHelpers","resolveBadge","widget","badge","resolveLoading","loading","resolveDisabled","disabled","handleHeadlessClick","showToolbar","displayedItems","overflowItems","WidgetScope","_toHandlers","FOCUSABLE_SELECTOR","SCROLL_LOCK_KEY","getScrollLockState","win","acquireBodyScrollLock","state","body","documentElement","scrollbarWidth","releaseBodyScrollLock","panelEl","sideEffectsActive","lastFocusedElement","titleId","panelWidths","panelHeights","normalizedWidth","normalizedHeight","hasHeader","hasFooter","isBottom","isFullSize","panelTransitionName","containerStyle","ariaDialogLabel","ariaDialogLabelledBy","handleOverlayClick","touchStartY","isDragging","handleTouchStart","handleTouchMove","delta","handleTouchEnd","panelHeight","threshold","getFocusableElements","style","isRedirectingFocus","focusFirstFocusable","firstFocusable","handleDocumentFocusIn","handleDocumentKeydown","focusables","first","last","restoreFocus","elementToFocus","activateSideEffects","deactivateSideEffects","__expose","showOverflow","isAnyVisible","VcSidebar","normalizedBladeId","bladeName","registeredExternalWidgetIds","registerExternalWidgets","externalWidget","unregisterExternalWidgets","widgetId","onUnmounted","widgets","visibleWidgets","WidgetContainerMobile","WidgetContainerDesktop","createLanguageService","savedLocale","useLocalStorage","resolveSupportedLocale","normalizedLocale","i18n","currentLocale","setLocale","resolvedLocale","localeMessages","veeValidate","localize","setVeeI18nLocale","getLocaleByTag","localeTag","twoLetterLanguageName","displayName","ISO6391","resolveCamelCaseLocale","getCountryCode","language","getFlag","countryCode","__vite_glob_0_0","__vite_glob_0_1","__vite_glob_0_2","__vite_glob_0_3","__vite_glob_0_4","__vite_glob_0_5","__vite_glob_0_6","__vite_glob_0_7","__vite_glob_0_8","__vite_glob_0_9","__vite_glob_0_10","__vite_glob_0_11","__vite_glob_0_12","__vite_glob_0_13","__vite_glob_0_14","__vite_glob_0_15","__vite_glob_0_16","__vite_glob_0_17","__vite_glob_0_18","__vite_glob_0_19","__vite_glob_0_20","__vite_glob_0_21","__vite_glob_0_22","__vite_glob_0_23","__vite_glob_0_24","__vite_glob_0_25","__vite_glob_0_26","__vite_glob_0_27","__vite_glob_0_28","__vite_glob_0_29","__vite_glob_0_30","__vite_glob_0_31","__vite_glob_0_32","__vite_glob_0_33","__vite_glob_0_34","__vite_glob_0_35","__vite_glob_0_36","__vite_glob_0_37","__vite_glob_0_38","__vite_glob_0_39","__vite_glob_0_40","__vite_glob_0_41","__vite_glob_0_42","__vite_glob_0_43","__vite_glob_0_44","__vite_glob_0_45","__vite_glob_0_46","__vite_glob_0_47","__vite_glob_0_48","__vite_glob_0_49","__vite_glob_0_50","__vite_glob_0_51","__vite_glob_0_52","__vite_glob_0_53","__vite_glob_0_54","__vite_glob_0_55","__vite_glob_0_56","__vite_glob_0_57","__vite_glob_0_58","__vite_glob_0_59","__vite_glob_0_60","fallbackLanguageService","getOrCreateFallbackLanguageService","provideLanguages","hasInjectionContext","existingService","LanguageServiceKey","useLanguages","languageService","provideAppBarWidget","AppBarWidgetServiceKey","createAppBarWidgetService","getCurrentScope","onScopeDispose","appBarWidgetBus","useAppBarWidget","STORAGE_KEY_PREFIX","HOVER_DELAY","getStorageKey","appName","useMenuExpanded","isHoverExpanded","expandTimeout","toggleExpanded","toggleHoverExpanded","shouldExpand","SIDEBAR_STATE_KEY","provideSidebarState","isPinned","togglePin","useSidebarState","PRESET_TO_LABEL","PRESET_TO_COLOR","PRESETS_TO_IGNORE","FALLBACK_COLOR","detectThemePreset","input","s","resolveEnvironment","hostString","fallbackHost","environmentName","isIgnored","color","resolveHostString","_createEnvironmentNameLogic","useEnvironmentName","createSharedComposable","bladeForm","BladeFormKey","effectiveModified","bladeTitleId","showSkeleton","BladeLoadingKey","_useSlots","isDesktop","bladeFull","hasBladeContext","maximizedRef","isClosable","attrs","useAttrs","rootAttrs","_class","_style","_onClose","handleClose","handleExpand","handleCollapse","backButton","setBladeTitle","watchEffect","bladeRef","BladeHeader","BladeStatusBanners","BladeToolbar","WidgetContainer","submit","VcForm","_Form","textareaId","labelId","errorId","hintId","invalid","resolvedDisabled","ariaRequired","ariaDescribedBy","useFormField","textareaRef","isFocused","onInput","newValue","VcHint","formattedValue","val","copyIcon","onCopy","onLinkClick","_createSlots","uid","triggerId","isExpandedInternal","hasScrollInExpandedState","contentWrapperStyle","expandedItems","isItemExpanded","handleToggle","expanded","emitModelValue","initializeExpandedItems","VcAccordionItem","VcAccordion","_Accordion","_AccordionItem","fieldId","resolvedName","groupContext","internalRules","veeErrorMessage","handleChange","validate","useField","resolvedErrorMessage","uploader","upload","fileList","toggleUploader","onDrop","dragLeave","dragOver","$emit","isDropdown","isButton","handleAction","handleDropdownChange","target","option","opt","VcEditorButton","showSizeDropdown","customSize","fontSizes","currentFontSize","toggleSizeDropdown","selectFontSize","selectCustomFontSize","closeDropdown","handleClickOutside","toolbarItems","sortedCustomButtons","groupA","groupB","orderA","orderB","setLink","previousUrl","triggerImageUpload","VcEditorFontSelector","customButton","VcEditorCustomButton","isFullscreen","imageInput","detectedType","filteredToolbar","characterCount","isNearLimit","detectContentType","content","htmlPatterns","markdownPatterns","htmlScore","markdownScore","matches","extensions","baseExtensions","StarterKit","Underline","TextStyle","FontSize","Table","TableRow","TableHeader","TableCell","Link","Image","Placeholder","Markdown","customNames","ext","formattedSource","beautify","previewContent","htmlContent","editor","editorMode","currentMode","togglePreview","toggleSourceView","toggleSideBySideView","settingContentFromProp","useEditor","tipTapEditor","output","handleSourceInput","handleImageSelection","files","formData","file","VcEditorToolbar","EditorContent","_hoisted_12","TIME_BEFORE_UNMOUNT","SWIPE_THRESHOLD","types","toRefs","toastRef","mounted","removed","yPosition","isFront","Timer","resizeObserver","reportHeight","originalHeight","height","callback","delay","timerId","from","remaining","pause","resume","start","clear","onMouseEnter","onMouseLeave","swipeStartX","swipeStartY","isSwiping","swipedOut","dragStartTime","onPointerDown","onPointerMove","deltaX","deltaY","onPointerUp","swipeAmountX","timeTaken","velocity","direction","MAX_PAGES_MOBILE","MAX_PAGES_DESKTOP","localCurrentPage","effectiveShowFirstLast","pageNumber","pagesToShow","totalPages","current","maxPages","end","VcPagination","_Pagination","modules","Navigation","buttonsList","Swiper","slide","SwiperSlide","VcSlider","_Slider","triggerRef","onInputBlur","_withKeys","_hoisted_13","dropdownElRef","searchInputRef","viewportRef","canScrollUp","canScrollDown","scrollAnimationId","updateScrollState","startScroll","stopScroll","speed","tick","onDropdownWheel","atTop","atBottom","vOnClickOutside","useMultivalueMode","isDictionaryMode","htmlInputType","useMultivalueValues","formatValue","label","removeAtIndex","clearAll","addItem","useMultivalueInput","inputValue","onInputSubmit","hexColor","convertColorNameToHex","onKeyDown","allowedKeys","useMultivalueColor","colorPickerRefs","setColorPickerRef","openColorPicker","handleColorChange","updatedValues","useMultivalueDropdown","isOpened","dropdownToggleRef","dropdownRef","searchRef","sameWidth","rects","popper","flip","offset","dropdownStyle","keyboardNavigation","useKeyboardNavigation","openDropdown","toggleDropdown","useMultivalueOptions","currentOptions","currentValue","valueKey","listboxId","triggerComponentRef","dropdownComponentRef","availableOptions","onItemSelect","onSearch","MultivalueTrigger","scope","MultivalueDropdown","radioId","checked","isEqual","onChange","model","describedBy","ariaLabelledBy","InputGroupContextKey","generatedName","onUpdate","getOptionKey","VcInputGroup","VcRadioButton","checkboxId","checkboxRef","modelVal","normalizedModelValue","VcCheckbox","switchId","hintText","invertValue","panelAnchorRegistry","floatingRef","registeredPanelEl","anchorRefAsRef","anchorEl","availableHeight","registerPanel","panel","unregisterPanel","handlePointerDownOutside","enclosingPanel","enclosingAnchor","selectDropdown","handleKeydown","newShow","VcMenuExpandedKey","skeletonSections","section","sIdx","iIdx","child","cIdx","injectedExpanded","menuExpanded","abbreviation","word","badgeVisible","c","VcTooltip","storageKey","VcMenuItem","VcMenu","_VcMenu","_VcMenuItem","VcMenuGroup","_VcMenuGroup","useImageLoad","src","isLoaded","onLoad","onError","imageState","onImageError","onTileClick","deactivate","currentLanguageOption","onTriggerClick","ShellIndicatorsKey","stripTenantPrefix","firstParam","tenant","useMenuActiveState","useRoute","urlValue","path","menuItems","menuBadges","useMenuService","hasAccessToItem","accessibleChildren","visibleMenuItems","filteredMenuItems","children","matchedChildren","getGroupId","isItemActive","resolveRawBadge","rawContent","isDot","resolvedBadges","resolveForItem","resolved","user","useUserManagement","$te","useSettingsMenu","groupedItems","groups","groupName","groupItems","group","groupIndex","SettingsMenu","isMenuOpened","CloseSettingsMenuKey","UserInfo","VcDropdownPanel","UserSidebar","UserDropdownButton","_UserDropdownButton","isEmbedded","EmbeddedModeKey","scrollContainer","searchQuery","handleMenuItemClick","VcInput","VcScrollableContainer","VcAppMenu","useToggleableContent","itemsGetter","activeIdRef","currentItem","isAnyItemVisible","useAppBarWidgets","activeWidgetId","useAppBarState","showWidget","hideAllWidgets","toggleWidget","currentWidget","isAnyWidgetVisible","useAppHub","normalizedQuery","hasQuery","accessibleApps","filteredApps","filteredWidgets","getWidgetTitle","humanizeWidgetId","char","widgetProps","PROGRESSIVE_RENDER_THRESHOLD","INITIAL_RENDER_BATCH_SIZE","RENDER_BATCH_SIZE","LOAD_MORE_TRIGGER_OFFSET","hasCustomApplicationsSlot","appsScrollContainerRef","widgetsScrollContainerRef","appsRenderLimit","widgetsRenderLimit","shouldProgressiveRenderApps","shouldProgressiveRenderWidgets","visibleApps","length","progressive","refreshScrollState","resolveScrollViewport","viewport","previousViewport","handleAppsScroll","handleWidgetsScroll","normalizeIconUrl","isAppActive","currentPath","normalizePath","appPath","handleSwitchApp","getAppTestId","maybeExtendRenderLimit","handleWidgetClick","isWidgetActive","isBadgeActive","_hoisted_14","AppBarWidgetContent","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","nextValue","AppHubContent","applicationsScope","MINUTE","HOUR","DAY","pushTime","created","now","diffSec","absDiffSec","rtf","NotificationTemplate","_NotificationTemplate","store","currentTemplate","notifications","NotificationItem","NotificationDropdown","_NotificationDropdown","sidebar","appHubAnchorRef","isNotificationsOpen","notificationAnchorRef","showHeader","handleToggleMenu","handleToggleNotifications","handleAppHubVisibility","SidebarCollapseButton","SidebarHeader","SidebarContent","menuScope","footerScope","AppHubPopover","slotAppsList","slotSwitchApp","createAppBarMobileButtonsService","registeredButtonsState","registeredButtons","register","button","existingButtonIndex","unregister","buttonId","getButton","getButtons","provideAppBarMobileButtonsService","AppBarMobileButtonsServiceKey","useAppBarMobileButtons","useAppBarMobileActions","activeMobileActionId","showAction","hideAllActions","toggleAction","currentAction","isAnyActionVisible","closeAction","newButtons","activeButton","handleButtonClick","wrapperComponent","wrapperProps","_normalizeProps","_guardReactiveProps","MENU_TAB_INDEX","HUB_TAB_INDEX","GESTURE_LOCK_THRESHOLD","SWIPE_DISTANCE_RATIO","SWIPE_VELOCITY_THRESHOLD","MAX_DRAG_RATIO","BOUNDARY_RESISTANCE_RATIO","SLIDER_TRANSITION","widgetItems","hasWidgetBadge","showHubTab","showTabs","dragOffsetX","sliderViewportRef","gestureState","touchStartX","lastTouchX","touchStartTime","sliderStyle","baseTranslate","viewportWidth","dragTranslate","indicatorStyle","dragProgress","setActiveIndex","resetDragState","getRubberBandOffset","dimension","absoluteOffset","resistedOffset","getDragOffset","isLeadingBoundary","isTrailingBoundary","maxDragDistance","onTouchStart","touch","onTouchMove","absDeltaX","absDeltaY","onTouchEnd","duration","distanceThreshold","viewTitle","currentTitle","lastBladeTitle","AppBarMobileActions","MenuSidebar","PLATFORM_LOCALE_STORAGE_KEY","usePlatformLocaleSync","platformLocale","apply","hasSubmenu","isSubmenuOpen","handleTriggerClick","VcImage","availableLocales","getLocaleMessage","languageItems","lang","currentLanguageName","l","handleLanguageSelect","SettingsMenuItem","LanguageSelector","_LanguageSelector","currentThemeKey","currentLocalizedName","themes","setTheme","useTheme","handleThemeSelect","theme","changeUserPassword","validatePassword","signOut","useForm","isValid","useIsFormValid","isDirty","useIsFormDirty","form","cancelChange","changePassword","VcPopup","VcStatus","Field","errorMessage","errors","ChangePassword","_ChangePassword","closeSettingsMenu","closeBlade","handleLogout","activeChild","useShellBootstrap","settingsMenuService","SettingsMenuServiceKey","mobileButtons","provideDashboardService","InternalRoutesKey","DynamicModulesKey","provideAiAgentService","useShellDefaults","ctx","notificationStore","ThemeSelector","ChangePasswordButton","LogoutButton","useShellNavigation","openBlade","itemUrl","menuRoute","staticSegments","itemSegment","openRoot","appsList","getApiClient","AppsClient","getApps","client","switchApp","useShellLifecycle","isAppReady","isBootstrapped","isAuthenticated","isReady","isAuth","hasBladeNavigation","appRootRef","AppRootElementKey","provideAppBarState","internalRoutes","BladeRoutesKey","dynamicModules","aiAgentConfig","aiAgentAddGlobalToolbarButton","modulesLoadError","ModulesLoadErrorKey","isEnvironmentIgnored","environmentColor","VcEnvironmentBanner","DesktopLayout","MobileLayout","headerScope","VcBladeNavigation","VcAiAgentPanel","useBadge","badgeConfig","routeId","groupId","resolvedRouteId","resolvedGroupId","displayContent","numValue","appRootEl","toggleContent","nextState","AppBarWidgetItem","version","logoLoaded","bgLoaded","te","initialOptions","internalProperty","internalModel","measurementOptions","measurementLoading","measureUnit","cloneDeep","measurementSymbol","displaySymbol","localizedSymbol","computedProperty","rules","propertyDisplayName","propertyDisplayNameLocalized","optionLabelField","colorCode","getOptions","getMeasurements","onUpdateUnit","newUnitOfMeasureId","keyword","measurements","firstVal","defaultValue","VcSelect","VcMultivalue","VcTextarea","VcSwitch","VcInputDropdown","resolvedActions","VcImageTile","swiperModules","Mousewheel","FreeMode","Grid","prevRef","nextRef","swiperInstance","onSwiperInit","swiper","onSwiperResize","onSlidesUpdated","isLoading","prevImageCount","newCount","image","localIndex","mainModules","Keyboard","thumbModules","mainSwiper","thumbSwiper","currentImage","onMainSwiperInit","onThumbSwiperInit","onMainSlideChange","slideTo","slidePrev","slideNext","onThumbImageError","fallbackUrl","onCopyLink","link","fullLink","handleKeyDown","scrollLock","useScrollLock","useGalleryPreview","images","previewIndex","VcGalleryPreview","openPreview","imagesArray","preview","placeholderText","onPreviewClick","VcFileUpload","useGalleryReorder","galleryRef","draggedId","disableDrag","sortableInstance","edgeInterval","mouseX","startEdgeDetection","EDGE_THRESHOLD","rect","stopEdgeDetection","createSortable","destroySortable","Sortable","evt","arr","moved","sorted","IMAGE_EXT_RE","isImageFile","useGalleryUpload","onUpload","imageFiles","currentImages","existingNames","uploadedFiles","fileName","baseName","dt","f","lastSortOrder","useGalleryFilmstrip","swiperRef","toggleExpand","checkOverflow","isLegacySingleImageMode","legacyPlaceholder","localImages","hasImages","uploadCustomText","reorder","filmstrip","step","currentTranslate","minTranslate","maxTranslate","tileThumbnailSizeMap","resolvedThumbnailSize","fileInputRef","onHeaderUploadClick","onFileInputChange","isDragOver","dragCounter","onGlobalDragEnter","onGlobalDragLeave","onGlobalDrop","VcImageUpload","VcGalleryFilmstrip","VcGalleryItem","context","TableContextKey","tableContext","fillerWidth","FillerWidthKey","isColumnReordering","IsColumnReorderingKey","isClickable","actionsCellRole","handleSpacePress","handleMouseEnter","handleMouseLeave","ariaSort","cellStyle","handleSort","isResizing","handleResizerMouseDown","handleMouseUp","handleMouseDown","handleDragStart","handleDragOver","handleDragLeave","handleDrop","DEFAULT_LINE_CLAMP","effectiveLineClamp","contentClasses","clamp","contentStyle","isColumnVisible","columnId","toggleColumn","currentVisible","newVisible","handleShowAll","handleReset","column","isBackdropVisible","referenceRef","triggerBtnRef","isActionsVisible","visibleActions","action","isDropdownMode","quickActions","overflowActions","showDropdownTrigger","handleActionClick","focusFirstItem","openAndFocusFirst","handleDropdownKeydown","currentIndex","next","prev","handleEscape","escapeListenerAttached","attachEscapeListener","detachEscapeListener","isChecked","boolValue","allSelectedText","currentPageSelectedText","selectAllItemsText","cancelText","isFilterOpen","handleInput","toggleFilter","closeFilter","filterRef","overlayRef","inputRef","localValue","localStartDate","localEndDate","initLocalState","rangeVal","updateLocalValue","updateLocalStartDate","updateLocalEndDate","hasActiveFilter","v","overlayStyle","updateOverlayPosition","triggerRect","overlayRect","top","left","toggleOverlay","closeOverlay","handleOverlayKeydown","focusable","buildPayload","payload","applyFilter","clearFilter","overlayListenersAttached","attachOverlayListeners","detachOverlayListeners","isSelectFilter","isSelectFilterWithField","isDateRangeFilter","useColumnFilter","filter","getFilterType","getFilterOptions","isMultipleSelect","getRangeFields","filterTypes","getType","filterId","localValues","initLocalValues","values","updateFilterValue","getDateRangeStart","getDateRangeEnd","toDateOnly","m","updateDateRangeStart","updateDateRangeEnd","rangeFields","applyAll","cleared","displayLabel","fieldRef","isEmpty","onBlur","CellEditableWrapper","formatted","VcInputCurrency","titleText","agoText","VcStatusIcon","MAX_CACHE_SIZE","sanitizedHtmlCache","getSanitizedHtml","sanitized","DOMPurify.default","firstKey","sanitizedHtml","truncatedHtml","htmlTruncate","get","useCellRegistry","CellDefault","CellNumber","CellMoney","CellDate","CellDateAgo","CellImage","CellStatus","CellStatusIcon","CellLink","CellHtml","cellComponent","cellProps","isEditable","baseProps","handleEditorCallback","fieldName","completeEdit","cancelEdit","handleEditorFocusOut","wrapper","relatedTarget","handleEditorKeyDown","uniqueFieldName","isInlineEditing","cellValue","currency","dateVariant","handleCellUpdate","handleCellBlur","_payload","TableCheckbox","SlotProxy","DynamicCellRenderer","handleRowClick","handleRowSpacePress","_event","handleRowMouseEnter","handleRowMouseLeave","handleSelectionChange","handleCellSelectionChange","handleExpandToggle","handleRowEdit","handleRowSave","handleRowCancel","handleEditComplete","handleEditCancel","handleCellValueChange","handleCellClick","col","handleGroupToggle","TableGroupRow","DataTableCellRenderer","ROW_WIDTHS","getSkeletonProps","_rowIndex","rowIndex","skeletonRows","iterationItems","g","groupCountMap","map","getGroupKey","isFirstInGroup","isLastInGroup","getEffectiveIndex","handleRowSelectionChange","rowsContainerRef","listEl","TableEmpty","TableSkeletonRows","DataTableRow","slotProps","textEl","isTruncated","checkTruncation","columnSwitcherBtnRef","handleSelectAllChange","colProps","handleResizeStart","handleReorderDragStart","handleReorderDragOver","handleReorderDrop","handleFilterApply","handleFilterClear","TableHead","HeaderTitle","ColumnFilter","updateValue","startDate","updateStartDate","endDate","updateEndDate","TableSwipeKey","provideTableSwipe","activeSwipeId","setActiveSwipe","useTableSwipe","DIRECTION_LOCK_THRESHOLD","SPRING_STIFFNESS","SPRING_DAMPING","SPRING_MASS","cardRef","isLongPressing","longPressTimeoutId","handleLongPressStart","translateX","isAnimating","handleLongPressEnd","actionsWidth","isActionSheetOpen","animationId","startX","startY","startTranslateX","lastTime","lastX","directionLock","showCheckbox","hasMoreActions","displayActions","allActions","totalActionsWidth","count","springAnimation","targetValue","startValue","startTime","springVelocity","animate","time","springForce","dampingForce","acceleration","currentX","newTranslateX","overscroll","wasVertical","absVelocity","handleSelect","handleMoreClick","handleSheetAction","MobileCellRenderer","status","_component_VcIcon","MobileActionSheet","FIELD_POSITIONS","MAX_FIELDS","STATUS_TYPES","TITLE_PRIORITY_TYPES","mapPositionToRole","position","isFirstTopLeft","createColumnConfig","isTitle","isServiceColumn","selectionMode","rowEditor","rowReorder","expander","createDefaultMobileConfigs","columns","configs","eligibleColumns","imageColumn","statusColumns","regularColumns","titleColumn","statusColumn","fieldColumns","useMobileCardLayout","mobileVisibleColumns","fallbackColumns","hasExplicitMobileConfig","firstTopLeftSeen","mobileRole","mobilePosition","hasExplicitConfig","role","hasMobileColumns","layout","titleCols","imageCols","fieldCols","statusCols","occupiedPositions","explicitlyPlacedFields","autoPlaceFields","pos","allFields","freePositions","posA","posB","INDICATOR_HEIGHT","pullDistance","isPulling","canRelease","lastY","indicatorIcon","iconClasses","statusText","isAtTop","currentY","resistance","newPullDistance","maxPull","oldValue","columnsRef","mobileLayout","isItemSelected","itemKey","isItemSelectable","getItemActions","actions","mapActionType","actionItem","handleRowSelect","listRef","PullToRefresh","DataTableMobileCard","useTableContext","DEFAULT_MIN_COLUMN_PX","computeColumnWidths","mode","widths","desired","clamped","w","finalize","distributeGrow","distributeShrink","crisisSqueeze","surplus","maxIters","iter","eligible","totalCapacity","capacity","hasInfinite","distributed","totalWeight","share","actual","deficit","floats","fillerFloat","floored","remainders","flooredFiller","shortage","indices","_","fillerRemainder","idxPointer","assigned","ci","parseColumnWidth","trimmed","pxMatch","warnUnsupportedWidthOnce","warnedWidthValues","buildInitialWeights","parsed","weights","equal","fixedSum","autoIds","desiredMap","autoShare","normalizeWeights","specs","visibleIds","useTableColumnsResize","columnState","engineOutput","recompute","getAvailableWidth","minColumnWidth","getVisibleRegularColumnIds","onResizeEnd","containerEl","rafId","initialSpecs","rightNeighborIds","cloneSpecs","cloned","spec","getActiveOrder","visibleRegular","renderedIds","activeOrder","update","rawDeltaPx","applyResize","handleResizeMove","handleResizeEnd","rawDelta","available","initialPx","maxGrowthPx","min","totalInitialPx","fillerPx","draggedMin","maxShrinkPx","clampedDelta","newPx","applied","actualChange","newSpecs","getResizeHeadProps","settled","rafRecomputeId","scheduleRecompute","setupResizeObserver","useTableColumnsReorder","onReorderEnd","draggedColumnId","dragThrottleTimer","transparentPixel","dragElement","cleanupDrag","header","hoveredColumnId","middleX","dragIndex","dropIndex","movingLeft","movingRight","newOrder","movedId","handleDragEnd","getReorderHeadProps","useTableRowReorder","reorderedItems","pendingReorder","oldIndex","newIndex","parent","dragged","safeClone","obj","toRaw","_key","useTableInlineEdit","_rules","onCellUpdate","onSave","onCancel","isEditing","snapshot","parentForm","PublicFormContextKey","ownForm","activeForm","meta","setFieldValue","veeErrors","safeResetForm","modifiedCells","newRowIndices","clearNewRowFlag","cellKey","startEditing","cancelEditing","saveChanges","valid","pendingChanges","updateCell","row","newModified","getCellValue","isCellDirty","changes","rowStr","defaults","newRow","newIdx","newNewRowIndices","cellRules","useVirtualScroll","itemSize","numToleratedItems","lazy","onScrollCallback","onLazyLoad","scrollTop","containerHeight","scrollTimeout","lastLazyLoadRange","visibleRange","buffer","itemCount","firstVisibleIndex","visibleCount","totalHeight","offsetY","handleScroll","updateScroll","range","scrollToIndex","behavior","targetScrollTop","scrollToTop","scrollToBottom","maxScroll","initializeContainer","handleResize","newRef","newLength","oldLength","useTableRowGrouping","groupRowsBy","_rowGroupMode","expandableRowGroups","expandedRowGroups","onExpandedRowGroupsChange","onRowGroupExpand","onRowGroupCollapse","internalExpandedRowGroups","isGroupingEnabled","primaryGroupField","getItemGroupKey","_.get","groupedData","isGroupExpanded","groupKey","toggleGroupExpansion","k","expandGroup","collapseGroup","expandAllGroups","keys","collapseAllGroups","useFilterState","filterValues","isValueEmpty","updateFilter","notifyChange","updateRangeFilter","newValues","clearAllFilters","isObjectWithValues","hasActiveFilters","activeFilterCount","sortMode","multiSortMeta","removableSort","onSort","internalSortField","internalSortOrder","internalMultiSortMeta","handleMultiSort","handleSingleSort","currentMeta","getSortDirection","useTableEditing","editMode","editingRows","editingCell","editingMeta","internalEditingRows","editingRowSnapshot","editedData","fields","newMeta","finalNewValue","originalData","useTableExpansion","expandedRows","isRowExpandable","internalExpandedRows","expandedRowKeys","canExpand","isRowExpanded","_index","expandRow","collapseRow","useTableSelectionV2","selection","isRowSelectable","selectAllActive","selectAllEnabled","onSelectAllChange","internalSelection","isSelectAllActive","selectionKeys","selectableItems","isSelected","someSelected","selectedCount","showSelectAllChoice","selectionInfo","canSelect","unselectItem","eventOrValue","isCurrentlySelected","originalEvent","clearSelection","selectAll","clearSelectAll","getSelectionState","createTableSelectionFacade","handlers","isSpecialColumn","SPECIAL_COLUMN_WIDTHS","useTableColumns","visibleColumns","resizableColumns","reorderableColumns","fitMode","headerRefs","isColumnResizable","isColumnReorderable","getEffectiveColumnWidth","declared","getHeaderAlign","align","getCellAlign","getHeaderStyle","px","getCellStyle","getSortField","setHeaderRef","domEl","orderedVisibleColumns","validColumns","orderMap","specialCols","dataCols","selectionCol","expanderCol","reorderCol","editorCol","isLastResizableColumn","resizableCols","totalColumns","buildSpec","fallbackWeight","minParsed","maxParsed","applyInitFromProps","regularCols","orderSet","markStateRestored","needsPropsReinit","resetFromProps","cols","prevVisibleIdSet","isFirstRun","newIds","newIdSet","trackedIds","brandNewIds","justShownIds","justHiddenIds","visibleSetChanged","isInitialEmpty","existingVisible","avgWeight","SCHEMA_VERSION","migrateV1toV2","totalPx","useDataTableState","stateStorage","hiddenColumnIds","shownColumnIds","onStateSave","onStateRestore","restoringCount","debounceTimer","getStorage","readPersistedState","storage","raw","v2","pendingState","pendingColumnRestore","buildState","saveState","clearState","resetState","applyColumnRestore","currentState","stopColumnWatch","canPersist","debouncedSave","ROW_REORDER_HANDLE_SELECTOR","useDataTableOrchestrator","declaredColumns","shownDataDiscoveredColumnIds","dataDiscoveredColumns","tableContainerRef","selectionColumn","hasSelectionColumn","effectiveSelectionMode","isSelectionViaColumn","computedVariant","newSelection","editing","expansion","expandedKeysArray","newExpanded","newKeys","newKeysStr","rowGrouping","inlineEdit","cachedWrapper","measureAvailableWidth","specialWidth","implicitCells","cell","dataDiscoveredIds","switcherColumns","discovered","switcherVisibleColumnIds","statePersistence","oldIds","updatedHidden","updatedShown","hiddenChanged","shownChanged","declaredIds","rowReorderColumn","isRowReorderEnabled","showRowDragHandle","rowReorderListRef","expanderColumn","hasExpanderColumn","colFilter","showColumnFilter","getColumnFilterField","getColumnFilterType","getColumnFilterOptions","isColumnFilterMultiple","getColumnRangeFields","getColumnFilterValue","globalFilterPayload","emitFilterPayload","handleColumnFilterApply","filterType","handleColumnFilterClear","displayItems","getGlobalIndex","safeColumns","handleColumnDragStart","handleColumnDragOver","handleColumnDrop","wasSelected","isSameItem","isCheckboxClick","cancelled","visibleSet","allToggleableIds","discoveredToggleableIds","toggleableSet","discoveredSet","newHidden","newShown","wasExpanded","ColumnCollector","defaultSlot","columnVNodes","processVNode","vnode","autofocus","binding","PAGINATION_ITEM_SLOT","PAGINATION_BASE_WIDTH","emptyTitle","emptyDescription","notFoundTitle","notFoundDescription","isNotFoundState","internalSearchValue","resolvedEmptyIcon","resolvedEmptyTitle","resolvedEmptyDescription","resolvedEmptyActionLabel","resolvedEmptyActionHandler","loadingText","hasLoadedOnce","paginationRangeText","kebabToCamel","str","letter","BOOLEAN_PROPS","normalizeProps","camelKey","extractColumnsFromSlots","rawProps","columnCollector","ColumnCollectorKey","columnsVersion","slotCols","firstItem","tableRootRef","paginationRef","handleAddRow","handleRemoveRow","handleColumnVisibilityChange","handleTableReset","handleCellEditComplete","handleCellEditCancel","handleStartRowEdit","handleSaveRowEdit","handleCancelRowEdit","handleRowAction","handleMobileRowClick","handleMobileRowSelect","handleMobileRowAction","desktopBodyRef","mobileViewRef","FilterContextKey","handlePaginationClick","searchTimer","handleSearchInput","handleContentScroll","showAddRowButton","addRowPosition","addRowLabel","addRowIcon","showGlobalFiltersPanel","globalFilterValues","globalFiltersButtonRef","globalFiltersButtonEl","inst","showColumnSwitcherPanel","dataTableHeaderRef","columnSwitcherButtonEl","globalActiveFilterCount","handleGlobalFilterApply","handleGlobalFilterClear","getRowProps","paginationWidth","paginationMaxPages","slotsForPages","paginationShowFirstLast","TableSearchHeader","GlobalFiltersButton","GlobalFiltersPanel","TableColumnSwitcher","TableAddRowButton","TableSelectAllBar","DataTableMobileView","DataTableHeader","DataTableBody","TableRowActions","TableFooter","vLoading","showLegacyFiltersPanel","legacyFiltersButtonRef","legacyFiltersButtonEl","closeLegacyFiltersPanel","sortFieldValue","sortOrderValue","lastSortField","rowSelectable","effectiveRowActions","paginationConfig","effectiveColumns","mappedEmptyState","mappedNotFoundState","loadingValue","addRowConfig","editModeValue","showSearch","columnSwitcherValue","mapColumnType","mapColumnAlign","mapMobileRole","mapMobilePosition","sortId","handleSelectionUpdate","handleSearchChange","handleRowReorder","handlePullRefresh","handleSelectAll","VcDataTable","VcColumn"],"mappings":"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"}
|