@memberjunction/ng-trees 5.10.1 → 5.12.0

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.
@@ -1606,11 +1606,11 @@ export class TreeComponent {
1606
1606
  i0.ɵɵconditional(ctx.IsLoaded && ctx.Nodes.length === 0 && !ctx.ErrorMessage && !ctx.IsLoading ? 4 : -1);
1607
1607
  i0.ɵɵadvance();
1608
1608
  i0.ɵɵconditional(ctx.Nodes.length > 0 && !ctx.IsLoading ? 5 : -1);
1609
- } }, dependencies: [i1.NgClass, i1.NgTemplateOutlet], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --tree-bg: #ffffff;\n --tree-border-color: #e0e0e0;\n --tree-text-color: #333333;\n --tree-text-secondary: #666666;\n --tree-text-muted: #999999;\n\n \n\n --tree-node-hover-bg: #f5f7fa;\n --tree-node-selected-bg: #e3f2fd;\n --tree-node-selected-border: #2196f3;\n --tree-node-focused-outline: rgba(33, 150, 243, 0.5);\n --tree-node-match-bg: #fff3cd;\n\n \n\n --tree-icon-color: #5c6bc0;\n --tree-icon-leaf-color: #78909c;\n --tree-toggle-color: #9e9e9e;\n\n \n\n --tree-node-padding-y: 8px;\n --tree-node-padding-x: 12px;\n --tree-node-gap: 8px;\n --tree-icon-size: 16px;\n --tree-toggle-size: 12px;\n\n \n\n --tree-transition-duration: 150ms;\n --tree-animation-easing: ease-out;\n\n \n\n --tree-badge-bg: #e0e0e0;\n --tree-badge-color: #666666;\n --tree-badge-size: 12px;\n\n display: block;\n width: 100%;\n height: 100%;\n}\n\n\n\n\n\n\n.tree-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: var(--tree-bg);\n border-radius: 8px;\n overflow: hidden;\n outline: none;\n}\n\n.tree-container[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n\n\n\n\n\n.tree-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-loading__spinner[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--tree-icon-color);\n}\n\n.tree-loading__text[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n\n\n\n.tree-error[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n text-align: center;\n}\n\n.tree-error__icon[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #f44336;\n}\n\n.tree-error__message[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--tree-text-secondary);\n max-width: 280px;\n}\n\n.tree-error__retry[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--tree-border-color);\n border-radius: 6px;\n background: var(--tree-bg);\n color: var(--tree-text-color);\n font-size: 13px;\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-error__retry[_ngcontent-%COMP%]:hover {\n background: var(--tree-node-hover-bg);\n border-color: var(--tree-icon-color);\n color: var(--tree-icon-color);\n}\n\n\n\n\n\n\n.tree-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-empty__icon[_ngcontent-%COMP%] {\n font-size: 40px;\n opacity: 0.5;\n}\n\n.tree-empty__message[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n\n\n\n.tree-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--tree-border-color);\n background: var(--tree-node-hover-bg);\n}\n\n.tree-toolbar__btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--tree-text-secondary);\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-toolbar__btn[_ngcontent-%COMP%]:hover {\n background: var(--tree-bg);\n color: var(--tree-icon-color);\n}\n\n\n\n\n\n\n.tree-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 4px 0;\n}\n\n\n\n\n\n\n.tree-node[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--tree-node-gap);\n padding: var(--tree-node-padding-y) var(--tree-node-padding-x);\n cursor: pointer;\n user-select: none;\n border-left: 3px solid transparent;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n min-height: 36px;\n}\n\n.tree-node[_ngcontent-%COMP%]:hover {\n background: var(--tree-node-hover-bg);\n}\n\n.tree-node--selected[_ngcontent-%COMP%] {\n background: var(--tree-node-selected-bg);\n border-left-color: var(--tree-node-selected-border);\n}\n\n.tree-node--selected[_ngcontent-%COMP%]:hover {\n background: var(--tree-node-selected-bg);\n}\n\n.tree-node--focused[_ngcontent-%COMP%] {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n\n\n.tree-search-highlight[_ngcontent-%COMP%] {\n background: var(--tree-node-match-bg);\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.tree-node-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n border-radius: 4px;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node-toggle[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.tree-node-toggle__icon[_ngcontent-%COMP%] {\n font-size: var(--tree-toggle-size);\n color: var(--tree-toggle-color);\n transition: transform var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node--expanded[_ngcontent-%COMP%] .tree-node-toggle__icon[_ngcontent-%COMP%] {\n color: var(--tree-icon-color);\n}\n\n.tree-node-toggle__spacer[_ngcontent-%COMP%] {\n width: var(--tree-toggle-size);\n}\n\n.tree-node-leaf-spacer[_ngcontent-%COMP%] {\n width: 20px;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.tree-node-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--tree-icon-size);\n flex-shrink: 0;\n font-size: var(--tree-icon-size);\n color: var(--tree-icon-color);\n}\n\n.tree-node--leaf[_ngcontent-%COMP%] .tree-node-icon[_ngcontent-%COMP%] {\n color: var(--tree-icon-leaf-color);\n}\n\n\n\n\n\n\n.tree-node-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.tree-node-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--tree-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-node--leaf[_ngcontent-%COMP%] .tree-node-label[_ngcontent-%COMP%] {\n font-weight: 400;\n}\n\n.tree-node-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--tree-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n\n\n.tree-node-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--tree-badge-bg);\n color: var(--tree-badge-color);\n font-size: var(--tree-badge-size);\n font-weight: 500;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.tree-node-selected-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--tree-node-selected-border);\n color: white;\n font-size: 10px;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.tree-node-children[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n.tree-node-children--animated[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_tree-expand var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n@keyframes _ngcontent-%COMP%_tree-expand {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n\n\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--tree-border-color);\n border-radius: 4px;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--tree-toggle-color);\n}\n\n\n\n\n\n\n@media (max-width: 480px) {\n [_nghost-%COMP%] {\n --tree-node-padding-y: 10px;\n --tree-node-padding-x: 10px;\n --tree-icon-size: 18px;\n }\n\n .tree-node-label[_ngcontent-%COMP%] {\n font-size: 15px;\n }\n}"] });
1609
+ } }, dependencies: [i1.NgClass, i1.NgTemplateOutlet], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --tree-bg: var(--mj-bg-surface);\n --tree-border-color: var(--mj-border-default);\n --tree-text-color: var(--mj-text-primary);\n --tree-text-secondary: var(--mj-text-muted);\n --tree-text-muted: var(--mj-text-disabled);\n\n \n\n --tree-node-hover-bg: var(--mj-bg-surface-sunken);\n --tree-node-selected-bg: var(--mj-brand-primary-subtle);\n --tree-node-selected-border: var(--mj-brand-primary);\n --tree-node-focused-outline: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n --tree-node-match-bg: var(--mj-status-warning-subtle);\n\n \n\n --tree-icon-color: var(--mj-brand-primary);\n --tree-icon-leaf-color: var(--mj-text-muted);\n --tree-toggle-color: var(--mj-text-disabled);\n\n \n\n --tree-node-padding-y: 8px;\n --tree-node-padding-x: 12px;\n --tree-node-gap: 8px;\n --tree-icon-size: 16px;\n --tree-toggle-size: 12px;\n\n \n\n --tree-transition-duration: 150ms;\n --tree-animation-easing: ease-out;\n\n \n\n --tree-badge-bg: var(--mj-border-default);\n --tree-badge-color: var(--mj-text-muted);\n --tree-badge-size: 12px;\n\n display: block;\n width: 100%;\n height: 100%;\n}\n\n\n\n\n\n\n.tree-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: var(--tree-bg);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n}\n\n.tree-container[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n\n\n\n\n\n.tree-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-loading__spinner[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n color: var(--tree-icon-color);\n}\n\n.tree-loading__text[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n\n\n.tree-error[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n text-align: center;\n}\n\n.tree-error__icon[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-status-error);\n}\n\n.tree-error__message[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--tree-text-secondary);\n max-width: 280px;\n}\n\n.tree-error__retry[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--tree-border-color);\n border-radius: var(--mj-radius-md);\n background: var(--tree-bg);\n color: var(--tree-text-color);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-error__retry[_ngcontent-%COMP%]:hover {\n background: var(--tree-node-hover-bg);\n border-color: var(--tree-icon-color);\n color: var(--tree-icon-color);\n}\n\n\n\n\n\n\n.tree-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-empty__icon[_ngcontent-%COMP%] {\n font-size: 40px;\n opacity: 0.5;\n}\n\n.tree-empty__message[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n\n\n.tree-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--tree-border-color);\n background: var(--tree-node-hover-bg);\n}\n\n.tree-toolbar__btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: var(--mj-radius-sm);\n background: transparent;\n color: var(--tree-text-secondary);\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-toolbar__btn[_ngcontent-%COMP%]:hover {\n background: var(--tree-bg);\n color: var(--tree-icon-color);\n}\n\n\n\n\n\n\n.tree-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 4px 0;\n}\n\n\n\n\n\n\n.tree-node[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--tree-node-gap);\n padding: var(--tree-node-padding-y) var(--tree-node-padding-x);\n cursor: pointer;\n user-select: none;\n border-left: 3px solid transparent;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n min-height: 36px;\n}\n\n.tree-node[_ngcontent-%COMP%]:hover {\n background: var(--tree-node-hover-bg);\n}\n\n.tree-node--selected[_ngcontent-%COMP%] {\n background: var(--tree-node-selected-bg);\n border-left-color: var(--tree-node-selected-border);\n}\n\n.tree-node--selected[_ngcontent-%COMP%]:hover {\n background: var(--tree-node-selected-bg);\n}\n\n.tree-node--focused[_ngcontent-%COMP%] {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n\n\n.tree-search-highlight[_ngcontent-%COMP%] {\n background: var(--tree-node-match-bg);\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.tree-node-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n border-radius: var(--mj-radius-sm);\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node-toggle[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.tree-node-toggle__icon[_ngcontent-%COMP%] {\n font-size: var(--tree-toggle-size);\n color: var(--tree-toggle-color);\n transition: transform var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node--expanded[_ngcontent-%COMP%] .tree-node-toggle__icon[_ngcontent-%COMP%] {\n color: var(--tree-icon-color);\n}\n\n.tree-node-toggle__spacer[_ngcontent-%COMP%] {\n width: var(--tree-toggle-size);\n}\n\n.tree-node-leaf-spacer[_ngcontent-%COMP%] {\n width: 20px;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.tree-node-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--tree-icon-size);\n flex-shrink: 0;\n font-size: var(--tree-icon-size);\n color: var(--tree-icon-color);\n}\n\n.tree-node--leaf[_ngcontent-%COMP%] .tree-node-icon[_ngcontent-%COMP%] {\n color: var(--tree-icon-leaf-color);\n}\n\n\n\n\n\n\n.tree-node-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.tree-node-label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: 500;\n color: var(--tree-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-node--leaf[_ngcontent-%COMP%] .tree-node-label[_ngcontent-%COMP%] {\n font-weight: 400;\n}\n\n.tree-node-description[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--tree-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n\n\n.tree-node-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--tree-badge-bg);\n color: var(--tree-badge-color);\n font-size: var(--tree-badge-size);\n font-weight: 500;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.tree-node-selected-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: var(--mj-radius-full);\n background: var(--tree-node-selected-border);\n color: var(--mj-text-inverse);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.tree-node-children[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n.tree-node-children--animated[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_tree-expand var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n@keyframes _ngcontent-%COMP%_tree-expand {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n\n\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--tree-border-color);\n border-radius: var(--mj-radius-sm);\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--tree-toggle-color);\n}\n\n\n\n\n\n\n@media (max-width: 480px) {\n [_nghost-%COMP%] {\n --tree-node-padding-y: 10px;\n --tree-node-padding-x: 10px;\n --tree-icon-size: 18px;\n }\n\n .tree-node-label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n }\n}"] });
1610
1610
  }
1611
1611
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TreeComponent, [{
1612
1612
  type: Component,
1613
- args: [{ standalone: false, selector: 'mj-tree', template: "<!-- Tree Component Template -->\n<div [ngClass]=\"getContainerClasses()\" tabindex=\"0\">\n\n <!-- Loading State -->\n @if (IsLoading && ShowLoading) {\n <div class=\"tree-loading\">\n <div class=\"tree-loading__spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n <span class=\"tree-loading__text\">Loading...</span>\n </div>\n }\n\n <!-- Error State -->\n @if (ErrorMessage && !IsLoading) {\n <div class=\"tree-error\">\n <i class=\"fa-solid fa-exclamation-triangle tree-error__icon\"></i>\n <span class=\"tree-error__message\">{{ ErrorMessage }}</span>\n <button class=\"tree-error__retry\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Retry\n </button>\n </div>\n }\n\n <!-- Toolbar -->\n @if (ShowExpandCollapseAll && Nodes.length > 0 && !IsLoading) {\n <div class=\"tree-toolbar\">\n <button\n class=\"tree-toolbar__btn\"\n (click)=\"ExpandAll()\"\n title=\"Expand All\">\n <i class=\"fa-solid fa-plus-square\"></i>\n </button>\n <button\n class=\"tree-toolbar__btn\"\n (click)=\"CollapseAll()\"\n title=\"Collapse All\">\n <i class=\"fa-solid fa-minus-square\"></i>\n </button>\n </div>\n }\n\n <!-- Empty State -->\n @if (IsLoaded && Nodes.length === 0 && !ErrorMessage && !IsLoading) {\n <div class=\"tree-empty\">\n <i [class]=\"EmptyIcon + ' tree-empty__icon'\"></i>\n <span class=\"tree-empty__message\">{{ EmptyMessage }}</span>\n </div>\n }\n\n <!-- Tree Content -->\n @if (Nodes.length > 0 && !IsLoading) {\n <div class=\"tree-content\">\n @for (node of Nodes; track trackNode($index, node)) {\n @if (node.Visible) {\n <ng-container *ngTemplateOutlet=\"nodeTemplate; context: { node: node }\"></ng-container>\n }\n }\n </div>\n }\n</div>\n\n<!-- Recursive Node Template -->\n<ng-template #nodeTemplate let-node=\"node\">\n <div\n [ngClass]=\"getNodeClasses(node)\"\n [style.padding-left]=\"getNodePadding(node)\"\n [attr.data-node-id]=\"node.ID\"\n [attr.data-node-type]=\"node.Type\"\n [attr.aria-expanded]=\"node.Type === 'branch' ? node.Expanded : null\"\n [attr.aria-selected]=\"node.Selected\"\n role=\"treeitem\"\n (click)=\"onNodeClick(node, $event)\"\n (dblclick)=\"onNodeDoubleClick(node, $event)\">\n\n <!-- Toggle Button (for branches with children) -->\n @if (node.Type === 'branch') {\n <span\n class=\"tree-node-toggle\"\n (click)=\"onToggleClick(node, $event)\">\n @if (node.Children.length > 0) {\n <i\n class=\"fa-solid tree-node-toggle__icon\"\n [ngClass]=\"{\n 'fa-chevron-right': !node.Expanded,\n 'fa-chevron-down': node.Expanded\n }\">\n </i>\n }\n @if (node.Children.length === 0) {\n <span\n class=\"tree-node-toggle__spacer\">\n </span>\n }\n </span>\n }\n\n <!-- Leaf Spacer (to align with branches, only when not at root level) -->\n @if (node.Type === 'leaf' && node.Level > 0) {\n <span\n class=\"tree-node-leaf-spacer\"\n >\n </span>\n }\n\n <!-- Icon -->\n @if (ShowIcons) {\n <span\n class=\"tree-node-icon\"\n [style.color]=\"node.Color || null\">\n <i [class]=\"node.Icon\"></i>\n </span>\n }\n\n <!-- Content -->\n <span class=\"tree-node-content\">\n <!-- Label with search highlight -->\n <span class=\"tree-node-label\" [innerHTML]=\"getHighlightedLabel(node)\"></span>\n\n <!-- Description -->\n @if (ShowDescriptions && node.Description) {\n <span\n class=\"tree-node-description\"\n >\n {{ node.Description }}\n </span>\n }\n </span>\n\n <!-- Badge -->\n @if (ShowBadges && node.Badge) {\n <span\n class=\"tree-node-badge\"\n >\n {{ node.Badge }}\n </span>\n }\n\n <!-- Selection Indicator -->\n @if (node.Selected) {\n <span class=\"tree-node-selected-indicator\">\n <i class=\"fa-solid fa-check\"></i>\n </span>\n }\n </div>\n\n <!-- Children (if expanded) -->\n @if (node.Type === 'branch' && node.Expanded && node.Children.length > 0) {\n <div\n class=\"tree-node-children\"\n [class.tree-node-children--animated]=\"AnimateExpandCollapse\"\n role=\"group\">\n @for (child of node.Children; track trackNode($index, child)) {\n @if (child.Visible) {\n <ng-container *ngTemplateOutlet=\"nodeTemplate; context: { node: child }\"></ng-container>\n }\n }\n </div>\n }\n</ng-template>\n", styles: ["/**\n * Tree Component Styles\n *\n * Uses CSS custom properties for easy theming.\n * Containers can override these variables to customize appearance.\n */\n\n/* ========================================\n CSS Variables (Theming)\n ======================================== */\n\n:host {\n /* Colors */\n --tree-bg: #ffffff;\n --tree-border-color: #e0e0e0;\n --tree-text-color: #333333;\n --tree-text-secondary: #666666;\n --tree-text-muted: #999999;\n\n /* Node Colors */\n --tree-node-hover-bg: #f5f7fa;\n --tree-node-selected-bg: #e3f2fd;\n --tree-node-selected-border: #2196f3;\n --tree-node-focused-outline: rgba(33, 150, 243, 0.5);\n --tree-node-match-bg: #fff3cd;\n\n /* Icon Colors */\n --tree-icon-color: #5c6bc0;\n --tree-icon-leaf-color: #78909c;\n --tree-toggle-color: #9e9e9e;\n\n /* Spacing */\n --tree-node-padding-y: 8px;\n --tree-node-padding-x: 12px;\n --tree-node-gap: 8px;\n --tree-icon-size: 16px;\n --tree-toggle-size: 12px;\n\n /* Animation */\n --tree-transition-duration: 150ms;\n --tree-animation-easing: ease-out;\n\n /* Badge */\n --tree-badge-bg: #e0e0e0;\n --tree-badge-color: #666666;\n --tree-badge-size: 12px;\n\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ========================================\n Container\n ======================================== */\n\n.tree-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: var(--tree-bg);\n border-radius: 8px;\n overflow: hidden;\n outline: none;\n}\n\n.tree-container:focus-visible {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n/* ========================================\n Loading State\n ======================================== */\n\n.tree-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-loading__spinner {\n font-size: 24px;\n color: var(--tree-icon-color);\n}\n\n.tree-loading__text {\n font-size: 14px;\n}\n\n/* ========================================\n Error State\n ======================================== */\n\n.tree-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n text-align: center;\n}\n\n.tree-error__icon {\n font-size: 32px;\n color: #f44336;\n}\n\n.tree-error__message {\n font-size: 14px;\n color: var(--tree-text-secondary);\n max-width: 280px;\n}\n\n.tree-error__retry {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--tree-border-color);\n border-radius: 6px;\n background: var(--tree-bg);\n color: var(--tree-text-color);\n font-size: 13px;\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-error__retry:hover {\n background: var(--tree-node-hover-bg);\n border-color: var(--tree-icon-color);\n color: var(--tree-icon-color);\n}\n\n/* ========================================\n Empty State\n ======================================== */\n\n.tree-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-empty__icon {\n font-size: 40px;\n opacity: 0.5;\n}\n\n.tree-empty__message {\n font-size: 14px;\n}\n\n/* ========================================\n Toolbar\n ======================================== */\n\n.tree-toolbar {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--tree-border-color);\n background: var(--tree-node-hover-bg);\n}\n\n.tree-toolbar__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--tree-text-secondary);\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-toolbar__btn:hover {\n background: var(--tree-bg);\n color: var(--tree-icon-color);\n}\n\n/* ========================================\n Tree Content\n ======================================== */\n\n.tree-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 4px 0;\n}\n\n/* ========================================\n Tree Node\n ======================================== */\n\n.tree-node {\n display: flex;\n align-items: center;\n gap: var(--tree-node-gap);\n padding: var(--tree-node-padding-y) var(--tree-node-padding-x);\n cursor: pointer;\n user-select: none;\n border-left: 3px solid transparent;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n min-height: 36px;\n}\n\n.tree-node:hover {\n background: var(--tree-node-hover-bg);\n}\n\n.tree-node--selected {\n background: var(--tree-node-selected-bg);\n border-left-color: var(--tree-node-selected-border);\n}\n\n.tree-node--selected:hover {\n background: var(--tree-node-selected-bg);\n}\n\n.tree-node--focused {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n/* Search highlight for matching text portion */\n.tree-search-highlight {\n background: var(--tree-node-match-bg);\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: 500;\n}\n\n/* ========================================\n Toggle Button\n ======================================== */\n\n.tree-node-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n border-radius: 4px;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node-toggle:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.tree-node-toggle__icon {\n font-size: var(--tree-toggle-size);\n color: var(--tree-toggle-color);\n transition: transform var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node--expanded .tree-node-toggle__icon {\n color: var(--tree-icon-color);\n}\n\n.tree-node-toggle__spacer {\n width: var(--tree-toggle-size);\n}\n\n.tree-node-leaf-spacer {\n width: 20px;\n flex-shrink: 0;\n}\n\n/* ========================================\n Node Icon\n ======================================== */\n\n.tree-node-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--tree-icon-size);\n flex-shrink: 0;\n font-size: var(--tree-icon-size);\n color: var(--tree-icon-color);\n}\n\n.tree-node--leaf .tree-node-icon {\n color: var(--tree-icon-leaf-color);\n}\n\n/* ========================================\n Node Content\n ======================================== */\n\n.tree-node-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.tree-node-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--tree-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-node--leaf .tree-node-label {\n font-weight: 400;\n}\n\n.tree-node-description {\n font-size: 12px;\n color: var(--tree-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ========================================\n Node Badge\n ======================================== */\n\n.tree-node-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--tree-badge-bg);\n color: var(--tree-badge-color);\n font-size: var(--tree-badge-size);\n font-weight: 500;\n flex-shrink: 0;\n}\n\n/* ========================================\n Selection Indicator\n ======================================== */\n\n.tree-node-selected-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--tree-node-selected-border);\n color: white;\n font-size: 10px;\n flex-shrink: 0;\n}\n\n/* ========================================\n Children Container\n ======================================== */\n\n.tree-node-children {\n overflow: hidden;\n}\n\n.tree-node-children--animated {\n animation: tree-expand var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n@keyframes tree-expand {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* ========================================\n Scrollbar Styling\n ======================================== */\n\n.tree-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.tree-content::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.tree-content::-webkit-scrollbar-thumb {\n background: var(--tree-border-color);\n border-radius: 4px;\n}\n\n.tree-content::-webkit-scrollbar-thumb:hover {\n background: var(--tree-toggle-color);\n}\n\n/* ========================================\n Responsive Adjustments\n ======================================== */\n\n@media (max-width: 480px) {\n :host {\n --tree-node-padding-y: 10px;\n --tree-node-padding-x: 10px;\n --tree-icon-size: 18px;\n }\n\n .tree-node-label {\n font-size: 15px;\n }\n}\n"] }]
1613
+ args: [{ standalone: false, selector: 'mj-tree', template: "<!-- Tree Component Template -->\n<div [ngClass]=\"getContainerClasses()\" tabindex=\"0\">\n\n <!-- Loading State -->\n @if (IsLoading && ShowLoading) {\n <div class=\"tree-loading\">\n <div class=\"tree-loading__spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n <span class=\"tree-loading__text\">Loading...</span>\n </div>\n }\n\n <!-- Error State -->\n @if (ErrorMessage && !IsLoading) {\n <div class=\"tree-error\">\n <i class=\"fa-solid fa-exclamation-triangle tree-error__icon\"></i>\n <span class=\"tree-error__message\">{{ ErrorMessage }}</span>\n <button class=\"tree-error__retry\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Retry\n </button>\n </div>\n }\n\n <!-- Toolbar -->\n @if (ShowExpandCollapseAll && Nodes.length > 0 && !IsLoading) {\n <div class=\"tree-toolbar\">\n <button\n class=\"tree-toolbar__btn\"\n (click)=\"ExpandAll()\"\n title=\"Expand All\">\n <i class=\"fa-solid fa-plus-square\"></i>\n </button>\n <button\n class=\"tree-toolbar__btn\"\n (click)=\"CollapseAll()\"\n title=\"Collapse All\">\n <i class=\"fa-solid fa-minus-square\"></i>\n </button>\n </div>\n }\n\n <!-- Empty State -->\n @if (IsLoaded && Nodes.length === 0 && !ErrorMessage && !IsLoading) {\n <div class=\"tree-empty\">\n <i [class]=\"EmptyIcon + ' tree-empty__icon'\"></i>\n <span class=\"tree-empty__message\">{{ EmptyMessage }}</span>\n </div>\n }\n\n <!-- Tree Content -->\n @if (Nodes.length > 0 && !IsLoading) {\n <div class=\"tree-content\">\n @for (node of Nodes; track trackNode($index, node)) {\n @if (node.Visible) {\n <ng-container *ngTemplateOutlet=\"nodeTemplate; context: { node: node }\"></ng-container>\n }\n }\n </div>\n }\n</div>\n\n<!-- Recursive Node Template -->\n<ng-template #nodeTemplate let-node=\"node\">\n <div\n [ngClass]=\"getNodeClasses(node)\"\n [style.padding-left]=\"getNodePadding(node)\"\n [attr.data-node-id]=\"node.ID\"\n [attr.data-node-type]=\"node.Type\"\n [attr.aria-expanded]=\"node.Type === 'branch' ? node.Expanded : null\"\n [attr.aria-selected]=\"node.Selected\"\n role=\"treeitem\"\n (click)=\"onNodeClick(node, $event)\"\n (dblclick)=\"onNodeDoubleClick(node, $event)\">\n\n <!-- Toggle Button (for branches with children) -->\n @if (node.Type === 'branch') {\n <span\n class=\"tree-node-toggle\"\n (click)=\"onToggleClick(node, $event)\">\n @if (node.Children.length > 0) {\n <i\n class=\"fa-solid tree-node-toggle__icon\"\n [ngClass]=\"{\n 'fa-chevron-right': !node.Expanded,\n 'fa-chevron-down': node.Expanded\n }\">\n </i>\n }\n @if (node.Children.length === 0) {\n <span\n class=\"tree-node-toggle__spacer\">\n </span>\n }\n </span>\n }\n\n <!-- Leaf Spacer (to align with branches, only when not at root level) -->\n @if (node.Type === 'leaf' && node.Level > 0) {\n <span\n class=\"tree-node-leaf-spacer\"\n >\n </span>\n }\n\n <!-- Icon -->\n @if (ShowIcons) {\n <span\n class=\"tree-node-icon\"\n [style.color]=\"node.Color || null\">\n <i [class]=\"node.Icon\"></i>\n </span>\n }\n\n <!-- Content -->\n <span class=\"tree-node-content\">\n <!-- Label with search highlight -->\n <span class=\"tree-node-label\" [innerHTML]=\"getHighlightedLabel(node)\"></span>\n\n <!-- Description -->\n @if (ShowDescriptions && node.Description) {\n <span\n class=\"tree-node-description\"\n >\n {{ node.Description }}\n </span>\n }\n </span>\n\n <!-- Badge -->\n @if (ShowBadges && node.Badge) {\n <span\n class=\"tree-node-badge\"\n >\n {{ node.Badge }}\n </span>\n }\n\n <!-- Selection Indicator -->\n @if (node.Selected) {\n <span class=\"tree-node-selected-indicator\">\n <i class=\"fa-solid fa-check\"></i>\n </span>\n }\n </div>\n\n <!-- Children (if expanded) -->\n @if (node.Type === 'branch' && node.Expanded && node.Children.length > 0) {\n <div\n class=\"tree-node-children\"\n [class.tree-node-children--animated]=\"AnimateExpandCollapse\"\n role=\"group\">\n @for (child of node.Children; track trackNode($index, child)) {\n @if (child.Visible) {\n <ng-container *ngTemplateOutlet=\"nodeTemplate; context: { node: child }\"></ng-container>\n }\n }\n </div>\n }\n</ng-template>\n", styles: ["/**\n * Tree Component Styles\n *\n * Uses CSS custom properties for easy theming.\n * Containers can override these variables to customize appearance.\n */\n\n/* ========================================\n CSS Variables (Theming)\n ======================================== */\n\n:host {\n /* Colors */\n --tree-bg: var(--mj-bg-surface);\n --tree-border-color: var(--mj-border-default);\n --tree-text-color: var(--mj-text-primary);\n --tree-text-secondary: var(--mj-text-muted);\n --tree-text-muted: var(--mj-text-disabled);\n\n /* Node Colors */\n --tree-node-hover-bg: var(--mj-bg-surface-sunken);\n --tree-node-selected-bg: var(--mj-brand-primary-subtle);\n --tree-node-selected-border: var(--mj-brand-primary);\n --tree-node-focused-outline: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n --tree-node-match-bg: var(--mj-status-warning-subtle);\n\n /* Icon Colors */\n --tree-icon-color: var(--mj-brand-primary);\n --tree-icon-leaf-color: var(--mj-text-muted);\n --tree-toggle-color: var(--mj-text-disabled);\n\n /* Spacing */\n --tree-node-padding-y: 8px;\n --tree-node-padding-x: 12px;\n --tree-node-gap: 8px;\n --tree-icon-size: 16px;\n --tree-toggle-size: 12px;\n\n /* Animation */\n --tree-transition-duration: 150ms;\n --tree-animation-easing: ease-out;\n\n /* Badge */\n --tree-badge-bg: var(--mj-border-default);\n --tree-badge-color: var(--mj-text-muted);\n --tree-badge-size: 12px;\n\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ========================================\n Container\n ======================================== */\n\n.tree-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: var(--tree-bg);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n}\n\n.tree-container:focus-visible {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n/* ========================================\n Loading State\n ======================================== */\n\n.tree-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-loading__spinner {\n font-size: var(--mj-text-2xl);\n color: var(--tree-icon-color);\n}\n\n.tree-loading__text {\n font-size: var(--mj-text-sm);\n}\n\n/* ========================================\n Error State\n ======================================== */\n\n.tree-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px 16px;\n gap: 12px;\n text-align: center;\n}\n\n.tree-error__icon {\n font-size: 32px;\n color: var(--mj-status-error);\n}\n\n.tree-error__message {\n font-size: var(--mj-text-sm);\n color: var(--tree-text-secondary);\n max-width: 280px;\n}\n\n.tree-error__retry {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--tree-border-color);\n border-radius: var(--mj-radius-md);\n background: var(--tree-bg);\n color: var(--tree-text-color);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-error__retry:hover {\n background: var(--tree-node-hover-bg);\n border-color: var(--tree-icon-color);\n color: var(--tree-icon-color);\n}\n\n/* ========================================\n Empty State\n ======================================== */\n\n.tree-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 16px;\n gap: 12px;\n color: var(--tree-text-muted);\n}\n\n.tree-empty__icon {\n font-size: 40px;\n opacity: 0.5;\n}\n\n.tree-empty__message {\n font-size: var(--mj-text-sm);\n}\n\n/* ========================================\n Toolbar\n ======================================== */\n\n.tree-toolbar {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--tree-border-color);\n background: var(--tree-node-hover-bg);\n}\n\n.tree-toolbar__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: var(--mj-radius-sm);\n background: transparent;\n color: var(--tree-text-secondary);\n cursor: pointer;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-toolbar__btn:hover {\n background: var(--tree-bg);\n color: var(--tree-icon-color);\n}\n\n/* ========================================\n Tree Content\n ======================================== */\n\n.tree-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 4px 0;\n}\n\n/* ========================================\n Tree Node\n ======================================== */\n\n.tree-node {\n display: flex;\n align-items: center;\n gap: var(--tree-node-gap);\n padding: var(--tree-node-padding-y) var(--tree-node-padding-x);\n cursor: pointer;\n user-select: none;\n border-left: 3px solid transparent;\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n min-height: 36px;\n}\n\n.tree-node:hover {\n background: var(--tree-node-hover-bg);\n}\n\n.tree-node--selected {\n background: var(--tree-node-selected-bg);\n border-left-color: var(--tree-node-selected-border);\n}\n\n.tree-node--selected:hover {\n background: var(--tree-node-selected-bg);\n}\n\n.tree-node--focused {\n outline: 2px solid var(--tree-node-focused-outline);\n outline-offset: -2px;\n}\n\n/* Search highlight for matching text portion */\n.tree-search-highlight {\n background: var(--tree-node-match-bg);\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: 500;\n}\n\n/* ========================================\n Toggle Button\n ======================================== */\n\n.tree-node-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n border-radius: var(--mj-radius-sm);\n transition: all var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node-toggle:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.tree-node-toggle__icon {\n font-size: var(--tree-toggle-size);\n color: var(--tree-toggle-color);\n transition: transform var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n.tree-node--expanded .tree-node-toggle__icon {\n color: var(--tree-icon-color);\n}\n\n.tree-node-toggle__spacer {\n width: var(--tree-toggle-size);\n}\n\n.tree-node-leaf-spacer {\n width: 20px;\n flex-shrink: 0;\n}\n\n/* ========================================\n Node Icon\n ======================================== */\n\n.tree-node-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--tree-icon-size);\n flex-shrink: 0;\n font-size: var(--tree-icon-size);\n color: var(--tree-icon-color);\n}\n\n.tree-node--leaf .tree-node-icon {\n color: var(--tree-icon-leaf-color);\n}\n\n/* ========================================\n Node Content\n ======================================== */\n\n.tree-node-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.tree-node-label {\n font-size: var(--mj-text-sm);\n font-weight: 500;\n color: var(--tree-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-node--leaf .tree-node-label {\n font-weight: 400;\n}\n\n.tree-node-description {\n font-size: var(--mj-text-xs);\n color: var(--tree-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ========================================\n Node Badge\n ======================================== */\n\n.tree-node-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--tree-badge-bg);\n color: var(--tree-badge-color);\n font-size: var(--tree-badge-size);\n font-weight: 500;\n flex-shrink: 0;\n}\n\n/* ========================================\n Selection Indicator\n ======================================== */\n\n.tree-node-selected-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: var(--mj-radius-full);\n background: var(--tree-node-selected-border);\n color: var(--mj-text-inverse);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n/* ========================================\n Children Container\n ======================================== */\n\n.tree-node-children {\n overflow: hidden;\n}\n\n.tree-node-children--animated {\n animation: tree-expand var(--tree-transition-duration) var(--tree-animation-easing);\n}\n\n@keyframes tree-expand {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* ========================================\n Scrollbar Styling\n ======================================== */\n\n.tree-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.tree-content::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.tree-content::-webkit-scrollbar-thumb {\n background: var(--tree-border-color);\n border-radius: var(--mj-radius-sm);\n}\n\n.tree-content::-webkit-scrollbar-thumb:hover {\n background: var(--tree-toggle-color);\n}\n\n/* ========================================\n Responsive Adjustments\n ======================================== */\n\n@media (max-width: 480px) {\n :host {\n --tree-node-padding-y: 10px;\n --tree-node-padding-x: 10px;\n --tree-icon-size: 18px;\n }\n\n .tree-node-label {\n font-size: var(--mj-text-base);\n }\n}\n"] }]
1614
1614
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], { BranchConfig: [{
1615
1615
  type: Input
1616
1616
  }], LeafConfig: [{
@@ -933,11 +933,11 @@ export class TreeDropdownComponent {
933
933
  i0.ɵɵproperty("ngClass", ctx.IsOpen ? "fa-chevron-up" : "fa-chevron-down");
934
934
  i0.ɵɵadvance();
935
935
  i0.ɵɵconditional(ctx.IsOpen ? 12 : -1);
936
- } }, dependencies: [i1.NgClass, i1.NgStyle, i2.TreeComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --dropdown-bg: #ffffff;\n --dropdown-border-color: #d0d0d0;\n --dropdown-border-hover: #999999;\n --dropdown-border-focus: #2196f3;\n --dropdown-text-color: #333333;\n --dropdown-text-placeholder: #999999;\n --dropdown-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n\n \n\n --dropdown-trigger-bg: #ffffff;\n --dropdown-trigger-height: 40px;\n --dropdown-trigger-padding: 8px 12px;\n --dropdown-trigger-radius: 8px;\n\n \n\n --dropdown-search-bg: #f5f5f5;\n --dropdown-search-height: 36px;\n\n \n\n --dropdown-animation-duration: 150ms;\n --dropdown-animation-easing: ease-out;\n\n display: block;\n position: relative;\n width: 100%;\n}\n\n\n\n\n\n\n.tree-dropdown[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n.tree-dropdown--disabled[_ngcontent-%COMP%] {\n opacity: 0.6;\n pointer-events: none;\n}\n\n\n\n\n\n\n.tree-dropdown-trigger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-height: var(--dropdown-trigger-height);\n padding: var(--dropdown-trigger-padding);\n background: var(--dropdown-trigger-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: var(--dropdown-trigger-radius);\n cursor: pointer;\n outline: none;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger[_ngcontent-%COMP%]:hover {\n border-color: var(--dropdown-border-hover);\n}\n\n.tree-dropdown-trigger[_ngcontent-%COMP%]:focus, \n.tree-dropdown-trigger--open[_ngcontent-%COMP%] {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.15);\n}\n\n.tree-dropdown-trigger--disabled[_ngcontent-%COMP%] {\n cursor: not-allowed;\n background: #f5f5f5;\n}\n\n.tree-dropdown-trigger__content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n overflow: hidden;\n}\n\n.tree-dropdown-trigger__icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: var(--dropdown-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-dropdown-trigger__text--placeholder[_ngcontent-%COMP%] {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-trigger__loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n color: var(--dropdown-border-focus);\n font-size: 12px;\n}\n\n.tree-dropdown-trigger__actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__clear[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: #e0e0e0;\n color: #666;\n cursor: pointer;\n font-size: 10px;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger__clear[_ngcontent-%COMP%]:hover {\n background: #d0d0d0;\n color: #333;\n}\n\n.tree-dropdown-trigger__chevron[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n color: var(--dropdown-text-placeholder);\n font-size: 12px;\n transition: transform var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger--open[_ngcontent-%COMP%] .tree-dropdown-trigger__chevron[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n\n\n\n.tree-dropdown-panel[_ngcontent-%COMP%] {\n position: fixed;\n z-index: 10000;\n display: flex;\n flex-direction: column;\n background: var(--dropdown-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: 8px;\n box-shadow: var(--dropdown-shadow);\n overflow: hidden;\n animation: _ngcontent-%COMP%_dropdown-open var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n \n\n box-sizing: border-box;\n}\n\n.tree-dropdown-panel--above[_ngcontent-%COMP%] {\n transform-origin: bottom center;\n}\n\n.tree-dropdown-panel--below[_ngcontent-%COMP%] {\n transform-origin: top center;\n}\n\n@keyframes _ngcontent-%COMP%_dropdown-open {\n from {\n opacity: 0;\n transform: scaleY(0.95);\n }\n to {\n opacity: 1;\n transform: scaleY(1);\n }\n}\n\n\n\n\n\n\n.tree-dropdown-search[_ngcontent-%COMP%] {\n padding: 8px;\n border-bottom: 1px solid #e8e8e8;\n background: var(--dropdown-search-bg);\n}\n\n.tree-dropdown-search__input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n height: var(--dropdown-search-height);\n padding: 0 10px;\n background: var(--dropdown-bg);\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.1);\n}\n\n.tree-dropdown-search__icon[_ngcontent-%COMP%] {\n color: #999;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-search__input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n color: var(--dropdown-text-color);\n outline: none;\n min-width: 0;\n}\n\n.tree-dropdown-search__input[_ngcontent-%COMP%]::placeholder {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-search__clear[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: #e0e0e0;\n color: #666;\n cursor: pointer;\n font-size: 9px;\n flex-shrink: 0;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__clear[_ngcontent-%COMP%]:hover {\n background: #d0d0d0;\n color: #333;\n}\n\n\n\n\n\n\n.tree-dropdown-tree[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n min-height: 0;\n max-height: 100%;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] mj-tree[_ngcontent-%COMP%] {\n display: block;\n height: auto;\n max-height: 100%;\n}\n\n\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-container {\n border-radius: 0;\n height: auto;\n max-height: none;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-content {\n padding: 4px 0;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-node {\n padding: 6px 12px;\n min-height: 32px;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-empty {\n padding: 24px 16px;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-loading {\n padding: 24px 16px;\n}\n\n\n\n\n\n\n[_nghost-%COMP%] .mj-tree-dropdown-portal {\n pointer-events: none;\n}\n\n[_nghost-%COMP%] .mj-tree-dropdown-portal > * {\n pointer-events: auto;\n}\n\n\n\n\n\n\n.tree-dropdown-pills[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n padding: 4px;\n}\n\n.tree-dropdown-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: #e3f2fd;\n border-radius: 12px;\n font-size: 12px;\n color: #1976d2;\n}\n\n.tree-dropdown-pill__remove[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: #1976d2;\n cursor: pointer;\n font-size: 8px;\n transition: background var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-pill__remove[_ngcontent-%COMP%]:hover {\n background: rgba(25, 118, 210, 0.2);\n}\n\n\n\n\n\n\n@media (max-width: 480px) {\n [_nghost-%COMP%] {\n --dropdown-trigger-height: 44px;\n }\n\n .tree-dropdown-trigger__text[_ngcontent-%COMP%] {\n font-size: 15px;\n }\n\n .tree-dropdown-search__input[_ngcontent-%COMP%] {\n font-size: 16px; \n\n }\n}"] });
936
+ } }, dependencies: [i1.NgClass, i1.NgStyle, i2.TreeComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --dropdown-bg: var(--mj-bg-surface);\n --dropdown-border-color: var(--mj-border-strong);\n --dropdown-border-hover: var(--mj-text-disabled);\n --dropdown-border-focus: var(--mj-brand-primary);\n --dropdown-text-color: var(--mj-text-primary);\n --dropdown-text-placeholder: var(--mj-text-disabled);\n --dropdown-shadow: var(--mj-shadow-lg);\n\n \n\n --dropdown-trigger-bg: var(--mj-bg-surface);\n --dropdown-trigger-height: 40px;\n --dropdown-trigger-padding: 8px 12px;\n --dropdown-trigger-radius: var(--mj-radius-md);\n\n \n\n --dropdown-search-bg: var(--mj-bg-surface-card);\n --dropdown-search-height: 36px;\n\n \n\n --dropdown-animation-duration: 150ms;\n --dropdown-animation-easing: ease-out;\n\n display: block;\n position: relative;\n width: 100%;\n}\n\n\n\n\n\n\n.tree-dropdown[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n.tree-dropdown--disabled[_ngcontent-%COMP%] {\n opacity: 0.6;\n pointer-events: none;\n}\n\n\n\n\n\n\n.tree-dropdown-trigger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-height: var(--dropdown-trigger-height);\n padding: var(--dropdown-trigger-padding);\n background: var(--dropdown-trigger-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: var(--dropdown-trigger-radius);\n cursor: pointer;\n outline: none;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger[_ngcontent-%COMP%]:hover {\n border-color: var(--dropdown-border-hover);\n}\n\n.tree-dropdown-trigger[_ngcontent-%COMP%]:focus, \n.tree-dropdown-trigger--open[_ngcontent-%COMP%] {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tree-dropdown-trigger--disabled[_ngcontent-%COMP%] {\n cursor: not-allowed;\n background: var(--mj-bg-surface-card);\n}\n\n.tree-dropdown-trigger__content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n overflow: hidden;\n}\n\n.tree-dropdown-trigger__icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: var(--mj-text-sm);\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: var(--mj-text-sm);\n color: var(--dropdown-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-dropdown-trigger__text--placeholder[_ngcontent-%COMP%] {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-trigger__loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n color: var(--dropdown-border-focus);\n font-size: var(--mj-text-xs);\n}\n\n.tree-dropdown-trigger__actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__clear[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 10px;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger__clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.tree-dropdown-trigger__chevron[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n color: var(--dropdown-text-placeholder);\n font-size: var(--mj-text-xs);\n transition: transform var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger--open[_ngcontent-%COMP%] .tree-dropdown-trigger__chevron[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n\n\n\n.tree-dropdown-panel[_ngcontent-%COMP%] {\n position: fixed;\n z-index: 10000;\n display: flex;\n flex-direction: column;\n background: var(--dropdown-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--dropdown-shadow);\n overflow: hidden;\n animation: _ngcontent-%COMP%_dropdown-open var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n \n\n box-sizing: border-box;\n}\n\n.tree-dropdown-panel--above[_ngcontent-%COMP%] {\n transform-origin: bottom center;\n}\n\n.tree-dropdown-panel--below[_ngcontent-%COMP%] {\n transform-origin: top center;\n}\n\n@keyframes _ngcontent-%COMP%_dropdown-open {\n from {\n opacity: 0;\n transform: scaleY(0.95);\n }\n to {\n opacity: 1;\n transform: scaleY(1);\n }\n}\n\n\n\n\n\n\n.tree-dropdown-search[_ngcontent-%COMP%] {\n padding: 8px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--dropdown-search-bg);\n}\n\n.tree-dropdown-search__input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n height: var(--dropdown-search-height);\n padding: 0 10px;\n background: var(--dropdown-bg);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tree-dropdown-search__icon[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: var(--mj-text-xs);\n flex-shrink: 0;\n}\n\n.tree-dropdown-search__input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n font-size: var(--mj-text-sm);\n color: var(--dropdown-text-color);\n outline: none;\n min-width: 0;\n}\n\n.tree-dropdown-search__input[_ngcontent-%COMP%]::placeholder {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-search__clear[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 9px;\n flex-shrink: 0;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n\n.tree-dropdown-tree[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n min-height: 0;\n max-height: 100%;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] mj-tree[_ngcontent-%COMP%] {\n display: block;\n height: auto;\n max-height: 100%;\n}\n\n\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-container {\n border-radius: 0;\n height: auto;\n max-height: none;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-content {\n padding: 4px 0;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-node {\n padding: 6px 12px;\n min-height: 32px;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-empty {\n padding: 24px 16px;\n}\n\n.tree-dropdown-tree[_ngcontent-%COMP%] .tree-loading {\n padding: 24px 16px;\n}\n\n\n\n\n\n\n[_nghost-%COMP%] .mj-tree-dropdown-portal {\n pointer-events: none;\n}\n\n[_nghost-%COMP%] .mj-tree-dropdown-portal > * {\n pointer-events: auto;\n}\n\n\n\n\n\n\n.tree-dropdown-pills[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n padding: 4px;\n}\n\n.tree-dropdown-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--mj-brand-primary-subtle);\n border-radius: var(--mj-radius-lg);\n font-size: var(--mj-text-xs);\n color: var(--mj-brand-primary);\n}\n\n.tree-dropdown-pill__remove[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 8px;\n transition: background var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-pill__remove[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n\n\n\n\n\n@media (max-width: 480px) {\n [_nghost-%COMP%] {\n --dropdown-trigger-height: 44px;\n }\n\n .tree-dropdown-trigger__text[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n }\n\n .tree-dropdown-search__input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base); \n\n }\n}"] });
937
937
  }
938
938
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TreeDropdownComponent, [{
939
939
  type: Component,
940
- args: [{ standalone: false, selector: 'mj-tree-dropdown', template: "<!-- Tree Dropdown Component Template -->\n<div class=\"tree-dropdown\" [class.tree-dropdown--disabled]=\"Disabled\">\n\n <!-- Trigger Button -->\n <div\n #triggerElement\n [ngClass]=\"getTriggerClasses()\"\n [class]=\"StyleConfig.SearchInputClass || ''\"\n tabindex=\"0\"\n role=\"combobox\"\n [attr.aria-expanded]=\"IsOpen\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-disabled]=\"Disabled\"\n (click)=\"onTriggerClick()\"\n (keydown)=\"onTriggerKeyDown($event)\">\n\n <!-- Selected Value Display -->\n <div class=\"tree-dropdown-trigger__content\">\n <!-- Icon -->\n @if (getDisplayIcon()) {\n <span\n class=\"tree-dropdown-trigger__icon\"\n [style.color]=\"getDisplayColor()\">\n <i [class]=\"getDisplayIcon()\"></i>\n </span>\n }\n\n <!-- Text -->\n <span\n class=\"tree-dropdown-trigger__text\"\n [class.tree-dropdown-trigger__text--placeholder]=\"!hasSelection()\">\n {{ hasSelection() ? getDisplayText() : Placeholder }}\n </span>\n\n <!-- Loading Spinner -->\n @if (IsLoading && ShowLoadingInTrigger) {\n <span class=\"tree-dropdown-trigger__loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </span>\n }\n </div>\n\n <!-- Actions -->\n <div class=\"tree-dropdown-trigger__actions\">\n <!-- Clear Button -->\n @if (Clearable && hasSelection() && !Disabled) {\n <button\n type=\"button\"\n class=\"tree-dropdown-trigger__clear\"\n (click)=\"Clear($event)\"\n title=\"Clear selection\"\n tabindex=\"-1\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n\n <!-- Chevron -->\n <span class=\"tree-dropdown-trigger__chevron\">\n <i\n class=\"fa-solid\"\n [ngClass]=\"IsOpen ? 'fa-chevron-up' : 'fa-chevron-down'\">\n </i>\n </span>\n </div>\n </div>\n\n <!-- Dropdown Panel (rendered in place, will be moved to portal when open) -->\n @if (IsOpen) {\n <div\n #dropdownPanel\n class=\"tree-dropdown-panel\"\n [class.tree-dropdown-panel--open]=\"IsOpen\"\n [class.tree-dropdown-panel--above]=\"Position?.renderAbove\"\n [class.tree-dropdown-panel--below]=\"!Position?.renderAbove\"\n [class]=\"StyleConfig.DropdownClass || ''\"\n [ngStyle]=\"IsOpen ? getDropdownStyles() : {}\"\n role=\"tree\">\n <!-- Search Input -->\n @if (EnableSearch) {\n <div class=\"tree-dropdown-search\">\n <div class=\"tree-dropdown-search__input-wrapper\">\n <i class=\"fa-solid fa-search tree-dropdown-search__icon\"></i>\n <input\n #searchInput\n type=\"text\"\n class=\"tree-dropdown-search__input\"\n [placeholder]=\"SearchConfig.Placeholder || 'Type to search...'\"\n [value]=\"SearchText\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeyDown($event)\"\n autocomplete=\"off\"\n spellcheck=\"false\">\n @if (SearchText) {\n <button\n type=\"button\"\n class=\"tree-dropdown-search__clear\"\n (click)=\"onClearSearch()\"\n tabindex=\"-1\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n <!-- Tree -->\n <div class=\"tree-dropdown-tree\">\n <mj-tree\n #treeComponent\n [BranchConfig]=\"BranchConfig\"\n [LeafConfig]=\"LeafConfig\"\n [SelectionMode]=\"SelectionMode\"\n [SelectableTypes]=\"SelectableTypes\"\n [SelectedIDs]=\"getSelectedIDsArray()\"\n [AutoLoad]=\"AutoLoad\"\n [ShowIcons]=\"true\"\n [ShowExpandCollapseAll]=\"false\"\n [AnimateExpandCollapse]=\"true\"\n [EmptyMessage]=\"SearchText ? 'No matches found' : 'No items available'\"\n [EmptyIcon]=\"SearchText ? 'fa-solid fa-search' : 'fa-solid fa-folder-open'\"\n (SelectionChange)=\"onTreeSelectionChange($event)\"\n (BeforeNodeSelect)=\"onTreeBeforeNodeSelect($event)\"\n (AfterNodeSelect)=\"onTreeAfterNodeSelect($event)\"\n (BeforeDataLoad)=\"onTreeBeforeDataLoad($event)\"\n (AfterDataLoad)=\"onTreeAfterDataLoad($event)\">\n </mj-tree>\n </div>\n </div>\n }\n</div>\n", styles: ["/**\n * Tree Dropdown Component Styles\n *\n * Uses CSS custom properties for easy theming.\n * Containers can override these variables to customize appearance.\n */\n\n/* ========================================\n CSS Variables (Theming)\n ======================================== */\n\n:host {\n /* Colors */\n --dropdown-bg: #ffffff;\n --dropdown-border-color: #d0d0d0;\n --dropdown-border-hover: #999999;\n --dropdown-border-focus: #2196f3;\n --dropdown-text-color: #333333;\n --dropdown-text-placeholder: #999999;\n --dropdown-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n\n /* Trigger */\n --dropdown-trigger-bg: #ffffff;\n --dropdown-trigger-height: 40px;\n --dropdown-trigger-padding: 8px 12px;\n --dropdown-trigger-radius: 8px;\n\n /* Search */\n --dropdown-search-bg: #f5f5f5;\n --dropdown-search-height: 36px;\n\n /* Animation */\n --dropdown-animation-duration: 150ms;\n --dropdown-animation-easing: ease-out;\n\n display: block;\n position: relative;\n width: 100%;\n}\n\n/* ========================================\n Container\n ======================================== */\n\n.tree-dropdown {\n position: relative;\n width: 100%;\n}\n\n.tree-dropdown--disabled {\n opacity: 0.6;\n pointer-events: none;\n}\n\n/* ========================================\n Trigger\n ======================================== */\n\n.tree-dropdown-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-height: var(--dropdown-trigger-height);\n padding: var(--dropdown-trigger-padding);\n background: var(--dropdown-trigger-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: var(--dropdown-trigger-radius);\n cursor: pointer;\n outline: none;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger:hover {\n border-color: var(--dropdown-border-hover);\n}\n\n.tree-dropdown-trigger:focus,\n.tree-dropdown-trigger--open {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.15);\n}\n\n.tree-dropdown-trigger--disabled {\n cursor: not-allowed;\n background: #f5f5f5;\n}\n\n.tree-dropdown-trigger__content {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n overflow: hidden;\n}\n\n.tree-dropdown-trigger__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__text {\n flex: 1;\n font-size: 14px;\n color: var(--dropdown-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-dropdown-trigger__text--placeholder {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-trigger__loading {\n display: flex;\n align-items: center;\n color: var(--dropdown-border-focus);\n font-size: 12px;\n}\n\n.tree-dropdown-trigger__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__clear {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: #e0e0e0;\n color: #666;\n cursor: pointer;\n font-size: 10px;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger__clear:hover {\n background: #d0d0d0;\n color: #333;\n}\n\n.tree-dropdown-trigger__chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n color: var(--dropdown-text-placeholder);\n font-size: 12px;\n transition: transform var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger--open .tree-dropdown-trigger__chevron {\n transform: rotate(180deg);\n}\n\n/* ========================================\n Dropdown Panel\n ======================================== */\n\n.tree-dropdown-panel {\n position: fixed;\n z-index: 10000;\n display: flex;\n flex-direction: column;\n background: var(--dropdown-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: 8px;\n box-shadow: var(--dropdown-shadow);\n overflow: hidden;\n animation: dropdown-open var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n /* Ensure the panel respects its maxHeight and allows child scrolling */\n box-sizing: border-box;\n}\n\n.tree-dropdown-panel--above {\n transform-origin: bottom center;\n}\n\n.tree-dropdown-panel--below {\n transform-origin: top center;\n}\n\n@keyframes dropdown-open {\n from {\n opacity: 0;\n transform: scaleY(0.95);\n }\n to {\n opacity: 1;\n transform: scaleY(1);\n }\n}\n\n/* ========================================\n Search\n ======================================== */\n\n.tree-dropdown-search {\n padding: 8px;\n border-bottom: 1px solid #e8e8e8;\n background: var(--dropdown-search-bg);\n}\n\n.tree-dropdown-search__input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n height: var(--dropdown-search-height);\n padding: 0 10px;\n background: var(--dropdown-bg);\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__input-wrapper:focus-within {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.1);\n}\n\n.tree-dropdown-search__icon {\n color: #999;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-search__input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n color: var(--dropdown-text-color);\n outline: none;\n min-width: 0;\n}\n\n.tree-dropdown-search__input::placeholder {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-search__clear {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: #e0e0e0;\n color: #666;\n cursor: pointer;\n font-size: 9px;\n flex-shrink: 0;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__clear:hover {\n background: #d0d0d0;\n color: #333;\n}\n\n/* ========================================\n Tree Container\n ======================================== */\n\n.tree-dropdown-tree {\n flex: 1;\n overflow: auto;\n min-height: 0;\n max-height: 100%;\n}\n\n.tree-dropdown-tree mj-tree {\n display: block;\n height: auto;\n max-height: 100%;\n}\n\n/* Override tree styles for dropdown context */\n.tree-dropdown-tree ::ng-deep .tree-container {\n border-radius: 0;\n height: auto;\n max-height: none;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-content {\n padding: 4px 0;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-node {\n padding: 6px 12px;\n min-height: 32px;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-empty {\n padding: 24px 16px;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-loading {\n padding: 24px 16px;\n}\n\n/* ========================================\n Portal Container (in body)\n ======================================== */\n\n:host ::ng-deep .mj-tree-dropdown-portal {\n pointer-events: none;\n}\n\n:host ::ng-deep .mj-tree-dropdown-portal > * {\n pointer-events: auto;\n}\n\n/* ========================================\n Multiple Selection Pills\n ======================================== */\n\n.tree-dropdown-pills {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n padding: 4px;\n}\n\n.tree-dropdown-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: #e3f2fd;\n border-radius: 12px;\n font-size: 12px;\n color: #1976d2;\n}\n\n.tree-dropdown-pill__remove {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: #1976d2;\n cursor: pointer;\n font-size: 8px;\n transition: background var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-pill__remove:hover {\n background: rgba(25, 118, 210, 0.2);\n}\n\n/* ========================================\n Responsive\n ======================================== */\n\n@media (max-width: 480px) {\n :host {\n --dropdown-trigger-height: 44px;\n }\n\n .tree-dropdown-trigger__text {\n font-size: 15px;\n }\n\n .tree-dropdown-search__input {\n font-size: 16px; /* Prevents zoom on iOS */\n }\n}\n"] }]
940
+ args: [{ standalone: false, selector: 'mj-tree-dropdown', template: "<!-- Tree Dropdown Component Template -->\n<div class=\"tree-dropdown\" [class.tree-dropdown--disabled]=\"Disabled\">\n\n <!-- Trigger Button -->\n <div\n #triggerElement\n [ngClass]=\"getTriggerClasses()\"\n [class]=\"StyleConfig.SearchInputClass || ''\"\n tabindex=\"0\"\n role=\"combobox\"\n [attr.aria-expanded]=\"IsOpen\"\n [attr.aria-haspopup]=\"'tree'\"\n [attr.aria-disabled]=\"Disabled\"\n (click)=\"onTriggerClick()\"\n (keydown)=\"onTriggerKeyDown($event)\">\n\n <!-- Selected Value Display -->\n <div class=\"tree-dropdown-trigger__content\">\n <!-- Icon -->\n @if (getDisplayIcon()) {\n <span\n class=\"tree-dropdown-trigger__icon\"\n [style.color]=\"getDisplayColor()\">\n <i [class]=\"getDisplayIcon()\"></i>\n </span>\n }\n\n <!-- Text -->\n <span\n class=\"tree-dropdown-trigger__text\"\n [class.tree-dropdown-trigger__text--placeholder]=\"!hasSelection()\">\n {{ hasSelection() ? getDisplayText() : Placeholder }}\n </span>\n\n <!-- Loading Spinner -->\n @if (IsLoading && ShowLoadingInTrigger) {\n <span class=\"tree-dropdown-trigger__loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </span>\n }\n </div>\n\n <!-- Actions -->\n <div class=\"tree-dropdown-trigger__actions\">\n <!-- Clear Button -->\n @if (Clearable && hasSelection() && !Disabled) {\n <button\n type=\"button\"\n class=\"tree-dropdown-trigger__clear\"\n (click)=\"Clear($event)\"\n title=\"Clear selection\"\n tabindex=\"-1\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n\n <!-- Chevron -->\n <span class=\"tree-dropdown-trigger__chevron\">\n <i\n class=\"fa-solid\"\n [ngClass]=\"IsOpen ? 'fa-chevron-up' : 'fa-chevron-down'\">\n </i>\n </span>\n </div>\n </div>\n\n <!-- Dropdown Panel (rendered in place, will be moved to portal when open) -->\n @if (IsOpen) {\n <div\n #dropdownPanel\n class=\"tree-dropdown-panel\"\n [class.tree-dropdown-panel--open]=\"IsOpen\"\n [class.tree-dropdown-panel--above]=\"Position?.renderAbove\"\n [class.tree-dropdown-panel--below]=\"!Position?.renderAbove\"\n [class]=\"StyleConfig.DropdownClass || ''\"\n [ngStyle]=\"IsOpen ? getDropdownStyles() : {}\"\n role=\"tree\">\n <!-- Search Input -->\n @if (EnableSearch) {\n <div class=\"tree-dropdown-search\">\n <div class=\"tree-dropdown-search__input-wrapper\">\n <i class=\"fa-solid fa-search tree-dropdown-search__icon\"></i>\n <input\n #searchInput\n type=\"text\"\n class=\"tree-dropdown-search__input\"\n [placeholder]=\"SearchConfig.Placeholder || 'Type to search...'\"\n [value]=\"SearchText\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeyDown($event)\"\n autocomplete=\"off\"\n spellcheck=\"false\">\n @if (SearchText) {\n <button\n type=\"button\"\n class=\"tree-dropdown-search__clear\"\n (click)=\"onClearSearch()\"\n tabindex=\"-1\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n <!-- Tree -->\n <div class=\"tree-dropdown-tree\">\n <mj-tree\n #treeComponent\n [BranchConfig]=\"BranchConfig\"\n [LeafConfig]=\"LeafConfig\"\n [SelectionMode]=\"SelectionMode\"\n [SelectableTypes]=\"SelectableTypes\"\n [SelectedIDs]=\"getSelectedIDsArray()\"\n [AutoLoad]=\"AutoLoad\"\n [ShowIcons]=\"true\"\n [ShowExpandCollapseAll]=\"false\"\n [AnimateExpandCollapse]=\"true\"\n [EmptyMessage]=\"SearchText ? 'No matches found' : 'No items available'\"\n [EmptyIcon]=\"SearchText ? 'fa-solid fa-search' : 'fa-solid fa-folder-open'\"\n (SelectionChange)=\"onTreeSelectionChange($event)\"\n (BeforeNodeSelect)=\"onTreeBeforeNodeSelect($event)\"\n (AfterNodeSelect)=\"onTreeAfterNodeSelect($event)\"\n (BeforeDataLoad)=\"onTreeBeforeDataLoad($event)\"\n (AfterDataLoad)=\"onTreeAfterDataLoad($event)\">\n </mj-tree>\n </div>\n </div>\n }\n</div>\n", styles: ["/**\n * Tree Dropdown Component Styles\n *\n * Uses CSS custom properties for easy theming.\n * Containers can override these variables to customize appearance.\n */\n\n/* ========================================\n CSS Variables (Theming)\n ======================================== */\n\n:host {\n /* Colors */\n --dropdown-bg: var(--mj-bg-surface);\n --dropdown-border-color: var(--mj-border-strong);\n --dropdown-border-hover: var(--mj-text-disabled);\n --dropdown-border-focus: var(--mj-brand-primary);\n --dropdown-text-color: var(--mj-text-primary);\n --dropdown-text-placeholder: var(--mj-text-disabled);\n --dropdown-shadow: var(--mj-shadow-lg);\n\n /* Trigger */\n --dropdown-trigger-bg: var(--mj-bg-surface);\n --dropdown-trigger-height: 40px;\n --dropdown-trigger-padding: 8px 12px;\n --dropdown-trigger-radius: var(--mj-radius-md);\n\n /* Search */\n --dropdown-search-bg: var(--mj-bg-surface-card);\n --dropdown-search-height: 36px;\n\n /* Animation */\n --dropdown-animation-duration: 150ms;\n --dropdown-animation-easing: ease-out;\n\n display: block;\n position: relative;\n width: 100%;\n}\n\n/* ========================================\n Container\n ======================================== */\n\n.tree-dropdown {\n position: relative;\n width: 100%;\n}\n\n.tree-dropdown--disabled {\n opacity: 0.6;\n pointer-events: none;\n}\n\n/* ========================================\n Trigger\n ======================================== */\n\n.tree-dropdown-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-height: var(--dropdown-trigger-height);\n padding: var(--dropdown-trigger-padding);\n background: var(--dropdown-trigger-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: var(--dropdown-trigger-radius);\n cursor: pointer;\n outline: none;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger:hover {\n border-color: var(--dropdown-border-hover);\n}\n\n.tree-dropdown-trigger:focus,\n.tree-dropdown-trigger--open {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tree-dropdown-trigger--disabled {\n cursor: not-allowed;\n background: var(--mj-bg-surface-card);\n}\n\n.tree-dropdown-trigger__content {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n overflow: hidden;\n}\n\n.tree-dropdown-trigger__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: var(--mj-text-sm);\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__text {\n flex: 1;\n font-size: var(--mj-text-sm);\n color: var(--dropdown-text-color);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tree-dropdown-trigger__text--placeholder {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-trigger__loading {\n display: flex;\n align-items: center;\n color: var(--dropdown-border-focus);\n font-size: var(--mj-text-xs);\n}\n\n.tree-dropdown-trigger__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.tree-dropdown-trigger__clear {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 10px;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger__clear:hover {\n background: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.tree-dropdown-trigger__chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n color: var(--dropdown-text-placeholder);\n font-size: var(--mj-text-xs);\n transition: transform var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-trigger--open .tree-dropdown-trigger__chevron {\n transform: rotate(180deg);\n}\n\n/* ========================================\n Dropdown Panel\n ======================================== */\n\n.tree-dropdown-panel {\n position: fixed;\n z-index: 10000;\n display: flex;\n flex-direction: column;\n background: var(--dropdown-bg);\n border: 1px solid var(--dropdown-border-color);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--dropdown-shadow);\n overflow: hidden;\n animation: dropdown-open var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n /* Ensure the panel respects its maxHeight and allows child scrolling */\n box-sizing: border-box;\n}\n\n.tree-dropdown-panel--above {\n transform-origin: bottom center;\n}\n\n.tree-dropdown-panel--below {\n transform-origin: top center;\n}\n\n@keyframes dropdown-open {\n from {\n opacity: 0;\n transform: scaleY(0.95);\n }\n to {\n opacity: 1;\n transform: scaleY(1);\n }\n}\n\n/* ========================================\n Search\n ======================================== */\n\n.tree-dropdown-search {\n padding: 8px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--dropdown-search-bg);\n}\n\n.tree-dropdown-search__input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n height: var(--dropdown-search-height);\n padding: 0 10px;\n background: var(--dropdown-bg);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__input-wrapper:focus-within {\n border-color: var(--dropdown-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tree-dropdown-search__icon {\n color: var(--mj-text-disabled);\n font-size: var(--mj-text-xs);\n flex-shrink: 0;\n}\n\n.tree-dropdown-search__input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: var(--mj-text-sm);\n color: var(--dropdown-text-color);\n outline: none;\n min-width: 0;\n}\n\n.tree-dropdown-search__input::placeholder {\n color: var(--dropdown-text-placeholder);\n}\n\n.tree-dropdown-search__clear {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 9px;\n flex-shrink: 0;\n transition: all var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-search__clear:hover {\n background: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n/* ========================================\n Tree Container\n ======================================== */\n\n.tree-dropdown-tree {\n flex: 1;\n overflow: auto;\n min-height: 0;\n max-height: 100%;\n}\n\n.tree-dropdown-tree mj-tree {\n display: block;\n height: auto;\n max-height: 100%;\n}\n\n/* Override tree styles for dropdown context */\n.tree-dropdown-tree ::ng-deep .tree-container {\n border-radius: 0;\n height: auto;\n max-height: none;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-content {\n padding: 4px 0;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-node {\n padding: 6px 12px;\n min-height: 32px;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-empty {\n padding: 24px 16px;\n}\n\n.tree-dropdown-tree ::ng-deep .tree-loading {\n padding: 24px 16px;\n}\n\n/* ========================================\n Portal Container (in body)\n ======================================== */\n\n:host ::ng-deep .mj-tree-dropdown-portal {\n pointer-events: none;\n}\n\n:host ::ng-deep .mj-tree-dropdown-portal > * {\n pointer-events: auto;\n}\n\n/* ========================================\n Multiple Selection Pills\n ======================================== */\n\n.tree-dropdown-pills {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n padding: 4px;\n}\n\n.tree-dropdown-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--mj-brand-primary-subtle);\n border-radius: var(--mj-radius-lg);\n font-size: var(--mj-text-xs);\n color: var(--mj-brand-primary);\n}\n\n.tree-dropdown-pill__remove {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 8px;\n transition: background var(--dropdown-animation-duration) var(--dropdown-animation-easing);\n}\n\n.tree-dropdown-pill__remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n/* ========================================\n Responsive\n ======================================== */\n\n@media (max-width: 480px) {\n :host {\n --dropdown-trigger-height: 44px;\n }\n\n .tree-dropdown-trigger__text {\n font-size: var(--mj-text-base);\n }\n\n .tree-dropdown-search__input {\n font-size: var(--mj-text-base); /* Prevents zoom on iOS */\n }\n}\n"] }]
941
941
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }], { BranchConfig: [{
942
942
  type: Input
943
943
  }], LeafConfig: [{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-trees",
3
- "version": "5.10.1",
3
+ "version": "5.12.0",
4
4
  "description": "MemberJunction: Angular tree and tree dropdown components for hierarchical entity selection",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -32,9 +32,9 @@
32
32
  "@angular/forms": "21.1.3"
33
33
  },
34
34
  "dependencies": {
35
- "@memberjunction/core": "5.10.1",
36
- "@memberjunction/core-entities": "5.10.1",
37
- "@memberjunction/global": "5.10.1",
35
+ "@memberjunction/core": "5.12.0",
36
+ "@memberjunction/core-entities": "5.12.0",
37
+ "@memberjunction/global": "5.12.0",
38
38
  "tslib": "^2.8.1",
39
39
  "rxjs": "^7.8.2"
40
40
  },