@basis-ng/primitives 0.0.1-alpha.136 → 0.0.1-alpha.138

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.
@@ -3520,10 +3520,6 @@ class TreeNode {
3520
3520
  * Whether this node is expanded to show nested content.
3521
3521
  */
3522
3522
  expanded = model(false, ...(ngDevMode ? [{ debugName: "expanded" }] : []));
3523
- /**
3524
- * Whether drag-and-drop is only enabled when this node is collapsed.
3525
- */
3526
- dragOnlyWhenCollapsed = input(false, ...(ngDevMode ? [{ debugName: "dragOnlyWhenCollapsed" }] : []));
3527
3523
  /**
3528
3524
  * Injected CDK drag instance for this node.
3529
3525
  */
@@ -3540,12 +3536,29 @@ class TreeNode {
3540
3536
  * Computed signal for node disabled state.
3541
3537
  */
3542
3538
  isNodeDisabled = computed(() => this.node.disabled, ...(ngDevMode ? [{ debugName: "isNodeDisabled" }] : []));
3539
+ /**
3540
+ * Internal state for dragOnlyWhenCollapsed from parent Tree.
3541
+ */
3542
+ _dragOnlyWhenCollapsed = false;
3543
+ /**
3544
+ * Track if any parent node is expanded (disables drag when dragOnlyWhenCollapsed is active).
3545
+ */
3546
+ _hasExpandedParent = false;
3547
+ /**
3548
+ * Computed to determine if drag handle should be hidden.
3549
+ */
3550
+ shouldHideDragHandle = computed(() => {
3551
+ if (!this._dragOnlyWhenCollapsed)
3552
+ return false;
3553
+ // Hide if this node is expanded and has nested tree, or if any parent is expanded
3554
+ return (this.hasNestedTree() && this.expanded()) || this._hasExpandedParent;
3555
+ }, ...(ngDevMode ? [{ debugName: "shouldHideDragHandle" }] : []));
3543
3556
  /**
3544
3557
  * Emitted when a nested tree is closed.
3545
3558
  */
3546
3559
  closeEmitter = output();
3547
3560
  constructor() {
3548
- // Track expanded state changes for close events
3561
+ // Track expanded state changes for close events and drag state
3549
3562
  let previousExpanded = this.expanded();
3550
3563
  effect(() => {
3551
3564
  const currentExpanded = this.expanded();
@@ -3553,19 +3566,47 @@ class TreeNode {
3553
3566
  if (previousExpanded && !currentExpanded && this.nestedTree()) {
3554
3567
  this.closeEmitter.emit();
3555
3568
  }
3556
- previousExpanded = currentExpanded;
3557
- });
3558
- // Control drag based on expanded state and dragOnlyWhenCollapsed
3559
- effect(() => {
3560
- if (this.dragOnlyWhenCollapsed() && this.hasNestedTree()) {
3561
- this.node.disabled = this.expanded();
3569
+ // Update drag state when dragOnlyWhenCollapsed is active
3570
+ if (this._dragOnlyWhenCollapsed) {
3571
+ this.updateDragState(currentExpanded, previousExpanded);
3562
3572
  }
3573
+ previousExpanded = currentExpanded;
3563
3574
  });
3564
3575
  }
3565
3576
  ngOnInit() {
3566
3577
  // Static configuration - only needs to run once
3567
3578
  this.node.lockAxis = 'y';
3568
3579
  }
3580
+ /**
3581
+ * Update drag state based on expanded state and parent state.
3582
+ */
3583
+ updateDragState(isExpanded, wasExpanded) {
3584
+ if (this.hasNestedTree()) {
3585
+ this.handleNodeWithChildren(isExpanded, wasExpanded);
3586
+ }
3587
+ else {
3588
+ this.handleLeafNode();
3589
+ }
3590
+ }
3591
+ /**
3592
+ * Handle drag state for nodes with children.
3593
+ */
3594
+ handleNodeWithChildren(isExpanded, wasExpanded) {
3595
+ if (isExpanded) {
3596
+ this.node.disabled = true;
3597
+ this.nestedTree()?.disableDirectChildren();
3598
+ }
3599
+ else if (wasExpanded) {
3600
+ this.node.disabled = false;
3601
+ this.nestedTree()?.enableDirectChildren();
3602
+ }
3603
+ }
3604
+ /**
3605
+ * Handle drag state for leaf nodes (no children).
3606
+ */
3607
+ handleLeafNode() {
3608
+ this.node.disabled = this._hasExpandedParent;
3609
+ }
3569
3610
  /**
3570
3611
  * Enable or disable the underlying CDK drag for this node.
3571
3612
  * @param disabled - Whether the node should be disabled.
@@ -3573,6 +3614,31 @@ class TreeNode {
3573
3614
  handleNodeDisability(disabled) {
3574
3615
  this.node.disabled = disabled;
3575
3616
  }
3617
+ /**
3618
+ * Set drag only when collapsed mode from parent Tree.
3619
+ * @param enabled - Whether drag should only work when collapsed.
3620
+ */
3621
+ setDragOnlyWhenCollapsed(enabled) {
3622
+ this._dragOnlyWhenCollapsed = enabled;
3623
+ // Apply immediately if node has nested tree and is expanded
3624
+ if (enabled && this.hasNestedTree() && this.expanded()) {
3625
+ this.node.disabled = true;
3626
+ this.nestedTree()?.disableDirectChildren();
3627
+ }
3628
+ }
3629
+ /**
3630
+ * Set whether this node has an expanded parent.
3631
+ * @param hasExpandedParent - Whether the direct parent is expanded.
3632
+ */
3633
+ setHasExpandedParent(hasExpandedParent) {
3634
+ this._hasExpandedParent = hasExpandedParent;
3635
+ if (!this._dragOnlyWhenCollapsed)
3636
+ return;
3637
+ // Update drag state based on parent state
3638
+ if (!this.hasNestedTree() || !this.expanded()) {
3639
+ this.node.disabled = hasExpandedParent;
3640
+ }
3641
+ }
3576
3642
  /**
3577
3643
  * Toggle the node expansion.
3578
3644
  */
@@ -3580,13 +3646,13 @@ class TreeNode {
3580
3646
  this.expanded.update((current) => !current);
3581
3647
  }
3582
3648
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TreeNode, deps: [], target: i0.ɵɵFactoryTarget.Component });
3583
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TreeNode, isStandalone: true, selector: "b-tree-node", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, dragOnlyWhenCollapsed: { classPropertyName: "dragOnlyWhenCollapsed", publicName: "dragOnlyWhenCollapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange", closeEmitter: "closeEmitter" }, providers: [
3649
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TreeNode, isStandalone: true, selector: "b-tree-node", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange", closeEmitter: "closeEmitter" }, providers: [
3584
3650
  provideIcons({
3585
3651
  lucideGripVertical,
3586
3652
  }),
3587
3653
  ], queries: [{ propertyName: "nestedTree", first: true, predicate: Tree, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$3.CdkDrag, inputs: ["cdkDragDisabled", "disabled"] }], ngImport: i0, template: `
3588
3654
  <section>
3589
- @if (!isNodeDisabled()) {
3655
+ @if (!isNodeDisabled() && !shouldHideDragHandle()) {
3590
3656
  <ng-icon name="lucideGripVertical" size="16" color="currentColor" cdkDragHandle />
3591
3657
  }
3592
3658
  <div
@@ -3629,7 +3695,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
3629
3695
  imports: [CdkDragHandle, NgIcon],
3630
3696
  template: `
3631
3697
  <section>
3632
- @if (!isNodeDisabled()) {
3698
+ @if (!isNodeDisabled() && !shouldHideDragHandle()) {
3633
3699
  <ng-icon name="lucideGripVertical" size="16" color="currentColor" cdkDragHandle />
3634
3700
  }
3635
3701
  <div
@@ -3676,7 +3742,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
3676
3742
  }),
3677
3743
  ],
3678
3744
  }]
3679
- }], ctorParameters: () => [], propDecorators: { expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], dragOnlyWhenCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragOnlyWhenCollapsed", required: false }] }], nestedTree: [{ type: i0.ContentChild, args: [i0.forwardRef(() => Tree), { isSignal: true }] }], closeEmitter: [{ type: i0.Output, args: ["closeEmitter"] }] } });
3745
+ }], ctorParameters: () => [], propDecorators: { expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], nestedTree: [{ type: i0.ContentChild, args: [i0.forwardRef(() => Tree), { isSignal: true }] }], closeEmitter: [{ type: i0.Output, args: ["closeEmitter"] }] } });
3680
3746
 
3681
3747
  /**
3682
3748
  * Root container for a tree structure, enabling drag-and-drop and nested nodes.
@@ -3719,6 +3785,13 @@ class Tree {
3719
3785
  node.handleNodeDisability(disabled);
3720
3786
  });
3721
3787
  });
3788
+ // Propagate dragOnlyWhenCollapsed to nodes
3789
+ effect(() => {
3790
+ const dragOnlyCollapsed = this.dragOnlyWhenCollapsed();
3791
+ this.nestedNodes().forEach((node) => {
3792
+ node.setDragOnlyWhenCollapsed(dragOnlyCollapsed);
3793
+ });
3794
+ });
3722
3795
  }
3723
3796
  ngOnInit() {
3724
3797
  // Setup recursive close only once based on initial input value
@@ -3745,6 +3818,22 @@ class Tree {
3745
3818
  node.nestedTree()?.closeNestedNodes();
3746
3819
  });
3747
3820
  }
3821
+ /**
3822
+ * Disable drag for all direct children nodes.
3823
+ */
3824
+ disableDirectChildren() {
3825
+ this.nestedNodes().forEach((node) => {
3826
+ node.setHasExpandedParent(true);
3827
+ });
3828
+ }
3829
+ /**
3830
+ * Enable drag for all direct children nodes.
3831
+ */
3832
+ enableDirectChildren() {
3833
+ this.nestedNodes().forEach((node) => {
3834
+ node.setHasExpandedParent(false);
3835
+ });
3836
+ }
3748
3837
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: Tree, deps: [], target: i0.ɵɵFactoryTarget.Component });
3749
3838
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.0", type: Tree, isStandalone: true, selector: "b-tree", inputs: { draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, closeRecursively: { classPropertyName: "closeRecursively", publicName: "closeRecursively", isSignal: true, isRequired: false, transformFunction: null }, dragOnlyWhenCollapsed: { classPropertyName: "dragOnlyWhenCollapsed", publicName: "dragOnlyWhenCollapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropEmitter: "dropEmitter" }, host: { listeners: { "cdkDropListDropped": "dropEmitter.emit($event)" } }, queries: [{ propertyName: "nestedNodes", predicate: TreeNode, isSignal: true }], hostDirectives: [{ directive: i1$3.CdkDropList, inputs: ["id", "id", "cdkDropListConnectedTo", "connectedTo"], outputs: ["cdkDropListDropped", "cdkDropListDropped"] }, { directive: i1$3.CdkDropListGroup }], ngImport: i0, template: ` <ng-content /> `, isInline: true });
3750
3839
  }