atomicuilibrary 0.0.1
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/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/cjs/category-section.cjs.entry.js +30 -0
- package/dist/cjs/component-size-DsYFUZcz.js +29 -0
- package/dist/cjs/dom-oP1E4Rd3.js +267 -0
- package/dist/cjs/event-bus-B6M2f8CQ.js +23 -0
- package/dist/cjs/exploration-project-tailwind.cjs.js +24 -0
- package/dist/cjs/focus-trap-i9T6oXLc.js +139 -0
- package/dist/cjs/index-ClkOYpT8.js +2275 -0
- package/dist/cjs/index.cjs.js +260 -0
- package/dist/cjs/layout-manager.cjs.entry.js +616 -0
- package/dist/cjs/library-card.cjs.entry.js +63 -0
- package/dist/cjs/lm-container_2.cjs.entry.js +79 -0
- package/dist/cjs/lm-panel_3.cjs.entry.js +108 -0
- package/dist/cjs/loader.cjs.js +12 -0
- package/dist/cjs/my-component.cjs.entry.js +33 -0
- package/dist/cjs/my-step.cjs.entry.js +29 -0
- package/dist/cjs/nav-bar.cjs.entry.js +247 -0
- package/dist/cjs/security-E1JcwxGc.js +1547 -0
- package/dist/cjs/smart-step.cjs.entry.js +47 -0
- package/dist/cjs/timeline-item.cjs.entry.js +29 -0
- package/dist/cjs/ui-accordion_10.cjs.entry.js +5733 -0
- package/dist/cjs/ui-advanced-data-table.cjs.entry.js +2684 -0
- package/dist/cjs/ui-anchor.cjs.entry.js +558 -0
- package/dist/cjs/ui-animate-on-scroll.cjs.entry.js +285 -0
- package/dist/cjs/ui-aside-panel.cjs.entry.js +638 -0
- package/dist/cjs/ui-avatar-group_3.cjs.entry.js +634 -0
- package/dist/cjs/ui-breadcrumb-item.cjs.entry.js +56 -0
- package/dist/cjs/ui-breadcrumb.cjs.entry.js +201 -0
- package/dist/cjs/ui-callout-banner.cjs.entry.js +291 -0
- package/dist/cjs/ui-card.cjs.entry.js +411 -0
- package/dist/cjs/ui-carousel.cjs.entry.js +547 -0
- package/dist/cjs/ui-checkbox-group.cjs.entry.js +330 -0
- package/dist/cjs/ui-checkbox.cjs.entry.js +260 -0
- package/dist/cjs/ui-code-editor.cjs.entry.js +961 -0
- package/dist/cjs/ui-code-preview.cjs.entry.js +315 -0
- package/dist/cjs/ui-color-controller.cjs.entry.js +150 -0
- package/dist/cjs/ui-color-picker.cjs.entry.js +658 -0
- package/dist/cjs/ui-command-palette.cjs.entry.js +178 -0
- package/dist/cjs/ui-dialog-box.cjs.entry.js +1808 -0
- package/dist/cjs/ui-dialog-content.cjs.entry.js +31 -0
- package/dist/cjs/ui-dialog-footer_2.cjs.entry.js +193 -0
- package/dist/cjs/ui-divider.cjs.entry.js +481 -0
- package/dist/cjs/ui-dock-host.cjs.entry.js +128 -0
- package/dist/cjs/ui-dock.cjs.entry.js +221 -0
- package/dist/cjs/ui-drag-drop.cjs.entry.js +172 -0
- package/dist/cjs/ui-dropdown_2.cjs.entry.js +1552 -0
- package/dist/cjs/ui-empty-state.cjs.entry.js +398 -0
- package/dist/cjs/ui-fab-item.cjs.entry.js +39 -0
- package/dist/cjs/ui-fab.cjs.entry.js +277 -0
- package/dist/cjs/ui-file-upload.cjs.entry.js +418 -0
- package/dist/cjs/ui-horizontal-nav.cjs.entry.js +135 -0
- package/dist/cjs/ui-image-button.cjs.entry.js +67 -0
- package/dist/cjs/ui-input-pair.cjs.entry.js +44 -0
- package/dist/cjs/ui-knob.cjs.entry.js +447 -0
- package/dist/cjs/ui-library.cjs.entry.js +134 -0
- package/dist/cjs/ui-list-group_2.cjs.entry.js +586 -0
- package/dist/cjs/ui-list.cjs.entry.js +732 -0
- package/dist/cjs/ui-masonry.cjs.entry.js +478 -0
- package/dist/cjs/ui-meter-group.cjs.entry.js +173 -0
- package/dist/cjs/ui-navigation-item.cjs.entry.js +104 -0
- package/dist/cjs/ui-number-input.cjs.entry.js +191 -0
- package/dist/cjs/ui-otp-input.cjs.entry.js +246 -0
- package/dist/cjs/ui-pagination_3.cjs.entry.js +1621 -0
- package/dist/cjs/ui-panel.cjs.entry.js +614 -0
- package/dist/cjs/ui-pattern-input.cjs.entry.js +278 -0
- package/dist/cjs/ui-popover.cjs.entry.js +517 -0
- package/dist/cjs/ui-progress.cjs.entry.js +516 -0
- package/dist/cjs/ui-radio-group.cjs.entry.js +205 -0
- package/dist/cjs/ui-radio.cjs.entry.js +206 -0
- package/dist/cjs/ui-range-slider.cjs.entry.js +637 -0
- package/dist/cjs/ui-resizable-panel.cjs.entry.js +484 -0
- package/dist/cjs/ui-scroll-top.cjs.entry.js +459 -0
- package/dist/cjs/ui-smart-context-menu.cjs.entry.js +376 -0
- package/dist/cjs/ui-smart-location-dropdown.cjs.entry.js +565 -0
- package/dist/cjs/ui-smart-stepper.cjs.entry.js +137 -0
- package/dist/cjs/ui-snackbar.cjs.entry.js +863 -0
- package/dist/cjs/ui-speed-dial.cjs.entry.js +520 -0
- package/dist/cjs/ui-speedometer.cjs.entry.js +428 -0
- package/dist/cjs/ui-splitter.cjs.entry.js +282 -0
- package/dist/cjs/ui-step.cjs.entry.js +30 -0
- package/dist/cjs/ui-stepper.cjs.entry.js +640 -0
- package/dist/cjs/ui-switch.cjs.entry.js +405 -0
- package/dist/cjs/ui-tabs.cjs.entry.js +703 -0
- package/dist/cjs/ui-tag.cjs.entry.js +299 -0
- package/dist/cjs/ui-timeline.cjs.entry.js +267 -0
- package/dist/cjs/ui-timer.cjs.entry.js +502 -0
- package/dist/cjs/ui-toolbar.cjs.entry.js +619 -0
- package/dist/cjs/ui-tooltip.cjs.entry.js +697 -0
- package/dist/cjs/ui-top-bar.cjs.entry.js +121 -0
- package/dist/cjs/ui-transfer-list.cjs.entry.js +592 -0
- package/dist/cjs/ui-tree.cjs.entry.js +874 -0
- package/dist/cjs/ui-workspace-manager.cjs.entry.js +1201 -0
- package/dist/cjs/utils-DVZ6gul6.js +26 -0
- package/dist/collection/assets/js/component-config.js +41 -0
- package/dist/collection/assets/js/demo-loader.js +147 -0
- package/dist/collection/assets/js/demo-nav.js +273 -0
- package/dist/collection/assets/js/demos/about-demo.js +60 -0
- package/dist/collection/assets/js/demos/accordion-demo.js +1954 -0
- package/dist/collection/assets/js/demos/advanced-data-table-demo.js +2952 -0
- package/dist/collection/assets/js/demos/anchor-demo.js +527 -0
- package/dist/collection/assets/js/demos/animate-on-scroll-demo.js +174 -0
- package/dist/collection/assets/js/demos/aside-panel-demo.js +1109 -0
- package/dist/collection/assets/js/demos/avatar-demo.js +508 -0
- package/dist/collection/assets/js/demos/badge-demo.js +620 -0
- package/dist/collection/assets/js/demos/breadcrumb-demo.js +365 -0
- package/dist/collection/assets/js/demos/button-demo.js +1223 -0
- package/dist/collection/assets/js/demos/button-toggle-demo.js +978 -0
- package/dist/collection/assets/js/demos/callout-banner-demo.js +366 -0
- package/dist/collection/assets/js/demos/card-demo.js +427 -0
- package/dist/collection/assets/js/demos/carousel-demo.js +360 -0
- package/dist/collection/assets/js/demos/checkbox-demo.js +489 -0
- package/dist/collection/assets/js/demos/code-preview-demo.js +216 -0
- package/dist/collection/assets/js/demos/color-picker-demo.js +117 -0
- package/dist/collection/assets/js/demos/command-palette-demo.js +105 -0
- package/dist/collection/assets/js/demos/complex-form-demo.js +45 -0
- package/dist/collection/assets/js/demos/context-menu-data.js +436 -0
- package/dist/collection/assets/js/demos/context-menu-demo.js +829 -0
- package/dist/collection/assets/js/demos/dashboard-demo.js +5 -0
- package/dist/collection/assets/js/demos/dialog-demo-temp.js +411 -0
- package/dist/collection/assets/js/demos/dialog-demo.js +2567 -0
- package/dist/collection/assets/js/demos/divider-demo.js +853 -0
- package/dist/collection/assets/js/demos/dock-demo.js +422 -0
- package/dist/collection/assets/js/demos/dock-host-init.js +117 -0
- package/dist/collection/assets/js/demos/dock-host-playground.js +59 -0
- package/dist/collection/assets/js/demos/documentation-demo.js +34 -0
- package/dist/collection/assets/js/demos/drag-drop-demo.js +132 -0
- package/dist/collection/assets/js/demos/dropdown-demo.js +1410 -0
- package/dist/collection/assets/js/demos/dropdown-subtitle-demo.js +18 -0
- package/dist/collection/assets/js/demos/empty-state-demo.js +580 -0
- package/dist/collection/assets/js/demos/fab-demo.js +374 -0
- package/dist/collection/assets/js/demos/file-upload-demo.js +171 -0
- package/dist/collection/assets/js/demos/home-components.js +750 -0
- package/dist/collection/assets/js/demos/home-demo.js +441 -0
- package/dist/collection/assets/js/demos/horizontal-nav-demo.js +277 -0
- package/dist/collection/assets/js/demos/icon-demo.js +380 -0
- package/dist/collection/assets/js/demos/input-demo.js +1932 -0
- package/dist/collection/assets/js/demos/knob-demo.js +570 -0
- package/dist/collection/assets/js/demos/layout-manager-demo.js +918 -0
- package/dist/collection/assets/js/demos/list-demo.js +1402 -0
- package/dist/collection/assets/js/demos/loader-demo.js +453 -0
- package/dist/collection/assets/js/demos/meter-group-demo.js +499 -0
- package/dist/collection/assets/js/demos/multi-level-context-menu-demo.js +924 -0
- package/dist/collection/assets/js/demos/my-profile-demo.js +237 -0
- package/dist/collection/assets/js/demos/nav-bar-demo.js +187 -0
- package/dist/collection/assets/js/demos/number-input-demo.js +242 -0
- package/dist/collection/assets/js/demos/overview-demo.js +11 -0
- package/dist/collection/assets/js/demos/pagination-demo.js +1042 -0
- package/dist/collection/assets/js/demos/panel-demo.js +789 -0
- package/dist/collection/assets/js/demos/pattern-input-demo.js +241 -0
- package/dist/collection/assets/js/demos/popover-demo.js +882 -0
- package/dist/collection/assets/js/demos/progress-demo.js +462 -0
- package/dist/collection/assets/js/demos/radio-demo.js +413 -0
- package/dist/collection/assets/js/demos/range-slider-demo.js +1217 -0
- package/dist/collection/assets/js/demos/rating-demo.js +383 -0
- package/dist/collection/assets/js/demos/scroll-top-demo.js +353 -0
- package/dist/collection/assets/js/demos/skeleton-demo.js +490 -0
- package/dist/collection/assets/js/demos/skeleton-performance-demo.js +26 -0
- package/dist/collection/assets/js/demos/smart-dialog-demo.js +552 -0
- package/dist/collection/assets/js/demos/smart-menu-demo.js +375 -0
- package/dist/collection/assets/js/demos/smart-stepper-demo.js +50 -0
- package/dist/collection/assets/js/demos/snackbar-demo.js +1040 -0
- package/dist/collection/assets/js/demos/speed-dial-demo.js +764 -0
- package/dist/collection/assets/js/demos/speedometer-demo.js +425 -0
- package/dist/collection/assets/js/demos/split-button-demo.js +201 -0
- package/dist/collection/assets/js/demos/stack-demo.js +228 -0
- package/dist/collection/assets/js/demos/stepper-demo.js +798 -0
- package/dist/collection/assets/js/demos/switch-demo.js +849 -0
- package/dist/collection/assets/js/demos/tabs-demo.js +1032 -0
- package/dist/collection/assets/js/demos/tag-demo.js +842 -0
- package/dist/collection/assets/js/demos/theme-selector-demo.js +466 -0
- package/dist/collection/assets/js/demos/timeline-demo.js +365 -0
- package/dist/collection/assets/js/demos/timeline-playground.js +59 -0
- package/dist/collection/assets/js/demos/timer-demo.js +313 -0
- package/dist/collection/assets/js/demos/toolbar-demo.js +643 -0
- package/dist/collection/assets/js/demos/tooltip-demo.js +730 -0
- package/dist/collection/assets/js/demos/top-bar-demo.js +417 -0
- package/dist/collection/assets/js/demos/transfer-list-demo.js +555 -0
- package/dist/collection/assets/js/demos/tree-demo.js +693 -0
- package/dist/collection/assets/js/demos/workspace-manager-demo.js +241 -0
- package/dist/collection/assets/js/index-boot.js +104 -0
- package/dist/collection/assets/js/nav-bar-demo.js +20 -0
- package/dist/collection/assets/js/nav-bar-init.js +119 -0
- package/dist/collection/assets/js/utils/layout-loader.js +80 -0
- package/dist/collection/collection-manifest.json +113 -0
- package/dist/collection/components/accordion/accordion.css +2090 -0
- package/dist/collection/components/accordion/accordion.js +2955 -0
- package/dist/collection/components/accordion/types.js +1 -0
- package/dist/collection/components/advanced-data-table/advanced-data-table.css +2606 -0
- package/dist/collection/components/advanced-data-table/advanced-data-table.js +5394 -0
- package/dist/collection/components/advanced-data-table/types.js +1 -0
- package/dist/collection/components/anchor/anchor.css +395 -0
- package/dist/collection/components/anchor/anchor.js +1404 -0
- package/dist/collection/components/anchor/types.js +1 -0
- package/dist/collection/components/animate-on-scroll/animate-on-scroll.css +804 -0
- package/dist/collection/components/animate-on-scroll/animate-on-scroll.js +696 -0
- package/dist/collection/components/aside-panel/aside-panel.css +472 -0
- package/dist/collection/components/aside-panel/aside-panel.js +1697 -0
- package/dist/collection/components/avatar/avatar.css +696 -0
- package/dist/collection/components/avatar/avatar.js +2007 -0
- package/dist/collection/components/avatar/types.js +1 -0
- package/dist/collection/components/avatar-group/avatar-group.css +253 -0
- package/dist/collection/components/avatar-group/avatar-group.js +405 -0
- package/dist/collection/components/avatar-group/types.js +1 -0
- package/dist/collection/components/badge/badge.css +580 -0
- package/dist/collection/components/badge/badge.js +723 -0
- package/dist/collection/components/badge/types.js +1 -0
- package/dist/collection/components/breadcrumb/breadcrumb-item.js +231 -0
- package/dist/collection/components/breadcrumb/breadcrumb.css +313 -0
- package/dist/collection/components/breadcrumb/breadcrumb.js +510 -0
- package/dist/collection/components/breadcrumb/types.js +1 -0
- package/dist/collection/components/button/button.css +1862 -0
- package/dist/collection/components/button/button.js +1380 -0
- package/dist/collection/components/button/types.js +1 -0
- package/dist/collection/components/button-toggle/button-toggle.css +97 -0
- package/dist/collection/components/button-toggle/button-toggle.js +620 -0
- package/dist/collection/components/button-toggle-group/button-toggle-group.css +401 -0
- package/dist/collection/components/button-toggle-group/button-toggle-group.js +1572 -0
- package/dist/collection/components/button-toggle-group/types.js +1 -0
- package/dist/collection/components/callout-banner/callout-banner.css +684 -0
- package/dist/collection/components/callout-banner/callout-banner.js +1076 -0
- package/dist/collection/components/callout-banner/types.js +1 -0
- package/dist/collection/components/card/card.css +663 -0
- package/dist/collection/components/card/card.js +1697 -0
- package/dist/collection/components/card/types.js +1 -0
- package/dist/collection/components/carousel/carousel.css +549 -0
- package/dist/collection/components/carousel/carousel.js +1512 -0
- package/dist/collection/components/carousel/types.js +1 -0
- package/dist/collection/components/checkbox/checkbox.css +863 -0
- package/dist/collection/components/checkbox/checkbox.js +1201 -0
- package/dist/collection/components/checkbox/types.js +1 -0
- package/dist/collection/components/checkbox-group/checkbox-group.css +223 -0
- package/dist/collection/components/checkbox-group/checkbox-group.js +1001 -0
- package/dist/collection/components/checkbox-group/types.js +1 -0
- package/dist/collection/components/code-editor/code-editor.css +1081 -0
- package/dist/collection/components/code-editor/code-editor.js +1211 -0
- package/dist/collection/components/code-editor/types.js +1 -0
- package/dist/collection/components/code-preview/types.js +1 -0
- package/dist/collection/components/code-preview/ui-code-preview.css +209 -0
- package/dist/collection/components/code-preview/ui-code-preview.js +548 -0
- package/dist/collection/components/color-controller/color-controller.css +108 -0
- package/dist/collection/components/color-controller/color-controller.js +224 -0
- package/dist/collection/components/color-picker/color-picker.css +323 -0
- package/dist/collection/components/color-picker/color-picker.js +1139 -0
- package/dist/collection/components/color-picker/types.js +1 -0
- package/dist/collection/components/command-palette/command-palette.css +260 -0
- package/dist/collection/components/command-palette/command-palette.js +429 -0
- package/dist/collection/components/command-palette/types.js +1 -0
- package/dist/collection/components/context-menu/context-menu.css +388 -0
- package/dist/collection/components/context-menu/context-menu.js +1412 -0
- package/dist/collection/components/context-menu/types.js +1 -0
- package/dist/collection/components/dialog-box/dialog-box.css +1261 -0
- package/dist/collection/components/dialog-box/dialog-box.js +4314 -0
- package/dist/collection/components/dialog-box/dialog-tray.css +268 -0
- package/dist/collection/components/dialog-box/types.js +1 -0
- package/dist/collection/components/dialog-content/dialog-content.css +83 -0
- package/dist/collection/components/dialog-content/dialog-content.js +96 -0
- package/dist/collection/components/dialog-footer/dialog-footer.css +89 -0
- package/dist/collection/components/dialog-footer/dialog-footer.js +94 -0
- package/dist/collection/components/dialog-footer/types.js +1 -0
- package/dist/collection/components/dialog-header/dialog-header.css +203 -0
- package/dist/collection/components/dialog-header/dialog-header.js +630 -0
- package/dist/collection/components/dialog-header/types.js +1 -0
- package/dist/collection/components/divider/divider.css +948 -0
- package/dist/collection/components/divider/divider.js +1612 -0
- package/dist/collection/components/divider/types.js +1 -0
- package/dist/collection/components/dock/dock.css +348 -0
- package/dist/collection/components/dock/dock.js +464 -0
- package/dist/collection/components/dock/types.js +1 -0
- package/dist/collection/components/dock-host/index.js +1 -0
- package/dist/collection/components/dock-host/types.js +1 -0
- package/dist/collection/components/dock-host/ui-dock-host.css +155 -0
- package/dist/collection/components/dock-host/ui-dock-host.js +226 -0
- package/dist/collection/components/drag-drop/drag-drop.css +103 -0
- package/dist/collection/components/drag-drop/drag-drop.js +385 -0
- package/dist/collection/components/drag-drop/types.js +1 -0
- package/dist/collection/components/dropdown/dropdown.css +1142 -0
- package/dist/collection/components/dropdown/dropdown.js +2033 -0
- package/dist/collection/components/dropdown/types.js +1 -0
- package/dist/collection/components/empty-state/empty-state.css +712 -0
- package/dist/collection/components/empty-state/empty-state.js +1256 -0
- package/dist/collection/components/empty-state/types.js +1 -0
- package/dist/collection/components/fab/fab.css +601 -0
- package/dist/collection/components/fab/fab.js +1124 -0
- package/dist/collection/components/fab-item/fab-item.css +107 -0
- package/dist/collection/components/fab-item/fab-item.js +177 -0
- package/dist/collection/components/fab-item/types.js +1 -0
- package/dist/collection/components/file-upload/file-upload.css +243 -0
- package/dist/collection/components/file-upload/file-upload.js +1022 -0
- package/dist/collection/components/file-upload/types.js +1 -0
- package/dist/collection/components/horizontal-nav/horizontal-nav.css +394 -0
- package/dist/collection/components/horizontal-nav/horizontal-nav.js +375 -0
- package/dist/collection/components/icon/icon.css +113 -0
- package/dist/collection/components/icon/icon.js +583 -0
- package/dist/collection/components/image-button/image-button.css +154 -0
- package/dist/collection/components/image-button/image-button.js +310 -0
- package/dist/collection/components/image-button/types.js +1 -0
- package/dist/collection/components/input/input.css +1544 -0
- package/dist/collection/components/input/input.js +3690 -0
- package/dist/collection/components/input/types.js +1 -0
- package/dist/collection/components/input-pair/input-pair.css +72 -0
- package/dist/collection/components/input-pair/input-pair.js +309 -0
- package/dist/collection/components/knob/knob.css +162 -0
- package/dist/collection/components/knob/knob.js +986 -0
- package/dist/collection/components/knob/types.js +1 -0
- package/dist/collection/components/layout-manager/layout-manager.css +41 -0
- package/dist/collection/components/layout-manager/layout-manager.js +525 -0
- package/dist/collection/components/layout-manager/lm-container/lm-container.css +117 -0
- package/dist/collection/components/layout-manager/lm-container/lm-container.js +110 -0
- package/dist/collection/components/layout-manager/lm-floating-window/lm-floating-window.css +0 -0
- package/dist/collection/components/layout-manager/lm-floating-window/lm-floating-window.js +49 -0
- package/dist/collection/components/layout-manager/lm-panel/lm-panel.css +97 -0
- package/dist/collection/components/layout-manager/lm-panel/lm-panel.js +58 -0
- package/dist/collection/components/layout-manager/lm-splitter/lm-splitter.css +57 -0
- package/dist/collection/components/layout-manager/lm-splitter/lm-splitter.js +120 -0
- package/dist/collection/components/layout-manager/lm-tabs/lm-tabs.css +149 -0
- package/dist/collection/components/layout-manager/lm-tabs/lm-tabs.js +130 -0
- package/dist/collection/components/layout-manager/types.js +1 -0
- package/dist/collection/components/library/category-section.css +147 -0
- package/dist/collection/components/library/category-section.js +139 -0
- package/dist/collection/components/library/data.js +74 -0
- package/dist/collection/components/library/library-card.css +181 -0
- package/dist/collection/components/library/library-card.js +203 -0
- package/dist/collection/components/library/library.css +358 -0
- package/dist/collection/components/library/library.js +91 -0
- package/dist/collection/components/list/list.css +1029 -0
- package/dist/collection/components/list/list.js +2167 -0
- package/dist/collection/components/list-group/list-group.css +275 -0
- package/dist/collection/components/list-group/list-group.js +356 -0
- package/dist/collection/components/list-item/list-item.css +1491 -0
- package/dist/collection/components/list-item/list-item.js +2184 -0
- package/dist/collection/components/masonry/masonry.css +414 -0
- package/dist/collection/components/masonry/masonry.js +1104 -0
- package/dist/collection/components/masonry/types.js +1 -0
- package/dist/collection/components/meter-group/meter-group.css +184 -0
- package/dist/collection/components/meter-group/meter-group.js +471 -0
- package/dist/collection/components/meter-group/types.js +1 -0
- package/dist/collection/components/my-component/my-component.css +27 -0
- package/dist/collection/components/my-component/my-component.js +95 -0
- package/dist/collection/components/my-step/my-step.css +25 -0
- package/dist/collection/components/my-step/my-step.js +237 -0
- package/dist/collection/components/nav-bar/nav-bar.css +448 -0
- package/dist/collection/components/nav-bar/nav-bar.js +608 -0
- package/dist/collection/components/number-input/number-input.css +200 -0
- package/dist/collection/components/number-input/number-input.js +695 -0
- package/dist/collection/components/otp-input/otp-input.css +243 -0
- package/dist/collection/components/otp-input/otp-input.js +761 -0
- package/dist/collection/components/otp-input/types.js +1 -0
- package/dist/collection/components/pagination/pagination.css +1399 -0
- package/dist/collection/components/pagination/pagination.js +2033 -0
- package/dist/collection/components/pagination/types.js +1 -0
- package/dist/collection/components/panel/panel.css +837 -0
- package/dist/collection/components/panel/panel.js +1842 -0
- package/dist/collection/components/panel/types.js +1 -0
- package/dist/collection/components/pattern-input/pattern-input.css +252 -0
- package/dist/collection/components/pattern-input/pattern-input.js +788 -0
- package/dist/collection/components/popover/popover.css +399 -0
- package/dist/collection/components/popover/popover.js +1449 -0
- package/dist/collection/components/popover/types.js +1 -0
- package/dist/collection/components/progress/progress.css +588 -0
- package/dist/collection/components/progress/progress.js +1414 -0
- package/dist/collection/components/progress/types.js +1 -0
- package/dist/collection/components/radio/radio.css +773 -0
- package/dist/collection/components/radio/radio.js +1059 -0
- package/dist/collection/components/radio/types.js +1 -0
- package/dist/collection/components/radio-group/radio-group.css +202 -0
- package/dist/collection/components/radio-group/radio-group.js +903 -0
- package/dist/collection/components/radio-group/types.js +1 -0
- package/dist/collection/components/range-slider/range-slider.css +602 -0
- package/dist/collection/components/range-slider/range-slider.js +1369 -0
- package/dist/collection/components/range-slider/types.js +1 -0
- package/dist/collection/components/rating/rating.css +768 -0
- package/dist/collection/components/rating/rating.js +1062 -0
- package/dist/collection/components/rating/types.js +1 -0
- package/dist/collection/components/resizable-panel/resizable-panel.css +247 -0
- package/dist/collection/components/resizable-panel/resizable-panel.js +874 -0
- package/dist/collection/components/resizable-panel/types.js +1 -0
- package/dist/collection/components/scroll-top/scroll-top.css +397 -0
- package/dist/collection/components/scroll-top/scroll-top.js +1178 -0
- package/dist/collection/components/scroll-top/types.js +1 -0
- package/dist/collection/components/skeleton/skeleton-loader.css +429 -0
- package/dist/collection/components/skeleton/skeleton-loader.js +1193 -0
- package/dist/collection/components/skeleton/types.js +1 -0
- package/dist/collection/components/smart-location-dropdown/smart-location-dropdown.css +357 -0
- package/dist/collection/components/smart-location-dropdown/smart-location-dropdown.js +1190 -0
- package/dist/collection/components/smart-location-dropdown/types.js +1 -0
- package/dist/collection/components/smart-menu/menu-item.interface.js +1 -0
- package/dist/collection/components/smart-menu/smart-menu.css +119 -0
- package/dist/collection/components/smart-menu/smart-menu.js +544 -0
- package/dist/collection/components/smart-stepper/smart-step.css +213 -0
- package/dist/collection/components/smart-stepper/smart-step.js +170 -0
- package/dist/collection/components/smart-stepper/smart-stepper.css +146 -0
- package/dist/collection/components/smart-stepper/smart-stepper.js +338 -0
- package/dist/collection/components/snackbar/snackbar.css +1480 -0
- package/dist/collection/components/snackbar/snackbar.js +1759 -0
- package/dist/collection/components/snackbar/types.js +1 -0
- package/dist/collection/components/speed-dial/speed-dial.css +478 -0
- package/dist/collection/components/speed-dial/speed-dial.js +1183 -0
- package/dist/collection/components/speed-dial/types.js +1 -0
- package/dist/collection/components/speedometer/speedometer.css +95 -0
- package/dist/collection/components/speedometer/speedometer.js +868 -0
- package/dist/collection/components/speedometer/types.js +1 -0
- package/dist/collection/components/splitter/splitter.css +269 -0
- package/dist/collection/components/splitter/splitter.js +713 -0
- package/dist/collection/components/splitter/types.js +1 -0
- package/dist/collection/components/stack/stack.css +269 -0
- package/dist/collection/components/stack/stack.js +297 -0
- package/dist/collection/components/stack/types.js +1 -0
- package/dist/collection/components/step/step.css +77 -0
- package/dist/collection/components/step/step.js +214 -0
- package/dist/collection/components/step/types.js +1 -0
- package/dist/collection/components/stepper/stepper.css +1079 -0
- package/dist/collection/components/stepper/stepper.js +1850 -0
- package/dist/collection/components/stepper/types.js +1 -0
- package/dist/collection/components/switch/switch.css +1099 -0
- package/dist/collection/components/switch/switch.js +1578 -0
- package/dist/collection/components/tabs/tabs.css +1355 -0
- package/dist/collection/components/tabs/tabs.js +1474 -0
- package/dist/collection/components/tabs/types.js +1 -0
- package/dist/collection/components/tag/tag.css +893 -0
- package/dist/collection/components/tag/tag.js +1119 -0
- package/dist/collection/components/tag/types.js +1 -0
- package/dist/collection/components/tag-group/tag-group.css +144 -0
- package/dist/collection/components/tag-group/tag-group.js +887 -0
- package/dist/collection/components/tag-group/types.js +1 -0
- package/dist/collection/components/timeline/timeline.css +1850 -0
- package/dist/collection/components/timeline/timeline.js +889 -0
- package/dist/collection/components/timeline/types.js +1 -0
- package/dist/collection/components/timeline/ui-timeline.stories.js +19 -0
- package/dist/collection/components/timeline-item/timeline-item.css +75 -0
- package/dist/collection/components/timeline-item/timeline-item.js +91 -0
- package/dist/collection/components/timer/timer.css +367 -0
- package/dist/collection/components/timer/timer.js +1292 -0
- package/dist/collection/components/timer/types.js +1 -0
- package/dist/collection/components/timer/ui-timer.stories.js +19 -0
- package/dist/collection/components/toggle-group/toggle-group.css +361 -0
- package/dist/collection/components/toggle-group/toggle-group.js +1212 -0
- package/dist/collection/components/toggle-group/types.js +1 -0
- package/dist/collection/components/toolbar/toolbar-types.js +1 -0
- package/dist/collection/components/toolbar/toolbar.css +1186 -0
- package/dist/collection/components/toolbar/toolbar.js +1635 -0
- package/dist/collection/components/tooltip/tooltip.css +609 -0
- package/dist/collection/components/tooltip/tooltip.js +1882 -0
- package/dist/collection/components/tooltip/types.js +1 -0
- package/dist/collection/components/top-bar/top-bar.css +274 -0
- package/dist/collection/components/top-bar/top-bar.js +383 -0
- package/dist/collection/components/transfer-list/transfer-list.css +520 -0
- package/dist/collection/components/transfer-list/transfer-list.js +1225 -0
- package/dist/collection/components/transfer-list/types.js +1 -0
- package/dist/collection/components/tree/tree.css +1197 -0
- package/dist/collection/components/tree/tree.js +2509 -0
- package/dist/collection/components/tree/types.js +1 -0
- package/dist/collection/components/ui-navigation-bar/navigation-bar/navigation-bar.css +830 -0
- package/dist/collection/components/ui-navigation-bar/navigation-bar/navigation-bar.js +1231 -0
- package/dist/collection/components/ui-navigation-bar/navigation-bar/navigation-types.js +1 -0
- package/dist/collection/components/ui-navigation-bar/navigation-item.css +679 -0
- package/dist/collection/components/ui-navigation-bar/navigation-item.js +385 -0
- package/dist/collection/components/ui-navigation-bar/navigation-types.js +1 -0
- package/dist/collection/components/workspace-manager/types.js +1 -0
- package/dist/collection/components/workspace-manager/workspace-manager.css +1094 -0
- package/dist/collection/components/workspace-manager/workspace-manager.js +1914 -0
- package/dist/collection/components.js +51 -0
- package/dist/collection/index.js +108 -0
- package/dist/collection/service/drag-manager.js +23 -0
- package/dist/collection/service/event-bus.js +19 -0
- package/dist/collection/service/serialization.js +8 -0
- package/dist/collection/service/state-engine.js +247 -0
- package/dist/collection/service/theme-switcher.js +146 -0
- package/dist/collection/stories/Button.stories.js +15 -0
- package/dist/collection/types/common.js +1 -0
- package/dist/collection/types/index.js +4 -0
- package/dist/collection/utils/aria-live.js +60 -0
- package/dist/collection/utils/component-size.js +25 -0
- package/dist/collection/utils/dom.js +260 -0
- package/dist/collection/utils/focus-trap.js +135 -0
- package/dist/collection/utils/security.js +10 -0
- package/dist/collection/utils/test/setup-component-test-env.js +92 -0
- package/dist/collection/utils/utils.js +21 -0
- package/dist/collection/utils/validation.js +74 -0
- package/dist/components/avatar-group.js +1 -0
- package/dist/components/avatar.js +1 -0
- package/dist/components/badge.js +1 -0
- package/dist/components/button-toggle.js +1 -0
- package/dist/components/category-section.d.ts +11 -0
- package/dist/components/category-section.js +1 -0
- package/dist/components/category-section2.js +1 -0
- package/dist/components/checkbox.js +1 -0
- package/dist/components/context-menu.js +1 -0
- package/dist/components/dialog-footer.js +1 -0
- package/dist/components/dialog-header.js +1 -0
- package/dist/components/dom.js +1 -0
- package/dist/components/dropdown.js +1 -0
- package/dist/components/event-bus.js +1 -0
- package/dist/components/focus-trap.js +1 -0
- package/dist/components/icon.js +2 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/input.js +1 -0
- package/dist/components/layout-manager.d.ts +11 -0
- package/dist/components/layout-manager.js +1 -0
- package/dist/components/library-card.d.ts +11 -0
- package/dist/components/library-card.js +1 -0
- package/dist/components/library-card2.js +1 -0
- package/dist/components/list-group.js +1 -0
- package/dist/components/list-item.js +1 -0
- package/dist/components/lm-container.d.ts +11 -0
- package/dist/components/lm-container.js +1 -0
- package/dist/components/lm-container2.js +1 -0
- package/dist/components/lm-floating-window.d.ts +11 -0
- package/dist/components/lm-floating-window.js +1 -0
- package/dist/components/lm-floating-window2.js +1 -0
- package/dist/components/lm-panel.d.ts +11 -0
- package/dist/components/lm-panel.js +1 -0
- package/dist/components/lm-panel2.js +1 -0
- package/dist/components/lm-splitter.d.ts +11 -0
- package/dist/components/lm-splitter.js +1 -0
- package/dist/components/lm-splitter2.js +1 -0
- package/dist/components/lm-tabs.d.ts +11 -0
- package/dist/components/lm-tabs.js +1 -0
- package/dist/components/lm-tabs2.js +1 -0
- package/dist/components/my-component.d.ts +11 -0
- package/dist/components/my-component.js +1 -0
- package/dist/components/my-step.d.ts +11 -0
- package/dist/components/my-step.js +1 -0
- package/dist/components/nav-bar.d.ts +11 -0
- package/dist/components/nav-bar.js +1 -0
- package/dist/components/pagination.js +1 -0
- package/dist/components/radio.js +1 -0
- package/dist/components/range-slider.js +1 -0
- package/dist/components/rating.js +1 -0
- package/dist/components/resizable-panel.js +1 -0
- package/dist/components/skeleton-loader.js +1 -0
- package/dist/components/smart-step.d.ts +11 -0
- package/dist/components/smart-step.js +1 -0
- package/dist/components/stack.js +1 -0
- package/dist/components/switch.js +1 -0
- package/dist/components/tag-group.js +1 -0
- package/dist/components/tag.js +1 -0
- package/dist/components/timeline-item.d.ts +11 -0
- package/dist/components/timeline-item.js +1 -0
- package/dist/components/toggle-group.js +1 -0
- package/dist/components/tooltip.js +1 -0
- package/dist/components/ui-accordion.d.ts +11 -0
- package/dist/components/ui-accordion.js +1 -0
- package/dist/components/ui-advanced-data-table.d.ts +11 -0
- package/dist/components/ui-advanced-data-table.js +1 -0
- package/dist/components/ui-anchor.d.ts +11 -0
- package/dist/components/ui-anchor.js +1 -0
- package/dist/components/ui-animate-on-scroll.d.ts +11 -0
- package/dist/components/ui-animate-on-scroll.js +1 -0
- package/dist/components/ui-aside-panel.d.ts +11 -0
- package/dist/components/ui-aside-panel.js +1 -0
- package/dist/components/ui-avatar-group.d.ts +11 -0
- package/dist/components/ui-avatar-group.js +1 -0
- package/dist/components/ui-avatar.d.ts +11 -0
- package/dist/components/ui-avatar.js +1 -0
- package/dist/components/ui-badge.d.ts +11 -0
- package/dist/components/ui-badge.js +1 -0
- package/dist/components/ui-breadcrumb-item.d.ts +11 -0
- package/dist/components/ui-breadcrumb-item.js +1 -0
- package/dist/components/ui-breadcrumb.d.ts +11 -0
- package/dist/components/ui-breadcrumb.js +1 -0
- package/dist/components/ui-button-toggle-group.d.ts +11 -0
- package/dist/components/ui-button-toggle-group.js +1 -0
- package/dist/components/ui-button-toggle.d.ts +11 -0
- package/dist/components/ui-button-toggle.js +1 -0
- package/dist/components/ui-button.d.ts +11 -0
- package/dist/components/ui-button.js +1 -0
- package/dist/components/ui-callout-banner.d.ts +11 -0
- package/dist/components/ui-callout-banner.js +1 -0
- package/dist/components/ui-card.d.ts +11 -0
- package/dist/components/ui-card.js +1 -0
- package/dist/components/ui-carousel.d.ts +11 -0
- package/dist/components/ui-carousel.js +1 -0
- package/dist/components/ui-checkbox-group.d.ts +11 -0
- package/dist/components/ui-checkbox-group.js +1 -0
- package/dist/components/ui-checkbox.d.ts +11 -0
- package/dist/components/ui-checkbox.js +1 -0
- package/dist/components/ui-code-editor.d.ts +11 -0
- package/dist/components/ui-code-editor.js +1 -0
- package/dist/components/ui-code-preview.d.ts +11 -0
- package/dist/components/ui-code-preview.js +1 -0
- package/dist/components/ui-color-controller.d.ts +11 -0
- package/dist/components/ui-color-controller.js +1 -0
- package/dist/components/ui-color-picker.d.ts +11 -0
- package/dist/components/ui-color-picker.js +1 -0
- package/dist/components/ui-command-palette.d.ts +11 -0
- package/dist/components/ui-command-palette.js +1 -0
- package/dist/components/ui-context-menu.d.ts +11 -0
- package/dist/components/ui-context-menu.js +1 -0
- package/dist/components/ui-dialog-box.d.ts +11 -0
- package/dist/components/ui-dialog-box.js +1 -0
- package/dist/components/ui-dialog-content.d.ts +11 -0
- package/dist/components/ui-dialog-content.js +1 -0
- package/dist/components/ui-dialog-footer.d.ts +11 -0
- package/dist/components/ui-dialog-footer.js +1 -0
- package/dist/components/ui-dialog-header.d.ts +11 -0
- package/dist/components/ui-dialog-header.js +1 -0
- package/dist/components/ui-divider.d.ts +11 -0
- package/dist/components/ui-divider.js +1 -0
- package/dist/components/ui-dock-host.d.ts +11 -0
- package/dist/components/ui-dock-host.js +1 -0
- package/dist/components/ui-dock.d.ts +11 -0
- package/dist/components/ui-dock.js +1 -0
- package/dist/components/ui-drag-drop.d.ts +11 -0
- package/dist/components/ui-drag-drop.js +1 -0
- package/dist/components/ui-dropdown.d.ts +11 -0
- package/dist/components/ui-dropdown.js +1 -0
- package/dist/components/ui-empty-state.d.ts +11 -0
- package/dist/components/ui-empty-state.js +1 -0
- package/dist/components/ui-fab-item.d.ts +11 -0
- package/dist/components/ui-fab-item.js +1 -0
- package/dist/components/ui-fab.d.ts +11 -0
- package/dist/components/ui-fab.js +1 -0
- package/dist/components/ui-file-upload.d.ts +11 -0
- package/dist/components/ui-file-upload.js +1 -0
- package/dist/components/ui-horizontal-nav.d.ts +11 -0
- package/dist/components/ui-horizontal-nav.js +1 -0
- package/dist/components/ui-icon.d.ts +11 -0
- package/dist/components/ui-icon.js +1 -0
- package/dist/components/ui-image-button.d.ts +11 -0
- package/dist/components/ui-image-button.js +1 -0
- package/dist/components/ui-input-pair.d.ts +11 -0
- package/dist/components/ui-input-pair.js +1 -0
- package/dist/components/ui-input.d.ts +11 -0
- package/dist/components/ui-input.js +1 -0
- package/dist/components/ui-knob.d.ts +11 -0
- package/dist/components/ui-knob.js +1 -0
- package/dist/components/ui-library.d.ts +11 -0
- package/dist/components/ui-library.js +1 -0
- package/dist/components/ui-list-group.d.ts +11 -0
- package/dist/components/ui-list-group.js +1 -0
- package/dist/components/ui-list-item.d.ts +11 -0
- package/dist/components/ui-list-item.js +1 -0
- package/dist/components/ui-list.d.ts +11 -0
- package/dist/components/ui-list.js +1 -0
- package/dist/components/ui-masonry.d.ts +11 -0
- package/dist/components/ui-masonry.js +1 -0
- package/dist/components/ui-meter-group.d.ts +11 -0
- package/dist/components/ui-meter-group.js +1 -0
- package/dist/components/ui-navigation-bar.d.ts +11 -0
- package/dist/components/ui-navigation-bar.js +1 -0
- package/dist/components/ui-navigation-item.d.ts +11 -0
- package/dist/components/ui-navigation-item.js +1 -0
- package/dist/components/ui-number-input.d.ts +11 -0
- package/dist/components/ui-number-input.js +1 -0
- package/dist/components/ui-otp-input.d.ts +11 -0
- package/dist/components/ui-otp-input.js +1 -0
- package/dist/components/ui-pagination.d.ts +11 -0
- package/dist/components/ui-pagination.js +1 -0
- package/dist/components/ui-panel.d.ts +11 -0
- package/dist/components/ui-panel.js +1 -0
- package/dist/components/ui-pattern-input.d.ts +11 -0
- package/dist/components/ui-pattern-input.js +1 -0
- package/dist/components/ui-popover.d.ts +11 -0
- package/dist/components/ui-popover.js +1 -0
- package/dist/components/ui-progress.d.ts +11 -0
- package/dist/components/ui-progress.js +1 -0
- package/dist/components/ui-radio-group.d.ts +11 -0
- package/dist/components/ui-radio-group.js +1 -0
- package/dist/components/ui-radio.d.ts +11 -0
- package/dist/components/ui-radio.js +1 -0
- package/dist/components/ui-range-slider.d.ts +11 -0
- package/dist/components/ui-range-slider.js +1 -0
- package/dist/components/ui-rating.d.ts +11 -0
- package/dist/components/ui-rating.js +1 -0
- package/dist/components/ui-resizable-panel.d.ts +11 -0
- package/dist/components/ui-resizable-panel.js +1 -0
- package/dist/components/ui-scroll-top.d.ts +11 -0
- package/dist/components/ui-scroll-top.js +1 -0
- package/dist/components/ui-skeleton.d.ts +11 -0
- package/dist/components/ui-skeleton.js +1 -0
- package/dist/components/ui-smart-context-menu.d.ts +11 -0
- package/dist/components/ui-smart-context-menu.js +1 -0
- package/dist/components/ui-smart-location-dropdown.d.ts +11 -0
- package/dist/components/ui-smart-location-dropdown.js +1 -0
- package/dist/components/ui-smart-stepper.d.ts +11 -0
- package/dist/components/ui-smart-stepper.js +1 -0
- package/dist/components/ui-snackbar.d.ts +11 -0
- package/dist/components/ui-snackbar.js +1 -0
- package/dist/components/ui-speed-dial.d.ts +11 -0
- package/dist/components/ui-speed-dial.js +1 -0
- package/dist/components/ui-speedometer.d.ts +11 -0
- package/dist/components/ui-speedometer.js +1 -0
- package/dist/components/ui-splitter.d.ts +11 -0
- package/dist/components/ui-splitter.js +1 -0
- package/dist/components/ui-stack.d.ts +11 -0
- package/dist/components/ui-stack.js +1 -0
- package/dist/components/ui-step.d.ts +11 -0
- package/dist/components/ui-step.js +1 -0
- package/dist/components/ui-stepper.d.ts +11 -0
- package/dist/components/ui-stepper.js +1 -0
- package/dist/components/ui-switch.d.ts +11 -0
- package/dist/components/ui-switch.js +1 -0
- package/dist/components/ui-tabs.d.ts +11 -0
- package/dist/components/ui-tabs.js +1 -0
- package/dist/components/ui-tag-group.d.ts +11 -0
- package/dist/components/ui-tag-group.js +1 -0
- package/dist/components/ui-tag.d.ts +11 -0
- package/dist/components/ui-tag.js +1 -0
- package/dist/components/ui-timeline.d.ts +11 -0
- package/dist/components/ui-timeline.js +1 -0
- package/dist/components/ui-timer.d.ts +11 -0
- package/dist/components/ui-timer.js +1 -0
- package/dist/components/ui-toggle-group.d.ts +11 -0
- package/dist/components/ui-toggle-group.js +1 -0
- package/dist/components/ui-toolbar.d.ts +11 -0
- package/dist/components/ui-toolbar.js +1 -0
- package/dist/components/ui-tooltip.d.ts +11 -0
- package/dist/components/ui-tooltip.js +1 -0
- package/dist/components/ui-top-bar.d.ts +11 -0
- package/dist/components/ui-top-bar.js +1 -0
- package/dist/components/ui-transfer-list.d.ts +11 -0
- package/dist/components/ui-transfer-list.js +1 -0
- package/dist/components/ui-tree.d.ts +11 -0
- package/dist/components/ui-tree.js +1 -0
- package/dist/components/ui-workspace-manager.d.ts +11 -0
- package/dist/components/ui-workspace-manager.js +1 -0
- package/dist/components/utils.js +1 -0
- package/dist/esm/category-section.entry.js +28 -0
- package/dist/esm/component-size-C7gf39HE.js +27 -0
- package/dist/esm/dom-BMFah5q3.js +262 -0
- package/dist/esm/event-bus-vwwmWKs9.js +21 -0
- package/dist/esm/exploration-project-tailwind.js +20 -0
- package/dist/esm/focus-trap-BSQ8klD4.js +137 -0
- package/dist/esm/index-DUsoYu9r.js +2264 -0
- package/dist/esm/index.js +256 -0
- package/dist/esm/layout-manager.entry.js +614 -0
- package/dist/esm/library-card.entry.js +61 -0
- package/dist/esm/lm-container_2.entry.js +76 -0
- package/dist/esm/lm-panel_3.entry.js +104 -0
- package/dist/esm/loader.js +10 -0
- package/dist/esm/my-component.entry.js +31 -0
- package/dist/esm/my-step.entry.js +27 -0
- package/dist/esm/nav-bar.entry.js +245 -0
- package/dist/esm/security-D2WzX6vR.js +1545 -0
- package/dist/esm/smart-step.entry.js +45 -0
- package/dist/esm/timeline-item.entry.js +27 -0
- package/dist/esm/ui-accordion_10.entry.js +5722 -0
- package/dist/esm/ui-advanced-data-table.entry.js +2682 -0
- package/dist/esm/ui-anchor.entry.js +556 -0
- package/dist/esm/ui-animate-on-scroll.entry.js +283 -0
- package/dist/esm/ui-aside-panel.entry.js +636 -0
- package/dist/esm/ui-avatar-group_3.entry.js +630 -0
- package/dist/esm/ui-breadcrumb-item.entry.js +54 -0
- package/dist/esm/ui-breadcrumb.entry.js +199 -0
- package/dist/esm/ui-callout-banner.entry.js +289 -0
- package/dist/esm/ui-card.entry.js +409 -0
- package/dist/esm/ui-carousel.entry.js +545 -0
- package/dist/esm/ui-checkbox-group.entry.js +328 -0
- package/dist/esm/ui-checkbox.entry.js +258 -0
- package/dist/esm/ui-code-editor.entry.js +959 -0
- package/dist/esm/ui-code-preview.entry.js +313 -0
- package/dist/esm/ui-color-controller.entry.js +148 -0
- package/dist/esm/ui-color-picker.entry.js +656 -0
- package/dist/esm/ui-command-palette.entry.js +176 -0
- package/dist/esm/ui-dialog-box.entry.js +1806 -0
- package/dist/esm/ui-dialog-content.entry.js +29 -0
- package/dist/esm/ui-dialog-footer_2.entry.js +190 -0
- package/dist/esm/ui-divider.entry.js +479 -0
- package/dist/esm/ui-dock-host.entry.js +126 -0
- package/dist/esm/ui-dock.entry.js +219 -0
- package/dist/esm/ui-drag-drop.entry.js +170 -0
- package/dist/esm/ui-dropdown_2.entry.js +1549 -0
- package/dist/esm/ui-empty-state.entry.js +396 -0
- package/dist/esm/ui-fab-item.entry.js +37 -0
- package/dist/esm/ui-fab.entry.js +275 -0
- package/dist/esm/ui-file-upload.entry.js +416 -0
- package/dist/esm/ui-horizontal-nav.entry.js +133 -0
- package/dist/esm/ui-image-button.entry.js +65 -0
- package/dist/esm/ui-input-pair.entry.js +42 -0
- package/dist/esm/ui-knob.entry.js +445 -0
- package/dist/esm/ui-library.entry.js +132 -0
- package/dist/esm/ui-list-group_2.entry.js +583 -0
- package/dist/esm/ui-list.entry.js +730 -0
- package/dist/esm/ui-masonry.entry.js +476 -0
- package/dist/esm/ui-meter-group.entry.js +171 -0
- package/dist/esm/ui-navigation-item.entry.js +102 -0
- package/dist/esm/ui-number-input.entry.js +189 -0
- package/dist/esm/ui-otp-input.entry.js +244 -0
- package/dist/esm/ui-pagination_3.entry.js +1617 -0
- package/dist/esm/ui-panel.entry.js +612 -0
- package/dist/esm/ui-pattern-input.entry.js +276 -0
- package/dist/esm/ui-popover.entry.js +515 -0
- package/dist/esm/ui-progress.entry.js +514 -0
- package/dist/esm/ui-radio-group.entry.js +203 -0
- package/dist/esm/ui-radio.entry.js +204 -0
- package/dist/esm/ui-range-slider.entry.js +635 -0
- package/dist/esm/ui-resizable-panel.entry.js +482 -0
- package/dist/esm/ui-scroll-top.entry.js +457 -0
- package/dist/esm/ui-smart-context-menu.entry.js +374 -0
- package/dist/esm/ui-smart-location-dropdown.entry.js +563 -0
- package/dist/esm/ui-smart-stepper.entry.js +135 -0
- package/dist/esm/ui-snackbar.entry.js +861 -0
- package/dist/esm/ui-speed-dial.entry.js +518 -0
- package/dist/esm/ui-speedometer.entry.js +426 -0
- package/dist/esm/ui-splitter.entry.js +280 -0
- package/dist/esm/ui-step.entry.js +28 -0
- package/dist/esm/ui-stepper.entry.js +638 -0
- package/dist/esm/ui-switch.entry.js +403 -0
- package/dist/esm/ui-tabs.entry.js +701 -0
- package/dist/esm/ui-tag.entry.js +297 -0
- package/dist/esm/ui-timeline.entry.js +265 -0
- package/dist/esm/ui-timer.entry.js +500 -0
- package/dist/esm/ui-toolbar.entry.js +617 -0
- package/dist/esm/ui-tooltip.entry.js +695 -0
- package/dist/esm/ui-top-bar.entry.js +119 -0
- package/dist/esm/ui-transfer-list.entry.js +590 -0
- package/dist/esm/ui-tree.entry.js +872 -0
- package/dist/esm/ui-workspace-manager.entry.js +1199 -0
- package/dist/esm/utils-Ck6jDuhz.js +23 -0
- package/dist/exploration-project-tailwind/exploration-project-tailwind.css +1 -0
- package/dist/exploration-project-tailwind/exploration-project-tailwind.esm.js +1 -0
- package/dist/exploration-project-tailwind/index.esm.js +1 -0
- package/dist/exploration-project-tailwind/p-01c7db7a.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-049744f9.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-06f0c679.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-0b004861.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-0d31c9e9.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-148e81df.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-200241f8.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-287dbf09.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-2d273118.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-2f1aebb3.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-2f961934.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-35296877.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-36861546.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-3d3d48fd.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-41cd6bf0.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-45482d86.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-46596a28.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-46efdea3.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-47e2a7ee.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-4d73c143.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-4de419d5.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-4f6bba75.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-5508874f.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-5ce0dbd8.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-5e3e80ae.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-61717490.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-62352ef2.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-64e3a484.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-6ab80ead.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-6e9694f2.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-6fa9dc15.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-70d82d79.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-717dad1f.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-7376ac95.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-73d29a4a.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-7515b1e3.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-77124686.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-77a21491.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-77cc333a.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-7f91d949.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-807c6555.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-81961fb1.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-85bf89fd.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-85e36111.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-875be805.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-898dd0fa.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-8d951aef.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-9d0c8760.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-9fa70359.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-9fc06ff0.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-BMFah5q3.js +1 -0
- package/dist/exploration-project-tailwind/p-BSQ8klD4.js +1 -0
- package/dist/exploration-project-tailwind/p-C7gf39HE.js +1 -0
- package/dist/exploration-project-tailwind/p-Ck6jDuhz.js +1 -0
- package/dist/exploration-project-tailwind/p-D2WzX6vR.js +2 -0
- package/dist/exploration-project-tailwind/p-DUsoYu9r.js +2 -0
- package/dist/exploration-project-tailwind/p-a1ad32a2.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-a3f465d9.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-a42fdc33.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-a4f52a76.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-aa85ff78.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-ab752761.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-ba21fed3.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c174a372.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c2ca71ac.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c4ba7e52.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c5ddc817.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c69dd43e.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c6fd72e1.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c7e87fbb.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c87aeab6.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-c90722ec.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-ccb5c737.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-ce1222a1.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-d16c9635.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-d2308a00.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-d30e24bd.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-d419eaf0.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-debede45.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-e5322e59.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-e8ba0c95.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-e90d5307.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-ea51c5d8.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-ecda1cc3.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-f0830120.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-f11e5cae.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-f5719913.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-ffb1754a.entry.js +1 -0
- package/dist/exploration-project-tailwind/p-vwwmWKs9.js +1 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/types/components/accordion/accordion.d.ts +352 -0
- package/dist/types/components/accordion/types.d.ts +69 -0
- package/dist/types/components/advanced-data-table/advanced-data-table.d.ts +697 -0
- package/dist/types/components/advanced-data-table/types.d.ts +120 -0
- package/dist/types/components/anchor/anchor.d.ts +133 -0
- package/dist/types/components/anchor/types.d.ts +17 -0
- package/dist/types/components/animate-on-scroll/animate-on-scroll.d.ts +101 -0
- package/dist/types/components/aside-panel/aside-panel.d.ts +249 -0
- package/dist/types/components/avatar/avatar.d.ts +201 -0
- package/dist/types/components/avatar/types.d.ts +132 -0
- package/dist/types/components/avatar-group/avatar-group.d.ts +52 -0
- package/dist/types/components/avatar-group/types.d.ts +31 -0
- package/dist/types/components/badge/badge.d.ts +109 -0
- package/dist/types/components/badge/types.d.ts +6 -0
- package/dist/types/components/breadcrumb/breadcrumb-item.d.ts +36 -0
- package/dist/types/components/breadcrumb/breadcrumb.d.ts +73 -0
- package/dist/types/components/breadcrumb/types.d.ts +5 -0
- package/dist/types/components/button/button.d.ts +133 -0
- package/dist/types/components/button/types.d.ts +1 -0
- package/dist/types/components/button-toggle/button-toggle.d.ts +64 -0
- package/dist/types/components/button-toggle-group/button-toggle-group.d.ts +141 -0
- package/dist/types/components/button-toggle-group/types.d.ts +7 -0
- package/dist/types/components/callout-banner/callout-banner.d.ts +115 -0
- package/dist/types/components/callout-banner/types.d.ts +7 -0
- package/dist/types/components/card/card.d.ts +160 -0
- package/dist/types/components/card/types.d.ts +13 -0
- package/dist/types/components/carousel/carousel.d.ts +150 -0
- package/dist/types/components/carousel/types.d.ts +8 -0
- package/dist/types/components/checkbox/checkbox.d.ts +92 -0
- package/dist/types/components/checkbox/types.d.ts +5 -0
- package/dist/types/components/checkbox-group/checkbox-group.d.ts +87 -0
- package/dist/types/components/checkbox-group/types.d.ts +8 -0
- package/dist/types/components/code-editor/code-editor.d.ts +147 -0
- package/dist/types/components/code-editor/types.d.ts +20 -0
- package/dist/types/components/code-preview/types.d.ts +5 -0
- package/dist/types/components/code-preview/ui-code-preview.d.ts +69 -0
- package/dist/types/components/color-controller/color-controller.d.ts +24 -0
- package/dist/types/components/color-picker/color-picker.d.ts +116 -0
- package/dist/types/components/color-picker/types.d.ts +24 -0
- package/dist/types/components/command-palette/command-palette.d.ts +41 -0
- package/dist/types/components/command-palette/types.d.ts +7 -0
- package/dist/types/components/context-menu/context-menu.d.ts +135 -0
- package/dist/types/components/context-menu/types.d.ts +20 -0
- package/dist/types/components/dialog-box/dialog-box.d.ts +648 -0
- package/dist/types/components/dialog-box/types.d.ts +1 -0
- package/dist/types/components/dialog-content/dialog-content.d.ts +9 -0
- package/dist/types/components/dialog-footer/dialog-footer.d.ts +9 -0
- package/dist/types/components/dialog-footer/types.d.ts +1 -0
- package/dist/types/components/dialog-header/dialog-header.d.ts +102 -0
- package/dist/types/components/dialog-header/types.d.ts +2 -0
- package/dist/types/components/divider/divider.d.ts +245 -0
- package/dist/types/components/divider/types.d.ts +14 -0
- package/dist/types/components/dock/dock.d.ts +37 -0
- package/dist/types/components/dock/types.d.ts +11 -0
- package/dist/types/components/dock-host/index.d.ts +1 -0
- package/dist/types/components/dock-host/types.d.ts +1 -0
- package/dist/types/components/dock-host/ui-dock-host.d.ts +23 -0
- package/dist/types/components/drag-drop/drag-drop.d.ts +52 -0
- package/dist/types/components/drag-drop/types.d.ts +9 -0
- package/dist/types/components/dropdown/dropdown.d.ts +264 -0
- package/dist/types/components/dropdown/types.d.ts +19 -0
- package/dist/types/components/empty-state/empty-state.d.ts +74 -0
- package/dist/types/components/empty-state/types.d.ts +13 -0
- package/dist/types/components/fab/fab.d.ts +73 -0
- package/dist/types/components/fab-item/fab-item.d.ts +14 -0
- package/dist/types/components/fab-item/types.d.ts +3 -0
- package/dist/types/components/file-upload/file-upload.d.ts +91 -0
- package/dist/types/components/file-upload/types.d.ts +15 -0
- package/dist/types/components/horizontal-nav/horizontal-nav.d.ts +68 -0
- package/dist/types/components/icon/icon.d.ts +66 -0
- package/dist/types/components/image-button/image-button.d.ts +31 -0
- package/dist/types/components/image-button/types.d.ts +1 -0
- package/dist/types/components/input/input.d.ts +217 -0
- package/dist/types/components/input/types.d.ts +6 -0
- package/dist/types/components/input-pair/input-pair.d.ts +28 -0
- package/dist/types/components/knob/knob.d.ts +147 -0
- package/dist/types/components/knob/types.d.ts +4 -0
- package/dist/types/components/layout-manager/layout-manager.d.ts +32 -0
- package/dist/types/components/layout-manager/lm-container/lm-container.d.ts +7 -0
- package/dist/types/components/layout-manager/lm-floating-window/lm-floating-window.d.ts +6 -0
- package/dist/types/components/layout-manager/lm-panel/lm-panel.d.ts +7 -0
- package/dist/types/components/layout-manager/lm-splitter/lm-splitter.d.ts +12 -0
- package/dist/types/components/layout-manager/lm-tabs/lm-tabs.d.ts +12 -0
- package/dist/types/components/layout-manager/types.d.ts +1 -0
- package/dist/types/components/library/category-section.d.ts +15 -0
- package/dist/types/components/library/data.d.ts +11 -0
- package/dist/types/components/library/library-card.d.ts +19 -0
- package/dist/types/components/library/library.d.ts +9 -0
- package/dist/types/components/list/list.d.ts +183 -0
- package/dist/types/components/list-group/list-group.d.ts +28 -0
- package/dist/types/components/list-item/list-item.d.ts +200 -0
- package/dist/types/components/masonry/masonry.d.ts +105 -0
- package/dist/types/components/masonry/types.d.ts +5 -0
- package/dist/types/components/meter-group/meter-group.d.ts +66 -0
- package/dist/types/components/meter-group/types.d.ts +12 -0
- package/dist/types/components/my-component/my-component.d.ts +16 -0
- package/dist/types/components/my-step/index.d.ts +12 -0
- package/dist/types/components/my-step/my-step.d.ts +13 -0
- package/dist/types/components/nav-bar/nav-bar.d.ts +119 -0
- package/dist/types/components/number-input/number-input.d.ts +72 -0
- package/dist/types/components/otp-input/otp-input.d.ts +64 -0
- package/dist/types/components/otp-input/types.d.ts +3 -0
- package/dist/types/components/pagination/pagination.d.ts +295 -0
- package/dist/types/components/pagination/types.d.ts +1 -0
- package/dist/types/components/panel/panel.d.ts +275 -0
- package/dist/types/components/panel/types.d.ts +7 -0
- package/dist/types/components/pattern-input/pattern-input.d.ts +88 -0
- package/dist/types/components/popover/popover.d.ts +161 -0
- package/dist/types/components/popover/types.d.ts +3 -0
- package/dist/types/components/progress/progress.d.ts +224 -0
- package/dist/types/components/progress/types.d.ts +6 -0
- package/dist/types/components/radio/radio.d.ts +87 -0
- package/dist/types/components/radio/types.d.ts +7 -0
- package/dist/types/components/radio-group/radio-group.d.ts +74 -0
- package/dist/types/components/radio-group/types.d.ts +2 -0
- package/dist/types/components/range-slider/range-slider.d.ts +201 -0
- package/dist/types/components/range-slider/types.d.ts +4 -0
- package/dist/types/components/rating/rating.d.ts +127 -0
- package/dist/types/components/rating/types.d.ts +1 -0
- package/dist/types/components/resizable-panel/resizable-panel.d.ts +59 -0
- package/dist/types/components/resizable-panel/types.d.ts +11 -0
- package/dist/types/components/scroll-top/scroll-top.d.ts +186 -0
- package/dist/types/components/scroll-top/types.d.ts +1 -0
- package/dist/types/components/skeleton/skeleton-loader.d.ts +149 -0
- package/dist/types/components/skeleton/types.d.ts +1 -0
- package/dist/types/components/smart-location-dropdown/smart-location-dropdown.d.ts +119 -0
- package/dist/types/components/smart-location-dropdown/types.d.ts +37 -0
- package/dist/types/components/smart-menu/menu-item.interface.d.ts +10 -0
- package/dist/types/components/smart-menu/smart-menu.d.ts +64 -0
- package/dist/types/components/smart-stepper/smart-step.d.ts +29 -0
- package/dist/types/components/smart-stepper/smart-stepper.d.ts +53 -0
- package/dist/types/components/snackbar/snackbar.d.ts +223 -0
- package/dist/types/components/snackbar/types.d.ts +104 -0
- package/dist/types/components/speed-dial/speed-dial.d.ts +171 -0
- package/dist/types/components/speed-dial/types.d.ts +11 -0
- package/dist/types/components/speedometer/speedometer.d.ts +125 -0
- package/dist/types/components/speedometer/types.d.ts +8 -0
- package/dist/types/components/splitter/splitter.d.ts +63 -0
- package/dist/types/components/splitter/types.d.ts +9 -0
- package/dist/types/components/stack/stack.d.ts +34 -0
- package/dist/types/components/stack/types.d.ts +3 -0
- package/dist/types/components/step/step.d.ts +16 -0
- package/dist/types/components/step/types.d.ts +1 -0
- package/dist/types/components/stepper/stepper.d.ts +218 -0
- package/dist/types/components/stepper/types.d.ts +39 -0
- package/dist/types/components/switch/switch.d.ts +162 -0
- package/dist/types/components/tabs/tabs.d.ts +182 -0
- package/dist/types/components/tabs/types.d.ts +17 -0
- package/dist/types/components/tag/tag.d.ts +172 -0
- package/dist/types/components/tag/types.d.ts +4 -0
- package/dist/types/components/tag-group/tag-group.d.ts +107 -0
- package/dist/types/components/tag-group/types.d.ts +2 -0
- package/dist/types/components/timeline/timeline.d.ts +73 -0
- package/dist/types/components/timeline/types.d.ts +28 -0
- package/dist/types/components/timeline/ui-timeline.stories.d.ts +9 -0
- package/dist/types/components/timeline-item/timeline-item.d.ts +15 -0
- package/dist/types/components/timer/timer.d.ts +123 -0
- package/dist/types/components/timer/types.d.ts +18 -0
- package/dist/types/components/timer/ui-timer.stories.d.ts +9 -0
- package/dist/types/components/toggle-group/toggle-group.d.ts +136 -0
- package/dist/types/components/toggle-group/types.d.ts +5 -0
- package/dist/types/components/toolbar/toolbar-types.d.ts +189 -0
- package/dist/types/components/toolbar/toolbar.d.ts +150 -0
- package/dist/types/components/tooltip/tooltip.d.ts +166 -0
- package/dist/types/components/tooltip/types.d.ts +3 -0
- package/dist/types/components/top-bar/top-bar.d.ts +76 -0
- package/dist/types/components/transfer-list/transfer-list.d.ts +137 -0
- package/dist/types/components/transfer-list/types.d.ts +13 -0
- package/dist/types/components/tree/tree.d.ts +180 -0
- package/dist/types/components/tree/types.d.ts +76 -0
- package/dist/types/components/ui-navigation-bar/navigation-bar/navigation-bar.d.ts +108 -0
- package/dist/types/components/ui-navigation-bar/navigation-bar/navigation-types.d.ts +17 -0
- package/dist/types/components/ui-navigation-bar/navigation-item.d.ts +26 -0
- package/dist/types/components/ui-navigation-bar/navigation-types.d.ts +19 -0
- package/dist/types/components/workspace-manager/types.d.ts +48 -0
- package/dist/types/components/workspace-manager/workspace-manager.d.ts +211 -0
- package/dist/types/components.d.ts +29634 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/service/drag-manager.d.ts +8 -0
- package/dist/types/service/event-bus.d.ts +9 -0
- package/dist/types/service/serialization.d.ts +5 -0
- package/dist/types/service/state-engine.d.ts +25 -0
- package/dist/types/service/theme-switcher.d.ts +46 -0
- package/dist/types/stencil-public-runtime.d.ts +1860 -0
- package/dist/types/types/animation.type.d.ts +96 -0
- package/dist/types/types/common.d.ts +52 -0
- package/dist/types/types/common.type.d.ts +608 -0
- package/dist/types/types/index.d.ts +37 -0
- package/dist/types/types/text.type.d.ts +32 -0
- package/dist/types/utils/aria-live.d.ts +20 -0
- package/dist/types/utils/component-size.d.ts +2 -0
- package/dist/types/utils/dom.d.ts +58 -0
- package/dist/types/utils/focus-trap.d.ts +35 -0
- package/dist/types/utils/security.d.ts +5 -0
- package/dist/types/utils/test/setup-component-test-env.d.ts +14 -0
- package/dist/types/utils/utils.d.ts +7 -0
- package/dist/types/utils/validation.d.ts +43 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +77 -0
|
@@ -0,0 +1,2682 @@
|
|
|
1
|
+
import { r as registerInstance, c as createEvent, a as getElement, h } from './index-DUsoYu9r.js';
|
|
2
|
+
|
|
3
|
+
const advancedDataTableCss = () => `.sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border-width:0 !important}.a11y-sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border-width:0 !important}:host([color=primary]),.table-color-primary{--table-primary:var(--color-primary-hover, #2563eb);--table-primary-rgb:var(--color-primary-rgb)}:host([color=secondary]),.table-color-secondary{--table-primary:var(--color-primary, #64748b);--table-primary-rgb:var(--color-primary-rgb)}:host([color=success]),.table-color-success{--table-primary:var(--color-success, #10b981);--table-primary-rgb:var(--color-primary-rgb)}:host([color=danger]),.table-color-danger{--table-primary:var(--color-danger, #ef4444);--table-primary-rgb:var(--color-primary-rgb)}:host([color=warning]),.table-color-warning{--table-primary:var(--color-warning, #f59e0b);--table-primary-rgb:var(--color-primary-rgb)}:host([color=info]),.table-color-info{--table-primary:var(--color-primary, #0ea5e9);--table-primary-rgb:var(--color-primary-rgb)}:host{display:block;font-family:"Inter", -apple-system, sans-serif;--table-bg:var(--bg-primary, #ffffff);--table-header-bg:var(--bg-primary, #f8fafc);--table-border:var(--border-subtle, #f1f5f9);--table-text:var(--text-primary, #1e293b);--table-text-secondary:var(--color-primary, #64748b);--table-text-secondary-rgb:100, 116, 139;--table-hover:var(--bg-primary, #f1f5f9);--table-primary:var(--color-primary-hover, #2563eb);--table-primary-rgb:37, 99, 235;--table-selected:rgba(var(--table-primary-rgb), 0.1);--table-shadow:rgba(0, 0, 0, 0.05);--table-striped-bg:rgba(0, 0, 0, 0.02);--table-striped-bg-dark:rgba(255, 255, 255, 0.02)}.data-table-container{background:var(--table-bg);border-radius:8px;box-shadow:0 1px 3px var(--table-shadow);overflow:hidden}.data-table-container.dark-mode{--table-bg:var(--bg-secondary, #0f172a);--table-header-bg:var(--bg-primary, #1e293b);--table-border:rgba(255, 255, 255, 0.05);--table-text:var(--bg-primary, #f8fafc);--table-text-secondary:var(--color-primary, #94a3b8);--table-hover:rgba(255, 255, 255, 0.03);--table-selected:rgba(var(--table-primary-rgb), 0.1);--table-shadow:rgba(0, 0, 0, 0.4)}.advanced-table-glass{background:transparent !important;box-shadow:none !important}.advanced-table-glass .table-toolbar{background:rgba(255, 255, 255, 0.03);backdrop-filter:blur(12px) saturate(160%);border-color:rgba(255, 255, 255, 0.08)}.advanced-table-glass .data-table thead{background:rgba(255, 255, 255, 0.05);backdrop-filter:blur(8px)}.advanced-table-glass .data-table tbody tr{background:transparent}.advanced-table-glass .data-table tbody tr:hover{background:rgba(255, 255, 255, 0.04)}.advanced-table-glass.dark-mode .table-toolbar{background:rgba(0, 0, 0, 0.2)}.advanced-table-glass.dark-mode .data-table thead{background:rgba(0, 0, 0, 0.3)}.advanced-table-raised{box-shadow:0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);border:1px solid rgba(0, 0, 0, 0.05)}.advanced-table-raised .data-table thead{background:linear-gradient(to bottom, var(--bg-primary, #f8fafc), var(--bg-secondary, #f1f5f9))}.table-toolbar{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;background:var(--table-header-bg);border-bottom:1px solid var(--table-border);gap:16px;flex-wrap:wrap;transition:all cubic-bezier(0.4, 0, 0.2, 1)}.toolbar-left,.toolbar-right{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.search-box{position:relative;min-width:250px}.search-box input{width:100%;padding:8px 36px 8px 12px;border:1px solid var(--table-border);border-radius:6px;font-size:14px;background:var(--table-bg);color:var(--table-text);transition:all 0.2s}.search-box input:focus{outline:none;border-color:var(--table-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.search-icon{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;opacity:0.5}.toolbar-btn{padding:8px 16px;background:var(--table-bg);color:var(--table-text);border:1px solid var(--table-border);border-radius:6px;font-size:14px;cursor:pointer;transition:all 0.2s;display:flex;align-items:center;gap:6px}.toolbar-btn:hover{background:var(--table-hover);border-color:var(--table-primary)}.toolbar-btn:active{transform:scale(0.98)}.table-wrapper{overflow-x:auto;overflow-y:auto;max-height:70vh;position:relative}.table-wrapper::-webkit-scrollbar{width:8px;height:8px}.table-wrapper::-webkit-scrollbar-track{background:var(--table-header-bg)}.table-wrapper::-webkit-scrollbar-thumb{background:var(--table-border);border-radius:4px}.table-wrapper::-webkit-scrollbar-thumb:hover{background:var(--table-text-secondary)}.data-table{width:100%;border-collapse:collapse;color:var(--table-text);font-size:13.5px;letter-spacing:-0.01em}.data-table.bordered{border:1px solid var(--table-border);border-radius:8px}.data-table thead{background:var(--table-header-bg);position:relative;z-index:10}.data-table.sticky-header thead{position:sticky;top:0;z-index:20}.data-table th{padding:14px 20px;text-align:left;font-weight:600;white-space:nowrap;background:var(--table-header-bg);color:var(--table-text-secondary);border-bottom:2px solid var(--table-border);user-select:none;text-transform:uppercase;font-size:11px;letter-spacing:0.05em;transition:background cubic-bezier(0.4, 0, 0.2, 1), color cubic-bezier(0.4, 0, 0.2, 1)}.data-table th.sticky-column{position:sticky;left:0;z-index:30;box-shadow:2px 0 4px var(--table-shadow)}.data-table th.sortable{cursor:pointer;transition:background 0.2s}.data-table th.sortable:hover{background:var(--table-hover)}.column-header-content{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:24px}.drag-handle{cursor:grab;padding:0 4px;margin-right:4px;color:var(--table-text-secondary);font-size:14px;line-height:1;opacity:0.6;transition:all 0.2s;user-select:none;letter-spacing:-2px}.drag-handle:hover{opacity:1;color:var(--table-primary)}.drag-handle:active{cursor:grabbing}.column-label{flex:1;cursor:pointer;user-select:none}.data-table th.sortable .column-label:hover{color:var(--table-primary)}.column-header-content span:first-child{flex:1}.sort-icon{font-size:12px;opacity:0.5;transition:opacity 0.2s}.data-table th.sorted .sort-icon{opacity:1;color:var(--table-primary)}.column-filter{margin-top:8px}.column-filter input{width:100%;padding:4px 8px;border:1px solid var(--table-border);border-radius:4px;font-size:12px;background:var(--table-bg);color:var(--table-text)}.column-filter input:focus{outline:none;border-color:var(--table-primary)}.column-group{border-bottom:1px solid var(--table-border);background:var(--table-header-bg);font-weight:700}.resize-handle{position:absolute;top:0;right:0;width:4px;height:100%;cursor:col-resize;user-select:none;background:transparent;transition:background 0.2s;z-index:10}.resize-handle:hover{background:var(--table-primary)}.resize-handle::before{content:"";position:absolute;top:0;bottom:0;left:-2px;right:-2px;}.data-table th.resizing{user-select:none;cursor:col-resize}.data-table th.resizing .resize-handle{background:var(--table-primary)}.data-table tbody tr{transition:background cubic-bezier(0.4, 0, 0.2, 1);border-bottom:1px solid var(--table-border)}.data-table.hoverable tbody tr:hover{background:var(--table-hover);box-shadow:inset 4px 0 0 var(--table-primary)}.data-table.striped tbody tr:nth-child(even){background:var(--table-striped-bg)}.data-table-container.dark-mode .data-table.striped tbody tr:nth-child(even){background:var(--table-striped-bg-dark)}.data-table tbody tr.selected{background:var(--table-selected) !important}.data-table td{padding:14px 20px;color:var(--table-text);transition:color cubic-bezier(0.4, 0, 0.2, 1)}.data-table.compact td,.data-table.compact th{padding:6px 12px}.data-table.comfortable td,.data-table.comfortable th{padding:16px 20px}.data-table td.sticky-column{position:sticky;left:0;background:var(--table-bg);z-index:15;box-shadow:2px 0 4px var(--table-shadow)}.data-table tbody tr:hover td.sticky-column{background:var(--table-hover)}.data-table tbody tr.selected td.sticky-column{background:var(--table-selected)}.select-column{width:48px;text-align:center !important;padding:8px !important}.select-column input[type=checkbox]{width:18px;height:18px;cursor:pointer;accent-color:var(--table-primary)}.actions-column{width:60px;text-align:center !important;padding:8px !important;position:relative}.row-actions-container{position:relative;display:inline-block}.row-actions-trigger{background:transparent;border:none;cursor:pointer;padding:4px 8px;border-radius:4px;color:var(--table-text-secondary);font-size:18px;line-height:1;transition:all 0.2s ease;display:flex;align-items:center;justify-content:center}.row-actions-trigger:hover{background:var(--table-hover);color:var(--table-text)}.row-actions-trigger:active{background:var(--table-border)}.action-dots{font-weight:bold;letter-spacing:-2px}.row-actions-menu{position:absolute;top:100%;right:0;background:var(--table-bg);border:1px solid var(--table-border);border-radius:6px;box-shadow:0 4px 12px rgba(0, 0, 0, 0.15);min-width:140px;z-index:1000;margin-top:4px;overflow:hidden;animation:fadeInMenu 0.15s ease-out}@keyframes fadeInMenu{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.row-action-item{display:flex;align-items:center;gap:8px;width:100%;padding:10px 14px;background:transparent;border:none;text-align:left;cursor:pointer;color:var(--table-text);font-size:14px;transition:background 0.15s ease;border-bottom:1px solid var(--table-border)}.row-action-item:last-child{border-bottom:none}.row-action-item:hover{background:var(--table-hover)}.row-action-item:active{background:var(--table-border)}.action-icon{font-size:16px;width:20px;display:flex;align-items:center;justify-content:center}.action-label{flex:1}.grouping-selector{display:flex;align-items:center;gap:8px;margin-left:16px}.grouping-selector label{font-size:14px;font-weight:500;color:var(--table-text);white-space:nowrap}.grouping-selector select{padding:8px 12px;border:1px solid var(--table-border);border-radius:6px;font-size:14px;background:var(--table-bg);color:var(--table-text);cursor:pointer;min-width:150px;transition:all 0.2s}.grouping-selector select:focus{outline:none;border-color:var(--table-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.grouping-selector select:hover{border-color:var(--table-primary)}.group-header-row{background:var(--table-header-bg);border-top:2px solid var(--table-border);border-bottom:2px solid var(--table-border);transition:background 0.2s}.group-header-row:hover{background:var(--table-hover)}.group-header-cell{cursor:pointer;user-select:none;font-weight:600;padding:12px 16px !important;outline:none}.group-header-cell:focus{outline:2px solid var(--table-primary);outline-offset:-2px}.group-header-content{display:flex;align-items:center;gap:10px}.group-expand-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:12px;color:var(--table-primary);transition:transform 0.2s ease}.group-header-row[aria-expanded=true] .group-expand-icon{transform:rotate(0deg)}.group-header-row[aria-expanded=false] .group-expand-icon{transform:rotate(-90deg)}.group-label{font-size:15px;color:var(--table-text);font-weight:600}.group-count{font-size:13px;color:var(--table-text-secondary);font-weight:normal;margin-left:4px}.group-data-row{animation:fadeIn 0.2s ease-in-out}@keyframes fadeIn{from{opacity:0}to{opacity:1}}.group-data-row td{padding-left:48px !important;border-left:3px solid transparent;transition:all 0.2s}.group-data-row td:first-child{border-left:3px solid var(--table-border)}.group-data-row.selected{background:var(--table-selected)}.group-data-row.selected td:first-child{border-left-color:var(--table-primary)}.group-data-row:hover{background:var(--table-hover)}.group-data-row:hover td:first-child{border-left-color:var(--table-primary)}.editable-cell{cursor:pointer;padding:4px;border-radius:4px;transition:background 0.15s}.editable-cell:hover{background:rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.data-table td input,.data-table td select{width:100%;padding:6px 8px;border:2px solid var(--table-primary);border-radius:4px;font-size:14px;background:var(--table-bg);color:var(--table-text)}.data-table td input:focus,.data-table td select:focus{outline:none;box-shadow:0 0 0 3px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.loading-cell,.empty-cell{text-align:center !important;padding:48px 16px !important;color:var(--table-text-secondary)}.loading-cell{display:flex;flex-direction:column;align-items:center;gap:12px}.loading-spinner{width:48px;height:48px;border:3px solid rgba(var(--table-primary-rgb), 0.1);border-top-color:var(--table-primary);border-radius:50%;animation:spin 0.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;box-shadow:0 0 20px rgba(var(--table-primary-rgb), 0.15)}.skeleton-row td{padding:14px 20px}.skeleton-content,.skeleton-checkbox{height:16px;width:100%;background:linear-gradient(90deg, rgba(var(--table-text-secondary-rgb), 0.05) 25%, rgba(var(--table-text-secondary-rgb), 0.15) 37%, rgba(var(--table-text-secondary-rgb), 0.05) 63%);background-size:400% 100%;animation:skeleton-shimmer 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;border-radius:4px}.skeleton-checkbox{width:18px;height:18px;margin:0 auto}@keyframes skeleton-shimmer{0%{background-position:100% 50%}100%{background-position:0% 50%}}.pagination-container{display:flex;justify-content:space-between;align-items:center;padding:16px;background:var(--table-header-bg);border-top:1px solid var(--table-border);gap:16px;flex-wrap:wrap}.pagination-info{color:var(--table-text-secondary);font-size:14px}.pagination-controls{display:flex;gap:4px;align-items:center}.page-btn{min-width:36px;height:36px;padding:8px 12px;background:var(--table-bg);color:var(--table-text);border:1px solid var(--table-border);border-radius:6px;font-size:14px;cursor:pointer;transition:all 0.2s;display:flex;align-items:center;justify-content:center}.page-btn:hover:not(:disabled){background:var(--table-hover);border-color:var(--table-primary)}.page-btn:disabled{opacity:0.4;cursor:not-allowed}.page-btn.active{background:var(--table-primary);color:var(--text-standard, #ffffff);border-color:var(--table-primary)}.page-size-selector{display:flex;align-items:center;gap:8px}.page-size-selector label{display:flex;align-items:center;gap:8px;color:var(--table-text-secondary);font-size:14px}.page-size-selector select{padding:6px 32px 6px 12px;border:1px solid var(--table-border);border-radius:6px;background:var(--table-bg);color:var(--table-text);font-size:14px;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M6 9L1 4h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center}.page-size-selector select:focus{outline:none;border-color:var(--table-primary)}.column-settings-dialog,.export-dialog{position:fixed;top:0;left:0;right:0;bottom:0;z-index:1000;display:flex;align-items:center;justify-content:center}.dialog-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.5);backdrop-filter:blur(4px)}.dialog-content{position:relative;background:var(--table-bg);border-radius:12px;box-shadow:0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);max-width:500px;width:90%;max-height:80vh;display:flex;flex-direction:column;animation:dialogSlideIn 0.2s ease-out}@keyframes dialogSlideIn{from{opacity:0;transform:scale(0.95) translateY(-20px)}to{opacity:1;transform:scale(1) translateY(0)}}.dialog-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid var(--table-border)}.dialog-header h3{margin:0;font-size:18px;font-weight:600;color:var(--table-text)}.close-btn{width:32px;height:32px;padding:0;background:transparent;border:none;color:var(--table-text-secondary);font-size:24px;cursor:pointer;border-radius:6px;transition:all 0.2s;display:flex;align-items:center;justify-content:center}.close-btn:hover{background:var(--table-hover);color:var(--table-text)}.dialog-body{padding:20px;overflow-y:auto;flex:1}.dialog-footer{padding:16px 20px;border-top:1px solid var(--table-border);display:flex;justify-content:flex-end;gap:12px}.dialog-footer button{padding:10px 20px;background:var(--table-primary);color:var(--text-standard, #ffffff);border:none;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;transition:all 0.2s}.dialog-footer button:hover{background:var(--table-primary-hover)}.column-list{display:flex;flex-direction:column;gap:8px}.column-item{display:flex;align-items:center;gap:12px;padding:12px;background:var(--table-header-bg);border-radius:6px;cursor:pointer;transition:background 0.2s}.column-item:hover{background:var(--table-hover)}.column-item input[type=checkbox]{width:18px;height:18px;cursor:pointer;accent-color:var(--table-primary)}.column-item span{flex:1;color:var(--table-text);font-size:14px}.export-options{display:flex;flex-direction:column;gap:12px}.export-btn{padding:16px;background:var(--table-bg);color:var(--table-text);border:2px solid var(--table-border);border-radius:8px;font-size:15px;font-weight:500;cursor:pointer;transition:all 0.2s;display:flex;align-items:center;gap:12px}.export-btn:hover{background:var(--table-hover);border-color:var(--table-primary);transform:translateX(4px)}@media (max-width: 768px){.table-toolbar{flex-direction:column;align-items:stretch}.toolbar-left,.toolbar-right{width:100%;justify-content:space-between}.search-box{min-width:100%}.pagination-container{flex-direction:column;align-items:stretch;gap:12px}.pagination-info,.pagination-controls,.page-size-selector{justify-content:center}.table-wrapper{max-height:60vh}.data-table{font-size:13px}.data-table th,.data-table td{padding:8px 12px}}@media (max-width: 480px){.data-table{font-size:12px}.data-table th,.data-table td{padding:6px 8px}.toolbar-btn{font-size:13px;padding:6px 12px}.pagination-controls .page-btn{min-width:32px;height:32px;padding:4px 8px;font-size:13px}}.data-table:focus-within{outline:2px solid var(--table-primary);outline-offset:2px}button:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid var(--table-primary);outline-offset:2px}.data-table-container *{box-sizing:border-box}.data-table tbody tr{contain:layout style}.data-table th[draggable=true]{cursor:move}.data-table th[draggable=true]:active{opacity:0.5}.skeleton-row{animation:pulse 1.5s ease-in-out infinite}.skeleton-cell{padding:12px 16px}.skeleton-content{height:16px;background:linear-gradient(90deg, var(--table-border) 25%, var(--table-hover) 50%, var(--table-border) 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:4px}.skeleton-checkbox{width:16px;height:16px;background:linear-gradient(90deg, var(--table-border) 25%, var(--table-hover) 50%, var(--table-border) 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:3px;margin:0 auto}@keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.7}}.cell-input{width:100%;padding:6px 8px;border:1px solid var(--table-border);border-radius:4px;background:var(--table-bg);color:var(--table-text);font-size:14px}.cell-input:focus{outline:none;border-color:var(--table-primary);box-shadow:0 0 0 2px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.cell-select{width:100%;padding:6px 8px;border:1px solid var(--table-border);border-radius:4px;background:var(--table-bg);color:var(--table-text);font-size:14px;cursor:pointer}.cell-radio-group{display:flex;flex-direction:column;gap:6px}.radio-label{display:flex;align-items:center;gap:6px;cursor:pointer;font-size:14px}.radio-label input[type=radio]{cursor:pointer}.cell-checkbox{width:18px;height:18px;cursor:pointer}.cell-switch{position:relative;display:inline-block;width:44px;height:24px}.cell-switch input{opacity:0;width:0;height:0}.switch-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:var(--bg-secondary, #ccc);transition:0.3s;border-radius:24px}.switch-slider:before{position:absolute;content:"";height:18px;width:18px;left:3px;bottom:3px;background-color:var(--bg-primary, #ffffff);transition:0.3s;border-radius:50%}.cell-switch input:checked+.switch-slider{background-color:var(--table-primary)}.cell-switch input:checked+.switch-slider:before{transform:translateX(20px)}.cell-rating{display:flex;gap:4px;font-size:18px}.cell-rating .star{cursor:pointer;color:var(--bg-secondary, #d1d5db);transition:color 0.2s}.cell-rating .star.filled{color:var(--color-danger, #fbbf24)}.cell-rating .star:hover{color:var(--color-danger, #fcd34d)}.cell-rating-display{display:flex;gap:2px;font-size:16px}.cell-rating-display .star{color:var(--bg-secondary, #d1d5db)}.cell-rating-display .star.filled{color:var(--color-danger, #fbbf24)}.cell-boolean{font-size:18px;font-weight:bold}.cell-switch-display{display:inline-block}.switch-indicator{display:inline-block;padding:2px 8px;border-radius:12px;font-size:11px;font-weight:600;background:var(--bg-primary, #e5e7eb);color:var(--text-muted, #6b7280);text-transform:uppercase}.switch-indicator.active{background:var(--table-primary);color:var(--text-standard, #ffffff)}.cell-image{display:block;object-fit:cover}.cell-password{letter-spacing:2px;font-family:monospace}.cell-link{color:var(--table-primary);text-decoration:none;transition:color 0.2s}.cell-link:hover{color:var(--table-primary-hover);text-decoration:underline}.column-group{background:var(--table-header-bg);font-weight:600;border-bottom:2px solid var(--table-border)}.data-table thead tr:has(.column-group)+tr th{border-top:1px solid var(--table-border)}.filter-panel{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%);background:var(--table-bg);border:1px solid var(--table-border);border-radius:12px;box-shadow:0 20px 25px -5px rgba(0, 0, 0, 0.2), 0 10px 10px -5px rgba(0, 0, 0, 0.1);min-width:600px;max-width:90vw;max-height:80vh;z-index:1000;display:flex;flex-direction:column;animation:slideIn 0.2s ease-out}@keyframes slideIn{from{opacity:0;transform:translate(-50%, -45%)}to{opacity:1;transform:translate(-50%, -50%)}}.filter-panel::before{content:"";position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.5);backdrop-filter:blur(4px);z-index:-1}.filter-panel-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;border-bottom:1px solid var(--table-border)}.filter-panel-header h4{margin:0;font-size:18px;font-weight:600;color:var(--table-text);display:flex;align-items:center;gap:8px}.filter-panel-header .close-btn{background:transparent;border:none;font-size:28px;line-height:1;cursor:pointer;color:var(--table-text-secondary);padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;transition:all 0.2s}.filter-panel-header .close-btn:hover{background:var(--table-hover);color:var(--table-text)}.filter-panel-body{padding:24px;overflow-y:auto;flex:1}.filter-builder{margin-bottom:24px}.filter-row{display:grid;grid-template-columns:1fr 1fr 1.5fr auto;gap:12px;align-items:center}.filter-field-select,.filter-operator-select{padding:10px 12px;border:1px solid var(--table-border);border-radius:6px;font-size:14px;background:var(--table-bg);color:var(--table-text);cursor:pointer;transition:all 0.2s}.filter-field-select:focus,.filter-operator-select:focus{outline:none;border-color:var(--table-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.filter-field-select:hover,.filter-operator-select:hover{border-color:var(--table-primary)}.filter-field-select:disabled,.filter-operator-select:disabled{opacity:0.5;cursor:not-allowed}.filter-value-input{padding:10px 12px;border:1px solid var(--table-border);border-radius:6px;font-size:14px;background:var(--table-bg);color:var(--table-text);transition:all 0.2s}.filter-value-input:focus{outline:none;border-color:var(--table-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.filter-value-input:disabled{opacity:0.5;cursor:not-allowed;background:var(--table-header-bg)}.add-filter-btn{padding:10px 20px;background:var(--table-primary);color:var(--text-standard, #ffffff);border:none;border-radius:6px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.2s;white-space:nowrap}.add-filter-btn:hover:not(:disabled){background:var(--table-primary-hover);transform:translateY(-1px);box-shadow:0 4px 6px rgba(var(--color-primary-rgb, 59, 130, 246), 0.2)}.add-filter-btn:active:not(:disabled){transform:translateY(0)}.add-filter-btn:disabled{opacity:0.5;cursor:not-allowed}.active-filters{border-top:1px solid var(--table-border);padding-top:20px}.active-filters-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.active-filters-header span{font-size:14px;font-weight:600;color:var(--table-text)}.clear-all-btn{padding:6px 12px;background:transparent;color:var(--color-danger, #ef4444);border:1px solid var(--color-danger, #ef4444);border-radius:6px;font-size:13px;cursor:pointer;transition:all 0.2s}.clear-all-btn:hover{background:var(--color-danger, #ef4444);color:var(--text-standard, #ffffff)}.filter-chips{display:flex;flex-wrap:wrap;gap:8px}.filter-chip{display:inline-flex;align-items:center;gap:8px;padding:8px 12px;background:var(--table-selected);border:1px solid var(--table-primary);border-radius:20px;font-size:13px;color:var(--table-text);animation:chipSlideIn 0.2s ease-out}@keyframes chipSlideIn{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}.filter-chip-label{display:flex;align-items:center;gap:4px}.filter-chip-label strong{color:var(--table-primary)}.filter-chip-remove{background:transparent;border:none;color:var(--table-text-secondary);font-size:20px;line-height:1;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:all 0.2s}.filter-chip-remove:hover{background:rgba(var(--color-danger-rgb, 239, 68, 68), 0.1);color:var(--color-danger, #ef4444)}.no-filters{text-align:center;padding:32px;color:var(--table-text-secondary);font-size:14px}.pinned-row-top{position:sticky !important;top:0;z-index:25;background:var(--table-bg);box-shadow:0 2px 4px rgba(0, 0, 0, 0.1)}.pinned-row-bottom{position:sticky !important;bottom:0;z-index:25;background:var(--table-bg);box-shadow:0 -2px 4px rgba(0, 0, 0, 0.1)}.pinned-row-top::before,.pinned-row-bottom::before{content:"";position:absolute;left:0;right:0;height:3px;background:linear-gradient(90deg, var(--color-primary, #10b981), var(--color-primary, #8b5cf6));opacity:0.6}.pinned-row-top::before{top:0}.pinned-row-bottom::before{bottom:0}.pinned-row-top:hover,.pinned-row-bottom:hover{background:var(--table-hover)}.sort-icon.multi-sort{position:relative;display:inline-flex;align-items:center;gap:4px}.sort-order-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 4px;background:var(--color-primary, #10b981);color:var(--text-standard, #ffffff);border-radius:50%;font-size:11px;font-weight:600;line-height:1}.aggregation-footer{background:var(--bg-primary, #f9fafb);border-top:2px solid var(--border-default, #e5e7eb);font-weight:600}.aggregation-cell{padding:12px}.aggregation-values{display:flex;gap:16px;flex-wrap:wrap}.agg-item{display:flex;gap:6px;align-items:center}.agg-label{color:var(--text-muted, #6b7280);font-size:12px;text-transform:uppercase}.agg-value{color:var(--text-primary, #111827);font-size:14px;font-weight:700}.row-details-row{background:var(--bg-primary, #f9fafb)}.row-details-panel{padding:20px;border:1px solid var(--border-default, #e5e7eb);border-radius:8px;margin:8px}.details-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;padding-bottom:12px;border-bottom:2px solid var(--border-default, #e5e7eb)}.details-header h4{margin:0;color:var(--text-primary, #111827);font-size:16px}.close-details-btn{background:none;border:none;font-size:24px;color:var(--text-muted, #6b7280);cursor:pointer;padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:4px}.close-details-btn:hover{background:var(--bg-primary, #e5e7eb);color:var(--text-primary, #111827)}.details-content{display:grid;grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));gap:12px}.detail-item{display:flex;gap:8px;padding:8px;background:var(--bg-primary, #ffffff);border-radius:4px;border:1px solid var(--border-default, #e5e7eb)}.detail-label{color:var(--text-muted, #6b7280);font-size:13px;min-width:100px}.detail-value{color:var(--text-primary, #111827);font-size:13px;word-break:break-word}.keyboard-shortcuts-modal{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.5);display:flex;align-items:center;justify-content:center;z-index:10000}.keyboard-shortcuts-modal .modal-content{background:var(--bg-primary, #ffffff);border-radius:12px;box-shadow:0 20px 25px -5px rgba(0, 0, 0, 0.1);max-width:500px;width:90%;max-height:80vh;overflow:auto}.keyboard-shortcuts-modal .modal-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid var(--border-default, #e5e7eb)}.keyboard-shortcuts-modal .modal-header h3{margin:0;font-size:18px;color:var(--text-primary, #111827)}.keyboard-shortcuts-modal .modal-header button{background:none;border:none;font-size:24px;color:var(--text-muted, #6b7280);cursor:pointer;padding:0;width:30px;height:30px}.keyboard-shortcuts-modal .modal-body{padding:20px}.shortcuts-table{width:100%;border-collapse:collapse}.shortcuts-table tr{border-bottom:1px solid var(--border-default, #e5e7eb)}.shortcuts-table tr:last-child{border-bottom:none}.shortcuts-table td{padding:12px 8px}.shortcut-key{font-family:"Courier New", monospace;background:var(--bg-secondary, #f3f4f6);padding:4px 8px;border-radius:4px;font-size:13px;font-weight:600;color:var(--text-secondary, #374151);white-space:nowrap}.shortcut-desc{color:var(--text-muted, #6b7280);font-size:14px}.validation-error-tooltip{position:absolute;bottom:100%;left:0;background:var(--color-danger, #ef4444);color:var(--text-standard, #ffffff);padding:6px 10px;border-radius:4px;font-size:12px;white-space:nowrap;z-index:100;margin-bottom:4px;display:flex;align-items:center;gap:6px;box-shadow:0 4px 6px -1px rgba(0, 0, 0, 0.1)}.validation-error-tooltip::after{content:"";position:absolute;top:100%;left:10px;border:5px solid transparent;border-top-color:var(--color-danger, #ef4444)}.error-icon{font-size:14px}.error-message{font-weight:500}td.has-validation-error{position:relative;border:2px solid var(--color-danger, #ef4444) !important;background:var(--bg-primary, #fef2f2)}.virtual-scroll-container{overflow-y:auto;position:relative;will-change:transform}.virtual-scroll-content{position:relative}.auto-size-btn{padding:4px 8px;font-size:12px;background:var(--bg-secondary, #f3f4f6);border:1px solid var(--border-strong, #d1d5db);border-radius:4px;cursor:pointer;color:var(--text-secondary, #374151)}.auto-size-btn:hover{background:var(--bg-primary, #e5e7eb)}.premium-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;background:linear-gradient(135deg, var(--color-primary, #667eea) 0%, var(--color-primary, #764ba2) 100%);color:var(--text-standard, #ffffff);border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px}@media (prefers-color-scheme: dark){.aggregation-footer{background:var(--bg-primary, #1f2937);border-top-color:var(--border-default, #374151)}.row-details-panel{background:var(--bg-primary, #1f2937);border-color:var(--border-default, #374151)}.keyboard-shortcuts-modal .modal-content{background:var(--bg-primary, #1f2937);color:var(--text-standard, #f3f4f6)}.detail-item{background:var(--bg-secondary, #111827);border-color:var(--border-default, #374151)}}.cell-editor{width:100%;padding:6px 8px;border:2px solid var(--color-primary, #10b981);border-radius:4px;font-size:14px;outline:none}.date-editor,.datetime-editor{cursor:pointer}.number-editor{text-align:right}.select-editor{cursor:pointer;background:var(--bg-primary, #ffffff)}.checkbox-editor{width:20px;height:20px;cursor:pointer}.formatted-currency{color:var(--color-success-hover, #059669);font-weight:600}.formatted-percentage{color:var(--color-primary, #7c3aed);font-weight:600}.formatted-date{color:var(--color-primary, #0284c7)}.cell-range-selected{background:var(--bg-primary, #dbeafe) !important;border:2px solid var(--color-primary, #10b981) !important}.range-selection-anchor{background:var(--color-primary, #bfdbfe) !important;border:2px dashed var(--color-primary, #10b981) !important}.copy-indicator{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:var(--color-success, #10b981);color:var(--text-standard, #ffffff);padding:8px 16px;border-radius:8px;font-size:14px;font-weight:600;z-index:1000;animation:fadeInOut 1s ease-in-out}@keyframes fadeInOut{0%,100%{opacity:0}50%{opacity:1}}.color-scale-cell{position:relative;color:var(--text-primary, #111827);font-weight:600}.data-bar-cell{position:relative;padding:8px}.data-bar-value{position:relative;z-index:1;font-weight:600}.icon-set{display:inline-flex;align-items:center;gap:6px}.icon-set-icon{font-size:16px}.icon-positive{color:var(--color-success, #10b981)}.icon-neutral{color:var(--color-warning, #f59e0b)}.icon-negative{color:var(--color-danger, #ef4444)}.cell-with-formatting{transition:all 0.2s ease}.cell-with-formatting:hover{transform:scale(1.02);box-shadow:0 2px 8px rgba(0, 0, 0, 0.1)}.cell-progress-bar{width:100%;height:24px;background:var(--bg-primary, #e5e7eb);border-radius:12px;overflow:hidden;position:relative}.cell-progress-fill{height:100%;background:linear-gradient(90deg, var(--color-primary, #10b981) 0%, var(--color-primary, #1d4ed8) 100%);transition:width 0.3s ease;display:flex;align-items:center;justify-content:center;color:var(--text-standard, #ffffff);font-size:12px;font-weight:600}.cell-editor:focus{border-color:var(--color-primary-hover, #2563eb);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.cell-editor-error{border-color:var(--color-danger, #ef4444)}.cell-editor-error:focus{box-shadow:0 0 0 3px rgba(var(--color-danger-rgb, 239, 68, 68), 0.1)}.bulk-actions-toolbar{position:sticky;top:0;z-index:100;background:var(--bg-secondary, #f3f4f6);border-bottom:2px solid var(--border-default, #e5e7eb);padding:12px 16px;display:flex;align-items:center;gap:12px;animation:slideDown 0.3s ease}@keyframes slideDown{from{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}.bulk-actions-count{font-weight:600;color:var(--text-secondary, #374151)}.bulk-action-btn{padding:6px 12px;background:var(--bg-primary, #ffffff);border:1px solid var(--border-strong, #d1d5db);border-radius:6px;font-size:14px;cursor:pointer;transition:all 0.2s}.bulk-action-btn:hover{background:var(--bg-primary, #f9fafb);border-color:var(--color-primary, #9ca3af)}.bulk-action-btn.primary{background:var(--color-primary, #10b981);color:var(--text-standard, #ffffff);border-color:var(--color-primary, #10b981)}.bulk-action-btn.primary:hover{background:var(--color-primary-hover, #2563eb)}.bulk-action-btn.danger{background:var(--color-danger, #ef4444);color:var(--text-standard, #ffffff);border-color:var(--color-danger, #ef4444)}.bulk-action-btn.danger:hover{background:var(--color-danger-hover, #dc2626)}@media print{.data-table-container{box-shadow:none !important;border:none !important;overflow:visible !important;max-height:none !important}.table-wrapper{max-height:none !important;overflow:visible !important}.table-toolbar,.pagination-container,.filter-panel,.column-settings-dialog,.export-dialog,.keyboard-shortcuts-modal,.actions-column,.select-column,.row-details-toggle-cell,.bulk-actions-bar{display:none !important}.data-table{width:100% !important;border-collapse:collapse !important}.data-table th,.data-table td{color:var(--text-primary, #000) !important;border:1px solid var(--border-default, #ccc) !important;padding:8px !important}tr{break-inside:avoid;page-break-inside:avoid}}.context-menu{position:fixed;background:var(--table-bg);border:1px solid var(--table-border);box-shadow:0 10px 15px -3px rgba(0, 0, 0, 0.1);border-radius:6px;padding:4px;min-width:160px;z-index:9999}.context-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;gap:8px;color:var(--table-text);font-size:14px;border-radius:4px}.context-menu-item:hover{background:var(--table-hover)}.mobile-cards-view{display:flex;flex-direction:column;gap:12px;padding:12px}.mobile-card{background:var(--table-bg);border:1px solid var(--table-border);border-radius:8px;padding:12px}.mobile-card .card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--table-border);font-weight:600}.mobile-card .card-field{display:flex;justify-content:space-between;margin-bottom:8px;font-size:14px}.mobile-card .card-field label{color:var(--table-text-secondary);font-weight:500}.data-table td.focused-cell{box-shadow:inset 0 0 0 2px var(--table-primary) !important;background:rgba(var(--color-primary-rgb, 59, 130, 246), 0.05);z-index:10}.data-table td:focus{outline:none}.data-table th.pinned-left,.data-table td.pinned-left{position:sticky;left:0;z-index:25;box-shadow:2px 0 4px var(--table-shadow)}.data-table th.pinned-right,.data-table td.pinned-right{position:sticky;right:0;z-index:25;box-shadow:-2px 0 4px var(--table-shadow)}.header-menu-trigger{background:transparent;border:none;cursor:pointer;padding:4px;border-radius:4px;color:var(--table-text-secondary);opacity:0;transition:all 0.2s;font-size:16px;line-height:1}.data-table th:hover .header-menu-trigger{opacity:1}.header-menu-trigger:hover{background:var(--table-hover);color:var(--table-text)}.context-menu.header-context-menu{min-width:200px}.context-menu-header{padding:8px 12px;font-size:12px;font-weight:700;text-transform:uppercase;color:var(--table-text-secondary);border-bottom:1px solid var(--table-border);margin-bottom:4px}.context-menu ul{list-style:none;padding:0;margin:0}.context-menu li{padding:8px 12px;cursor:pointer;font-size:14px;transition:background 0.2s;position:relative}.context-menu li:hover{background:var(--table-hover)}.context-menu li.divider{height:1px;background:var(--table-border);padding:0;margin:4px 0;cursor:default}.context-menu li.has-submenu::after{content:"";font-size:10px;position:absolute;right:12px;opacity:0.5}.context-menu .submenu{position:absolute;left:100%;top:0;display:none;background:var(--table-bg);border:1px solid var(--table-border);border-radius:6px;box-shadow:0 4px 12px rgba(0, 0, 0, 0.15);min-width:140px;padding:4px}.context-menu li.has-submenu:hover>.submenu{display:block}.sr-announcer{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}.data-table th.pinned-left,.data-table td.pinned-left{background:linear-gradient(to right, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent);border-right:2px solid rgba(var(--color-primary-rgb, 59, 130, 246), 0.3)}.data-table th.pinned-right,.data-table td.pinned-right{background:linear-gradient(to left, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent);border-left:2px solid rgba(var(--color-primary-rgb, 59, 130, 246), 0.3)}.data-table th.pinned-left::before,.data-table th.pinned-right::before{content:"";font-size:10px;opacity:0.6;margin-right:4px}.data-table th.pinned-left:hover,.data-table th.pinned-right:hover{background:rgba(var(--color-primary-rgb, 59, 130, 246), 0.1)}.pin-indicator{font-size:12px;margin-right:4px;opacity:0.8;display:inline-block;animation:pinPulse 2s ease-in-out infinite}@keyframes pinPulse{0%,100%{opacity:0.8}50%{opacity:1}}.data-table th.pinned-left,.data-table td.pinned-left{background:linear-gradient(to right, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent), var(--table-bg) !important;background-blend-mode:normal}.data-table th.pinned-right,.data-table td.pinned-right{background:linear-gradient(to left, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent), var(--table-bg) !important;background-blend-mode:normal}.data-table th.pinned-left{background:linear-gradient(to right, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent), var(--table-header-bg) !important}.data-table td.pinned-left{background:linear-gradient(to right, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent), var(--table-bg) !important}.data-table th.pinned-right{background:linear-gradient(to left, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent), var(--table-header-bg) !important}.data-table td.pinned-right{background:linear-gradient(to left, rgba(var(--color-primary-rgb, 59, 130, 246), 0.05), transparent), var(--table-bg) !important}.data-table-footer{background-color:var(--table-header-bg, #f8fafc);border-top:2px solid var(--border-subtle, #e2e8f0);font-weight:600;z-index:2}.data-table-container tfoot tr{position:sticky;bottom:0;background-color:var(--table-header-bg, #f8fafc);z-index:3;box-shadow:0 -1px 2px rgba(0, 0, 0, 0.05)}.data-table-footer td{padding:12px 16px;border-bottom:1px solid var(--border-subtle, #e2e8f0);background-color:inherit;vertical-align:top}.agg-item{display:flex;flex-direction:column;font-size:0.75rem;margin-bottom:4px}.agg-label{color:var(--text-muted, #64748b);text-transform:uppercase;font-size:0.65rem;margin-bottom:1px}.agg-value{color:var(--text-primary, #0f172a);font-weight:700;font-size:0.85rem}`;
|
|
4
|
+
|
|
5
|
+
const AdvancedDataTable = class {
|
|
6
|
+
constructor(hostRef) {
|
|
7
|
+
registerInstance(this, hostRef);
|
|
8
|
+
this.rowSelect = createEvent(this, "rowSelect");
|
|
9
|
+
this.rowDeselect = createEvent(this, "rowDeselect");
|
|
10
|
+
this.cellEdit = createEvent(this, "cellEdit");
|
|
11
|
+
this.cellEditStart = createEvent(this, "cellEditStart");
|
|
12
|
+
this.cellEditStop = createEvent(this, "cellEditStop");
|
|
13
|
+
this.rowEditStart = createEvent(this, "rowEditStart");
|
|
14
|
+
this.rowEditStop = createEvent(this, "rowEditStop");
|
|
15
|
+
this.sortChange = createEvent(this, "sortChange");
|
|
16
|
+
this.filterChange = createEvent(this, "filterChange");
|
|
17
|
+
this.pageChange = createEvent(this, "pageChange");
|
|
18
|
+
this.searchChange = createEvent(this, "searchChange");
|
|
19
|
+
this.columnOrderChange = createEvent(this, "columnOrderChange");
|
|
20
|
+
this.columnVisibilityChange = createEvent(this, "columnVisibilityChange");
|
|
21
|
+
this.columnPin = createEvent(this, "columnPin");
|
|
22
|
+
this.rowPin = createEvent(this, "rowPin");
|
|
23
|
+
this.rowReorderEvent = createEvent(this, "rowReorderEvent");
|
|
24
|
+
this.dataExport = createEvent(this, "dataExport");
|
|
25
|
+
this.groupToggle = createEvent(this, "groupToggle");
|
|
26
|
+
this.groupByChange = createEvent(this, "groupByChange");
|
|
27
|
+
this.rowEdit = createEvent(this, "rowEdit");
|
|
28
|
+
this.rowDelete = createEvent(this, "rowDelete");
|
|
29
|
+
this.rowAction = createEvent(this, "rowAction");
|
|
30
|
+
this.lazyLoadMore = createEvent(this, "lazyLoadMore");
|
|
31
|
+
}
|
|
32
|
+
get el() { return getElement(this); }
|
|
33
|
+
/**
|
|
34
|
+
* Table configuration
|
|
35
|
+
*/
|
|
36
|
+
config = {
|
|
37
|
+
columns: [],
|
|
38
|
+
data: [],
|
|
39
|
+
selectable: false,
|
|
40
|
+
pagination: true,
|
|
41
|
+
pageSize: 10,
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Columns definition
|
|
45
|
+
*/
|
|
46
|
+
columns = [];
|
|
47
|
+
/**
|
|
48
|
+
* Table data
|
|
49
|
+
*/
|
|
50
|
+
data = [];
|
|
51
|
+
/**
|
|
52
|
+
* Enable row selection
|
|
53
|
+
*/
|
|
54
|
+
selectable = false;
|
|
55
|
+
/**
|
|
56
|
+
* Enable multiple row selection
|
|
57
|
+
*/
|
|
58
|
+
multiSelect = true;
|
|
59
|
+
/**
|
|
60
|
+
* Enable inline editing
|
|
61
|
+
*/
|
|
62
|
+
editable = false;
|
|
63
|
+
/**
|
|
64
|
+
* Enable sticky header
|
|
65
|
+
*/
|
|
66
|
+
stickyHeader = true;
|
|
67
|
+
/**
|
|
68
|
+
* Enable pagination
|
|
69
|
+
*/
|
|
70
|
+
pagination = true;
|
|
71
|
+
/**
|
|
72
|
+
* Page size
|
|
73
|
+
*/
|
|
74
|
+
pageSize = 10;
|
|
75
|
+
/**
|
|
76
|
+
* Page size options
|
|
77
|
+
*/
|
|
78
|
+
pageSizeOptions = [5, 10, 25, 50, 100];
|
|
79
|
+
/**
|
|
80
|
+
* Pagination theme
|
|
81
|
+
*/
|
|
82
|
+
paginationTheme = 'default';
|
|
83
|
+
/**
|
|
84
|
+
* Pagination shape
|
|
85
|
+
*/
|
|
86
|
+
paginationShape = 'default';
|
|
87
|
+
/**
|
|
88
|
+
* Enable keyboard navigation for pagination
|
|
89
|
+
*/
|
|
90
|
+
paginationKeyboardNav = true;
|
|
91
|
+
/**
|
|
92
|
+
* Enable quick jump buttons
|
|
93
|
+
*/
|
|
94
|
+
paginationQuickJump = false;
|
|
95
|
+
/**
|
|
96
|
+
* Quick jump step size
|
|
97
|
+
*/
|
|
98
|
+
paginationQuickJumpStep = 5;
|
|
99
|
+
/**
|
|
100
|
+
* Show progress indicator
|
|
101
|
+
*/
|
|
102
|
+
paginationShowProgress = false;
|
|
103
|
+
/**
|
|
104
|
+
* Sticky pagination
|
|
105
|
+
*/
|
|
106
|
+
paginationSticky = false;
|
|
107
|
+
/**
|
|
108
|
+
* Sticky position
|
|
109
|
+
*/
|
|
110
|
+
paginationStickyPosition = 'bottom';
|
|
111
|
+
/**
|
|
112
|
+
* Enable page transitions
|
|
113
|
+
*/
|
|
114
|
+
paginationTransitions = true;
|
|
115
|
+
/**
|
|
116
|
+
* Sync pagination with URL
|
|
117
|
+
*/
|
|
118
|
+
paginationUrlSync = false;
|
|
119
|
+
/**
|
|
120
|
+
* URL parameter name
|
|
121
|
+
*/
|
|
122
|
+
paginationUrlParam = 'page';
|
|
123
|
+
/**
|
|
124
|
+
* Persist page to localStorage
|
|
125
|
+
*/
|
|
126
|
+
paginationPersistPage = false;
|
|
127
|
+
/**
|
|
128
|
+
* LocalStorage key
|
|
129
|
+
*/
|
|
130
|
+
paginationStorageKey = 'table-page';
|
|
131
|
+
/**
|
|
132
|
+
* Enable swipe gestures
|
|
133
|
+
*/
|
|
134
|
+
paginationSwipeGestures = true;
|
|
135
|
+
/**
|
|
136
|
+
* Smart compact mode
|
|
137
|
+
*/
|
|
138
|
+
paginationSmartCompact = false;
|
|
139
|
+
/**
|
|
140
|
+
* Smart compact threshold
|
|
141
|
+
*/
|
|
142
|
+
paginationSmartCompactThreshold = 20;
|
|
143
|
+
/**
|
|
144
|
+
* Auto-hide pagination on single page
|
|
145
|
+
*/
|
|
146
|
+
paginationAutoHide = true;
|
|
147
|
+
/**
|
|
148
|
+
* Responsive pagination mode
|
|
149
|
+
*/
|
|
150
|
+
paginationResponsive = true;
|
|
151
|
+
/**
|
|
152
|
+
* Mobile breakpoint for pagination
|
|
153
|
+
*/
|
|
154
|
+
paginationMobileBreakpoint = 768;
|
|
155
|
+
/**
|
|
156
|
+
* Enable virtual scrolling for performance with lg datasets
|
|
157
|
+
*/
|
|
158
|
+
virtualScroll = false;
|
|
159
|
+
/**
|
|
160
|
+
* Row height for virtual scrolling (px)
|
|
161
|
+
*/
|
|
162
|
+
virtualRowHeight = 48;
|
|
163
|
+
/**
|
|
164
|
+
* Enable advanced filter operators
|
|
165
|
+
*/
|
|
166
|
+
advancedFilters = false;
|
|
167
|
+
/**
|
|
168
|
+
* Enable column aggregation (sum, avg, min, max)
|
|
169
|
+
*/
|
|
170
|
+
columnAggregation = false;
|
|
171
|
+
/**
|
|
172
|
+
* Aggregation functions to show
|
|
173
|
+
*/
|
|
174
|
+
aggregationFunctions = ['sum', 'avg', 'min', 'max', 'count'];
|
|
175
|
+
/**
|
|
176
|
+
* Persist table state to localStorage
|
|
177
|
+
*/
|
|
178
|
+
persistState = false;
|
|
179
|
+
/**
|
|
180
|
+
* LocalStorage key for state persistence
|
|
181
|
+
*/
|
|
182
|
+
stateStorageKey = 'table-state';
|
|
183
|
+
/**
|
|
184
|
+
* Enable multi-column sorting
|
|
185
|
+
*/
|
|
186
|
+
multiSort = false;
|
|
187
|
+
/**
|
|
188
|
+
* Maximum number of sort columns
|
|
189
|
+
*/
|
|
190
|
+
maxSortColumns = 3;
|
|
191
|
+
/**
|
|
192
|
+
* Enable column auto-sizing
|
|
193
|
+
*/
|
|
194
|
+
autoSizeColumns = false;
|
|
195
|
+
/**
|
|
196
|
+
* Enable row details panel
|
|
197
|
+
*/
|
|
198
|
+
rowDetails = false;
|
|
199
|
+
/**
|
|
200
|
+
* Enable keyboard shortcuts
|
|
201
|
+
*/
|
|
202
|
+
keyboardShortcuts = true;
|
|
203
|
+
/**
|
|
204
|
+
* Enable Excel export (.xlsx)
|
|
205
|
+
*/
|
|
206
|
+
excelExport = false;
|
|
207
|
+
/**
|
|
208
|
+
* Enable inline validation
|
|
209
|
+
*/
|
|
210
|
+
inlineValidation = false;
|
|
211
|
+
/**
|
|
212
|
+
* Validation rules for columns
|
|
213
|
+
*/
|
|
214
|
+
validationRules = {};
|
|
215
|
+
// ========== NEW HIGH-VALUE FEATURES ==========
|
|
216
|
+
/**
|
|
217
|
+
* Enable advanced cell editors (date picker, dropdown, etc.)
|
|
218
|
+
*/
|
|
219
|
+
advancedCellEditors = true;
|
|
220
|
+
/**
|
|
221
|
+
* Enable column formatting (currency, date, percentage)
|
|
222
|
+
*/
|
|
223
|
+
columnFormatting = true;
|
|
224
|
+
/**
|
|
225
|
+
* Enable range selection (Shift+Click)
|
|
226
|
+
*/
|
|
227
|
+
rangeSelection = false;
|
|
228
|
+
/**
|
|
229
|
+
* Enable copy/paste functionality
|
|
230
|
+
*/
|
|
231
|
+
copyPaste = false;
|
|
232
|
+
/**
|
|
233
|
+
* Enable conditional formatting (color scales, data bars)
|
|
234
|
+
*/
|
|
235
|
+
conditionalFormatting = false;
|
|
236
|
+
/**
|
|
237
|
+
* Conditional formatting rules
|
|
238
|
+
*/
|
|
239
|
+
formattingRules = {};
|
|
240
|
+
// ========== PHASE 2 ADVANCED FEATURES ==========
|
|
241
|
+
/**
|
|
242
|
+
* Enable context menus on right click
|
|
243
|
+
*/
|
|
244
|
+
contextMenu = false;
|
|
245
|
+
/**
|
|
246
|
+
* Enable mobile card view for sm screens
|
|
247
|
+
*/
|
|
248
|
+
mobileCardView = true;
|
|
249
|
+
/**
|
|
250
|
+
* Enable lazy loading of data
|
|
251
|
+
*/
|
|
252
|
+
lazyLoad = false;
|
|
253
|
+
/**
|
|
254
|
+
* Enable PDF export
|
|
255
|
+
*/
|
|
256
|
+
pdfExport = false;
|
|
257
|
+
/**
|
|
258
|
+
* Enable sparklines in cells
|
|
259
|
+
*/
|
|
260
|
+
enableSparklines = false;
|
|
261
|
+
/**
|
|
262
|
+
* Enable undo/redo functionality
|
|
263
|
+
*/
|
|
264
|
+
undoRedo = false;
|
|
265
|
+
/**
|
|
266
|
+
* Enable print optimization
|
|
267
|
+
*/
|
|
268
|
+
printOptimized = false;
|
|
269
|
+
/**
|
|
270
|
+
* Enable enhanced accessibility features
|
|
271
|
+
*/
|
|
272
|
+
enhancedAccessibility = true;
|
|
273
|
+
/**
|
|
274
|
+
* Enable advanced validation (ranges, lists)
|
|
275
|
+
*/
|
|
276
|
+
advancedValidation = false;
|
|
277
|
+
/**
|
|
278
|
+
* Enable global search
|
|
279
|
+
*/
|
|
280
|
+
searchable = true;
|
|
281
|
+
/**
|
|
282
|
+
* Enable sorting
|
|
283
|
+
*/
|
|
284
|
+
sortable = true;
|
|
285
|
+
/**
|
|
286
|
+
* Enable filtering
|
|
287
|
+
*/
|
|
288
|
+
filterable = true;
|
|
289
|
+
/**
|
|
290
|
+
* Enable column reordering
|
|
291
|
+
*/
|
|
292
|
+
columnReorder = true;
|
|
293
|
+
/**
|
|
294
|
+
* Enable column visibility toggle
|
|
295
|
+
*/
|
|
296
|
+
columnVisibility = true;
|
|
297
|
+
/**
|
|
298
|
+
* Row height variant
|
|
299
|
+
*/
|
|
300
|
+
rowHeight = 'normal';
|
|
301
|
+
/**
|
|
302
|
+
* Enable striped rows
|
|
303
|
+
*/
|
|
304
|
+
striped = true;
|
|
305
|
+
/**
|
|
306
|
+
* Custom striped row color for light mode
|
|
307
|
+
*/
|
|
308
|
+
stripedColor;
|
|
309
|
+
/**
|
|
310
|
+
* Custom striped row color for dark mode
|
|
311
|
+
*/
|
|
312
|
+
stripedColorDark;
|
|
313
|
+
/**
|
|
314
|
+
* Enable hover effect
|
|
315
|
+
*/
|
|
316
|
+
hoverable = true;
|
|
317
|
+
/**
|
|
318
|
+
* Enable borders
|
|
319
|
+
*/
|
|
320
|
+
bordered = true;
|
|
321
|
+
/**
|
|
322
|
+
* Loading state
|
|
323
|
+
*/
|
|
324
|
+
loading = false;
|
|
325
|
+
/**
|
|
326
|
+
* Show skeleton while loading
|
|
327
|
+
*/
|
|
328
|
+
showSkeleton = true;
|
|
329
|
+
/**
|
|
330
|
+
* Number of skeleton rows to show
|
|
331
|
+
*/
|
|
332
|
+
skeletonRows = 5;
|
|
333
|
+
/**
|
|
334
|
+
* Empty message
|
|
335
|
+
*/
|
|
336
|
+
emptyMessage = 'No data available';
|
|
337
|
+
/**
|
|
338
|
+
* Server-side mode
|
|
339
|
+
*/
|
|
340
|
+
serverSide = false;
|
|
341
|
+
/**
|
|
342
|
+
* Total rows (for server-side pagination)
|
|
343
|
+
*/
|
|
344
|
+
totalRows = 0;
|
|
345
|
+
/**
|
|
346
|
+
* Enable export
|
|
347
|
+
*/
|
|
348
|
+
exportable = true;
|
|
349
|
+
/**
|
|
350
|
+
* Theme mode
|
|
351
|
+
*/
|
|
352
|
+
theme = 'auto';
|
|
353
|
+
/** High-Fidelity: Table variant */
|
|
354
|
+
variant = 'default';
|
|
355
|
+
/** High-Fidelity: Primary color theme */
|
|
356
|
+
color = 'primary';
|
|
357
|
+
/**
|
|
358
|
+
* Enable data grouping
|
|
359
|
+
*/
|
|
360
|
+
grouping = false;
|
|
361
|
+
/**
|
|
362
|
+
* Field to group by (for row grouping)
|
|
363
|
+
*/
|
|
364
|
+
groupBy = '';
|
|
365
|
+
/**
|
|
366
|
+
* Expand groups by default
|
|
367
|
+
*/
|
|
368
|
+
expandGroupsByDefault = true;
|
|
369
|
+
/**
|
|
370
|
+
* Show group count
|
|
371
|
+
*/
|
|
372
|
+
showGroupCount = true;
|
|
373
|
+
/**
|
|
374
|
+
* Enable column grouping (multi-level headers)
|
|
375
|
+
*/
|
|
376
|
+
columnGrouping = false;
|
|
377
|
+
/**
|
|
378
|
+
* Enable row grouping controls in toolbar
|
|
379
|
+
*/
|
|
380
|
+
showGroupingControls = true;
|
|
381
|
+
/**
|
|
382
|
+
* Enable Tree Data mode (hierarchical)
|
|
383
|
+
*/
|
|
384
|
+
treeData = false;
|
|
385
|
+
/**
|
|
386
|
+
* Show actions menu (3-dot menu) for each row
|
|
387
|
+
*/
|
|
388
|
+
showActions = false;
|
|
389
|
+
/**
|
|
390
|
+
* Custom actions to show in the row actions menu
|
|
391
|
+
*/
|
|
392
|
+
customActions;
|
|
393
|
+
/**
|
|
394
|
+
* Default library for icons
|
|
395
|
+
*/
|
|
396
|
+
iconLibrary = 'default';
|
|
397
|
+
/**
|
|
398
|
+
* Enable column pinning
|
|
399
|
+
*/
|
|
400
|
+
columnPinning = true;
|
|
401
|
+
/**
|
|
402
|
+
* Enable row pinning
|
|
403
|
+
*/
|
|
404
|
+
rowPinning = true;
|
|
405
|
+
/**
|
|
406
|
+
* Enable row spanning
|
|
407
|
+
*/
|
|
408
|
+
rowSpanning = false;
|
|
409
|
+
/**
|
|
410
|
+
* Enable row reordering via drag and drop
|
|
411
|
+
*/
|
|
412
|
+
rowReorder = false;
|
|
413
|
+
/**
|
|
414
|
+
* Enable multi-column filtering
|
|
415
|
+
*/
|
|
416
|
+
multiFilter = true;
|
|
417
|
+
/**
|
|
418
|
+
* Show filter panel
|
|
419
|
+
*/
|
|
420
|
+
showFilterPanel = false;
|
|
421
|
+
/**
|
|
422
|
+
* Show column panel
|
|
423
|
+
*/
|
|
424
|
+
showColumnPanel = false;
|
|
425
|
+
/**
|
|
426
|
+
* Custom header background (solid color or gradient)
|
|
427
|
+
*/
|
|
428
|
+
headerBackground;
|
|
429
|
+
// ========== PRIVATE STATE ==========
|
|
430
|
+
state = {
|
|
431
|
+
selectedRows: new Set(),
|
|
432
|
+
virtualVisibleRange: { start: 0, end: 50 },
|
|
433
|
+
sortConfig: { field: '', direction: null },
|
|
434
|
+
filterConfig: {},
|
|
435
|
+
searchQuery: '',
|
|
436
|
+
pagination: {
|
|
437
|
+
currentPage: 1,
|
|
438
|
+
pageSize: 10,
|
|
439
|
+
totalPages: 1,
|
|
440
|
+
totalRows: 0,
|
|
441
|
+
},
|
|
442
|
+
editingCell: null,
|
|
443
|
+
columnOrder: [],
|
|
444
|
+
visibleColumns: new Set(),
|
|
445
|
+
columnWidths: new Map(),
|
|
446
|
+
expandedGroups: new Set(),
|
|
447
|
+
groupBy: null,
|
|
448
|
+
expandedRows: new Set(),
|
|
449
|
+
focusedCell: null,
|
|
450
|
+
};
|
|
451
|
+
draggedColumn = null;
|
|
452
|
+
draggedRow = null;
|
|
453
|
+
showColumnSettings = false;
|
|
454
|
+
showExportDialog = false;
|
|
455
|
+
resizingColumn = null;
|
|
456
|
+
activeActionMenu = null;
|
|
457
|
+
pinnedColumns = { left: [], right: [] };
|
|
458
|
+
pinnedRows = { top: [], bottom: [] };
|
|
459
|
+
editingRow = null;
|
|
460
|
+
activeFilters = new Map();
|
|
461
|
+
filterPanelField = '';
|
|
462
|
+
filterPanelOperator = 'contains';
|
|
463
|
+
filterPanelValue = '';
|
|
464
|
+
draggedColumnInPanel = null;
|
|
465
|
+
columnSearchQuery = '';
|
|
466
|
+
// Premium features state
|
|
467
|
+
virtualScrollOffset = 0;
|
|
468
|
+
virtualVisibleRange = { start: 0, end: 50 };
|
|
469
|
+
multiSortConfig = [];
|
|
470
|
+
columnAggregations = new Map();
|
|
471
|
+
expandedRowDetails = new Set();
|
|
472
|
+
validationErrors = new Map(); // rowId -> field -> error
|
|
473
|
+
showKeyboardShortcutsHelp = false;
|
|
474
|
+
advancedFilterConfig = new Map();
|
|
475
|
+
// New features state
|
|
476
|
+
rangeSelectionAnchor = null;
|
|
477
|
+
clipboardData = [];
|
|
478
|
+
formattingCache = new Map();
|
|
479
|
+
// Phase 2 State
|
|
480
|
+
contextMenuState = { visible: false, x: 0, y: 0, type: 'cell', target: null };
|
|
481
|
+
undoStack = [];
|
|
482
|
+
redoStack = [];
|
|
483
|
+
lazyLoadedRows = new Set();
|
|
484
|
+
isMobileView = false;
|
|
485
|
+
/**
|
|
486
|
+
* Events
|
|
487
|
+
*/
|
|
488
|
+
rowSelect;
|
|
489
|
+
rowDeselect;
|
|
490
|
+
cellEdit;
|
|
491
|
+
cellEditStart;
|
|
492
|
+
cellEditStop;
|
|
493
|
+
rowEditStart;
|
|
494
|
+
rowEditStop;
|
|
495
|
+
sortChange;
|
|
496
|
+
filterChange;
|
|
497
|
+
pageChange;
|
|
498
|
+
searchChange;
|
|
499
|
+
columnOrderChange;
|
|
500
|
+
columnVisibilityChange;
|
|
501
|
+
columnPin;
|
|
502
|
+
rowPin;
|
|
503
|
+
rowReorderEvent;
|
|
504
|
+
dataExport;
|
|
505
|
+
groupToggle;
|
|
506
|
+
groupByChange;
|
|
507
|
+
rowEdit;
|
|
508
|
+
rowDelete;
|
|
509
|
+
rowAction;
|
|
510
|
+
lazyLoadMore;
|
|
511
|
+
resizeObserver;
|
|
512
|
+
lazyLoadObserver;
|
|
513
|
+
editInputRef;
|
|
514
|
+
resizeStartX = 0;
|
|
515
|
+
resizeStartWidth = 0;
|
|
516
|
+
resizingColumnId = '';
|
|
517
|
+
componentWillLoad() {
|
|
518
|
+
this.initializeState();
|
|
519
|
+
}
|
|
520
|
+
componentDidLoad() {
|
|
521
|
+
// Load saved state first
|
|
522
|
+
this.loadTableState();
|
|
523
|
+
this.setupResizeObserver();
|
|
524
|
+
this.applyTheme();
|
|
525
|
+
this.setupClickOutsideListener();
|
|
526
|
+
this.setupGlobalKeyboardShortcuts();
|
|
527
|
+
// Calculate aggregations if enabled
|
|
528
|
+
// if (this.columnAggregation) {
|
|
529
|
+
// this.calculateAggregations();
|
|
530
|
+
// }
|
|
531
|
+
// Add copy/paste listeners if enabled
|
|
532
|
+
if (this.copyPaste) {
|
|
533
|
+
document.addEventListener('copy', this.handleCopy);
|
|
534
|
+
document.addEventListener('paste', this.handlePaste);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
disconnectedCallback() {
|
|
538
|
+
if (this.resizeObserver) {
|
|
539
|
+
this.resizeObserver.disconnect();
|
|
540
|
+
}
|
|
541
|
+
if (this.lazyLoadObserver) {
|
|
542
|
+
this.lazyLoadObserver.disconnect();
|
|
543
|
+
}
|
|
544
|
+
// Clean up resize event listeners
|
|
545
|
+
document.removeEventListener('mousemove', this.handleResizeMove);
|
|
546
|
+
document.removeEventListener('mouseup', this.handleResizeEnd);
|
|
547
|
+
// Clean up copy/paste listeners
|
|
548
|
+
if (this.copyPaste) {
|
|
549
|
+
document.removeEventListener('copy', this.handleCopy);
|
|
550
|
+
document.removeEventListener('paste', this.handlePaste);
|
|
551
|
+
}
|
|
552
|
+
// Clean up click outside listener
|
|
553
|
+
document.removeEventListener('click', this.handleClickOutside);
|
|
554
|
+
}
|
|
555
|
+
onDataOrColumnsChange() {
|
|
556
|
+
this.initializeState();
|
|
557
|
+
}
|
|
558
|
+
onPageSizeChange(newSize) {
|
|
559
|
+
this.state = {
|
|
560
|
+
...this.state,
|
|
561
|
+
pagination: {
|
|
562
|
+
...this.state.pagination,
|
|
563
|
+
pageSize: newSize,
|
|
564
|
+
currentPage: 1,
|
|
565
|
+
totalPages: this.calculateTotalPages(newSize),
|
|
566
|
+
},
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
onGroupByChange(newGroupBy) {
|
|
570
|
+
this.handleGroupByChange(newGroupBy);
|
|
571
|
+
}
|
|
572
|
+
onThemeChange() {
|
|
573
|
+
this.applyTheme();
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Public methods
|
|
577
|
+
*/
|
|
578
|
+
async selectRow(rowId) {
|
|
579
|
+
const newSelected = new Set(this.state.selectedRows);
|
|
580
|
+
newSelected.add(rowId);
|
|
581
|
+
this.updateSelectedRows(newSelected);
|
|
582
|
+
}
|
|
583
|
+
async deselectRow(rowId) {
|
|
584
|
+
const newSelected = new Set(this.state.selectedRows);
|
|
585
|
+
newSelected.delete(rowId);
|
|
586
|
+
this.updateSelectedRows(newSelected);
|
|
587
|
+
}
|
|
588
|
+
async selectAllRows() {
|
|
589
|
+
const allIds = this.getProcessedData().map(row => row.id);
|
|
590
|
+
this.updateSelectedRows(new Set(allIds));
|
|
591
|
+
}
|
|
592
|
+
async deselectAllRows() {
|
|
593
|
+
this.updateSelectedRows(new Set());
|
|
594
|
+
}
|
|
595
|
+
async getSelectedRows() {
|
|
596
|
+
return Array.from(this.state.selectedRows);
|
|
597
|
+
}
|
|
598
|
+
async exportData(options = { format: 'csv' }) {
|
|
599
|
+
const data = this.prepareExportData(options);
|
|
600
|
+
this.performExport(data, options);
|
|
601
|
+
}
|
|
602
|
+
async resetFilters() {
|
|
603
|
+
this.state = {
|
|
604
|
+
...this.state,
|
|
605
|
+
filterConfig: {},
|
|
606
|
+
searchQuery: '',
|
|
607
|
+
pagination: { ...this.state.pagination, currentPage: 1 },
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
async resetSort() {
|
|
611
|
+
this.state = {
|
|
612
|
+
...this.state,
|
|
613
|
+
sortConfig: { field: '', direction: null },
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
async goToPage(page) {
|
|
617
|
+
if (page >= 1 && page <= this.state.pagination.totalPages) {
|
|
618
|
+
this.state = {
|
|
619
|
+
...this.state,
|
|
620
|
+
pagination: { ...this.state.pagination, currentPage: page },
|
|
621
|
+
};
|
|
622
|
+
this.pageChange.emit({ page, pageSize: this.state.pagination.pageSize });
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
async refresh() {
|
|
626
|
+
this.initializeState();
|
|
627
|
+
}
|
|
628
|
+
async print() {
|
|
629
|
+
if (this.printOptimized) {
|
|
630
|
+
window.print();
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
// Create a temporary print frame or styling
|
|
634
|
+
const style = document.createElement('style');
|
|
635
|
+
style.textContent = `
|
|
636
|
+
@media print {
|
|
637
|
+
body * { visibility: hidden; }
|
|
638
|
+
.data-table-container, .data-table-container * { visibility: visible; }
|
|
639
|
+
.data-table-container { position: absolute; left: 0; top: 0; width: 100%; }
|
|
640
|
+
.toolbar, .pagination-container, .column-settings-panel, .filter-panel { display: none !important; }
|
|
641
|
+
.data-table { width: 100% !important; border-collapse: collapse !important; }
|
|
642
|
+
.data-table td, .data-table th { border: 1px solid #ddd !important; padding: 8px !important; }
|
|
643
|
+
}
|
|
644
|
+
`;
|
|
645
|
+
document.head.appendChild(style);
|
|
646
|
+
window.print();
|
|
647
|
+
document.head.removeChild(style);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
initializeState() {
|
|
651
|
+
const cols = this.parseColumns();
|
|
652
|
+
const flatColumns = this.flattenColumns(cols);
|
|
653
|
+
// Initialize column widths with smart distribution
|
|
654
|
+
const columnWidths = this.calculateInitialColumnWidths(flatColumns);
|
|
655
|
+
// Initialize grouping
|
|
656
|
+
const initialGroupBy = this.groupBy || null;
|
|
657
|
+
const expandedGroups = new Set();
|
|
658
|
+
if (initialGroupBy && this.expandGroupsByDefault) {
|
|
659
|
+
// We'll populate this after data is available
|
|
660
|
+
const data = this.parseData();
|
|
661
|
+
const groups = this.groupData(data, initialGroupBy);
|
|
662
|
+
groups.forEach((_, key) => expandedGroups.add(key));
|
|
663
|
+
}
|
|
664
|
+
this.state = {
|
|
665
|
+
...this.state,
|
|
666
|
+
columnOrder: flatColumns.map(col => col.id),
|
|
667
|
+
visibleColumns: new Set(flatColumns.filter(col => col.visible !== false).map(col => col.id)),
|
|
668
|
+
columnWidths: columnWidths,
|
|
669
|
+
groupBy: initialGroupBy,
|
|
670
|
+
expandedGroups: expandedGroups,
|
|
671
|
+
pagination: {
|
|
672
|
+
currentPage: 1,
|
|
673
|
+
pageSize: this.pageSize,
|
|
674
|
+
totalPages: this.calculateTotalPages(this.pageSize),
|
|
675
|
+
totalRows: this.getTotalRows(),
|
|
676
|
+
},
|
|
677
|
+
focusedCell: null,
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
parseColumns() {
|
|
681
|
+
if (typeof this.columns === 'string') {
|
|
682
|
+
try {
|
|
683
|
+
return JSON.parse(this.columns);
|
|
684
|
+
}
|
|
685
|
+
catch {
|
|
686
|
+
return [];
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return this.columns || [];
|
|
690
|
+
}
|
|
691
|
+
parseData() {
|
|
692
|
+
if (typeof this.data === 'string') {
|
|
693
|
+
try {
|
|
694
|
+
return JSON.parse(this.data);
|
|
695
|
+
}
|
|
696
|
+
catch {
|
|
697
|
+
return [];
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
return this.data || [];
|
|
701
|
+
}
|
|
702
|
+
parsePageSizeOptions() {
|
|
703
|
+
if (typeof this.pageSizeOptions === 'string') {
|
|
704
|
+
try {
|
|
705
|
+
return JSON.parse(this.pageSizeOptions);
|
|
706
|
+
}
|
|
707
|
+
catch {
|
|
708
|
+
return [5, 10, 25, 50, 100];
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return this.pageSizeOptions;
|
|
712
|
+
}
|
|
713
|
+
flattenColumns(columns) {
|
|
714
|
+
const result = [];
|
|
715
|
+
const flatten = (cols) => {
|
|
716
|
+
cols.forEach(col => {
|
|
717
|
+
if (col.children && col.children.length > 0) {
|
|
718
|
+
flatten(col.children);
|
|
719
|
+
}
|
|
720
|
+
else {
|
|
721
|
+
result.push(col);
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
};
|
|
725
|
+
flatten(columns);
|
|
726
|
+
return result;
|
|
727
|
+
}
|
|
728
|
+
getVisibleColumns() {
|
|
729
|
+
const cols = this.parseColumns();
|
|
730
|
+
const flatColumns = this.flattenColumns(cols);
|
|
731
|
+
return this.state.columnOrder
|
|
732
|
+
.map(id => flatColumns.find(col => col.id === id))
|
|
733
|
+
.filter((col) => !!col && this.state.visibleColumns.has(col.id));
|
|
734
|
+
}
|
|
735
|
+
getTotalRows() {
|
|
736
|
+
if (this.serverSide) {
|
|
737
|
+
return this.totalRows;
|
|
738
|
+
}
|
|
739
|
+
return this.parseData().length;
|
|
740
|
+
}
|
|
741
|
+
calculateTotalPages(pageSize) {
|
|
742
|
+
const total = this.getTotalRows();
|
|
743
|
+
return Math.ceil(total / pageSize);
|
|
744
|
+
}
|
|
745
|
+
getProcessedData() {
|
|
746
|
+
let data = this.parseData();
|
|
747
|
+
// Handle Tree Data Flattening
|
|
748
|
+
if (this.treeData) {
|
|
749
|
+
if (!this.state.searchQuery && Object.keys(this.state.filterConfig).length === 0 && !this.state.sortConfig.field) {
|
|
750
|
+
data = this.flattenTreeData(data);
|
|
751
|
+
}
|
|
752
|
+
else {
|
|
753
|
+
data = this.flattenTreeData(data);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
// Apply search
|
|
757
|
+
if (this.searchable && this.state.searchQuery) {
|
|
758
|
+
data = this.applySearch(data, this.state.searchQuery);
|
|
759
|
+
}
|
|
760
|
+
// Apply basic filters
|
|
761
|
+
if (this.filterable && Object.keys(this.state.filterConfig).length > 0) {
|
|
762
|
+
data = this.applyFilters(data, this.state.filterConfig);
|
|
763
|
+
}
|
|
764
|
+
// Apply advanced filters (PREMIUM)
|
|
765
|
+
if (this.advancedFilters) {
|
|
766
|
+
data = this.applyAdvancedFilters(data);
|
|
767
|
+
}
|
|
768
|
+
// Apply sort (multi-sort or single sort) (PREMIUM)
|
|
769
|
+
if (this.sortable) {
|
|
770
|
+
if (this.multiSort && this.multiSortConfig.length > 0) {
|
|
771
|
+
data = this.applyMultiSort(data);
|
|
772
|
+
}
|
|
773
|
+
else if (this.state.sortConfig.field && this.state.sortConfig.direction) {
|
|
774
|
+
data = this.applySort(data, this.state.sortConfig);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
// Update total rows after filtering
|
|
778
|
+
if (!this.serverSide) {
|
|
779
|
+
this.state.pagination.totalRows = data.length;
|
|
780
|
+
this.state.pagination.totalPages = this.calculateTotalPages(this.state.pagination.pageSize);
|
|
781
|
+
}
|
|
782
|
+
// Calculate aggregations (PREMIUM)
|
|
783
|
+
// if (this.columnAggregation) {
|
|
784
|
+
// this.calculateAggregations();
|
|
785
|
+
// }
|
|
786
|
+
// Apply pagination (skip if virtual scroll)
|
|
787
|
+
if (this.pagination && !this.serverSide && !this.virtualScroll) {
|
|
788
|
+
data = this.applyPagination(data);
|
|
789
|
+
}
|
|
790
|
+
// Save state if persistence enabled (PREMIUM)
|
|
791
|
+
if (this.persistState) {
|
|
792
|
+
this.saveTableState();
|
|
793
|
+
}
|
|
794
|
+
return data;
|
|
795
|
+
}
|
|
796
|
+
applySearch(data, query) {
|
|
797
|
+
const lowerQuery = query.toLowerCase();
|
|
798
|
+
const columns = this.getVisibleColumns();
|
|
799
|
+
return data.filter(row => {
|
|
800
|
+
return columns.some(col => {
|
|
801
|
+
const value = col.field ? row[col.field] : '';
|
|
802
|
+
return String(value).toLowerCase().includes(lowerQuery);
|
|
803
|
+
});
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
applyFilters(data, filters) {
|
|
807
|
+
return data.filter(row => {
|
|
808
|
+
return Object.keys(filters).every(field => {
|
|
809
|
+
const filterValue = filters[field];
|
|
810
|
+
if (filterValue === null || filterValue === '')
|
|
811
|
+
return true;
|
|
812
|
+
const rowValue = row[field];
|
|
813
|
+
if (typeof filterValue === 'string') {
|
|
814
|
+
return String(rowValue).toLowerCase().includes(filterValue.toLowerCase());
|
|
815
|
+
}
|
|
816
|
+
return rowValue === filterValue;
|
|
817
|
+
});
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
applySort(data, sort) {
|
|
821
|
+
return [...data].sort((a, b) => {
|
|
822
|
+
const aVal = a[sort.field];
|
|
823
|
+
const bVal = b[sort.field];
|
|
824
|
+
if (aVal === bVal)
|
|
825
|
+
return 0;
|
|
826
|
+
const comparison = aVal < bVal ? -1 : 1;
|
|
827
|
+
return sort.direction === 'asc' ? comparison : -comparison;
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
applyPagination(data) {
|
|
831
|
+
const { currentPage, pageSize } = this.state.pagination;
|
|
832
|
+
const start = (currentPage - 1) * pageSize;
|
|
833
|
+
const end = start + pageSize;
|
|
834
|
+
return data.slice(start, end);
|
|
835
|
+
}
|
|
836
|
+
groupData(data, groupByField) {
|
|
837
|
+
const groups = new Map();
|
|
838
|
+
data.forEach(row => {
|
|
839
|
+
const groupValue = row[groupByField] !== undefined && row[groupByField] !== null
|
|
840
|
+
? String(row[groupByField])
|
|
841
|
+
: '(Empty)';
|
|
842
|
+
if (!groups.has(groupValue)) {
|
|
843
|
+
groups.set(groupValue, []);
|
|
844
|
+
}
|
|
845
|
+
groups.get(groupValue).push(row);
|
|
846
|
+
});
|
|
847
|
+
return groups;
|
|
848
|
+
}
|
|
849
|
+
handleGroupToggle(groupKey) {
|
|
850
|
+
const newExpanded = new Set(this.state.expandedGroups);
|
|
851
|
+
if (newExpanded.has(groupKey)) {
|
|
852
|
+
newExpanded.delete(groupKey);
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
newExpanded.add(groupKey);
|
|
856
|
+
}
|
|
857
|
+
this.state = { ...this.state, expandedGroups: newExpanded };
|
|
858
|
+
this.groupToggle.emit({ groupKey, expanded: newExpanded.has(groupKey) });
|
|
859
|
+
}
|
|
860
|
+
handleGroupByChange(field) {
|
|
861
|
+
const newGroupBy = field === this.state.groupBy ? null : field;
|
|
862
|
+
// Initialize expanded groups based on expandGroupsByDefault prop
|
|
863
|
+
const expandedGroups = new Set();
|
|
864
|
+
if (newGroupBy && this.expandGroupsByDefault) {
|
|
865
|
+
const data = this.getProcessedData();
|
|
866
|
+
const groups = this.groupData(data, newGroupBy);
|
|
867
|
+
groups.forEach((_, key) => expandedGroups.add(key));
|
|
868
|
+
}
|
|
869
|
+
this.state = {
|
|
870
|
+
...this.state,
|
|
871
|
+
groupBy: newGroupBy,
|
|
872
|
+
expandedGroups: expandedGroups,
|
|
873
|
+
};
|
|
874
|
+
if (newGroupBy) {
|
|
875
|
+
this.groupByChange.emit({ field: newGroupBy });
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
handleSort(field) {
|
|
879
|
+
if (!this.sortable)
|
|
880
|
+
return;
|
|
881
|
+
this.pushUndoState();
|
|
882
|
+
const currentSort = this.state.sortConfig;
|
|
883
|
+
let newDirection = 'asc';
|
|
884
|
+
if (currentSort.field === field) {
|
|
885
|
+
if (currentSort.direction === 'asc') {
|
|
886
|
+
newDirection = 'desc';
|
|
887
|
+
}
|
|
888
|
+
else if (currentSort.direction === 'desc') {
|
|
889
|
+
newDirection = null;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
const newSort = {
|
|
893
|
+
field: newDirection ? field : '',
|
|
894
|
+
direction: newDirection,
|
|
895
|
+
};
|
|
896
|
+
this.state = { ...this.state, sortConfig: newSort };
|
|
897
|
+
this.sortChange.emit(newSort);
|
|
898
|
+
// Announce to screen readers
|
|
899
|
+
if (this.enhancedAccessibility && newDirection) {
|
|
900
|
+
this.announceToScreenReader(`Sorted by ${field} ${newDirection === 'asc' ? 'ascending' : 'descending'}`);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
handleSearch(event) {
|
|
904
|
+
this.pushUndoState();
|
|
905
|
+
const input = event.target;
|
|
906
|
+
this.state = {
|
|
907
|
+
...this.state,
|
|
908
|
+
searchQuery: input.value,
|
|
909
|
+
pagination: { ...this.state.pagination, currentPage: 1 },
|
|
910
|
+
};
|
|
911
|
+
this.searchChange.emit({ query: input.value });
|
|
912
|
+
}
|
|
913
|
+
handleFilter(field, value) {
|
|
914
|
+
this.pushUndoState();
|
|
915
|
+
const newFilters = { ...this.state.filterConfig };
|
|
916
|
+
if (value === '') {
|
|
917
|
+
delete newFilters[field];
|
|
918
|
+
}
|
|
919
|
+
else {
|
|
920
|
+
newFilters[field] = value;
|
|
921
|
+
}
|
|
922
|
+
this.state = {
|
|
923
|
+
...this.state,
|
|
924
|
+
filterConfig: newFilters,
|
|
925
|
+
pagination: { ...this.state.pagination, currentPage: 1 },
|
|
926
|
+
};
|
|
927
|
+
this.filterChange.emit(newFilters);
|
|
928
|
+
// Announce to screen readers
|
|
929
|
+
if (this.enhancedAccessibility) {
|
|
930
|
+
const filterCount = Object.keys(newFilters).length;
|
|
931
|
+
this.announceToScreenReader(`${filterCount} filter${filterCount !== 1 ? 's' : ''} applied`);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
handleRowSelect(rowId, event) {
|
|
935
|
+
const checkbox = event.target;
|
|
936
|
+
const newSelected = new Set(this.state.selectedRows);
|
|
937
|
+
if (checkbox.checked) {
|
|
938
|
+
if (this.multiSelect) {
|
|
939
|
+
newSelected.add(rowId);
|
|
940
|
+
}
|
|
941
|
+
else {
|
|
942
|
+
newSelected.clear();
|
|
943
|
+
newSelected.add(rowId);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
newSelected.delete(rowId);
|
|
948
|
+
}
|
|
949
|
+
this.updateSelectedRows(newSelected);
|
|
950
|
+
}
|
|
951
|
+
handleSelectAll(event) {
|
|
952
|
+
const checkbox = event.target;
|
|
953
|
+
if (checkbox.checked) {
|
|
954
|
+
const allIds = this.getProcessedData().map(row => row.id);
|
|
955
|
+
this.updateSelectedRows(new Set(allIds));
|
|
956
|
+
}
|
|
957
|
+
else {
|
|
958
|
+
this.updateSelectedRows(new Set());
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
updateSelectedRows(selected) {
|
|
962
|
+
this.pushUndoState();
|
|
963
|
+
this.state = { ...this.state, selectedRows: selected };
|
|
964
|
+
const selectedArray = Array.from(selected);
|
|
965
|
+
if (selected.size > 0) {
|
|
966
|
+
this.rowSelect.emit({ selectedRows: selectedArray });
|
|
967
|
+
// Announce to screen readers
|
|
968
|
+
if (this.enhancedAccessibility) {
|
|
969
|
+
this.announceToScreenReader(`${selected.size} row${selected.size !== 1 ? 's' : ''} selected`);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
else {
|
|
973
|
+
this.rowDeselect.emit({ selectedRows: selectedArray });
|
|
974
|
+
if (this.enhancedAccessibility) {
|
|
975
|
+
this.announceToScreenReader('All rows deselected');
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
handleCellEdit(rowId, field, value) {
|
|
980
|
+
// Phase 2: Inline Validation
|
|
981
|
+
if (this.advancedValidation) {
|
|
982
|
+
const error = this.validateCell(rowId, field, value);
|
|
983
|
+
const rowKey = String(rowId);
|
|
984
|
+
if (error) {
|
|
985
|
+
const rowErrors = this.validationErrors.get(rowKey) || new Map();
|
|
986
|
+
rowErrors.set(field, error);
|
|
987
|
+
this.validationErrors = new Map(this.validationErrors).set(rowKey, rowErrors);
|
|
988
|
+
}
|
|
989
|
+
else {
|
|
990
|
+
const rowErrors = this.validationErrors.get(rowKey);
|
|
991
|
+
if (rowErrors && rowErrors.has(field)) {
|
|
992
|
+
rowErrors.delete(field);
|
|
993
|
+
this.validationErrors = new Map(this.validationErrors);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
// Emit stop event before edit
|
|
998
|
+
this.cellEditStop.emit({ rowId, field, value });
|
|
999
|
+
// Emit main edit event
|
|
1000
|
+
this.cellEdit.emit({ rowId, field, value });
|
|
1001
|
+
// Clear editing state
|
|
1002
|
+
this.state = { ...this.state, editingCell: null };
|
|
1003
|
+
// Check if row editing should stop
|
|
1004
|
+
if (this.editingRow === rowId && !this.editable) {
|
|
1005
|
+
this.stopRowEdit(rowId);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
startCellEdit(rowId, field) {
|
|
1009
|
+
if (!this.editable)
|
|
1010
|
+
return;
|
|
1011
|
+
const row = Array.isArray(this.data) ? this.data.find(r => r.id === rowId) : null;
|
|
1012
|
+
const currentValue = row ? row[field] : null;
|
|
1013
|
+
// Emit start event
|
|
1014
|
+
this.cellEditStart.emit({ rowId, field, value: currentValue });
|
|
1015
|
+
// Start row editing if not already started
|
|
1016
|
+
if (this.editingRow !== rowId) {
|
|
1017
|
+
this.startRowEdit(rowId);
|
|
1018
|
+
}
|
|
1019
|
+
this.state = { ...this.state, editingCell: { rowId, field } };
|
|
1020
|
+
setTimeout(() => {
|
|
1021
|
+
if (this.editInputRef) {
|
|
1022
|
+
this.editInputRef?.setFocus();
|
|
1023
|
+
if (this.editInputRef && 'select' in this.editInputRef) {
|
|
1024
|
+
this.editInputRef.select();
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}, 0);
|
|
1028
|
+
}
|
|
1029
|
+
startRowEdit(rowId) {
|
|
1030
|
+
const row = Array.isArray(this.data) ? this.data.find(r => r.id === rowId) : null;
|
|
1031
|
+
if (row) {
|
|
1032
|
+
this.editingRow = rowId;
|
|
1033
|
+
this.rowEditStart.emit({ row });
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
stopRowEdit(rowId) {
|
|
1037
|
+
const row = Array.isArray(this.data) ? this.data.find(r => r.id === rowId) : null;
|
|
1038
|
+
if (row) {
|
|
1039
|
+
this.editingRow = null;
|
|
1040
|
+
this.rowEditStop.emit({ row });
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
toggleRowExpansion(rowId, event) {
|
|
1044
|
+
event.stopPropagation();
|
|
1045
|
+
const newExpanded = new Set(this.state.expandedRows);
|
|
1046
|
+
if (newExpanded.has(rowId)) {
|
|
1047
|
+
newExpanded.delete(rowId);
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
newExpanded.add(rowId);
|
|
1051
|
+
}
|
|
1052
|
+
this.state = { ...this.state, expandedRows: newExpanded };
|
|
1053
|
+
}
|
|
1054
|
+
flattenTreeData(data, depth = 0) {
|
|
1055
|
+
let result = [];
|
|
1056
|
+
data.forEach(row => {
|
|
1057
|
+
// Clone row to avoid mutating original data property,
|
|
1058
|
+
// but simplistic clone might lose methods if any.
|
|
1059
|
+
// Assuming data is POJO.
|
|
1060
|
+
const flatRow = { ...row, _depth: depth, _hasChildren: row.children && row.children.length > 0 };
|
|
1061
|
+
result.push(flatRow);
|
|
1062
|
+
if (row.children && row.children.length > 0 && this.state.expandedRows.has(row.id)) {
|
|
1063
|
+
result = result.concat(this.flattenTreeData(row.children, depth + 1));
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
return result;
|
|
1067
|
+
}
|
|
1068
|
+
// New handlers for ui-pagination component
|
|
1069
|
+
handlePaginationChange(event) {
|
|
1070
|
+
const { page, itemsPerPage } = event.detail;
|
|
1071
|
+
this.state = {
|
|
1072
|
+
...this.state,
|
|
1073
|
+
pagination: {
|
|
1074
|
+
...this.state.pagination,
|
|
1075
|
+
currentPage: page,
|
|
1076
|
+
pageSize: itemsPerPage,
|
|
1077
|
+
},
|
|
1078
|
+
};
|
|
1079
|
+
this.pageChange.emit({ page, pageSize: itemsPerPage });
|
|
1080
|
+
}
|
|
1081
|
+
handlePageSizeChangeFromPagination(event) {
|
|
1082
|
+
const newPageSize = event.detail;
|
|
1083
|
+
this.state = {
|
|
1084
|
+
...this.state,
|
|
1085
|
+
pagination: {
|
|
1086
|
+
...this.state.pagination,
|
|
1087
|
+
pageSize: newPageSize,
|
|
1088
|
+
currentPage: 1,
|
|
1089
|
+
totalPages: this.calculateTotalPages(newPageSize),
|
|
1090
|
+
},
|
|
1091
|
+
};
|
|
1092
|
+
this.pageChange.emit({ page: 1, pageSize: newPageSize });
|
|
1093
|
+
}
|
|
1094
|
+
// ========== PREMIUM FEATURES HELPER METHODS ==========
|
|
1095
|
+
// Virtual Scrolling
|
|
1096
|
+
handleVirtualScroll = (event) => {
|
|
1097
|
+
if (!this.virtualScroll)
|
|
1098
|
+
return;
|
|
1099
|
+
const target = event.target;
|
|
1100
|
+
const scrollTop = target.scrollTop;
|
|
1101
|
+
const start = Math.floor(scrollTop / this.virtualRowHeight);
|
|
1102
|
+
const visibleCount = Math.ceil(target.clientHeight / this.virtualRowHeight);
|
|
1103
|
+
const end = start + visibleCount + 10; // buffer rows
|
|
1104
|
+
this.virtualVisibleRange = { start: Math.max(0, start - 5), end };
|
|
1105
|
+
};
|
|
1106
|
+
// Multi-Column Sort
|
|
1107
|
+
handleMultiSort(field, event) {
|
|
1108
|
+
if (!this.multiSort) {
|
|
1109
|
+
this.handleSort(field);
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
this.pushUndoState();
|
|
1113
|
+
const ctrl = event && (event.ctrlKey || event.metaKey);
|
|
1114
|
+
const existing = this.multiSortConfig.findIndex(s => s.field === field);
|
|
1115
|
+
let newConfig = [...this.multiSortConfig];
|
|
1116
|
+
if (ctrl) {
|
|
1117
|
+
// Add to multi-sort
|
|
1118
|
+
if (existing >= 0) {
|
|
1119
|
+
if (newConfig[existing].direction === 'asc') {
|
|
1120
|
+
newConfig[existing].direction = 'desc';
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
newConfig.splice(existing, 1);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
else {
|
|
1127
|
+
if (newConfig.length < this.maxSortColumns) {
|
|
1128
|
+
newConfig.push({ field, direction: 'asc' });
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
else {
|
|
1133
|
+
// Single sort
|
|
1134
|
+
newConfig = existing >= 0 && newConfig[existing].direction === 'asc'
|
|
1135
|
+
? [{ field, direction: 'desc' }]
|
|
1136
|
+
: [{ field, direction: 'asc' }];
|
|
1137
|
+
}
|
|
1138
|
+
this.multiSortConfig = newConfig;
|
|
1139
|
+
}
|
|
1140
|
+
applyMultiSort(data) {
|
|
1141
|
+
if (!this.multiSort || this.multiSortConfig.length === 0) {
|
|
1142
|
+
return this.applySort(data, this.state.sortConfig);
|
|
1143
|
+
}
|
|
1144
|
+
return [...data].sort((a, b) => {
|
|
1145
|
+
for (const sort of this.multiSortConfig) {
|
|
1146
|
+
const aVal = a[sort.field];
|
|
1147
|
+
const bVal = b[sort.field];
|
|
1148
|
+
if (aVal !== bVal) {
|
|
1149
|
+
const comparison = aVal < bVal ? -1 : 1;
|
|
1150
|
+
return sort.direction === 'asc' ? comparison : -comparison;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
return 0;
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
// Advanced Filters
|
|
1157
|
+
filterOperators = {
|
|
1158
|
+
equals: (value, filterValue) => value === filterValue,
|
|
1159
|
+
notEquals: (value, filterValue) => value !== filterValue,
|
|
1160
|
+
contains: (value, filterValue) => String(value).toLowerCase().includes(String(filterValue).toLowerCase()),
|
|
1161
|
+
startsWith: (value, filterValue) => String(value).toLowerCase().startsWith(String(filterValue).toLowerCase()),
|
|
1162
|
+
endsWith: (value, filterValue) => String(value).toLowerCase().endsWith(String(filterValue).toLowerCase()),
|
|
1163
|
+
greaterThan: (value, filterValue) => Number(value) > Number(filterValue),
|
|
1164
|
+
lessThan: (value, filterValue) => Number(value) < Number(filterValue),
|
|
1165
|
+
isEmpty: (value) => value === null || value === undefined || value === '',
|
|
1166
|
+
isNotEmpty: (value) => value !== null && value !== undefined && value !== '',
|
|
1167
|
+
};
|
|
1168
|
+
applyAdvancedFilters(data) {
|
|
1169
|
+
if (!this.advancedFilters || this.advancedFilterConfig.size === 0)
|
|
1170
|
+
return data;
|
|
1171
|
+
return data.filter(row => {
|
|
1172
|
+
return Array.from(this.advancedFilterConfig.entries()).every(([field, config]) => {
|
|
1173
|
+
const operator = this.filterOperators[config.operator];
|
|
1174
|
+
return operator ? operator(row[field], config.value) : true;
|
|
1175
|
+
});
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
// State Persistence
|
|
1179
|
+
saveTableState() {
|
|
1180
|
+
if (!this.persistState || typeof window === 'undefined')
|
|
1181
|
+
return;
|
|
1182
|
+
try {
|
|
1183
|
+
const state = {
|
|
1184
|
+
sortConfig: this.multiSort ? this.multiSortConfig : this.state.sortConfig,
|
|
1185
|
+
filterConfig: this.state.filterConfig,
|
|
1186
|
+
columnOrder: this.state.columnOrder,
|
|
1187
|
+
visibleColumns: Array.from(this.state.visibleColumns),
|
|
1188
|
+
columnWidths: Array.from(this.state.columnWidths.entries()),
|
|
1189
|
+
pagination: this.state.pagination,
|
|
1190
|
+
groupBy: this.state.groupBy,
|
|
1191
|
+
};
|
|
1192
|
+
localStorage.setItem(this.stateStorageKey, JSON.stringify(state));
|
|
1193
|
+
}
|
|
1194
|
+
catch (e) {
|
|
1195
|
+
console.error('Failed to save table state:', e);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
loadTableState() {
|
|
1199
|
+
if (!this.persistState || typeof window === 'undefined')
|
|
1200
|
+
return;
|
|
1201
|
+
try {
|
|
1202
|
+
const saved = localStorage.getItem(this.stateStorageKey);
|
|
1203
|
+
if (saved) {
|
|
1204
|
+
const state = JSON.parse(saved);
|
|
1205
|
+
if (this.multiSort && state.multiSortConfig) {
|
|
1206
|
+
this.multiSortConfig = state.multiSortConfig;
|
|
1207
|
+
}
|
|
1208
|
+
this.state = {
|
|
1209
|
+
...this.state,
|
|
1210
|
+
sortConfig: state.sortConfig || this.state.sortConfig,
|
|
1211
|
+
filterConfig: state.filterConfig || {},
|
|
1212
|
+
columnOrder: state.columnOrder || this.state.columnOrder,
|
|
1213
|
+
visibleColumns: new Set(state.visibleColumns || this.state.visibleColumns),
|
|
1214
|
+
columnWidths: new Map(state.columnWidths || []),
|
|
1215
|
+
groupBy: state.groupBy || null,
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
catch (e) {
|
|
1220
|
+
console.error('Failed to load table state:', e);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
// Row Details
|
|
1224
|
+
toggleRowDetails(rowId) {
|
|
1225
|
+
const newExpanded = new Set(this.expandedRowDetails);
|
|
1226
|
+
if (newExpanded.has(rowId)) {
|
|
1227
|
+
newExpanded.delete(rowId);
|
|
1228
|
+
}
|
|
1229
|
+
else {
|
|
1230
|
+
newExpanded.add(rowId);
|
|
1231
|
+
}
|
|
1232
|
+
this.expandedRowDetails = newExpanded;
|
|
1233
|
+
}
|
|
1234
|
+
// Column Auto-sizing
|
|
1235
|
+
// Inline Validation
|
|
1236
|
+
validateCell(_rowId, field, value) {
|
|
1237
|
+
if (!this.inlineValidation && !this.advancedValidation)
|
|
1238
|
+
return null;
|
|
1239
|
+
// Check column-level validator first
|
|
1240
|
+
const column = this.getVisibleColumns().find(c => c.field === field);
|
|
1241
|
+
if (column && column.validator) {
|
|
1242
|
+
const row = Array.isArray(this.data) ? this.data.find(r => r.id === _rowId) : null;
|
|
1243
|
+
const result = column.validator(value, row);
|
|
1244
|
+
if (result !== true && result !== null) {
|
|
1245
|
+
return typeof result === 'string' ? result : 'Invalid value';
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
if (!this.validationRules[field])
|
|
1249
|
+
return null;
|
|
1250
|
+
const rules = this.validationRules[field];
|
|
1251
|
+
if (rules.required && (value === null || value === undefined || value === '')) {
|
|
1252
|
+
return 'This field is required';
|
|
1253
|
+
}
|
|
1254
|
+
if (rules.minLength && String(value).length < rules.minLength) {
|
|
1255
|
+
return `Minimum length is ${rules.minLength}`;
|
|
1256
|
+
}
|
|
1257
|
+
if (rules.maxLength && String(value).length > rules.maxLength) {
|
|
1258
|
+
return `Maximum length is ${rules.maxLength}`;
|
|
1259
|
+
}
|
|
1260
|
+
if (rules.min !== undefined && Number(value) < rules.min) {
|
|
1261
|
+
return `Minimum value is ${rules.min}`;
|
|
1262
|
+
}
|
|
1263
|
+
if (rules.max !== undefined && Number(value) > rules.max) {
|
|
1264
|
+
return `Maximum value is ${rules.max}`;
|
|
1265
|
+
}
|
|
1266
|
+
if (rules.pattern && !new RegExp(rules.pattern).test(String(value))) {
|
|
1267
|
+
return rules.patternMessage || 'Invalid format';
|
|
1268
|
+
}
|
|
1269
|
+
// Advanced validation: Custom sync function
|
|
1270
|
+
if (this.advancedValidation && rules.custom && typeof rules.custom === 'function') {
|
|
1271
|
+
try {
|
|
1272
|
+
const result = rules.custom(value);
|
|
1273
|
+
if (result !== true) {
|
|
1274
|
+
return typeof result === 'string' ? result : 'Validation failed';
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
catch (error) {
|
|
1278
|
+
return 'Validation error';
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
// Advanced validation: Async custom function (handled separately)
|
|
1282
|
+
if (this.advancedValidation && rules.asyncCustom && typeof rules.asyncCustom === 'function') {
|
|
1283
|
+
this.validateCellAsync(_rowId, field, value, rules.asyncCustom);
|
|
1284
|
+
}
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1287
|
+
async validateCellAsync(rowId, field, value, asyncValidator) {
|
|
1288
|
+
try {
|
|
1289
|
+
const result = await asyncValidator(value);
|
|
1290
|
+
const rowKey = String(rowId);
|
|
1291
|
+
if (result !== true) {
|
|
1292
|
+
const error = typeof result === 'string' ? result : 'Async validation failed';
|
|
1293
|
+
const rowErrors = this.validationErrors.get(rowKey) || new Map();
|
|
1294
|
+
rowErrors.set(field, error);
|
|
1295
|
+
this.validationErrors = new Map(this.validationErrors).set(rowKey, rowErrors);
|
|
1296
|
+
}
|
|
1297
|
+
else {
|
|
1298
|
+
const rowErrors = this.validationErrors.get(rowKey);
|
|
1299
|
+
if (rowErrors && rowErrors.has(field)) {
|
|
1300
|
+
rowErrors.delete(field);
|
|
1301
|
+
this.validationErrors = new Map(this.validationErrors);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
catch (error) {
|
|
1306
|
+
const rowKey = String(rowId);
|
|
1307
|
+
const rowErrors = this.validationErrors.get(rowKey) || new Map();
|
|
1308
|
+
rowErrors.set(field, 'Async validation error');
|
|
1309
|
+
this.validationErrors = new Map(this.validationErrors).set(rowKey, rowErrors);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
// ========== NEW HIGH-VALUE FEATURES IMPLEMENTATION ==========
|
|
1313
|
+
// Feature 1: Advanced Cell Editors
|
|
1314
|
+
renderAdvancedCellEditor(row, column, value) {
|
|
1315
|
+
if (!this.advancedCellEditors) {
|
|
1316
|
+
return this.renderEditableCell(row, column, value);
|
|
1317
|
+
}
|
|
1318
|
+
const handleChange = (newValue) => {
|
|
1319
|
+
this.handleCellEdit(row.id, column.field, newValue);
|
|
1320
|
+
this.state = { ...this.state, editingCell: null };
|
|
1321
|
+
};
|
|
1322
|
+
switch (column.type) {
|
|
1323
|
+
case 'date':
|
|
1324
|
+
case 'datetime':
|
|
1325
|
+
case 'number':
|
|
1326
|
+
return (h("ui-input", { type: column.type === 'datetime' ? 'datetime-local' : column.type, value: value || '', onInputChange: (v) => handleChange(column.type === 'number' ? Number(v.detail) : v.detail), onInputBlur: () => this.state = { ...this.state, editingCell: null }, customClass: `cell-editor ${column.type}-editor`, size: "sm" }));
|
|
1327
|
+
case 'boolean':
|
|
1328
|
+
return (h("ui-checkbox", { checked: !!value, onCheckboxChange: (e) => handleChange(e.detail.checked), size: "sm" }));
|
|
1329
|
+
default:
|
|
1330
|
+
return this.renderEditableCell(row, column, value);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
// Feature 2: Column Formatting
|
|
1334
|
+
formatCellValue(value, column) {
|
|
1335
|
+
if (!this.columnFormatting || value === null || value === undefined) {
|
|
1336
|
+
return String(value || '');
|
|
1337
|
+
}
|
|
1338
|
+
// Use custom formatter if provided
|
|
1339
|
+
if (column.format) {
|
|
1340
|
+
return column.format(value);
|
|
1341
|
+
}
|
|
1342
|
+
// Auto-format based on column type
|
|
1343
|
+
switch (column.type) {
|
|
1344
|
+
case 'number':
|
|
1345
|
+
return new Intl.NumberFormat().format(Number(value));
|
|
1346
|
+
case 'date':
|
|
1347
|
+
return new Intl.DateTimeFormat().format(new Date(value));
|
|
1348
|
+
case 'datetime':
|
|
1349
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
1350
|
+
dateStyle: 'short',
|
|
1351
|
+
timeStyle: 'short'
|
|
1352
|
+
}).format(new Date(value));
|
|
1353
|
+
default:
|
|
1354
|
+
// Check for currency pattern in field name
|
|
1355
|
+
if (column.field?.toLowerCase().includes('price') ||
|
|
1356
|
+
column.field?.toLowerCase().includes('cost') ||
|
|
1357
|
+
column.field?.toLowerCase().includes('amount')) {
|
|
1358
|
+
return new Intl.NumberFormat(undefined, {
|
|
1359
|
+
style: 'currency',
|
|
1360
|
+
currency: 'USD'
|
|
1361
|
+
}).format(Number(value));
|
|
1362
|
+
}
|
|
1363
|
+
// Check for percentage pattern
|
|
1364
|
+
if (column.field?.toLowerCase().includes('percent') ||
|
|
1365
|
+
column.field?.toLowerCase().includes('rate')) {
|
|
1366
|
+
return new Intl.NumberFormat(undefined, {
|
|
1367
|
+
style: 'percent',
|
|
1368
|
+
minimumFractionDigits: 2
|
|
1369
|
+
}).format(Number(value) / 100);
|
|
1370
|
+
}
|
|
1371
|
+
return String(value);
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
// Feature 3: Range Selection
|
|
1375
|
+
handleCellClick(rowId, field, event) {
|
|
1376
|
+
if (!this.rangeSelection || !event.shiftKey) {
|
|
1377
|
+
return;
|
|
1378
|
+
}
|
|
1379
|
+
if (!this.rangeSelectionAnchor) {
|
|
1380
|
+
this.rangeSelectionAnchor = { rowId, field };
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
// Select range of cells
|
|
1384
|
+
const data = this.getProcessedData();
|
|
1385
|
+
const startRowIndex = data.findIndex(r => r.id === this.rangeSelectionAnchor.rowId);
|
|
1386
|
+
const endRowIndex = data.findIndex(r => r.id === rowId);
|
|
1387
|
+
const minRow = Math.min(startRowIndex, endRowIndex);
|
|
1388
|
+
const maxRow = Math.max(startRowIndex, endRowIndex);
|
|
1389
|
+
// Select all rows in range
|
|
1390
|
+
const selectedRows = new Set(this.state.selectedRows);
|
|
1391
|
+
for (let i = minRow; i <= maxRow; i++) {
|
|
1392
|
+
selectedRows.add(data[i].id);
|
|
1393
|
+
}
|
|
1394
|
+
this.state = { ...this.state, selectedRows };
|
|
1395
|
+
}
|
|
1396
|
+
// Feature 4: Copy/Paste
|
|
1397
|
+
handleCopy = (event) => {
|
|
1398
|
+
if (!this.copyPaste || this.state.selectedRows.size === 0) {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
event.preventDefault();
|
|
1402
|
+
const data = this.getProcessedData();
|
|
1403
|
+
const columns = this.getVisibleColumns();
|
|
1404
|
+
const selectedData = data.filter(row => this.state.selectedRows.has(row.id));
|
|
1405
|
+
// Create tab-separated values
|
|
1406
|
+
const headers = columns.map(col => col.label).join('\t');
|
|
1407
|
+
const rows = selectedData.map(row => columns.map(col => this.formatCellValue(row[col.field], col)).join('\t')).join('\n');
|
|
1408
|
+
const textData = headers + '\n' + rows;
|
|
1409
|
+
event.clipboardData?.setData('text/plain', textData);
|
|
1410
|
+
// Store for internal paste
|
|
1411
|
+
this.clipboardData = selectedData.map(row => columns.map(col => row[col.field]));
|
|
1412
|
+
};
|
|
1413
|
+
handlePaste = (event) => {
|
|
1414
|
+
if (!this.copyPaste || !this.editable) {
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1417
|
+
event.preventDefault();
|
|
1418
|
+
const pastedText = event.clipboardData?.getData('text/plain');
|
|
1419
|
+
if (!pastedText)
|
|
1420
|
+
return;
|
|
1421
|
+
// Parse pasted data
|
|
1422
|
+
const rows = pastedText.split('\n').map(row => row.split('\t'));
|
|
1423
|
+
// Emit paste event for external handling
|
|
1424
|
+
this.cellEdit.emit({
|
|
1425
|
+
rowId: 'paste',
|
|
1426
|
+
field: 'multiple',
|
|
1427
|
+
value: rows
|
|
1428
|
+
});
|
|
1429
|
+
};
|
|
1430
|
+
// Feature 5: Conditional Formatting
|
|
1431
|
+
getConditionalFormattingStyle(value, column) {
|
|
1432
|
+
if (!this.conditionalFormatting || !this.formattingRules[column.field]) {
|
|
1433
|
+
return {};
|
|
1434
|
+
}
|
|
1435
|
+
const rules = this.formattingRules[column.field];
|
|
1436
|
+
const numValue = Number(value);
|
|
1437
|
+
// Color scale
|
|
1438
|
+
if (rules.colorScale) {
|
|
1439
|
+
const { min, max, minColor, maxColor } = rules.colorScale;
|
|
1440
|
+
const ratio = (numValue - min) / (max - min);
|
|
1441
|
+
const r = Math.round(minColor.r + (maxColor.r - minColor.r) * ratio);
|
|
1442
|
+
const g = Math.round(minColor.g + (maxColor.g - minColor.g) * ratio);
|
|
1443
|
+
const b = Math.round(minColor.b + (maxColor.b - minColor.b) * ratio);
|
|
1444
|
+
return { backgroundColor: `rgb(${r}, ${g}, ${b})` };
|
|
1445
|
+
}
|
|
1446
|
+
// Data bars
|
|
1447
|
+
if (rules.dataBar) {
|
|
1448
|
+
const { min, max, color } = rules.dataBar;
|
|
1449
|
+
const percentage = ((numValue - min) / (max - min)) * 100;
|
|
1450
|
+
return {
|
|
1451
|
+
background: `linear-gradient(90deg, ${color} ${percentage}%, transparent ${percentage}%)`
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
// Custom rules
|
|
1455
|
+
if (rules.custom && typeof rules.custom === 'function') {
|
|
1456
|
+
return rules.custom(value);
|
|
1457
|
+
}
|
|
1458
|
+
return {};
|
|
1459
|
+
}
|
|
1460
|
+
toggleColumnVisibility(columnId) {
|
|
1461
|
+
const newVisible = new Set(this.state.visibleColumns);
|
|
1462
|
+
if (newVisible.has(columnId)) {
|
|
1463
|
+
newVisible.delete(columnId);
|
|
1464
|
+
}
|
|
1465
|
+
else {
|
|
1466
|
+
newVisible.add(columnId);
|
|
1467
|
+
}
|
|
1468
|
+
this.state = { ...this.state, visibleColumns: newVisible };
|
|
1469
|
+
this.columnVisibilityChange.emit({ visible: Array.from(newVisible) });
|
|
1470
|
+
}
|
|
1471
|
+
handleColumnDragStart(columnId, event) {
|
|
1472
|
+
this.draggedColumn = columnId;
|
|
1473
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
1474
|
+
}
|
|
1475
|
+
handleColumnDragOver(event) {
|
|
1476
|
+
event.preventDefault();
|
|
1477
|
+
event.dataTransfer.dropEffect = 'move';
|
|
1478
|
+
}
|
|
1479
|
+
handleColumnDrop(targetColumnId, event) {
|
|
1480
|
+
event.preventDefault();
|
|
1481
|
+
if (!this.draggedColumn || this.draggedColumn === targetColumnId)
|
|
1482
|
+
return;
|
|
1483
|
+
const newOrder = [...this.state.columnOrder];
|
|
1484
|
+
const draggedIndex = newOrder.indexOf(this.draggedColumn);
|
|
1485
|
+
const targetIndex = newOrder.indexOf(targetColumnId);
|
|
1486
|
+
newOrder.splice(draggedIndex, 1);
|
|
1487
|
+
newOrder.splice(targetIndex, 0, this.draggedColumn);
|
|
1488
|
+
this.state = { ...this.state, columnOrder: newOrder };
|
|
1489
|
+
this.columnOrderChange.emit({ order: newOrder });
|
|
1490
|
+
this.draggedColumn = null;
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Pin/Unpin column
|
|
1494
|
+
*/
|
|
1495
|
+
async handleColumnPin(columnId, position) {
|
|
1496
|
+
const newPinned = { ...this.pinnedColumns };
|
|
1497
|
+
// Remove from both sides first
|
|
1498
|
+
newPinned.left = newPinned.left.filter(id => id !== columnId);
|
|
1499
|
+
newPinned.right = newPinned.right.filter(id => id !== columnId);
|
|
1500
|
+
// Add to new position
|
|
1501
|
+
if (position === 'left') {
|
|
1502
|
+
newPinned.left.push(columnId);
|
|
1503
|
+
}
|
|
1504
|
+
else if (position === 'right') {
|
|
1505
|
+
newPinned.right.push(columnId);
|
|
1506
|
+
}
|
|
1507
|
+
this.pinnedColumns = newPinned;
|
|
1508
|
+
this.columnPin.emit({ columnId, position });
|
|
1509
|
+
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Pin/Unpin row
|
|
1512
|
+
*/
|
|
1513
|
+
async handleRowPin(rowId, position) {
|
|
1514
|
+
const newPinned = { ...this.pinnedRows };
|
|
1515
|
+
// Remove from both positions first
|
|
1516
|
+
newPinned.top = newPinned.top.filter(id => id !== rowId);
|
|
1517
|
+
newPinned.bottom = newPinned.bottom.filter(id => id !== rowId);
|
|
1518
|
+
// Add to new position
|
|
1519
|
+
if (position === 'top') {
|
|
1520
|
+
newPinned.top.push(rowId);
|
|
1521
|
+
}
|
|
1522
|
+
else if (position === 'bottom') {
|
|
1523
|
+
newPinned.bottom.push(rowId);
|
|
1524
|
+
}
|
|
1525
|
+
this.pinnedRows = newPinned;
|
|
1526
|
+
this.rowPin.emit({ rowId, position });
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Row reordering handlers
|
|
1530
|
+
*/
|
|
1531
|
+
handleRowDragStart(rowIndex, event) {
|
|
1532
|
+
if (!this.rowReorder)
|
|
1533
|
+
return;
|
|
1534
|
+
this.draggedRow = rowIndex;
|
|
1535
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
1536
|
+
}
|
|
1537
|
+
handleRowDragOver(event) {
|
|
1538
|
+
if (!this.rowReorder)
|
|
1539
|
+
return;
|
|
1540
|
+
event.preventDefault();
|
|
1541
|
+
event.dataTransfer.dropEffect = 'move';
|
|
1542
|
+
}
|
|
1543
|
+
handleRowDrop(targetRowIndex, event) {
|
|
1544
|
+
event.preventDefault();
|
|
1545
|
+
if (this.draggedRow === null || this.draggedRow === targetRowIndex)
|
|
1546
|
+
return;
|
|
1547
|
+
this.rowReorderEvent.emit({ fromIndex: this.draggedRow, toIndex: targetRowIndex });
|
|
1548
|
+
this.draggedRow = null;
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Multi-filter management
|
|
1552
|
+
*/
|
|
1553
|
+
addFilter(field, operator, value) {
|
|
1554
|
+
const fieldFilters = this.activeFilters.get(field) || [];
|
|
1555
|
+
fieldFilters.push({ operator, value });
|
|
1556
|
+
this.activeFilters.set(field, fieldFilters);
|
|
1557
|
+
// Update filter config
|
|
1558
|
+
const newFilters = { ...this.state.filterConfig };
|
|
1559
|
+
newFilters[field] = fieldFilters;
|
|
1560
|
+
this.state = { ...this.state, filterConfig: newFilters };
|
|
1561
|
+
this.filterChange.emit(newFilters);
|
|
1562
|
+
}
|
|
1563
|
+
removeFilter(field, index) {
|
|
1564
|
+
const fieldFilters = this.activeFilters.get(field) || [];
|
|
1565
|
+
fieldFilters.splice(index, 1);
|
|
1566
|
+
if (fieldFilters.length === 0) {
|
|
1567
|
+
this.activeFilters.delete(field);
|
|
1568
|
+
}
|
|
1569
|
+
else {
|
|
1570
|
+
this.activeFilters.set(field, fieldFilters);
|
|
1571
|
+
}
|
|
1572
|
+
// Update filter config
|
|
1573
|
+
const newFilters = { ...this.state.filterConfig };
|
|
1574
|
+
if (fieldFilters.length === 0) {
|
|
1575
|
+
delete newFilters[field];
|
|
1576
|
+
}
|
|
1577
|
+
else {
|
|
1578
|
+
newFilters[field] = fieldFilters;
|
|
1579
|
+
}
|
|
1580
|
+
this.state = { ...this.state, filterConfig: newFilters };
|
|
1581
|
+
this.filterChange.emit(newFilters);
|
|
1582
|
+
}
|
|
1583
|
+
clearAllFilters() {
|
|
1584
|
+
this.activeFilters.clear();
|
|
1585
|
+
this.state = { ...this.state, filterConfig: {} };
|
|
1586
|
+
this.filterChange.emit({});
|
|
1587
|
+
}
|
|
1588
|
+
handleResizeStart = (columnId, event) => {
|
|
1589
|
+
event.preventDefault();
|
|
1590
|
+
event.stopPropagation();
|
|
1591
|
+
this.resizingColumnId = columnId;
|
|
1592
|
+
this.resizeStartX = event.clientX;
|
|
1593
|
+
this.resizeStartWidth = this.state.columnWidths.get(columnId) || 150;
|
|
1594
|
+
this.resizingColumn = columnId;
|
|
1595
|
+
document.addEventListener('mousemove', this.handleResizeMove);
|
|
1596
|
+
document.addEventListener('mouseup', this.handleResizeEnd);
|
|
1597
|
+
// Prevent text selection during resize
|
|
1598
|
+
document.body.style.userSelect = 'none';
|
|
1599
|
+
};
|
|
1600
|
+
handleResizeMove = (event) => {
|
|
1601
|
+
if (!this.resizingColumnId)
|
|
1602
|
+
return;
|
|
1603
|
+
const diff = event.clientX - this.resizeStartX;
|
|
1604
|
+
const newWidth = Math.max(50, this.resizeStartWidth + diff); // Minimum width of 50px
|
|
1605
|
+
const newWidths = new Map(this.state.columnWidths);
|
|
1606
|
+
newWidths.set(this.resizingColumnId, newWidth);
|
|
1607
|
+
this.state = {
|
|
1608
|
+
...this.state,
|
|
1609
|
+
columnWidths: newWidths,
|
|
1610
|
+
};
|
|
1611
|
+
};
|
|
1612
|
+
handleResizeEnd = () => {
|
|
1613
|
+
this.resizingColumnId = '';
|
|
1614
|
+
this.resizingColumn = null;
|
|
1615
|
+
document.body.style.userSelect = '';
|
|
1616
|
+
document.removeEventListener('mousemove', this.handleResizeMove);
|
|
1617
|
+
document.removeEventListener('mouseup', this.handleResizeEnd);
|
|
1618
|
+
};
|
|
1619
|
+
calculateInitialColumnWidths(columns) {
|
|
1620
|
+
const widths = new Map();
|
|
1621
|
+
const visibleColumns = columns.filter(col => col.visible !== false);
|
|
1622
|
+
const columnCount = visibleColumns.length;
|
|
1623
|
+
// Base width calculation with non-linear scaling for many columns
|
|
1624
|
+
let baseWidth;
|
|
1625
|
+
if (columnCount <= 3) {
|
|
1626
|
+
baseWidth = 250;
|
|
1627
|
+
}
|
|
1628
|
+
else if (columnCount <= 6) {
|
|
1629
|
+
baseWidth = 200;
|
|
1630
|
+
}
|
|
1631
|
+
else if (columnCount <= 10) {
|
|
1632
|
+
baseWidth = 150;
|
|
1633
|
+
}
|
|
1634
|
+
else if (columnCount <= 15) {
|
|
1635
|
+
baseWidth = 120;
|
|
1636
|
+
}
|
|
1637
|
+
else {
|
|
1638
|
+
baseWidth = 100;
|
|
1639
|
+
}
|
|
1640
|
+
visibleColumns.forEach(col => {
|
|
1641
|
+
// Use specified width if available, otherwise use calculated base width
|
|
1642
|
+
if (col.width) {
|
|
1643
|
+
// Parse width (e.g., "200px" -> 200)
|
|
1644
|
+
const parsed = parseInt(col.width);
|
|
1645
|
+
widths.set(col.id, isNaN(parsed) ? baseWidth : parsed);
|
|
1646
|
+
}
|
|
1647
|
+
else {
|
|
1648
|
+
widths.set(col.id, baseWidth);
|
|
1649
|
+
}
|
|
1650
|
+
});
|
|
1651
|
+
return widths;
|
|
1652
|
+
}
|
|
1653
|
+
prepareExportData(options) {
|
|
1654
|
+
let data = options.selectedOnly
|
|
1655
|
+
? this.parseData().filter(row => this.state.selectedRows.has(row.id))
|
|
1656
|
+
: this.getProcessedData();
|
|
1657
|
+
const columns = options.visibleColumnsOnly
|
|
1658
|
+
? this.getVisibleColumns()
|
|
1659
|
+
: this.flattenColumns(this.parseColumns());
|
|
1660
|
+
return data.map(row => {
|
|
1661
|
+
const exportRow = {};
|
|
1662
|
+
columns.forEach(col => {
|
|
1663
|
+
if (col.field) {
|
|
1664
|
+
exportRow[col.label] = col.format
|
|
1665
|
+
? col.format(row[col.field])
|
|
1666
|
+
: row[col.field];
|
|
1667
|
+
}
|
|
1668
|
+
});
|
|
1669
|
+
return exportRow;
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1672
|
+
performExport(data, options) {
|
|
1673
|
+
if (options.format === 'csv') {
|
|
1674
|
+
this.exportToCSV(data, options.fileName || 'export.csv');
|
|
1675
|
+
}
|
|
1676
|
+
else if (options.format === 'json') {
|
|
1677
|
+
this.exportToJSON(data, options.fileName || 'export.json');
|
|
1678
|
+
}
|
|
1679
|
+
else if (options.format === 'excel') {
|
|
1680
|
+
this.exportToExcel(data, options.fileName || 'export.xlsx');
|
|
1681
|
+
}
|
|
1682
|
+
this.dataExport.emit({ data, format: options.format });
|
|
1683
|
+
this.showExportDialog = false;
|
|
1684
|
+
}
|
|
1685
|
+
exportToCSV(data, fileName) {
|
|
1686
|
+
if (data.length === 0)
|
|
1687
|
+
return;
|
|
1688
|
+
const headers = Object.keys(data[0]);
|
|
1689
|
+
const csvContent = [
|
|
1690
|
+
headers.join(','),
|
|
1691
|
+
...data.map(row => headers.map(header => {
|
|
1692
|
+
const value = row[header];
|
|
1693
|
+
return typeof value === 'string' && value.includes(',')
|
|
1694
|
+
? `"${value}"`
|
|
1695
|
+
: value;
|
|
1696
|
+
}).join(','))
|
|
1697
|
+
].join('\n');
|
|
1698
|
+
this.downloadFile(csvContent, fileName, 'text/csv');
|
|
1699
|
+
}
|
|
1700
|
+
exportToJSON(data, fileName) {
|
|
1701
|
+
const jsonContent = JSON.stringify(data, null, 2);
|
|
1702
|
+
this.downloadFile(jsonContent, fileName, 'application/json');
|
|
1703
|
+
}
|
|
1704
|
+
exportToExcel(data, fileName) {
|
|
1705
|
+
if (data.length === 0)
|
|
1706
|
+
return;
|
|
1707
|
+
const headers = Object.keys(data[0]);
|
|
1708
|
+
// Build Excel XML (SpreadsheetML format)
|
|
1709
|
+
let xml = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?>';
|
|
1710
|
+
xml += '<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" ';
|
|
1711
|
+
xml += 'xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">';
|
|
1712
|
+
xml += '<Styles>';
|
|
1713
|
+
xml += '<Style ss:ID="Header"><Font ss:Bold="1"/><Interior ss:Color="#4472C4" ss:Pattern="Solid"/></Style>';
|
|
1714
|
+
xml += '<Style ss:ID="Default"><Borders><Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/></Borders></Style>';
|
|
1715
|
+
xml += '</Styles>';
|
|
1716
|
+
xml += '<Worksheet ss:Name="Sheet1"><Table>';
|
|
1717
|
+
// Add header row
|
|
1718
|
+
xml += '<Row ss:StyleID="Header">';
|
|
1719
|
+
headers.forEach(header => {
|
|
1720
|
+
xml += `<Cell><Data ss:Type="String">${this.escapeXml(header)}</Data></Cell>`;
|
|
1721
|
+
});
|
|
1722
|
+
xml += '</Row>';
|
|
1723
|
+
// Add data rows
|
|
1724
|
+
data.forEach(row => {
|
|
1725
|
+
xml += '<Row ss:StyleID="Default">';
|
|
1726
|
+
headers.forEach(header => {
|
|
1727
|
+
const value = row[header];
|
|
1728
|
+
const type = typeof value === 'number' ? 'Number' : 'String';
|
|
1729
|
+
const cellValue = value !== null && value !== undefined ? value : '';
|
|
1730
|
+
xml += `<Cell><Data ss:Type="${type}">${this.escapeXml(String(cellValue))}</Data></Cell>`;
|
|
1731
|
+
});
|
|
1732
|
+
xml += '</Row>';
|
|
1733
|
+
});
|
|
1734
|
+
xml += '</Table></Worksheet></Workbook>';
|
|
1735
|
+
this.downloadFile(xml, fileName, 'application/vnd.ms-excel');
|
|
1736
|
+
}
|
|
1737
|
+
escapeXml(unsafe) {
|
|
1738
|
+
return unsafe
|
|
1739
|
+
.replace(/&/g, '&')
|
|
1740
|
+
.replace(/</g, '<')
|
|
1741
|
+
.replace(/>/g, '>')
|
|
1742
|
+
.replace(/"/g, '"')
|
|
1743
|
+
.replace(/'/g, ''');
|
|
1744
|
+
}
|
|
1745
|
+
downloadFile(content, fileName, mimeType) {
|
|
1746
|
+
const blob = new Blob([content], { type: mimeType });
|
|
1747
|
+
const url = URL.createObjectURL(blob);
|
|
1748
|
+
const link = document.createElement('a');
|
|
1749
|
+
link.href = url;
|
|
1750
|
+
link.download = fileName;
|
|
1751
|
+
link.click();
|
|
1752
|
+
URL.revokeObjectURL(url);
|
|
1753
|
+
}
|
|
1754
|
+
// ========== PHASE 2 EXPORT & UTILS ==========
|
|
1755
|
+
exportToPDF() {
|
|
1756
|
+
// Check if print optimization is enabled, use window.print as fallback
|
|
1757
|
+
if (this.printOptimized) {
|
|
1758
|
+
window.print();
|
|
1759
|
+
}
|
|
1760
|
+
else {
|
|
1761
|
+
console.warn('PDF Export requires jspdf library. Please enable print mode.');
|
|
1762
|
+
alert('PDF Export not fully implemented without jspdf. Printing page instead.');
|
|
1763
|
+
window.print();
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
// ========== UNDO/REDO ==========
|
|
1767
|
+
pushUndoState() {
|
|
1768
|
+
if (!this.undoRedo)
|
|
1769
|
+
return;
|
|
1770
|
+
// Deep copy state
|
|
1771
|
+
const stateCopy = JSON.parse(JSON.stringify(this.state));
|
|
1772
|
+
this.undoStack = [...this.undoStack, stateCopy];
|
|
1773
|
+
this.redoStack = []; // Clear redo
|
|
1774
|
+
// Limit stack size
|
|
1775
|
+
if (this.undoStack.length > 20)
|
|
1776
|
+
this.undoStack.shift();
|
|
1777
|
+
}
|
|
1778
|
+
handleUndo() {
|
|
1779
|
+
if (!this.undoRedo || this.undoStack.length === 0)
|
|
1780
|
+
return;
|
|
1781
|
+
const currentState = JSON.parse(JSON.stringify(this.state));
|
|
1782
|
+
this.redoStack = [...this.redoStack, currentState];
|
|
1783
|
+
const prevState = this.undoStack.pop();
|
|
1784
|
+
this.undoStack = [...this.undoStack]; // trigger update
|
|
1785
|
+
this.state = { ...prevState };
|
|
1786
|
+
}
|
|
1787
|
+
handleRedo() {
|
|
1788
|
+
if (!this.undoRedo || this.redoStack.length === 0)
|
|
1789
|
+
return;
|
|
1790
|
+
const currentState = JSON.parse(JSON.stringify(this.state));
|
|
1791
|
+
this.undoStack = [...this.undoStack, currentState];
|
|
1792
|
+
const nextState = this.redoStack.pop();
|
|
1793
|
+
this.redoStack = [...this.redoStack];
|
|
1794
|
+
this.state = { ...nextState };
|
|
1795
|
+
}
|
|
1796
|
+
setupGlobalKeyboardShortcuts() {
|
|
1797
|
+
document.addEventListener('keydown', (e) => {
|
|
1798
|
+
if (this.undoRedo) {
|
|
1799
|
+
if ((e.ctrlKey || e.metaKey) && e.key === 'z') {
|
|
1800
|
+
e.preventDefault();
|
|
1801
|
+
this.handleUndo();
|
|
1802
|
+
}
|
|
1803
|
+
if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || (e.shiftKey && e.key === 'z'))) {
|
|
1804
|
+
e.preventDefault();
|
|
1805
|
+
this.handleRedo();
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
// Cell Navigation
|
|
1809
|
+
if (this.keyboardShortcuts && !this.state.editingCell) {
|
|
1810
|
+
this.handleKeyboardNavigation(e);
|
|
1811
|
+
}
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
handleKeyboardNavigation(e) {
|
|
1815
|
+
const keys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Enter', 'Escape', 'Tab'];
|
|
1816
|
+
if (!keys.includes(e.key))
|
|
1817
|
+
return;
|
|
1818
|
+
const data = this.getProcessedData();
|
|
1819
|
+
const columns = this.getVisibleColumns();
|
|
1820
|
+
if (data.length === 0 || columns.length === 0)
|
|
1821
|
+
return;
|
|
1822
|
+
let { focusedCell } = this.state;
|
|
1823
|
+
// If no cell focused, focus first cell on any arrow key
|
|
1824
|
+
if (!focusedCell) {
|
|
1825
|
+
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
|
|
1826
|
+
this.setFocusedCell(data[0].id, columns[0].field ?? '');
|
|
1827
|
+
e.preventDefault();
|
|
1828
|
+
}
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1831
|
+
const currentRowIndex = data.findIndex(r => r.id === focusedCell.rowId);
|
|
1832
|
+
const currentColIndex = columns.findIndex(c => c.field === focusedCell.field);
|
|
1833
|
+
if (currentRowIndex === -1 || currentColIndex === -1)
|
|
1834
|
+
return;
|
|
1835
|
+
switch (e.key) {
|
|
1836
|
+
case 'ArrowUp':
|
|
1837
|
+
if (currentRowIndex > 0) {
|
|
1838
|
+
this.setFocusedCell(data[currentRowIndex - 1].id, focusedCell.field);
|
|
1839
|
+
e.preventDefault();
|
|
1840
|
+
}
|
|
1841
|
+
break;
|
|
1842
|
+
case 'ArrowDown':
|
|
1843
|
+
if (currentRowIndex < data.length - 1) {
|
|
1844
|
+
this.setFocusedCell(data[currentRowIndex + 1].id, focusedCell.field);
|
|
1845
|
+
e.preventDefault();
|
|
1846
|
+
}
|
|
1847
|
+
break;
|
|
1848
|
+
case 'ArrowLeft':
|
|
1849
|
+
if (currentColIndex > 0) {
|
|
1850
|
+
this.setFocusedCell(focusedCell.rowId, columns[currentColIndex - 1].field ?? '');
|
|
1851
|
+
e.preventDefault();
|
|
1852
|
+
}
|
|
1853
|
+
break;
|
|
1854
|
+
case 'ArrowRight':
|
|
1855
|
+
if (currentColIndex < columns.length - 1) {
|
|
1856
|
+
this.setFocusedCell(focusedCell.rowId, columns[currentColIndex + 1].field ?? '');
|
|
1857
|
+
e.preventDefault();
|
|
1858
|
+
}
|
|
1859
|
+
break;
|
|
1860
|
+
case 'Enter':
|
|
1861
|
+
if (this.editable) {
|
|
1862
|
+
this.startCellEdit(focusedCell.rowId, focusedCell.field);
|
|
1863
|
+
e.preventDefault();
|
|
1864
|
+
}
|
|
1865
|
+
break;
|
|
1866
|
+
case 'Escape':
|
|
1867
|
+
this.setFocusedCell(null, '');
|
|
1868
|
+
break;
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
setFocusedCell(rowId, field) {
|
|
1872
|
+
this.state = {
|
|
1873
|
+
...this.state,
|
|
1874
|
+
focusedCell: rowId ? { rowId, field } : null
|
|
1875
|
+
};
|
|
1876
|
+
// Scroll into view if needed
|
|
1877
|
+
if (rowId) {
|
|
1878
|
+
setTimeout(() => {
|
|
1879
|
+
const cell = this.el.shadowRoot?.querySelector(`td[data-row-id="${rowId}"][data-field="${field}"]`);
|
|
1880
|
+
if (cell) {
|
|
1881
|
+
cell.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
|
1882
|
+
}
|
|
1883
|
+
}, 0);
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
applyTheme() {
|
|
1887
|
+
const root = this.el.shadowRoot?.querySelector('.data-table-container');
|
|
1888
|
+
if (!root)
|
|
1889
|
+
return;
|
|
1890
|
+
if (this.theme === 'auto') {
|
|
1891
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
1892
|
+
root.classList.toggle('dark-mode', prefersDark);
|
|
1893
|
+
}
|
|
1894
|
+
else {
|
|
1895
|
+
root.classList.toggle('dark-mode', this.theme === 'dark');
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
setupClickOutsideListener = () => {
|
|
1899
|
+
document.addEventListener('click', this.handleClickOutside);
|
|
1900
|
+
document.addEventListener('contextmenu', (e) => {
|
|
1901
|
+
if (this.contextMenu && this.contextMenuState.visible) {
|
|
1902
|
+
// Did we click inside the menu?
|
|
1903
|
+
const target = e.target;
|
|
1904
|
+
const menu = (this.el.shadowRoot || this.el).querySelector('.context-menu');
|
|
1905
|
+
if (menu && menu.contains(target)) {
|
|
1906
|
+
return;
|
|
1907
|
+
}
|
|
1908
|
+
// If not, let default happen or just close?
|
|
1909
|
+
// If we right clicked elsewhere, we want to open new menu there.
|
|
1910
|
+
// So this handler shouldn't block new menu.
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
};
|
|
1914
|
+
handleClickOutside = (e) => {
|
|
1915
|
+
// Close actions menu if clicking outside
|
|
1916
|
+
if (this.activeActionMenu !== null) {
|
|
1917
|
+
const target = e.target;
|
|
1918
|
+
const actionsContainer = target.closest('.row-actions-container');
|
|
1919
|
+
// If click is outside any actions container, close the menu
|
|
1920
|
+
if (!actionsContainer) {
|
|
1921
|
+
this.activeActionMenu = null;
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
// Close context menu
|
|
1925
|
+
if (this.contextMenuState.visible) {
|
|
1926
|
+
// Check if click is inside menu
|
|
1927
|
+
const target = e.target;
|
|
1928
|
+
const menu = (this.el.shadowRoot || this.el).querySelector('.context-menu');
|
|
1929
|
+
if (menu && menu.contains(target))
|
|
1930
|
+
return;
|
|
1931
|
+
this.contextMenuState = { ...this.contextMenuState, visible: false };
|
|
1932
|
+
}
|
|
1933
|
+
};
|
|
1934
|
+
handleHeaderContextMenu(e, col) {
|
|
1935
|
+
e.preventDefault();
|
|
1936
|
+
e.stopPropagation();
|
|
1937
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
1938
|
+
this.contextMenuState = {
|
|
1939
|
+
visible: true,
|
|
1940
|
+
x: rect.left,
|
|
1941
|
+
y: rect.bottom + window.scrollY,
|
|
1942
|
+
type: 'header',
|
|
1943
|
+
target: col
|
|
1944
|
+
};
|
|
1945
|
+
}
|
|
1946
|
+
toggleColumnPin(columnId, side) {
|
|
1947
|
+
const newPinned = { ...this.pinnedColumns };
|
|
1948
|
+
// Remove from both sides first
|
|
1949
|
+
newPinned.left = newPinned.left.filter(id => id !== columnId);
|
|
1950
|
+
newPinned.right = newPinned.right.filter(id => id !== columnId);
|
|
1951
|
+
if (side === 'left') {
|
|
1952
|
+
newPinned.left.push(columnId);
|
|
1953
|
+
}
|
|
1954
|
+
else if (side === 'right') {
|
|
1955
|
+
newPinned.right.push(columnId);
|
|
1956
|
+
}
|
|
1957
|
+
this.pinnedColumns = newPinned;
|
|
1958
|
+
this.contextMenuState = { ...this.contextMenuState, visible: false };
|
|
1959
|
+
}
|
|
1960
|
+
handleContextMenu(e, type, target) {
|
|
1961
|
+
if (!this.contextMenu)
|
|
1962
|
+
return;
|
|
1963
|
+
e.preventDefault();
|
|
1964
|
+
e.stopPropagation();
|
|
1965
|
+
// Calculate position
|
|
1966
|
+
const x = e.clientX;
|
|
1967
|
+
const y = e.clientY;
|
|
1968
|
+
this.contextMenuState = {
|
|
1969
|
+
visible: true,
|
|
1970
|
+
x,
|
|
1971
|
+
y,
|
|
1972
|
+
type,
|
|
1973
|
+
target
|
|
1974
|
+
};
|
|
1975
|
+
}
|
|
1976
|
+
setupResizeObserver() {
|
|
1977
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
1978
|
+
this.el.shadowRoot?.host.dispatchEvent(new CustomEvent('tableResize'));
|
|
1979
|
+
// Update mobile view state
|
|
1980
|
+
for (const entry of entries) {
|
|
1981
|
+
this.isMobileView = entry.contentRect.width < 768;
|
|
1982
|
+
}
|
|
1983
|
+
});
|
|
1984
|
+
this.resizeObserver.observe(this.el);
|
|
1985
|
+
}
|
|
1986
|
+
setupLazyLoadObserver(element) {
|
|
1987
|
+
if (!element || !this.lazyLoad)
|
|
1988
|
+
return;
|
|
1989
|
+
// Disconnect existing observer if any
|
|
1990
|
+
if (this.lazyLoadObserver) {
|
|
1991
|
+
this.lazyLoadObserver.disconnect();
|
|
1992
|
+
}
|
|
1993
|
+
// Create new IntersectionObserver
|
|
1994
|
+
this.lazyLoadObserver = new IntersectionObserver((entries) => {
|
|
1995
|
+
entries.forEach(entry => {
|
|
1996
|
+
if (entry.isIntersecting && !this.loading) {
|
|
1997
|
+
// Emit event to load more data
|
|
1998
|
+
const currentCount = this.parseData().length;
|
|
1999
|
+
this.lazyLoadMore.emit({ currentCount });
|
|
2000
|
+
}
|
|
2001
|
+
});
|
|
2002
|
+
}, {
|
|
2003
|
+
root: null, // viewport
|
|
2004
|
+
rootMargin: '100px', // trigger 100px before reaching sentinel
|
|
2005
|
+
threshold: 0.1
|
|
2006
|
+
});
|
|
2007
|
+
this.lazyLoadObserver.observe(element);
|
|
2008
|
+
}
|
|
2009
|
+
announceToScreenReader(message) {
|
|
2010
|
+
if (!this.enhancedAccessibility)
|
|
2011
|
+
return;
|
|
2012
|
+
// Create or get ARIA live region
|
|
2013
|
+
let liveRegion = this.el.shadowRoot?.querySelector('.sr-announcer');
|
|
2014
|
+
if (!liveRegion) {
|
|
2015
|
+
liveRegion = document.createElement('div');
|
|
2016
|
+
liveRegion.className = 'sr-announcer';
|
|
2017
|
+
liveRegion.setAttribute('aria-live', 'polite');
|
|
2018
|
+
liveRegion.setAttribute('aria-atomic', 'true');
|
|
2019
|
+
liveRegion.setAttribute('role', 'status');
|
|
2020
|
+
this.el.shadowRoot?.appendChild(liveRegion);
|
|
2021
|
+
}
|
|
2022
|
+
// Clear and set message
|
|
2023
|
+
liveRegion.textContent = '';
|
|
2024
|
+
setTimeout(() => {
|
|
2025
|
+
liveRegion.textContent = message;
|
|
2026
|
+
}, 100);
|
|
2027
|
+
}
|
|
2028
|
+
// ========== AGGREGATION LOGIC ==========
|
|
2029
|
+
calculateAggregations(data) {
|
|
2030
|
+
const results = {};
|
|
2031
|
+
this.getVisibleColumns().forEach(col => {
|
|
2032
|
+
if (col.aggregation && col.aggregation.length > 0) {
|
|
2033
|
+
results[col.id] = {};
|
|
2034
|
+
col.aggregation.forEach(type => {
|
|
2035
|
+
const values = data.map(row => row[col.field]).filter(v => v !== null && v !== undefined && v !== '');
|
|
2036
|
+
switch (type) {
|
|
2037
|
+
case 'sum':
|
|
2038
|
+
results[col.id]['sum'] = values.reduce((a, b) => Number(a) + Number(b), 0);
|
|
2039
|
+
break;
|
|
2040
|
+
case 'avg':
|
|
2041
|
+
const sum = values.reduce((a, b) => Number(a) + Number(b), 0);
|
|
2042
|
+
results[col.id]['avg'] = values.length > 0 ? sum / values.length : 0;
|
|
2043
|
+
break;
|
|
2044
|
+
case 'min':
|
|
2045
|
+
if (col.type === 'date' || (col.id && col.id.toLowerCase().includes('date'))) {
|
|
2046
|
+
values.sort();
|
|
2047
|
+
results[col.id]['min'] = values[0];
|
|
2048
|
+
}
|
|
2049
|
+
else {
|
|
2050
|
+
results[col.id]['min'] = Math.min(...values.map(v => Number(v)));
|
|
2051
|
+
}
|
|
2052
|
+
break;
|
|
2053
|
+
case 'max':
|
|
2054
|
+
if (col.type === 'date' || (col.id && col.id.toLowerCase().includes('date'))) {
|
|
2055
|
+
values.sort();
|
|
2056
|
+
results[col.id]['max'] = values[values.length - 1];
|
|
2057
|
+
}
|
|
2058
|
+
else {
|
|
2059
|
+
results[col.id]['max'] = Math.max(...values.map(v => Number(v)));
|
|
2060
|
+
}
|
|
2061
|
+
break;
|
|
2062
|
+
case 'count':
|
|
2063
|
+
results[col.id]['count'] = values.length;
|
|
2064
|
+
break;
|
|
2065
|
+
}
|
|
2066
|
+
});
|
|
2067
|
+
}
|
|
2068
|
+
});
|
|
2069
|
+
return results;
|
|
2070
|
+
}
|
|
2071
|
+
renderAggregationFooter() {
|
|
2072
|
+
const data = this.getProcessedData();
|
|
2073
|
+
const aggregations = this.calculateAggregations(data);
|
|
2074
|
+
const hasAggregations = Object.keys(aggregations).length > 0;
|
|
2075
|
+
if (!hasAggregations)
|
|
2076
|
+
return null;
|
|
2077
|
+
return (h("tfoot", { class: "data-table-footer" }, h("tr", null, (this.selectable || this.multiSelect) && h("td", null), this.rowDetails && h("td", null), this.getVisibleColumns().map(col => {
|
|
2078
|
+
const agg = aggregations[col.id];
|
|
2079
|
+
const isPinnedLeft = this.pinnedColumns.left.includes(col.id);
|
|
2080
|
+
const isPinnedRight = this.pinnedColumns.right.includes(col.id);
|
|
2081
|
+
return (h("td", { class: {
|
|
2082
|
+
'pinned-left': isPinnedLeft,
|
|
2083
|
+
'pinned-right': isPinnedRight
|
|
2084
|
+
}, style: {
|
|
2085
|
+
position: (isPinnedLeft || isPinnedRight) ? 'sticky' : undefined,
|
|
2086
|
+
left: isPinnedLeft ? this.getPinnedOffset(col.id, 'left') : undefined,
|
|
2087
|
+
right: isPinnedRight ? this.getPinnedOffset(col.id, 'right') : undefined,
|
|
2088
|
+
zIndex: (isPinnedLeft || isPinnedRight) ? '3' : undefined,
|
|
2089
|
+
textAlign: col.align || 'left'
|
|
2090
|
+
} }, agg && Object.entries(agg).map(([key, value]) => (h("div", { class: "agg-item" }, h("span", { class: "agg-label" }, key, ":"), h("span", { class: "agg-value" }, col.format && typeof value === 'number' ? col.format(value) : value))))));
|
|
2091
|
+
}))));
|
|
2092
|
+
}
|
|
2093
|
+
renderSkeletonRows(columns) {
|
|
2094
|
+
return Array.from({ length: this.skeletonRows }, (_, rowIndex) => (h("tr", { key: `skeleton-${rowIndex}`, class: "skeleton-row" }, this.selectable && (h("td", { class: "skeleton-cell" }, h("ui-skeleton", { shape: "square", size: "sm", width: "16px", height: "16px" }))), columns.map(col => (h("td", { key: `skeleton-${rowIndex}-${col.id}`, class: "skeleton-cell" }, h("ui-skeleton", { shape: "text", animationType: "wave", width: `${30 + Math.random() * 40}%` })))))));
|
|
2095
|
+
}
|
|
2096
|
+
getPinnedOffset(columnId, side) {
|
|
2097
|
+
const visibleColumns = this.getVisibleColumns();
|
|
2098
|
+
const isPinned = (col) => side === 'left' ? this.pinnedColumns.left.includes(col.id) : this.pinnedColumns.right.includes(col.id);
|
|
2099
|
+
const pinnedCols = visibleColumns.filter(col => isPinned(col));
|
|
2100
|
+
const index = pinnedCols.findIndex(col => col.id === columnId);
|
|
2101
|
+
if (index <= 0)
|
|
2102
|
+
return '0px';
|
|
2103
|
+
let offset = 0;
|
|
2104
|
+
for (let i = 0; i < index; i++) {
|
|
2105
|
+
const colId = pinnedCols[i].id;
|
|
2106
|
+
const width = this.state.columnWidths.get(colId) || 150; // Default width assumption
|
|
2107
|
+
offset += width;
|
|
2108
|
+
}
|
|
2109
|
+
return `${offset}px`;
|
|
2110
|
+
}
|
|
2111
|
+
renderColumnHeader(column, rowSpan = 1) {
|
|
2112
|
+
if (column.children && column.children.length > 0) {
|
|
2113
|
+
return (h("th", { class: "column-group", colSpan: this.getLeafColumnCount(column), style: { textAlign: column.align || 'left' } }, h("div", { class: "column-header-content" }, h("span", null, column.label))));
|
|
2114
|
+
}
|
|
2115
|
+
const isSorted = this.state.sortConfig.field === column.field;
|
|
2116
|
+
const sortDirection = isSorted ? this.state.sortConfig.direction : null;
|
|
2117
|
+
const columnWidth = this.state.columnWidths.get(column.id);
|
|
2118
|
+
return (h("th", { rowSpan: rowSpan > 1 ? rowSpan : undefined, class: {
|
|
2119
|
+
'sortable': this.sortable && column.sortable !== false,
|
|
2120
|
+
'sorted': isSorted,
|
|
2121
|
+
'sticky-column': column.sticky || this.pinnedColumns.left.includes(column.id) || this.pinnedColumns.right.includes(column.id),
|
|
2122
|
+
'resizing': this.resizingColumn === column.id,
|
|
2123
|
+
'pinned-left': this.pinnedColumns.left.includes(column.id),
|
|
2124
|
+
'pinned-right': this.pinnedColumns.right.includes(column.id),
|
|
2125
|
+
}, style: {
|
|
2126
|
+
width: columnWidth ? `${columnWidth}px` : (column.width || 'auto'),
|
|
2127
|
+
minWidth: column.minWidth,
|
|
2128
|
+
textAlign: column.align || 'left',
|
|
2129
|
+
position: (column.sticky || this.pinnedColumns.left.includes(column.id) || this.pinnedColumns.right.includes(column.id)) ? 'sticky' : 'relative',
|
|
2130
|
+
left: this.pinnedColumns.left.includes(column.id) ? this.getPinnedOffset(column.id, 'left') : undefined,
|
|
2131
|
+
right: this.pinnedColumns.right.includes(column.id) ? this.getPinnedOffset(column.id, 'right') : undefined,
|
|
2132
|
+
zIndex: (column.sticky || this.pinnedColumns.left.includes(column.id) || this.pinnedColumns.right.includes(column.id)) ? '30' : undefined
|
|
2133
|
+
} }, h("div", { class: "column-header-content" }, this.columnReorder && (h("span", { class: "drag-handle", draggable: true, onDragStart: (e) => this.handleColumnDragStart(column.id, e), onDragOver: (e) => this.handleColumnDragOver(e), onDrop: (e) => this.handleColumnDrop(column.id, e), title: "Drag to reorder" }, h("ui-icon", { name: "grip-vertical", library: "lucide", size: "1.2em" }))), h("span", { class: "column-label", onClick: (e) => column.sortable !== false && this.handleMultiSort(column.field || column.id, e) }, (this.pinnedColumns.left.includes(column.id) || this.pinnedColumns.right.includes(column.id)) && (h("ui-icon", { name: "pin", library: "lucide", size: "14px", class: "pin-indicator" })), column.label), this.sortable && column.sortable !== false && (() => {
|
|
2134
|
+
// Multi-sort indicator
|
|
2135
|
+
if (this.multiSort) {
|
|
2136
|
+
const sortIndex = this.multiSortConfig.findIndex(s => s.field === (column.field || column.id));
|
|
2137
|
+
if (sortIndex >= 0) {
|
|
2138
|
+
const sort = this.multiSortConfig[sortIndex];
|
|
2139
|
+
return (h("span", { class: "sort-icon multi-sort" }, h("ui-icon", { name: sort.direction === 'asc' ? 'arrow-up' : 'arrow-down', library: "lucide", size: "14px" }), h("span", { class: "sort-order-badge" }, sortIndex + 1)));
|
|
2140
|
+
}
|
|
2141
|
+
return h("ui-icon", { name: "arrow-up-down", library: "lucide", size: "14px", class: "sort-icon" });
|
|
2142
|
+
}
|
|
2143
|
+
// Single sort indicator
|
|
2144
|
+
return (h("span", { class: "sort-icon" }, !isSorted && h("ui-icon", { name: "arrow-up-down", library: "lucide", size: "14px" }), isSorted && h("ui-icon", { name: sortDirection === 'asc' ? 'arrow-up' : 'arrow-down', library: "lucide", size: "14px" })));
|
|
2145
|
+
})(), h("ui-button", { variant: "ghost", class: "header-menu-trigger", onClick: (e) => this.handleHeaderContextMenu(e, column), ariaLabel: "Column options", icon: "more-vertical", iconLibrary: "lucide", iconOnly: true, size: "sm" })), this.filterable && column.filterable !== false && (h("div", { class: "column-filter" }, h("ui-input", { type: "text", placeholder: `Filter ${column.label}...`, value: this.state.filterConfig[column.field || column.id] || '', onInputChange: (e) => this.handleFilter(column.field || column.id, e.detail), onClick: (e) => e.stopPropagation(), size: "sm", variant: "outlined" }))), h("div", { class: "resize-handle", onMouseDown: (e) => this.handleResizeStart(column.id, e), onClick: (e) => e.stopPropagation() })));
|
|
2146
|
+
}
|
|
2147
|
+
renderTableHeaders() {
|
|
2148
|
+
const columns = this.parseColumns();
|
|
2149
|
+
const hasMultiLevel = columns.some(col => col.children && col.children.length > 0);
|
|
2150
|
+
if (!hasMultiLevel) {
|
|
2151
|
+
return (h("tr", null, this.selectable && (h("th", { class: "select-column" }, this.multiSelect && (h("ui-checkbox", { checked: this.state.selectedRows.size === this.getProcessedData().length, onCheckboxChange: (e) => this.handleSelectAll(e), ariaLabel: "Select all rows", size: "sm" })))), this.getVisibleColumns().map(col => this.renderColumnHeader(col)), this.showActions && (h("th", { class: "actions-column" }, "Actions")), this.rowDetails && (h("th", { class: "row-details-column" }, "Details"))));
|
|
2152
|
+
}
|
|
2153
|
+
// Multi-level headers
|
|
2154
|
+
const headerRows = [];
|
|
2155
|
+
const maxDepth = this.getMaxColumnDepth(columns);
|
|
2156
|
+
for (let depth = 0; depth < maxDepth; depth++) {
|
|
2157
|
+
headerRows.push(h("tr", null, depth === 0 && this.selectable && (h("th", { class: "select-column", rowSpan: maxDepth }, this.multiSelect && (h("ui-checkbox", { checked: this.state.selectedRows.size === this.getProcessedData().length, onCheckboxChange: (e) => this.handleSelectAll(e), ariaLabel: "Select all rows", size: "sm" })))), this.renderHeaderLevel(columns, depth, 0, maxDepth), depth === 0 && this.showActions && (h("th", { class: "actions-column", rowSpan: maxDepth }, "Actions")), depth === 0 && this.rowDetails && (h("th", { class: "row-details-column", rowSpan: maxDepth }, "Details"))));
|
|
2158
|
+
}
|
|
2159
|
+
return headerRows;
|
|
2160
|
+
}
|
|
2161
|
+
getMaxColumnDepth(columns) {
|
|
2162
|
+
let maxDepth = 1;
|
|
2163
|
+
const checkDepth = (cols, currentDepth) => {
|
|
2164
|
+
cols.forEach(col => {
|
|
2165
|
+
if (col.children && col.children.length > 0) {
|
|
2166
|
+
maxDepth = Math.max(maxDepth, currentDepth + 1);
|
|
2167
|
+
checkDepth(col.children, currentDepth + 1);
|
|
2168
|
+
}
|
|
2169
|
+
});
|
|
2170
|
+
};
|
|
2171
|
+
checkDepth(columns, 1);
|
|
2172
|
+
return maxDepth;
|
|
2173
|
+
}
|
|
2174
|
+
renderHeaderLevel(columns, targetDepth, currentDepth = 0, maxDepth = 1) {
|
|
2175
|
+
const result = [];
|
|
2176
|
+
columns.forEach(col => {
|
|
2177
|
+
const isGroup = col.children && col.children.length > 0;
|
|
2178
|
+
const isVisible = isGroup ? this.getLeafColumnCount(col) > 0 : this.state.visibleColumns.has(col.id);
|
|
2179
|
+
if (!isVisible)
|
|
2180
|
+
return;
|
|
2181
|
+
if (currentDepth === targetDepth) {
|
|
2182
|
+
const rowSpan = isGroup ? 1 : maxDepth - currentDepth;
|
|
2183
|
+
result.push(this.renderColumnHeader(col, rowSpan));
|
|
2184
|
+
}
|
|
2185
|
+
else if (isGroup) {
|
|
2186
|
+
result.push(...this.renderHeaderLevel(col.children, targetDepth, currentDepth + 1, maxDepth));
|
|
2187
|
+
}
|
|
2188
|
+
});
|
|
2189
|
+
return result;
|
|
2190
|
+
}
|
|
2191
|
+
renderCell(row, column) {
|
|
2192
|
+
const isEditing = this.state.editingCell?.rowId === row.id &&
|
|
2193
|
+
this.state.editingCell?.field === column.field;
|
|
2194
|
+
const value = column.field ? row[column.field] : '';
|
|
2195
|
+
// Determine content based on mode
|
|
2196
|
+
let content;
|
|
2197
|
+
if (this.editable && column.editable !== false) {
|
|
2198
|
+
// Use advanced cell editors if enabled
|
|
2199
|
+
content = this.advancedCellEditors
|
|
2200
|
+
? this.renderAdvancedCellEditor(row, column, value)
|
|
2201
|
+
: this.renderEditableCell(row, column, value);
|
|
2202
|
+
}
|
|
2203
|
+
else if (isEditing && column.editable !== false) {
|
|
2204
|
+
content = this.advancedCellEditors
|
|
2205
|
+
? this.renderAdvancedCellEditor(row, column, value)
|
|
2206
|
+
: this.renderEditableCell(row, column, value);
|
|
2207
|
+
}
|
|
2208
|
+
else {
|
|
2209
|
+
// Use column formatting for display
|
|
2210
|
+
const formattedValue = this.columnFormatting
|
|
2211
|
+
? this.formatCellValue(value, column)
|
|
2212
|
+
: this.renderDisplayCell(row, column, value);
|
|
2213
|
+
content = formattedValue;
|
|
2214
|
+
}
|
|
2215
|
+
// Handle Tree Data Indentation for the first visible column
|
|
2216
|
+
const visibleCols = this.getVisibleColumns();
|
|
2217
|
+
const isFirstColumn = visibleCols.length > 0 && visibleCols[0].id === column.id;
|
|
2218
|
+
if (this.treeData && isFirstColumn) {
|
|
2219
|
+
const depth = row._depth || 0;
|
|
2220
|
+
const hasChildren = row._hasChildren;
|
|
2221
|
+
const isExpanded = this.state.expandedRows.has(row.id);
|
|
2222
|
+
const indentation = depth * 24; // 24px per level
|
|
2223
|
+
return (h("div", { class: "cell-content-wrapper", style: { display: 'flex', alignItems: 'center' } }, h("span", { style: { paddingLeft: `${indentation}px` } }), hasChildren ? (h("span", { class: "tree-toggle-icon", onClick: (e) => this.toggleRowExpansion(row.id, e), style: {
|
|
2224
|
+
cursor: 'pointer',
|
|
2225
|
+
marginRight: '8px',
|
|
2226
|
+
display: 'inline-block',
|
|
2227
|
+
width: '16px',
|
|
2228
|
+
textAlign: 'center',
|
|
2229
|
+
userSelect: 'none'
|
|
2230
|
+
} }, h("ui-icon", { name: isExpanded ? 'chevron-down' : 'chevron-right', library: "lucide", size: "14px" }))) : (h("span", { style: { display: 'inline-block', width: '24px' } }) // Spacer for alignment
|
|
2231
|
+
), h("div", { class: "cell-inner-content", style: { flex: '1' } }, content)));
|
|
2232
|
+
}
|
|
2233
|
+
// Handle Column Reorder alignment spacer for standard cells
|
|
2234
|
+
if (this.columnReorder && (!column.align || column.align === 'left')) {
|
|
2235
|
+
return (h("div", { class: "cell-content-wrapper", style: { display: 'flex', alignItems: 'center' } }, h("span", { class: "drag-handle-spacer", style: { width: '22px', flexShrink: '0' } }), h("div", { class: "cell-inner-content", style: { flex: '1' } }, content)));
|
|
2236
|
+
}
|
|
2237
|
+
return content;
|
|
2238
|
+
}
|
|
2239
|
+
getLeafColumnCount(column) {
|
|
2240
|
+
if (!column.children || column.children.length === 0)
|
|
2241
|
+
return 1;
|
|
2242
|
+
let count = 0;
|
|
2243
|
+
column.children.forEach(child => {
|
|
2244
|
+
if (child.children && child.children.length > 0) {
|
|
2245
|
+
count += this.getLeafColumnCount(child);
|
|
2246
|
+
}
|
|
2247
|
+
else if (this.state.visibleColumns.has(child.id)) {
|
|
2248
|
+
count += 1;
|
|
2249
|
+
}
|
|
2250
|
+
});
|
|
2251
|
+
return count;
|
|
2252
|
+
}
|
|
2253
|
+
renderEditableCell(row, column, value) {
|
|
2254
|
+
// Only clear editing state on blur if table is not in global editable mode
|
|
2255
|
+
const handleBlur = () => {
|
|
2256
|
+
if (!this.editable) {
|
|
2257
|
+
this.state = { ...this.state, editingCell: null };
|
|
2258
|
+
}
|
|
2259
|
+
};
|
|
2260
|
+
const handleKeyDown = (e, inputEl) => {
|
|
2261
|
+
if (e.key === 'Enter') {
|
|
2262
|
+
this.handleCellEdit(row.id, column.field, inputEl.value);
|
|
2263
|
+
}
|
|
2264
|
+
else if (e.key === 'Escape') {
|
|
2265
|
+
if (!this.editable) {
|
|
2266
|
+
handleBlur();
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
};
|
|
2270
|
+
switch (column.type) {
|
|
2271
|
+
case 'select':
|
|
2272
|
+
return (h("select", { ref: (el) => {
|
|
2273
|
+
if (el) {
|
|
2274
|
+
this.editInputRef = el;
|
|
2275
|
+
el.value = value;
|
|
2276
|
+
}
|
|
2277
|
+
}, onChange: (e) => this.handleCellEdit(row.id, column.field, e.target.value), onBlur: handleBlur, class: "cell-select" }, column.selectOptions?.map(opt => (h("option", { value: opt.value, selected: opt.value === value }, opt.label)))));
|
|
2278
|
+
case 'radio':
|
|
2279
|
+
return (h("div", { class: "cell-radio-group" }, column.radioOptions?.map(opt => (h("label", { class: "radio-label" }, h("ui-radio", { name: `${row.id}-${column.field}`, value: opt.value, checked: opt.value === value, onRadioChange: (e) => this.handleCellEdit(row.id, column.field, e.detail.value), label: opt.label, size: "sm" }))))));
|
|
2280
|
+
case 'checkbox':
|
|
2281
|
+
return (h("ui-checkbox", { ref: (el) => (this.editInputRef = el), checked: value === true || value === 'true', onCheckboxChange: (e) => this.handleCellEdit(row.id, column.field, e.detail.checked), onCheckboxBlur: handleBlur, size: "sm" }));
|
|
2282
|
+
case 'switch':
|
|
2283
|
+
return (h("ui-switch", { checked: value === true || value === 'true', onSwitchChange: (e) => this.handleCellEdit(row.id, column.field, e.detail.checked), size: "sm" }));
|
|
2284
|
+
case 'rating':
|
|
2285
|
+
const maxRating = column.maxRating || 5;
|
|
2286
|
+
const currentRating = Number(value) || 0;
|
|
2287
|
+
return (h("div", { class: "cell-rating" }, Array.from({ length: maxRating }, (_, i) => i + 1).map(star => (h("span", { class: { 'star': true, 'filled': star <= currentRating }, onClick: () => this.handleCellEdit(row.id, column.field, star) }, h("ui-icon", { name: "star", library: "lucide", size: "1.2em", color: star <= currentRating ? '#ffc107' : '#bdbdbd' }))))));
|
|
2288
|
+
case 'date':
|
|
2289
|
+
case 'time':
|
|
2290
|
+
case 'datetime':
|
|
2291
|
+
case 'password':
|
|
2292
|
+
case 'email':
|
|
2293
|
+
return (h("ui-input", { ref: (el) => (this.editInputRef = el), type: column.type === 'datetime' ? 'datetime-local' : column.type, value: value, onInputChange: (e) => this.handleCellEdit(row.id, column.field, e.detail), onInputBlur: handleBlur, onInputKeydown: (e) => handleKeyDown(e.detail, e.target), customClass: "cell-input", variant: "plain", size: "sm" }));
|
|
2294
|
+
case 'url':
|
|
2295
|
+
return (h("ui-input", { ref: (el) => (this.editInputRef = el), type: column.type === 'number' ? 'number' : column.type === 'tel' ? 'tel' : column.type === 'url' ? 'url' : 'text', value: value, onInputChange: (e) => this.handleCellEdit(row.id, column.field, e.detail), onInputBlur: handleBlur, onInputKeydown: (e) => handleKeyDown(e.detail, e.target), customClass: "cell-input", variant: "plain", size: "sm" }));
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
renderDisplayCell(row, column, value) {
|
|
2299
|
+
// Handle custom render function
|
|
2300
|
+
if (column.render) {
|
|
2301
|
+
return (h("span", { class: { 'editable-cell': this.editable && column.editable !== false }, onDblClick: () => this.editable && column.editable !== false && this.startCellEdit(row.id, column.field) }, column.render(value, row, 0)));
|
|
2302
|
+
}
|
|
2303
|
+
// Handle Sparklines (Phase 2)
|
|
2304
|
+
if (this.enableSparklines && Array.isArray(value) && value.length > 0 && typeof value[0] === 'number') {
|
|
2305
|
+
return this.renderSparkline(value);
|
|
2306
|
+
}
|
|
2307
|
+
// Handle different display types
|
|
2308
|
+
let displayContent;
|
|
2309
|
+
switch (column.type) {
|
|
2310
|
+
case 'checkbox':
|
|
2311
|
+
case 'boolean':
|
|
2312
|
+
displayContent = (h("span", { class: "cell-boolean" }, h("ui-icon", { name: value ? 'check' : 'x', library: "lucide", size: "1.2em", color: value ? '#4caf50' : '#f44336' })));
|
|
2313
|
+
break;
|
|
2314
|
+
case 'switch':
|
|
2315
|
+
displayContent = h("ui-switch", { checked: !!value, readonly: true, size: "sm" });
|
|
2316
|
+
break;
|
|
2317
|
+
case 'rating':
|
|
2318
|
+
displayContent = h("ui-rating", { value: Number(value) || 0, max: column.maxRating || 5, readonly: true, size: "sm" });
|
|
2319
|
+
break;
|
|
2320
|
+
case 'image':
|
|
2321
|
+
const imageStyle = column.imageStyle || {};
|
|
2322
|
+
displayContent = value ? (h("img", { src: value, alt: "Cell image", class: "cell-image", style: {
|
|
2323
|
+
width: imageStyle.width || '40px',
|
|
2324
|
+
height: imageStyle.height || '40px',
|
|
2325
|
+
borderRadius: imageStyle.borderRadius || '4px',
|
|
2326
|
+
} })) : null;
|
|
2327
|
+
break;
|
|
2328
|
+
case 'password':
|
|
2329
|
+
displayContent = h("span", { class: "cell-password" }, '•'.repeat(value?.length || 8));
|
|
2330
|
+
break;
|
|
2331
|
+
case 'date':
|
|
2332
|
+
displayContent = value ? new Date(value).toLocaleDateString() : '';
|
|
2333
|
+
break;
|
|
2334
|
+
case 'datetime':
|
|
2335
|
+
displayContent = value ? new Date(value).toLocaleString() : '';
|
|
2336
|
+
break;
|
|
2337
|
+
case 'time':
|
|
2338
|
+
displayContent = value;
|
|
2339
|
+
break;
|
|
2340
|
+
case 'email':
|
|
2341
|
+
displayContent = h("a", { href: `mailto:${value}`, class: "cell-link" }, value);
|
|
2342
|
+
break;
|
|
2343
|
+
case 'url':
|
|
2344
|
+
displayContent = h("a", { href: value, target: "_blank", rel: "noopener noreferrer", class: "cell-link" }, value);
|
|
2345
|
+
break;
|
|
2346
|
+
case 'tel':
|
|
2347
|
+
displayContent = h("a", { href: `tel:${value}`, class: "cell-link" }, value);
|
|
2348
|
+
break;
|
|
2349
|
+
default:
|
|
2350
|
+
displayContent = column.format ? column.format(value) : value;
|
|
2351
|
+
}
|
|
2352
|
+
return (h("span", { class: { 'editable-cell': this.editable && column.editable !== false }, onDblClick: () => this.editable && column.editable !== false && this.startCellEdit(row.id, column.field) }, displayContent));
|
|
2353
|
+
}
|
|
2354
|
+
/**
|
|
2355
|
+
* Render row actions menu (3-dot menu)
|
|
2356
|
+
*/
|
|
2357
|
+
renderRowActions(row) {
|
|
2358
|
+
const isOpen = this.activeActionMenu === row.id;
|
|
2359
|
+
const defaultActions = [
|
|
2360
|
+
{ label: 'Edit', value: 'edit', icon: '✏️' },
|
|
2361
|
+
{ label: 'Delete', value: 'delete', icon: '🗑️' },
|
|
2362
|
+
];
|
|
2363
|
+
const actions = this.customActions || defaultActions;
|
|
2364
|
+
return (h("div", { class: "row-actions-container" }, h("ui-button", { variant: "ghost", class: "row-actions-trigger", onClick: (e) => {
|
|
2365
|
+
e.stopPropagation();
|
|
2366
|
+
this.activeActionMenu = isOpen ? null : row.id;
|
|
2367
|
+
}, ariaLabel: "Row actions", icon: "more-vertical", iconLibrary: "lucide", iconOnly: true, size: "sm" }), isOpen && (h("div", { class: "row-actions-menu" }, actions.map(action => (h("ui-button", { key: action.value, variant: "ghost", class: "row-action-item", onClick: (e) => {
|
|
2368
|
+
e.stopPropagation();
|
|
2369
|
+
this.handleRowAction(row, action.value);
|
|
2370
|
+
}, icon: action.icon, iconLibrary: action.iconLibrary || this.iconLibrary, label: action.label, size: "sm", block: true, align: "start" })))))));
|
|
2371
|
+
}
|
|
2372
|
+
/**
|
|
2373
|
+
* Handle row action
|
|
2374
|
+
*/
|
|
2375
|
+
handleRowAction(row, action) {
|
|
2376
|
+
this.activeActionMenu = null; // Close menu
|
|
2377
|
+
if (action === 'edit') {
|
|
2378
|
+
this.rowEdit.emit({ row });
|
|
2379
|
+
}
|
|
2380
|
+
else if (action === 'delete') {
|
|
2381
|
+
this.rowDelete.emit({ row });
|
|
2382
|
+
}
|
|
2383
|
+
else {
|
|
2384
|
+
this.rowAction.emit({ row, action });
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
renderGroupedRows(data, columns) {
|
|
2388
|
+
const groups = this.groupData(data, this.state.groupBy);
|
|
2389
|
+
const rows = [];
|
|
2390
|
+
groups.forEach((groupRows, groupKey) => {
|
|
2391
|
+
const isExpanded = this.state.expandedGroups.has(groupKey);
|
|
2392
|
+
const groupCount = groupRows.length;
|
|
2393
|
+
// Render group header row
|
|
2394
|
+
rows.push(h("tr", { class: "group-header-row", key: `group-${groupKey}`, role: "row", "aria-expanded": isExpanded }, h("td", { colSpan: columns.length + (this.selectable ? 1 : 0) + (this.showActions ? 1 : 0), class: "group-header-cell", onClick: () => this.handleGroupToggle(groupKey), role: "button", tabIndex: 0, onKeyDown: (e) => {
|
|
2395
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
2396
|
+
e.preventDefault();
|
|
2397
|
+
this.handleGroupToggle(groupKey);
|
|
2398
|
+
}
|
|
2399
|
+
}, "aria-label": `${isExpanded ? 'Collapse' : 'Expand'} group ${groupKey}` }, h("div", { class: "group-header-content" }, h("span", { class: "group-expand-icon" }, h("ui-icon", { name: isExpanded ? 'chevron-down' : 'chevron-right', library: "lucide", size: "14px" })), h("span", { class: "group-label" }, groupKey), this.showGroupCount && (h("span", { class: "group-count" }, "(", groupCount, " ", groupCount === 1 ? 'item' : 'items', ")"))))));
|
|
2400
|
+
// Only render group rows when expanded - rows are completely hidden when collapsed
|
|
2401
|
+
if (isExpanded) {
|
|
2402
|
+
groupRows.forEach((row, rowIndex) => {
|
|
2403
|
+
rows.push(h("tr", { class: {
|
|
2404
|
+
'group-data-row': true,
|
|
2405
|
+
'selected': this.state.selectedRows.has(row.id),
|
|
2406
|
+
}, key: row.id, role: "row", "data-group": groupKey, "aria-label": `Row ${rowIndex + 1} in group ${groupKey}` }, this.selectable && (h("td", { class: "select-column", role: "cell" }, h("ui-checkbox", { checked: this.state.selectedRows.has(row.id), onCheckboxChange: (e) => this.handleRowSelect(row.id, e.detail), ariaLabel: `Select row ${rowIndex + 1}`, size: "sm" }))), columns.map(col => (h("td", { key: col.id, class: {
|
|
2407
|
+
'sticky-column': !!col.sticky,
|
|
2408
|
+
'focused-cell': this.state.focusedCell?.rowId === row.id && this.state.focusedCell?.field === col.field,
|
|
2409
|
+
'pinned-left': this.pinnedColumns.left.includes(col.id),
|
|
2410
|
+
'pinned-right': this.pinnedColumns.right.includes(col.id)
|
|
2411
|
+
}, style: { textAlign: col.align || 'left' }, role: "cell", "data-row-id": row.id, "data-field": col.field, tabIndex: 0, onFocus: () => this.setFocusedCell(row.id, col.field) }, this.renderCell(row, col)))), this.showActions && (h("td", { class: "actions-column", role: "cell" }, this.renderRowActions(row))), this.rowDetails && (h("td", { class: "row-details-toggle-cell", role: "cell" }, h("ui-button", { variant: "ghost", size: "sm", onClick: () => this.toggleRowDetails(row.id), ariaLabel: "Toggle row details", icon: this.expandedRowDetails.has(row.id) ? 'chevron-down' : 'chevron-right', iconLibrary: "lucide", iconOnly: true, iconSize: "1.2em" })))));
|
|
2412
|
+
if (this.rowDetails && this.expandedRowDetails.has(row.id)) {
|
|
2413
|
+
rows.push(this.renderRowDetailsPanel(row));
|
|
2414
|
+
}
|
|
2415
|
+
});
|
|
2416
|
+
}
|
|
2417
|
+
});
|
|
2418
|
+
return rows;
|
|
2419
|
+
}
|
|
2420
|
+
// ========== PREMIUM UI RENDER METHODS ==========
|
|
2421
|
+
renderRowDetailsPanel(row) {
|
|
2422
|
+
if (!this.rowDetails || !this.expandedRowDetails.has(row.id))
|
|
2423
|
+
return null;
|
|
2424
|
+
const columns = this.getVisibleColumns();
|
|
2425
|
+
const colSpan = columns.length +
|
|
2426
|
+
(this.selectable ? 1 : 0) +
|
|
2427
|
+
(this.rowReorder ? 1 : 0) +
|
|
2428
|
+
(this.showActions ? 1 : 0);
|
|
2429
|
+
return (h("tr", { key: `${row.id}-details`, class: "row-details-row" }, h("td", { colSpan: colSpan }, h("div", { class: "row-details-panel" }, h("div", { class: "details-header" }, h("h4", null, "Row Details"), h("ui-button", { variant: "ghost", onClick: () => this.toggleRowDetails(row.id), icon: "x", iconLibrary: "lucide", iconOnly: true, size: "sm" })), h("div", { class: "details-content" }, Object.entries(row).map(([key, value]) => (h("div", { key: key, class: "detail-item" }, h("strong", { class: "detail-label" }, key, ":"), h("span", { class: "detail-value" }, String(value))))))))));
|
|
2430
|
+
}
|
|
2431
|
+
renderKeyboardShortcutsModal() {
|
|
2432
|
+
if (!this.showKeyboardShortcutsHelp)
|
|
2433
|
+
return null;
|
|
2434
|
+
return (h("div", { class: "keyboard-shortcuts-modal", onClick: () => this.showKeyboardShortcutsHelp = false }, h("div", { class: "modal-content", onClick: (e) => e.stopPropagation() }, h("div", { class: "modal-header" }, h("h3", null, "Keyboard Shortcuts"), h("ui-button", { variant: "ghost", icon: "x", iconLibrary: "lucide", iconOnly: true, size: "sm", onClick: () => this.showKeyboardShortcutsHelp = false })), h("div", { class: "modal-body" }, h("table", { class: "shortcuts-table" }, h("tbody", null, h("tr", null, h("td", { class: "shortcut-key" }, "Ctrl + F"), h("td", { class: "shortcut-desc" }, "Focus search")), h("tr", null, h("td", { class: "shortcut-key" }, "Ctrl + A"), h("td", { class: "shortcut-desc" }, "Select all rows")), h("tr", null, h("td", { class: "shortcut-key" }, "Ctrl + E"), h("td", { class: "shortcut-desc" }, "Export data")), h("tr", null, h("td", { class: "shortcut-key" }, "Ctrl + Click"), h("td", { class: "shortcut-desc" }, "Multi-column sort")), h("tr", null, h("td", { class: "shortcut-key" }, "Shift + ?"), h("td", { class: "shortcut-desc" }, "Show this help")), h("tr", null, h("td", { class: "shortcut-key" }, "Arrow Keys"), h("td", { class: "shortcut-desc" }, "Navigate cells"))))))));
|
|
2435
|
+
}
|
|
2436
|
+
// ========== PHASE 2 RENDER METHODS ==========
|
|
2437
|
+
renderSparkline(data) {
|
|
2438
|
+
if (data.length < 2)
|
|
2439
|
+
return data.join(', ');
|
|
2440
|
+
const width = 100;
|
|
2441
|
+
const height = 20;
|
|
2442
|
+
const min = Math.min(...data);
|
|
2443
|
+
const max = Math.max(...data);
|
|
2444
|
+
const range = max - min || 1;
|
|
2445
|
+
const points = data.map((val, i) => {
|
|
2446
|
+
const x = (i / (data.length - 1)) * width;
|
|
2447
|
+
const y = height - ((val - min) / range) * height;
|
|
2448
|
+
return `${x},${y}`;
|
|
2449
|
+
}).join(' ');
|
|
2450
|
+
return (h("svg", { width: width, height: height, class: "sparkline", style: { display: 'block' } }, h("polyline", { points: points, fill: "none", stroke: "currentColor", "stroke-width": "1.5" })));
|
|
2451
|
+
}
|
|
2452
|
+
renderContextMenu() {
|
|
2453
|
+
if (!this.contextMenuState.visible)
|
|
2454
|
+
return null;
|
|
2455
|
+
const { x, y, type, target } = this.contextMenuState;
|
|
2456
|
+
const style = { top: `${y}px`, left: `${x}px`, position: 'fixed', zIndex: '1000' };
|
|
2457
|
+
if (type === 'header') {
|
|
2458
|
+
const col = target;
|
|
2459
|
+
const isPinnedLeft = this.pinnedColumns.left.includes(col.id);
|
|
2460
|
+
const isPinnedRight = this.pinnedColumns.right.includes(col.id);
|
|
2461
|
+
return (h("div", { class: "context-menu header-context-menu", style: style }, h("div", { class: "context-menu-header" }, col.label, " Options"), h("ul", null, h("li", { onClick: () => this.handleSort(col.field || col.id) }, this.state.sortConfig.field === (col.field || col.id) && this.state.sortConfig.direction === 'asc' ? h("span", null, h("ui-icon", { name: "check", library: "lucide", size: "1.2em" }), " Sort Decending") : 'Sort Ascending'), h("li", { class: "divider" }), h("li", { class: "has-submenu" }, "Pin Column", h("ul", { class: "submenu" }, h("li", { onClick: () => this.toggleColumnPin(col.id, 'left') }, isPinnedLeft && h("ui-icon", { name: "check", library: "lucide", size: "1.2em" }), "Pin to Left"), h("li", { onClick: () => this.toggleColumnPin(col.id, 'right') }, isPinnedRight && h("ui-icon", { name: "check", library: "lucide", size: "1.2em" }), "Pin to Right"), h("li", { onClick: () => this.toggleColumnPin(col.id, 'none') }, !isPinnedLeft && !isPinnedRight && h("ui-icon", { name: "check", library: "lucide", size: "1.2em" }), "No Pin"))), h("li", { onClick: () => this.toggleColumnVisibility(col.id) }, "Hide Column"), h("li", { class: "divider" }), h("li", { onClick: () => { this.handleFilter(col.field || col.id, ''); this.contextMenuState = { ...this.contextMenuState, visible: false }; } }, "Clear Column Filter"))));
|
|
2462
|
+
}
|
|
2463
|
+
return (h("div", { class: "context-menu", style: style }, h("ul", null, h("li", { onClick: () => this.handleContextAction('copy') }, "Copy"), type === 'row' && h("li", { onClick: () => this.handleContextAction('delete') }, "Delete Row"), type === 'cell' && h("li", { onClick: () => this.handleContextAction('edit') }, "Edit Cell"), h("li", { class: "divider" }), h("li", { onClick: () => this.handleContextAction('export') }, "Export Row"))));
|
|
2464
|
+
}
|
|
2465
|
+
handleContextAction(action) {
|
|
2466
|
+
const { target, type } = this.contextMenuState;
|
|
2467
|
+
if (action === 'copy') {
|
|
2468
|
+
let text = '';
|
|
2469
|
+
if (type === 'cell') {
|
|
2470
|
+
text = String(target.value || '');
|
|
2471
|
+
}
|
|
2472
|
+
else if (type === 'row') {
|
|
2473
|
+
text = JSON.stringify(target);
|
|
2474
|
+
}
|
|
2475
|
+
if (text) {
|
|
2476
|
+
navigator.clipboard.writeText(text).catch(err => console.error('Copy failed', err));
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
else if (action === 'edit' && type === 'cell') {
|
|
2480
|
+
this.startCellEdit(target.rowId, target.field);
|
|
2481
|
+
}
|
|
2482
|
+
this.contextMenuState = { ...this.contextMenuState, visible: false };
|
|
2483
|
+
}
|
|
2484
|
+
renderMobileCards(data) {
|
|
2485
|
+
const columns = this.getVisibleColumns();
|
|
2486
|
+
return (h("div", { class: "mobile-cards-view" }, data.map(row => (h("div", { class: "mobile-card", key: row.id }, h("div", { class: "card-header" }, this.selectable && (h("ui-checkbox", { checked: this.state.selectedRows.has(row.id), onCheckboxChange: (e) => this.handleRowSelect(row.id, e.detail), size: "sm" })), h("span", { class: "card-title" }, "Row #", row.id), this.showActions && h("div", { class: "card-actions" }, this.renderRowActions(row))), h("div", { class: "card-body" }, columns.map(col => (h("div", { class: "card-field", key: col.id }, h("label", null, col.label || col.field), h("div", { class: "card-value" }, this.renderCell(row, col))))))))), this.renderLazyLoadSentinel()));
|
|
2487
|
+
}
|
|
2488
|
+
renderLazyLoadSentinel() {
|
|
2489
|
+
if (!this.lazyLoad)
|
|
2490
|
+
return null;
|
|
2491
|
+
// Sentinel for IntersectionObserver
|
|
2492
|
+
return (h("div", { class: "lazy-load-sentinel", ref: (el) => {
|
|
2493
|
+
if (el)
|
|
2494
|
+
this.setupLazyLoadObserver(el);
|
|
2495
|
+
}, style: { height: '20px', textAlign: 'center', padding: '10px' } }, this.loading ? 'Loading more...' : ''));
|
|
2496
|
+
}
|
|
2497
|
+
renderValidationError(rowId, field) {
|
|
2498
|
+
if (!this.advancedValidation)
|
|
2499
|
+
return null;
|
|
2500
|
+
const rowKey = String(rowId);
|
|
2501
|
+
const error = this.validationErrors.get(rowKey)?.get(field);
|
|
2502
|
+
if (!error)
|
|
2503
|
+
return null;
|
|
2504
|
+
return (h("div", { class: "validation-error-tooltip" }, h("ui-icon", { name: "alert-triangle", library: "lucide", size: "14px", class: "error-icon", color: "#f44336" }), h("span", { class: "error-message" }, error)));
|
|
2505
|
+
}
|
|
2506
|
+
renderPagination() {
|
|
2507
|
+
if (!this.pagination)
|
|
2508
|
+
return null;
|
|
2509
|
+
const { currentPage, pageSize, totalRows } = this.state.pagination;
|
|
2510
|
+
return (h("div", { class: "pagination-container" }, h("ui-pagination", { "total-items": totalRows, "items-per-page": pageSize, "current-page": currentPage, "show-first-last": true, "show-page-size": true, "show-total": true, "page-size-options": JSON.stringify(this.parsePageSizeOptions()), theme: this.paginationTheme, shape: this.paginationShape, "keyboard-nav": this.paginationKeyboardNav, "quick-jump": this.paginationQuickJump, "quick-jump-step": this.paginationQuickJumpStep, "show-progress": this.paginationShowProgress, sticky: this.paginationSticky, "sticky-position": this.paginationStickyPosition, "page-transition": this.paginationTransitions, "url-sync": this.paginationUrlSync, "url-param": this.paginationUrlParam, "persist-page": this.paginationPersistPage, "storage-key": this.paginationStorageKey, "swipe-gestures": this.paginationSwipeGestures, "smart-compact": this.paginationSmartCompact, "smart-compact-threshold": this.paginationSmartCompactThreshold, "auto-hide": this.paginationAutoHide, "responsive-mode": this.paginationResponsive, "mobile-breakpoint": this.paginationMobileBreakpoint, onPageChange: (e) => this.handlePaginationChange(e), onItemsPerPageChange: (e) => this.handlePageSizeChangeFromPagination(e) })));
|
|
2511
|
+
}
|
|
2512
|
+
renderToolbar() {
|
|
2513
|
+
return (h("div", { class: "table-toolbar" }, h("div", { class: "toolbar-left" }, this.searchable && (h("div", { class: "search-box" }, h("ui-input", { type: "text", placeholder: "Search...", value: this.state.searchQuery, onInputChange: (e) => this.handleSearch(e.detail), ariaLabel: "Search table", size: "sm", prefixIcon: "search", variant: "outlined" }))), this.grouping && this.renderGroupingSelector()), h("div", { class: "toolbar-right" }, this.filterable && (h("ui-button", { variant: "ghost", size: "sm", icon: "filter", iconLibrary: "lucide", iconSize: "1.1em", label: "Filters", ariaLabel: "Filter panel", onClick: () => this.showFilterPanel = !this.showFilterPanel, "data-expanded": this.showFilterPanel })), this.columnVisibility && (h("ui-button", { variant: "ghost", size: "sm", icon: "settings", iconLibrary: "lucide", iconSize: "1.1em", label: "Columns", ariaLabel: "Column settings", onClick: () => this.showColumnSettings = !this.showColumnSettings, "data-expanded": this.showColumnSettings })), this.exportable && (h("ui-button", { variant: "ghost", size: "sm", icon: "download", iconLibrary: "lucide", iconSize: "1.1em", label: "Export", ariaLabel: "Export data", onClick: () => this.showExportDialog = !this.showExportDialog })), h("ui-button", { variant: "ghost", size: "sm", icon: "refresh-cw", iconLibrary: "lucide", iconSize: "1.1em", label: "Refresh", ariaLabel: "Refresh table", onClick: () => this.refresh() }))));
|
|
2514
|
+
}
|
|
2515
|
+
renderGroupingSelector() {
|
|
2516
|
+
const groupableColumns = this.getVisibleColumns().filter(col => col.groupBy !== false);
|
|
2517
|
+
if (groupableColumns.length === 0)
|
|
2518
|
+
return null;
|
|
2519
|
+
return (h("div", { class: "grouping-selector" }, h("label", { htmlFor: "group-by-select" }, "Group by:"), h("select", { id: "group-by-select", onInput: (e) => this.handleGroupByChange(e.target.value), "aria-label": "Group table by column" }, h("option", { value: "", selected: !this.state.groupBy }, "None"), groupableColumns.map(col => (h("option", { value: col.field || col.id, key: col.id, selected: this.state.groupBy === (col.field || col.id) }, col.label))))));
|
|
2520
|
+
}
|
|
2521
|
+
renderFilterPanel() {
|
|
2522
|
+
if (!this.showFilterPanel)
|
|
2523
|
+
return null;
|
|
2524
|
+
const flatColumns = this.flattenColumns(this.parseColumns());
|
|
2525
|
+
const filterableColumns = flatColumns.filter(col => col.filterable !== false);
|
|
2526
|
+
const getColumnType = (col) => {
|
|
2527
|
+
if (col.type)
|
|
2528
|
+
return col.type;
|
|
2529
|
+
// Auto-detect from field name
|
|
2530
|
+
if (col.field?.includes('date') || col.field?.includes('Date'))
|
|
2531
|
+
return 'date';
|
|
2532
|
+
if (col.field?.includes('price') || col.field?.includes('salary') || col.field?.includes('amount'))
|
|
2533
|
+
return 'number';
|
|
2534
|
+
if (col.field?.includes('email'))
|
|
2535
|
+
return 'email';
|
|
2536
|
+
return 'text';
|
|
2537
|
+
};
|
|
2538
|
+
const getOperatorsForType = (type) => {
|
|
2539
|
+
const commonOps = [
|
|
2540
|
+
{ value: 'equals', label: 'Equals' },
|
|
2541
|
+
{ value: 'notEquals', label: 'Not Equals' },
|
|
2542
|
+
];
|
|
2543
|
+
if (type === 'number' || type === 'date') {
|
|
2544
|
+
return [
|
|
2545
|
+
...commonOps,
|
|
2546
|
+
{ value: 'greaterThan', label: 'Greater Than' },
|
|
2547
|
+
{ value: 'lessThan', label: 'Less Than' },
|
|
2548
|
+
{ value: 'between', label: 'Between' },
|
|
2549
|
+
];
|
|
2550
|
+
}
|
|
2551
|
+
if (type === 'text' || type === 'email' || type === 'url') {
|
|
2552
|
+
return [
|
|
2553
|
+
...commonOps,
|
|
2554
|
+
{ value: 'contains', label: 'Contains' },
|
|
2555
|
+
{ value: 'notContains', label: 'Not Contains' },
|
|
2556
|
+
{ value: 'startsWith', label: 'Starts With' },
|
|
2557
|
+
{ value: 'endsWith', label: 'Ends With' },
|
|
2558
|
+
];
|
|
2559
|
+
}
|
|
2560
|
+
return commonOps;
|
|
2561
|
+
};
|
|
2562
|
+
const selectedColumn = filterableColumns.find(col => col.id === this.filterPanelField);
|
|
2563
|
+
const columnType = selectedColumn ? getColumnType(selectedColumn) : 'text';
|
|
2564
|
+
const operators = getOperatorsForType(columnType);
|
|
2565
|
+
return (h("div", { class: "filter-panel" }, h("div", { class: "filter-panel-header" }, h("h4", null, h("ui-icon", { name: "filter", library: "lucide", size: "1.1em" }), " Advanced Filters"), h("ui-button", { variant: "ghost", size: "sm", icon: "x", iconLibrary: "lucide", iconSize: "1.1em", onClick: () => this.showFilterPanel = false })), h("div", { class: "filter-panel-body" }, h("div", { class: "filter-builder" }, h("div", { class: "filter-row" }, h("select", { class: "filter-field-select", onChange: (e) => {
|
|
2566
|
+
this.filterPanelField = e.target.value;
|
|
2567
|
+
this.filterPanelValue = '';
|
|
2568
|
+
} }, h("option", { value: "", selected: this.filterPanelField === '' }, "Select Column..."), filterableColumns.map(col => (h("option", { value: col.id, selected: this.filterPanelField === col.id }, col.label)))), h("select", { class: "filter-operator-select", onChange: (e) => this.filterPanelOperator = e.target.value, disabled: !this.filterPanelField }, operators.map(op => (h("option", { value: op.value, selected: this.filterPanelOperator === op.value }, op.label)))), h("ui-input", { type: columnType === 'number' ? 'number' : columnType === 'date' ? 'date' : 'text', customClass: "filter-value-input", value: this.filterPanelValue, onInputChange: (e) => this.filterPanelValue = e.detail, placeholder: "Filter value...", disabled: !this.filterPanelField, size: "sm", variant: "outlined" }), h("ui-button", { variant: "ghost", size: "sm", icon: "plus", iconLibrary: "lucide", iconSize: "1.2em", label: "Add", onClick: () => {
|
|
2569
|
+
if (this.filterPanelField && this.filterPanelValue) {
|
|
2570
|
+
this.addFilter(this.filterPanelField, this.filterPanelOperator, this.filterPanelValue);
|
|
2571
|
+
this.filterPanelField = '';
|
|
2572
|
+
this.filterPanelValue = '';
|
|
2573
|
+
}
|
|
2574
|
+
}, disabled: !this.filterPanelField || !this.filterPanelValue }))), h("div", { class: "active-filters" }, h("div", { class: "active-filters-header" }, h("span", null, "Active Filters (", Array.from(this.activeFilters.values()).flat().length, ")"), this.activeFilters.size > 0 && (h("ui-button", { variant: "ghost", size: "sm", label: "Clear All", onClick: () => this.clearAllFilters() }))), h("div", { class: "filter-chips" }, Array.from(this.activeFilters.entries()).map(([field, filters]) => {
|
|
2575
|
+
const column = flatColumns.find(col => col.id === field);
|
|
2576
|
+
return filters.map((filter, index) => (h("div", { class: "filter-chip" }, h("span", { class: "filter-chip-label" }, h("strong", null, column?.label || field), " ", filter.operator, " \"", filter.value, "\""), h("ui-button", { variant: "ghost", size: "sm", class: "filter-chip-remove", icon: "x", iconLibrary: "lucide", iconSize: "14px", onClick: () => this.removeFilter(field, index) }))));
|
|
2577
|
+
}), this.activeFilters.size === 0 && (h("div", { class: "no-filters" }, "No active filters")))))));
|
|
2578
|
+
}
|
|
2579
|
+
renderColumnSettings() {
|
|
2580
|
+
if (!this.showColumnSettings)
|
|
2581
|
+
return null;
|
|
2582
|
+
const flatColumns = this.flattenColumns(this.parseColumns());
|
|
2583
|
+
return (h("div", { class: "column-settings-dialog" }, h("div", { class: "dialog-overlay", onClick: () => this.showColumnSettings = false }), h("div", { class: "dialog-content" }, h("div", { class: "dialog-header" }, h("h3", null, "Column Settings"), h("ui-button", { variant: "ghost", size: "sm", icon: "x", iconLibrary: "lucide", iconSize: "1.2em", onClick: () => this.showColumnSettings = false })), h("div", { class: "dialog-body" }, h("div", { class: "column-list" }, flatColumns.map(col => (h("label", { class: "column-item" }, h("ui-checkbox", { checked: this.state.visibleColumns.has(col.id), onCheckboxChange: () => this.toggleColumnVisibility(col.id), label: col.label, size: "sm" })))))), h("div", { class: "dialog-footer" }, h("ui-button", { variant: "primary", label: "Done", onClick: () => this.showColumnSettings = false })))));
|
|
2584
|
+
}
|
|
2585
|
+
renderExportDialog() {
|
|
2586
|
+
if (!this.showExportDialog)
|
|
2587
|
+
return null;
|
|
2588
|
+
return (h("div", { class: "export-dialog" }, h("div", { class: "dialog-overlay", onClick: () => this.showExportDialog = false }), h("div", { class: "dialog-content" }, h("div", { class: "dialog-header" }, h("h3", null, "Export Data"), h("ui-button", { variant: "ghost", size: "sm", icon: "x", iconLibrary: "lucide", iconSize: "1.2em", onClick: () => this.showExportDialog = false })), h("div", { class: "dialog-body" }, h("div", { class: "export-options" }, h("ui-button", { variant: "ghost", fullWidth: true, icon: "file-text", iconLibrary: "lucide", iconSize: "1.2em", label: "Export as CSV", onClick: () => this.exportData({ format: 'csv', visibleColumnsOnly: true }) }), h("ui-button", { variant: "ghost", fullWidth: true, icon: "clipboard", iconLibrary: "lucide", iconSize: "1.2em", label: "Export as JSON", onClick: () => this.exportData({ format: 'json', visibleColumnsOnly: true }) }), this.pdfExport && (h("ui-button", { variant: "ghost", fullWidth: true, icon: "book", iconLibrary: "lucide", iconSize: "1.2em", label: "Export as PDF", onClick: () => this.exportToPDF() })), this.state.selectedRows.size > 0 && (h("ui-button", { variant: "ghost", fullWidth: true, icon: "check-circle", iconLibrary: "lucide", iconSize: "1.2em", label: `Export Selected Only (${this.state.selectedRows.size} rows)`, onClick: () => this.exportData({ format: 'csv', selectedOnly: true }) })))))));
|
|
2589
|
+
}
|
|
2590
|
+
getHostStyles() {
|
|
2591
|
+
const styles = {};
|
|
2592
|
+
if (this.headerBackground)
|
|
2593
|
+
styles['--table-header-bg'] = this.headerBackground;
|
|
2594
|
+
if (this.stripedColor)
|
|
2595
|
+
styles['--table-striped-bg'] = this.stripedColor;
|
|
2596
|
+
if (this.stripedColorDark)
|
|
2597
|
+
styles['--table-striped-bg-dark'] = this.stripedColorDark;
|
|
2598
|
+
return styles;
|
|
2599
|
+
}
|
|
2600
|
+
render() {
|
|
2601
|
+
const allData = this.getProcessedData();
|
|
2602
|
+
const columns = this.getVisibleColumns();
|
|
2603
|
+
// Virtual Scrolling Logic
|
|
2604
|
+
let displayData = allData;
|
|
2605
|
+
let topSpacer = 0;
|
|
2606
|
+
let bottomSpacer = 0;
|
|
2607
|
+
if (this.virtualScroll) {
|
|
2608
|
+
const { start, end } = this.state.virtualVisibleRange;
|
|
2609
|
+
// Ensure range is valid
|
|
2610
|
+
const safeStart = Math.max(0, start);
|
|
2611
|
+
const safeEnd = Math.min(allData.length, end);
|
|
2612
|
+
displayData = allData.slice(safeStart, safeEnd);
|
|
2613
|
+
topSpacer = safeStart * this.virtualRowHeight;
|
|
2614
|
+
bottomSpacer = (allData.length - safeEnd) * this.virtualRowHeight;
|
|
2615
|
+
}
|
|
2616
|
+
// Mobile View Check (Phase 2)
|
|
2617
|
+
if (this.mobileCardView && this.isMobileView) {
|
|
2618
|
+
return (h("div", { class: {
|
|
2619
|
+
'data-table-container': true,
|
|
2620
|
+
'mobile-view': true,
|
|
2621
|
+
[`advanced-table-${this.variant}`]: true,
|
|
2622
|
+
[`table-color-${this.color}`]: true,
|
|
2623
|
+
'dark-mode': this.theme === 'dark',
|
|
2624
|
+
[this.rowHeight]: !!this.rowHeight
|
|
2625
|
+
}, style: this.getHostStyles() }, this.renderToolbar(), this.renderMobileCards(displayData), this.renderPagination(), this.renderFilterPanel(), this.renderColumnSettings(), this.renderExportDialog(), this.renderKeyboardShortcutsModal(), this.renderContextMenu()));
|
|
2626
|
+
}
|
|
2627
|
+
return (h("div", { class: {
|
|
2628
|
+
'data-table-container': true,
|
|
2629
|
+
[`advanced-table-${this.variant}`]: true,
|
|
2630
|
+
[`table-color-${this.color}`]: true,
|
|
2631
|
+
'dark-mode': this.theme === 'dark',
|
|
2632
|
+
[this.rowHeight]: !!this.rowHeight
|
|
2633
|
+
}, style: this.getHostStyles() }, this.renderToolbar(), h("div", { class: {
|
|
2634
|
+
'table-wrapper': true,
|
|
2635
|
+
'virtual-scroll': this.virtualScroll
|
|
2636
|
+
}, onScroll: this.virtualScroll ? this.handleVirtualScroll : undefined }, h("table", { class: {
|
|
2637
|
+
'data-table': true,
|
|
2638
|
+
'sticky-header': this.stickyHeader,
|
|
2639
|
+
'striped': this.striped,
|
|
2640
|
+
'hoverable': this.hoverable,
|
|
2641
|
+
'bordered': this.bordered,
|
|
2642
|
+
}, role: "table", "aria-label": "Data table" }, h("thead", null, this.renderTableHeaders()), h("tbody", null, this.loading && this.showSkeleton && this.renderSkeletonRows(columns), this.loading && !this.showSkeleton && (h("tr", null, h("td", { colSpan: columns.length + (this.selectable ? 1 : 0) + (this.showActions ? 1 : 0) + (this.rowDetails ? 1 : 0), class: "loading-cell" }, h("div", { class: "loading-container" }, h("ui-loader", { type: "spinner", size: "2em", color: "primary" }), h("span", null, "Loading..."))))), !this.loading && allData.length === 0 && (h("tr", null, h("td", { colSpan: columns.length + (this.selectable ? 1 : 0) + (this.showActions ? 1 : 0) + (this.rowDetails ? 1 : 0), class: "empty-cell" }, this.emptyMessage))), topSpacer > 0 && (h("tr", { style: { height: `${topSpacer}px` }, role: "presentation" }, h("td", { colSpan: columns.length + (this.selectable ? 1 : 0) + (this.showActions ? 1 : 0), style: { padding: '0', border: 'none' } }))), !this.loading && displayData.length > 0 && this.state.groupBy && this.renderGroupedRows(displayData, columns), !this.loading && displayData.length > 0 && !this.state.groupBy && displayData.map((row, rowIndex) => [
|
|
2643
|
+
h("tr", { class: {
|
|
2644
|
+
'selected': this.state.selectedRows.has(row.id),
|
|
2645
|
+
'pinned-row-top': this.pinnedRows.top.includes(row.id),
|
|
2646
|
+
'pinned-row-bottom': this.pinnedRows.bottom.includes(row.id),
|
|
2647
|
+
}, key: row.id, role: "row", onContextMenu: (e) => this.handleContextMenu(e, 'row', row), "data-row-id": row.id }, this.selectable && (h("td", { class: "select-column", role: "cell" }, h("ui-checkbox", { checked: this.state.selectedRows.has(row.id), onCheckboxChange: (e) => this.handleRowSelect(row.id, e), ariaLabel: `Select row ${rowIndex + 1}`, size: "sm" }))), columns.map(col => (h("td", { key: col.id, class: {
|
|
2648
|
+
'sticky-column': !!col.sticky,
|
|
2649
|
+
'range-selection-cell': true,
|
|
2650
|
+
'focused-cell': this.state.focusedCell?.rowId === row.id && this.state.focusedCell?.field === col.field,
|
|
2651
|
+
'pinned-left': this.pinnedColumns.left.includes(col.id),
|
|
2652
|
+
'pinned-right': this.pinnedColumns.right.includes(col.id)
|
|
2653
|
+
}, style: {
|
|
2654
|
+
textAlign: col.align || 'left',
|
|
2655
|
+
left: this.pinnedColumns.left.includes(col.id) ? this.getPinnedOffset(col.id, 'left') : undefined,
|
|
2656
|
+
right: this.pinnedColumns.right.includes(col.id) ? this.getPinnedOffset(col.id, 'right') : undefined,
|
|
2657
|
+
...this.getConditionalFormattingStyle(row[col.field], col)
|
|
2658
|
+
}, role: "cell", onClick: (e) => this.handleCellClick(row.id, col.field, e), onContextMenu: (e) => this.handleContextMenu(e, 'cell', { rowId: row.id, field: col.field, value: row[col.field] }), "data-row-id": row.id, "data-field": col.field, tabIndex: 0, onFocus: () => this.setFocusedCell(row.id, col.field) }, this.renderCell(row, col), this.renderValidationError(row.id, col.field)))), this.showActions && (h("td", { class: "actions-column", role: "cell" }, this.renderRowActions(row))), this.rowDetails && (h("td", { class: "row-details-toggle-cell", role: "cell" }, h("ui-button", { variant: "ghost", size: "sm", icon: this.expandedRowDetails.has(row.id) ? 'chevron-down' : 'chevron-right', iconLibrary: "lucide", iconSize: "16px", ariaLabel: "Toggle row details", onClick: () => this.toggleRowDetails(row.id) })))),
|
|
2659
|
+
this.renderRowDetailsPanel(row)
|
|
2660
|
+
]), bottomSpacer > 0 && (h("tr", { style: { height: `${bottomSpacer}px` }, role: "presentation" }, h("td", { colSpan: 100, style: { padding: '0', border: 'none' } })))), this.columnAggregation && this.renderAggregationFooter()), this.renderLazyLoadSentinel()), this.renderPagination(), this.renderFilterPanel(), this.renderColumnSettings(), this.renderExportDialog(), this.renderKeyboardShortcutsModal(), this.renderContextMenu()));
|
|
2661
|
+
}
|
|
2662
|
+
static get watchers() { return {
|
|
2663
|
+
"data": [{
|
|
2664
|
+
"onDataOrColumnsChange": 0
|
|
2665
|
+
}],
|
|
2666
|
+
"columns": [{
|
|
2667
|
+
"onDataOrColumnsChange": 0
|
|
2668
|
+
}],
|
|
2669
|
+
"pageSize": [{
|
|
2670
|
+
"onPageSizeChange": 0
|
|
2671
|
+
}],
|
|
2672
|
+
"groupBy": [{
|
|
2673
|
+
"onGroupByChange": 0
|
|
2674
|
+
}],
|
|
2675
|
+
"theme": [{
|
|
2676
|
+
"onThemeChange": 0
|
|
2677
|
+
}]
|
|
2678
|
+
}; }
|
|
2679
|
+
};
|
|
2680
|
+
AdvancedDataTable.style = advancedDataTableCss();
|
|
2681
|
+
|
|
2682
|
+
export { AdvancedDataTable as ui_advanced_data_table };
|