ywana-core8 0.1.83 → 0.1.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -11343,10 +11343,20 @@
11343
11343
  variant: 'default'
11344
11344
  };
11345
11345
 
11346
- var _excluded$4 = ["nodes", "children", "searchable", "searchPlaceholder", "searchBy", "filterable", "sortable", "sortBy", "sortDirection", "multiSelect", "onMultiSelect", "expandAll", "collapseAll", "onExpandAll", "onCollapseAll", "disabled", "loading", "empty", "emptyMessage", "emptyIcon", "className", "style", "ariaLabel"],
11346
+ var _excluded$4 = ["nodes", "children", "searchable", "searchPlaceholder", "searchBy", "filterable", "sortable", "sortBy", "sortDirection", "multiSelect", "onMultiSelect", "showExpandIcon", "onExpandAll", "onCollapseAll", "disabled", "loading", "empty", "emptyMessage", "emptyIcon", "className", "style", "ariaLabel"],
11347
11347
  _excluded2$1 = ["id", "icon", "label", "tooltip", "open", "children", "actions", "onSelect", "disabled", "draggable", "onDragStart", "onDragEnd", "onDrop", "expandable", "level", "hasChildren", "loading", "badge", "className", "style"],
11348
11348
  _excluded3 = ["id", "icon", "label", "actions", "onSelect", "selected", "onCheck", "checked", "disabled", "draggable", "onDragStart", "onDragEnd", "onDrop", "level", "badge", "tooltip", "className", "style"];
11349
11349
 
11350
+ // Context for tree state
11351
+ var TreeContext = React.createContext({
11352
+ multiSelect: false,
11353
+ selectedItems: [],
11354
+ onMultiSelect: null,
11355
+ searchTerm: '',
11356
+ forceExpandAll: false,
11357
+ forceCollapseAll: false
11358
+ });
11359
+
11350
11360
  /**
11351
11361
  * Enhanced Tree component with improved functionality while maintaining 100% compatibility
11352
11362
  */
@@ -11358,13 +11368,13 @@
11358
11368
  searchable = _props$searchable === void 0 ? false : _props$searchable,
11359
11369
  _props$searchPlacehol = props.searchPlaceholder,
11360
11370
  searchPlaceholder = _props$searchPlacehol === void 0 ? "Search..." : _props$searchPlacehol,
11371
+ _props$searchBy = props.searchBy,
11372
+ searchBy = _props$searchBy === void 0 ? ['label'] : _props$searchBy,
11361
11373
  _props$multiSelect = props.multiSelect,
11362
11374
  multiSelect = _props$multiSelect === void 0 ? false : _props$multiSelect,
11363
11375
  onMultiSelect = props.onMultiSelect,
11364
- _props$expandAll = props.expandAll,
11365
- expandAll = _props$expandAll === void 0 ? false : _props$expandAll,
11366
- _props$collapseAll = props.collapseAll,
11367
- collapseAll = _props$collapseAll === void 0 ? false : _props$collapseAll,
11376
+ _props$showExpandIcon = props.showExpandIcon,
11377
+ showExpandIcon = _props$showExpandIcon === void 0 ? false : _props$showExpandIcon,
11368
11378
  onExpandAll = props.onExpandAll,
11369
11379
  onCollapseAll = props.onCollapseAll,
11370
11380
  _props$disabled = props.disabled,
@@ -11385,8 +11395,18 @@
11385
11395
  searchTerm = _useState[0],
11386
11396
  setSearchTerm = _useState[1];
11387
11397
  var _useState2 = React.useState([]),
11398
+ selectedItems = _useState2[0],
11388
11399
  setSelectedItems = _useState2[1];
11389
11400
  React.useState(new Set());
11401
+ var _useState4 = React.useState(false),
11402
+ allExpanded = _useState4[0],
11403
+ setAllExpanded = _useState4[1];
11404
+ var _useState5 = React.useState(false),
11405
+ forceExpandAll = _useState5[0],
11406
+ setForceExpandAll = _useState5[1];
11407
+ var _useState6 = React.useState(false),
11408
+ forceCollapseAll = _useState6[0],
11409
+ setForceCollapseAll = _useState6[1];
11390
11410
  var treeRef = React.useRef(null);
11391
11411
 
11392
11412
  // Validate props
@@ -11399,8 +11419,70 @@
11399
11419
  setSearchTerm(value);
11400
11420
  }, []);
11401
11421
 
11422
+ // Apply expansion state to nodes based on current tree state
11423
+ var applyExpansionState = React.useCallback(function (nodeElements) {
11424
+ return React__default["default"].Children.toArray(nodeElements).map(function (child) {
11425
+ var _child$type;
11426
+ if (!React__default["default"].isValidElement(child)) return child;
11427
+
11428
+ // If it's a TreeNode, apply the current expansion state
11429
+ if (((_child$type = child.type) == null ? void 0 : _child$type.displayName) === 'TreeNode' || child.props.hasOwnProperty('open')) {
11430
+ var processedChildren = child.props.children ? applyExpansionState(child.props.children) : child.props.children;
11431
+ return React__default["default"].cloneElement(child, _extends({}, child.props, {
11432
+ open: allExpanded,
11433
+ // Apply current expansion state
11434
+ children: processedChildren
11435
+ }));
11436
+ }
11437
+ return child;
11438
+ });
11439
+ }, [allExpanded]);
11440
+
11441
+ // Filter nodes based on search term and auto-expand matching nodes
11442
+ var filterNodes = React.useCallback(function (nodeElements, searchTerm) {
11443
+ if (!searchTerm.trim()) {
11444
+ // When search is cleared, apply current expansion state
11445
+ return applyExpansionState(nodeElements);
11446
+ }
11447
+ return React__default["default"].Children.toArray(nodeElements).map(function (child) {
11448
+ if (!React__default["default"].isValidElement(child)) return child;
11449
+
11450
+ // Check if current node matches search
11451
+ var label = child.props.label || '';
11452
+ var matches = searchBy.some(function (field) {
11453
+ var value = child.props[field] || label;
11454
+ return typeof value === 'string' && value.toLowerCase().includes(searchTerm.toLowerCase());
11455
+ });
11456
+
11457
+ // Check if any children match (recursive)
11458
+ var hasMatchingChildren = false;
11459
+ var filteredChildren = child.props.children;
11460
+ if (child.props.children) {
11461
+ filteredChildren = filterNodes(child.props.children, searchTerm);
11462
+ hasMatchingChildren = React__default["default"].Children.count(filteredChildren) > 0;
11463
+ }
11464
+
11465
+ // If current node or children match, include it and auto-expand
11466
+ if (matches || hasMatchingChildren) {
11467
+ var _child$type2;
11468
+ // Clone the element and force it to be open if it's a TreeNode
11469
+ if (((_child$type2 = child.type) == null ? void 0 : _child$type2.displayName) === 'TreeNode' || child.props.hasOwnProperty('open')) {
11470
+ return React__default["default"].cloneElement(child, _extends({}, child.props, {
11471
+ open: true,
11472
+ // Auto-expand nodes with matches during search
11473
+ children: filteredChildren
11474
+ }));
11475
+ }
11476
+ return React__default["default"].cloneElement(child, _extends({}, child.props, {
11477
+ children: filteredChildren
11478
+ }));
11479
+ }
11480
+ return null;
11481
+ }).filter(Boolean);
11482
+ }, [searchBy, applyExpansionState]);
11483
+
11402
11484
  // Handle multi-selection
11403
- React.useCallback(function (id, selected) {
11485
+ var handleMultiSelect = React.useCallback(function (id, selected) {
11404
11486
  if (!multiSelect) return;
11405
11487
  setSelectedItems(function (prev) {
11406
11488
  var newSelected = selected ? [].concat(prev, [id]) : prev.filter(function (item) {
@@ -11413,15 +11495,26 @@
11413
11495
  });
11414
11496
  }, [multiSelect, onMultiSelect]);
11415
11497
 
11416
- // Handle expand/collapse all
11417
- var handleExpandAll = React.useCallback(function () {
11418
- if (onExpandAll) onExpandAll();
11419
- // Implementation would depend on tree structure
11420
- }, [onExpandAll]);
11421
- var handleCollapseAll = React.useCallback(function () {
11422
- if (onCollapseAll) onCollapseAll();
11423
- // Implementation would depend on tree structure
11424
- }, [onCollapseAll]);
11498
+ // Handle expand/collapse toggle - using context to propagate to all TreeNodes
11499
+ var handleExpandToggle = React.useCallback(function () {
11500
+ var newState = !allExpanded;
11501
+ setAllExpanded(newState);
11502
+ if (newState) {
11503
+ if (onExpandAll) onExpandAll();
11504
+ // Trigger expand all via context
11505
+ setForceExpandAll(true);
11506
+ setTimeout(function () {
11507
+ return setForceExpandAll(false);
11508
+ }, 100);
11509
+ } else {
11510
+ if (onCollapseAll) onCollapseAll();
11511
+ // Trigger collapse all via context
11512
+ setForceCollapseAll(true);
11513
+ setTimeout(function () {
11514
+ return setForceCollapseAll(false);
11515
+ }, 100);
11516
+ }
11517
+ }, [allExpanded, onExpandAll, onCollapseAll]);
11425
11518
 
11426
11519
  // Generate CSS classes
11427
11520
  var cssClasses = ['tree', disabled && 'tree--disabled', loading && 'tree--loading', searchable && 'tree--searchable', multiSelect && 'tree--multi-select', className].filter(Boolean).join(' ');
@@ -11469,11 +11562,23 @@
11469
11562
  size: "large"
11470
11563
  }), /*#__PURE__*/React__default["default"].createElement(Text, null, emptyMessage)));
11471
11564
  }
11472
- return /*#__PURE__*/React__default["default"].createElement("div", _extends({
11565
+ var contextValue = {
11566
+ multiSelect: multiSelect,
11567
+ selectedItems: selectedItems,
11568
+ onMultiSelect: handleMultiSelect,
11569
+ searchTerm: searchTerm,
11570
+ forceExpandAll: forceExpandAll,
11571
+ forceCollapseAll: forceCollapseAll
11572
+ };
11573
+ return /*#__PURE__*/React__default["default"].createElement(TreeContext.Provider, {
11574
+ value: contextValue
11575
+ }, /*#__PURE__*/React__default["default"].createElement("div", _extends({
11473
11576
  className: cssClasses,
11474
11577
  style: style,
11475
11578
  ref: treeRef
11476
- }, ariaAttributes, restProps), searchable && /*#__PURE__*/React__default["default"].createElement("div", {
11579
+ }, ariaAttributes, restProps), (searchable || showExpandIcon) && /*#__PURE__*/React__default["default"].createElement("div", {
11580
+ className: "tree__header " + (!searchable && showExpandIcon ? 'tree__header--expand-only' : '')
11581
+ }, searchable && /*#__PURE__*/React__default["default"].createElement("div", {
11477
11582
  className: "tree__search"
11478
11583
  }, /*#__PURE__*/React__default["default"].createElement(TextField, {
11479
11584
  id: "tree-search",
@@ -11483,29 +11588,17 @@
11483
11588
  icon: "search",
11484
11589
  outlined: true,
11485
11590
  size: "small"
11486
- })), (expandAll || collapseAll) && /*#__PURE__*/React__default["default"].createElement("div", {
11487
- className: "tree__controls"
11488
- }, expandAll && /*#__PURE__*/React__default["default"].createElement("button", {
11489
- className: "tree__control-button",
11490
- onClick: handleExpandAll,
11491
- "aria-label": "Expand all nodes"
11591
+ })), showExpandIcon && /*#__PURE__*/React__default["default"].createElement("div", {
11592
+ className: "tree__expand-control"
11492
11593
  }, /*#__PURE__*/React__default["default"].createElement(Icon, {
11493
- icon: "unfold_more",
11494
- size: "small"
11495
- }), /*#__PURE__*/React__default["default"].createElement(Text, {
11496
- size: "sm"
11497
- }, "Expand All")), collapseAll && /*#__PURE__*/React__default["default"].createElement("button", {
11498
- className: "tree__control-button",
11499
- onClick: handleCollapseAll,
11500
- "aria-label": "Collapse all nodes"
11501
- }, /*#__PURE__*/React__default["default"].createElement(Icon, {
11502
- icon: "unfold_less",
11503
- size: "small"
11504
- }), /*#__PURE__*/React__default["default"].createElement(Text, {
11505
- size: "sm"
11506
- }, "Collapse All"))), /*#__PURE__*/React__default["default"].createElement("div", {
11594
+ icon: allExpanded ? "unfold_less" : "unfold_more",
11595
+ size: "small",
11596
+ clickable: true,
11597
+ action: handleExpandToggle,
11598
+ tooltip: allExpanded ? "Collapse all" : "Expand all"
11599
+ }))), /*#__PURE__*/React__default["default"].createElement("div", {
11507
11600
  className: "tree__content"
11508
- }, nodes, children));
11601
+ }, nodes, searchable ? filterNodes(children, searchTerm) : applyExpansionState(children))));
11509
11602
  };
11510
11603
 
11511
11604
  /**
@@ -11541,19 +11634,44 @@
11541
11634
  className = props.className,
11542
11635
  style = props.style,
11543
11636
  restProps = _objectWithoutPropertiesLoose(props, _excluded2$1);
11544
- var _useState4 = React.useState(open),
11545
- isOpen = _useState4[0],
11546
- setIsOpen = _useState4[1];
11547
- var _useState5 = React.useState(false),
11548
- isDragging = _useState5[0],
11549
- setIsDragging = _useState5[1];
11637
+ var _useState7 = React.useState(open),
11638
+ isOpen = _useState7[0],
11639
+ setIsOpen = _useState7[1];
11640
+ var _useState8 = React.useState(false),
11641
+ isDragging = _useState8[0],
11642
+ setIsDragging = _useState8[1];
11550
11643
  var nodeRef = React.useRef(null);
11551
11644
 
11645
+ // Get tree context for forced expand/collapse
11646
+ var treeContext = React.useContext(TreeContext);
11647
+ var forceExpandAll = treeContext.forceExpandAll,
11648
+ forceCollapseAll = treeContext.forceCollapseAll;
11649
+
11552
11650
  // Sync with open prop
11553
11651
  React.useEffect(function () {
11554
11652
  setIsOpen(open);
11555
11653
  }, [open]);
11556
11654
 
11655
+ // Handle forced expand/collapse from tree context
11656
+ React.useEffect(function () {
11657
+ if (forceExpandAll && expandable) {
11658
+ setIsOpen(true);
11659
+ // Also update the DOM element
11660
+ if (nodeRef.current) {
11661
+ nodeRef.current.open = true;
11662
+ }
11663
+ }
11664
+ }, [forceExpandAll, expandable]);
11665
+ React.useEffect(function () {
11666
+ if (forceCollapseAll && expandable) {
11667
+ setIsOpen(false);
11668
+ // Also update the DOM element
11669
+ if (nodeRef.current) {
11670
+ nodeRef.current.open = false;
11671
+ }
11672
+ }
11673
+ }, [forceCollapseAll, expandable]);
11674
+
11557
11675
  // Handle selection (maintaining original behavior)
11558
11676
  var handleSelect = React.useCallback(function (event) {
11559
11677
  if (disabled) return;
@@ -11561,14 +11679,13 @@
11561
11679
  if (onSelect) onSelect(id);
11562
11680
  }, [disabled, onSelect, id]);
11563
11681
 
11564
- // Handle toggle
11682
+ // Handle toggle - sync with details element
11565
11683
  var handleToggle = React.useCallback(function (event) {
11566
11684
  if (disabled || !expandable) return;
11567
- event.preventDefault();
11568
- event.stopPropagation();
11569
- setIsOpen(function (prev) {
11570
- return !prev;
11571
- });
11685
+
11686
+ // Sync our state with the details element
11687
+ var detailsElement = event.currentTarget;
11688
+ setIsOpen(detailsElement.open);
11572
11689
  }, [disabled, expandable]);
11573
11690
 
11574
11691
  // Handle keyboard interaction
@@ -11646,24 +11763,29 @@
11646
11763
  onDragStart: handleDragStart,
11647
11764
  onDragEnd: handleDragEnd,
11648
11765
  onDrop: handleDrop,
11649
- onDragOver: handleDragOver
11766
+ onDragOver: handleDragOver,
11767
+ onToggle: handleToggle
11650
11768
  }, restProps), /*#__PURE__*/React__default["default"].createElement("summary", _extends({
11651
11769
  className: "tree-item",
11652
11770
  onClick: function onClick(event) {
11653
- // Si se hace click en el área general del nodo (no en el label), toggle
11654
- if (event.target === event.currentTarget || event.target.closest('.tree-node__toggle')) {
11655
- handleToggle(event);
11771
+ // Si se hace click en el toggle, permitir el comportamiento natural
11772
+ if (event.target.closest('.tree-node__toggle')) {
11773
+ // No hacer nada, dejar que el details maneje el toggle
11774
+ return;
11656
11775
  }
11776
+
11777
+ // Si hay onSelect y se hace click fuera del toggle, seleccionar
11778
+ if (onSelect) {
11779
+ event.preventDefault(); // Prevenir el toggle del details
11780
+ handleSelect(event);
11781
+ }
11782
+ // Si no hay onSelect, permitir el comportamiento natural del details
11657
11783
  },
11658
11784
  onKeyDown: handleKeyDown
11659
11785
  }, ariaAttributes, {
11660
11786
  title: tooltip
11661
11787
  }), hasChildren && expandable && /*#__PURE__*/React__default["default"].createElement("div", {
11662
- className: "tree-node__toggle",
11663
- onClick: function onClick(event) {
11664
- event.stopPropagation();
11665
- handleToggle(event);
11666
- }
11788
+ className: "tree-node__toggle"
11667
11789
  }, /*#__PURE__*/React__default["default"].createElement(Icon, {
11668
11790
  icon: isOpen ? 'expand_less' : 'expand_more',
11669
11791
  size: "small",
@@ -11680,11 +11802,7 @@
11680
11802
  icon: "hourglass_empty",
11681
11803
  size: "small"
11682
11804
  })), /*#__PURE__*/React__default["default"].createElement("div", {
11683
- className: "label " + clickable,
11684
- onClick: function onClick(event) {
11685
- event.stopPropagation();
11686
- handleSelect(event);
11687
- }
11805
+ className: "label " + clickable
11688
11806
  }, /*#__PURE__*/React__default["default"].createElement("span", {
11689
11807
  className: "tree-node__label-text"
11690
11808
  }, labelTxt), badge && /*#__PURE__*/React__default["default"].createElement("span", {
@@ -11726,11 +11844,20 @@
11726
11844
  className = props.className,
11727
11845
  style = props.style,
11728
11846
  restProps = _objectWithoutPropertiesLoose(props, _excluded3);
11729
- var _useState6 = React.useState(false),
11730
- isDragging = _useState6[0],
11731
- setIsDragging = _useState6[1];
11847
+ var _useState9 = React.useState(false),
11848
+ isDragging = _useState9[0],
11849
+ setIsDragging = _useState9[1];
11732
11850
  var itemRef = React.useRef(null);
11733
11851
 
11852
+ // Get tree context
11853
+ var treeContext = React.useContext(TreeContext);
11854
+ var multiSelect = treeContext.multiSelect,
11855
+ selectedItems = treeContext.selectedItems,
11856
+ handleTreeMultiSelect = treeContext.onMultiSelect;
11857
+
11858
+ // Check if this item is selected in multi-select mode
11859
+ var isMultiSelected = multiSelect && selectedItems.includes(id);
11860
+
11734
11861
  // Handle selection (maintaining original behavior)
11735
11862
  var handleSelect = React.useCallback(function (event) {
11736
11863
  if (disabled) return;
@@ -11738,12 +11865,20 @@
11738
11865
  if (onSelect) onSelect(id);
11739
11866
  }, [disabled, onSelect, id]);
11740
11867
 
11741
- // Handle checkbox (maintaining original behavior)
11868
+ // Handle checkbox (maintaining original behavior + multi-select)
11742
11869
  var handleCheck = React.useCallback(function (event) {
11743
11870
  if (disabled) return;
11744
11871
  event.stopPropagation();
11745
- if (onCheck) onCheck(id, event.target.checked);
11746
- }, [disabled, onCheck, id]);
11872
+ var isChecked = event.target.checked;
11873
+
11874
+ // Handle original onCheck callback
11875
+ if (onCheck) onCheck(id, isChecked);
11876
+
11877
+ // Handle multi-select if enabled
11878
+ if (multiSelect && handleTreeMultiSelect) {
11879
+ handleTreeMultiSelect(id, isChecked);
11880
+ }
11881
+ }, [disabled, onCheck, id, multiSelect, handleTreeMultiSelect]);
11747
11882
 
11748
11883
  // Handle keyboard interaction
11749
11884
  var handleKeyDown = React.useCallback(function (event) {
@@ -11810,11 +11945,11 @@
11810
11945
  onDrop: handleDrop,
11811
11946
  onDragOver: handleDragOver,
11812
11947
  title: tooltip
11813
- }, ariaAttributes, restProps), onCheck && /*#__PURE__*/React__default["default"].createElement("div", {
11948
+ }, ariaAttributes, restProps), (onCheck || multiSelect) && /*#__PURE__*/React__default["default"].createElement("div", {
11814
11949
  className: "tree-item__checkbox"
11815
11950
  }, /*#__PURE__*/React__default["default"].createElement("input", {
11816
11951
  type: "checkbox",
11817
- checked: checked,
11952
+ checked: multiSelect ? isMultiSelected : checked,
11818
11953
  onChange: handleCheck,
11819
11954
  disabled: disabled,
11820
11955
  "aria-label": "Select " + (typeof label === 'string' ? label : 'item')
@@ -11857,10 +11992,8 @@
11857
11992
  multiSelect: PropTypes.bool,
11858
11993
  /** Multi-selection callback */
11859
11994
  onMultiSelect: PropTypes.func,
11860
- /** Show expand all button */
11861
- expandAll: PropTypes.bool,
11862
- /** Show collapse all button */
11863
- collapseAll: PropTypes.bool,
11995
+ /** Show expand/collapse icon */
11996
+ showExpandIcon: PropTypes.bool,
11864
11997
  /** Expand all callback */
11865
11998
  onExpandAll: PropTypes.func,
11866
11999
  /** Collapse all callback */