@laser-ui/components 2.4.0 → 2.5.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
4
4
 
5
+ # [2.5.0](https://github.com/laser-ui/laser-ui/compare/v2.4.0...v2.5.0) (2026-04-03)
6
+
7
+ ### Features
8
+
9
+ - **components:** cascader support `onScrollBottom` event ([19508bb](https://github.com/laser-ui/laser-ui/commit/19508bbd77fabdd3b884b40e77005d8f596985ac))
10
+
5
11
  # [2.4.0](https://github.com/laser-ui/laser-ui/compare/v2.3.5...v2.4.0) (2026-03-27)
6
12
 
7
13
  ### Bug Fixes
@@ -27,7 +27,7 @@ import { TREE_NODE_KEY } from '../tree/vars';
27
27
  import { getVerticalSidePosition, isPrintableCharacter, mergeCS } from '../utils';
28
28
  import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../vars';
29
29
  export function Cascader(props) {
30
- const _a = useComponentProps('Cascader', props), { ref, styleOverrides, styleProvider, formControl, list, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, onlyLeafSelectable = true, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, virtual = false, escClosable = true, customItem, customSelected, customSearch, inputProps, popupRender, onModelChange, onVisibleChange, onSearch, onClear, onFirstFocus, afterVisibleChange } = _a, restProps = __rest(_a, ["ref", "styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "onlyLeafSelectable", "clearable", "loading", "size", "disabled", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "inputProps", "popupRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onFirstFocus", "afterVisibleChange"]);
30
+ const _a = useComponentProps('Cascader', props), { ref, styleOverrides, styleProvider, formControl, list, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, onlyLeafSelectable = true, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, virtual = false, escClosable = true, customItem, customSelected, customSearch, inputProps, popupRender, onModelChange, onVisibleChange, onSearch, onClear, onFirstFocus, afterVisibleChange, onScrollBottom } = _a, restProps = __rest(_a, ["ref", "styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "onlyLeafSelectable", "clearable", "loading", "size", "disabled", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "inputProps", "popupRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onFirstFocus", "afterVisibleChange", "onScrollBottom"]);
31
31
  const namespace = useNamespace();
32
32
  const styled = useStyled(CLASSES, { cascader: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.cascader, 'cascader-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['cascader-popup'] }, styleOverrides);
33
33
  const { t } = useTranslation();
@@ -482,12 +482,16 @@ export function Cascader(props) {
482
482
  }, namespace: namespace, styled: styled, id: listId, list: searchList, customItem: customItem, itemId: getItemId, itemFocused: itemFocusedWithSearch, multiple: multiple, onlyLeafSelectable: onlyLeafSelectable, virtual: virtual, focusVisible: focusVisible, onClick: (item) => {
483
483
  changeItemFocusedWithSearch(item);
484
484
  changeSelectedByClickWithSearch(item);
485
+ }, onScrollBottom: () => {
486
+ onScrollBottom === null || onScrollBottom === void 0 ? void 0 : onScrollBottom([]);
485
487
  } })) : (_jsx(CascaderPanel, { ref: (instance) => {
486
488
  focusRef.current = instance;
487
489
  return () => {
488
490
  focusRef.current = null;
489
491
  };
490
- }, namespace: namespace, styled: styled, id: listId, list: nodes, customItem: customItem, itemId: getItemId, itemSelected: !multiple && hasSelected ? nodesMap.get(selected) : undefined, itemFocused: itemFocusedWithoutSearch, multiple: multiple, virtual: virtual, focusVisible: focusVisible, onFocus: changeItemFocusedWithoutSearch, onClick: changeSelectedByClickWithoutSearch }))] })));
492
+ }, namespace: namespace, styled: styled, id: listId, list: nodes, customItem: customItem, itemId: getItemId, itemSelected: !multiple && hasSelected ? nodesMap.get(selected) : undefined, itemFocused: itemFocusedWithoutSearch, multiple: multiple, virtual: virtual, focusVisible: focusVisible, onFocus: changeItemFocusedWithoutSearch, onClick: changeSelectedByClickWithoutSearch, onScrollBottom: (ancestors) => {
493
+ onScrollBottom === null || onScrollBottom === void 0 ? void 0 : onScrollBottom(ancestors);
494
+ } }))] })));
491
495
  return popupRender ? popupRender(el) : el;
492
496
  })() }))) }) })] }));
493
497
  }
@@ -17,6 +17,7 @@ interface CascaderPanelProps<V extends React.Key, T extends CascaderItem<V>> {
17
17
  focusVisible: boolean;
18
18
  onFocus: (item: AbstractTreeNode<V, T>) => void;
19
19
  onClick: (item: AbstractTreeNode<V, T>) => void;
20
+ onScrollBottom: (ancestors: V[]) => void;
20
21
  }
21
22
  export declare function CascaderPanel<V extends React.Key, T extends CascaderItem<V>>(props: CascaderPanelProps<V, T>): React.ReactElement | null;
22
23
  export {};
@@ -11,7 +11,7 @@ import { Empty } from '../../empty';
11
11
  import { Icon } from '../../icon';
12
12
  import { VirtualScroll } from '../../virtual-scroll';
13
13
  export function CascaderPanel(props) {
14
- const { ref, namespace, styled, id, list, customItem, itemId, itemSelected, itemFocused, multiple, virtual, focusVisible, onFocus, onClick, _root = true, } = props;
14
+ const { ref, namespace, styled, id, list, customItem, itemId, itemSelected, itemFocused, multiple, virtual, focusVisible, onFocus, onClick, onScrollBottom, _root = true, } = props;
15
15
  const listRef = useRef(null);
16
16
  const vsRef = useRef(null);
17
17
  const focusRef = useRef(null);
@@ -135,7 +135,9 @@ export function CascaderPanel(props) {
135
135
  } }) }))),
136
136
  _jsx("div", Object.assign({}, styled('cascader__option-content'), { children: customItem ? customItem(item.origin) : item.origin.label })),
137
137
  !item.isLeaf && (_jsx("div", Object.assign({}, styled('cascader__option-icon'), { children: _jsx(Icon, { children: item.origin.loading ? _jsx(CircularProgress, {}) : _jsx(KeyboardArrowRightOutlined, {}) }) })))));
138
- }, itemFocused: nodeFocused === null || nodeFocused === void 0 ? void 0 : nodeFocused.id, placeholder: "li", children: (vsList, onScroll) => (_jsx("ul", Object.assign({}, styled('cascader__list', 'cascader__list--inline'), { ref: (instance) => {
138
+ }, itemFocused: nodeFocused === null || nodeFocused === void 0 ? void 0 : nodeFocused.id, placeholder: "li", onScrollEnd: () => {
139
+ onScrollBottom([]);
140
+ }, children: (vsList, onScroll) => (_jsx("ul", Object.assign({}, styled('cascader__list', 'cascader__list--inline'), { ref: (instance) => {
139
141
  listRef.current = instance;
140
142
  return () => {
141
143
  listRef.current = null;
@@ -145,5 +147,7 @@ export function CascaderPanel(props) {
145
147
  return () => {
146
148
  focusRef.current = null;
147
149
  };
148
- }, id: undefined, list: nodeFocused.children })))] }));
150
+ }, id: undefined, list: nodeFocused.children, onScrollBottom: (ancestors) => {
151
+ onScrollBottom([nodeFocused.id].concat(ancestors));
152
+ } })))] }));
149
153
  }
@@ -16,6 +16,7 @@ interface CascaderSearchPanelProps<V extends React.Key, T extends CascaderItem<V
16
16
  virtual: boolean | number;
17
17
  focusVisible: boolean;
18
18
  onClick: (item: CascaderSearchPanelItem<V, T>) => void;
19
+ onScrollBottom: () => void;
19
20
  }
20
21
  export declare function CascaderSearchPanel<V extends React.Key, T extends CascaderItem<V>>(props: CascaderSearchPanelProps<V, T>): React.ReactElement | null;
21
22
  export {};
@@ -10,7 +10,7 @@ import { getTreeNodeLabel } from '../../tree/utils';
10
10
  import { TREE_NODE_KEY } from '../../tree/vars';
11
11
  import { VirtualScroll } from '../../virtual-scroll';
12
12
  export function CascaderSearchPanel(props) {
13
- const { ref, namespace, styled, id, list, customItem, itemId, itemFocused, multiple, onlyLeafSelectable, virtual, focusVisible, onClick, } = props;
13
+ const { ref, namespace, styled, id, list, customItem, itemId, itemFocused, multiple, onlyLeafSelectable, virtual, focusVisible, onClick, onScrollBottom, } = props;
14
14
  const listRef = useRef(null);
15
15
  const vsRef = useRef(null);
16
16
  const handleKeyDown = useEventCallback((code) => {
@@ -73,7 +73,7 @@ export function CascaderSearchPanel(props) {
73
73
  focusVisible && (itemFocused === null || itemFocused === void 0 ? void 0 : itemFocused.value) === item.value && _jsx("div", { className: `${namespace}-focus-outline` }),
74
74
  multiple && (_jsx("div", Object.assign({}, styled('cascader__option-prefix'), { children: _jsx(Checkbox, { model: node.checked, disabled: node.disabled }) }))),
75
75
  _jsx("div", Object.assign({}, styled('cascader__option-content'), { children: customItem ? customItem(node.origin) : getTreeNodeLabel(node) }))));
76
- }, itemFocused: itemFocused === null || itemFocused === void 0 ? void 0 : itemFocused.value, placeholder: "li", children: (vsList, onScroll) => (_jsx("ul", Object.assign({}, styled('cascader__list'), { ref: (instance) => {
76
+ }, itemFocused: itemFocused === null || itemFocused === void 0 ? void 0 : itemFocused.value, placeholder: "li", onScrollEnd: onScrollBottom, children: (vsList, onScroll) => (_jsx("ul", Object.assign({}, styled('cascader__list'), { ref: (instance) => {
77
77
  listRef.current = instance;
78
78
  return () => {
79
79
  listRef.current = null;
@@ -45,5 +45,6 @@ export interface CascaderProps<V extends React.Key, T extends CascaderItem<V>> e
45
45
  onSearch?: (value: string) => void;
46
46
  onClear?: () => void;
47
47
  onFirstFocus?: (value: V, origin: T) => void;
48
+ onScrollBottom?: (ancestors: V[]) => void;
48
49
  afterVisibleChange?: (visible: boolean) => void;
49
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laser-ui/components",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "React components.",
5
5
  "keywords": [
6
6
  "ui",
@@ -37,5 +37,5 @@
37
37
  "access": "public",
38
38
  "directory": "../../dist/libs/components"
39
39
  },
40
- "gitHead": "6aa6cb81ee51849b66dddeab0de811cadcb65c60"
40
+ "gitHead": "27f4c8861d51f0fbc8e83ef36df60fdac59afeb3"
41
41
  }