@laser-ui/components 0.4.0 → 0.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,18 @@
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
+ # [0.5.0](https://github.com/laser-ui/laser-ui/compare/v0.4.1...v0.5.0) (2024-01-31)
6
+
7
+ ### Features
8
+
9
+ - **components:** add `popupRender` prop for custom popup ([e9814ba](https://github.com/laser-ui/laser-ui/commit/e9814baccc1d38dd68645618b0ba92e323f843b0))
10
+
11
+ ## [0.4.1](https://github.com/laser-ui/laser-ui/compare/v0.4.0...v0.4.1) (2023-12-12)
12
+
13
+ ### Bug Fixes
14
+
15
+ - **ui:** fix get window size ([c909d89](https://github.com/laser-ui/laser-ui/commit/c909d898d48d715758744d4201888824e1e09af4))
16
+
5
17
  # [0.4.0](https://github.com/laser-ui/laser-ui/compare/v0.3.0...v0.4.0) (2023-12-06)
6
18
 
7
19
  ### Features
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <a href="//laser-ui.surge.sh/" rel="noopener" target="_blank"><img width="150" src="apps/site/public/logo.png" alt="logo"></a>
2
+ <a href="//laser-ui.github.io/" rel="noopener" target="_blank"><img width="150" src="apps/site/public/logo.png" alt="logo"></a>
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Laser UI</h1>
@@ -59,7 +59,7 @@ export default function App() {
59
59
 
60
60
  ## Links
61
61
 
62
- - [laser-ui.surge.sh](//laser-ui.surge.sh)
62
+ - [laser-admin.surge.sh](//laser-admin.surge.sh)
63
63
 
64
64
  ## Contributing
65
65
 
@@ -26,7 +26,7 @@ import { TREE_NODE_KEY } from '../tree/vars';
26
26
  import { getVerticalSidePosition, isPrintableCharacter, mergeCS } from '../utils';
27
27
  import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../vars';
28
28
  function CascaderFC(props, ref) {
29
- const _a = useComponentProps('Cascader', props), { 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, inputRef: inputRefProp, inputRender, onModelChange, onVisibleChange, onSearch, onClear, onFirstFocus, afterVisibleChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "onlyLeafSelectable", "clearable", "loading", "size", "disabled", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "inputRef", "inputRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onFirstFocus", "afterVisibleChange"]);
29
+ const _a = useComponentProps('Cascader', props), { 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, inputRef: inputRefProp, inputRender, popupRender, onModelChange, onVisibleChange, onSearch, onClear, onFirstFocus, afterVisibleChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "onlyLeafSelectable", "clearable", "loading", "size", "disabled", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "inputRef", "inputRender", "popupRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onFirstFocus", "afterVisibleChange"]);
30
30
  const namespace = useNamespace();
31
31
  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);
32
32
  const sheet = useJSS();
@@ -471,18 +471,21 @@ function CascaderFC(props, ref) {
471
471
  default:
472
472
  break;
473
473
  }
474
- return (_jsxs("div", Object.assign({}, mergeCS(styled('cascader-popup'), {
474
+ return (_jsx("div", Object.assign({}, mergeCS(styled('cascader-popup'), {
475
475
  style: Object.assign({ zIndex }, transitionStyle),
476
476
  }), { ref: popupRef, onMouseDown: (e) => {
477
477
  preventBlur(e);
478
478
  }, onMouseUp: (e) => {
479
479
  preventBlur(e);
480
- }, children: [loading && (_jsx("div", Object.assign({}, styled('cascader-popup__loading', {
481
- 'cascader-popup__loading--empty': isEmpty,
482
- }), { children: _jsx(Icon, { children: _jsx(CircularProgress, {}) }) }))), loading && isEmpty ? null : hasSearch ? (_jsx(CascaderSearchPanel, { ref: focusRef, 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
- changeItemFocusedWithSearch(item);
484
- changeSelectedByClickWithSearch(item);
485
- } })) : (_jsx(CascaderPanel, { ref: focusRef, 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 }))] })));
480
+ }, children: (() => {
481
+ const el = (_jsxs("div", Object.assign({}, styled('cascader-popup__content'), { children: [loading && (_jsx("div", Object.assign({}, styled('cascader-popup__loading', {
482
+ 'cascader-popup__loading--empty': isEmpty,
483
+ }), { children: _jsx(Icon, { children: _jsx(CircularProgress, {}) }) }))), loading && isEmpty ? null : hasSearch ? (_jsx(CascaderSearchPanel, { ref: focusRef, namespace: namespace, styled: styled, id: listId, list: searchList, customItem: customItem, itemId: getItemId, itemFocused: itemFocusedWithSearch, multiple: multiple, onlyLeafSelectable: onlyLeafSelectable, virtual: virtual, focusVisible: focusVisible, onClick: (item) => {
484
+ changeItemFocusedWithSearch(item);
485
+ changeSelectedByClickWithSearch(item);
486
+ } })) : (_jsx(CascaderPanel, { ref: focusRef, 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 }))] })));
487
+ return popupRender ? popupRender(el) : el;
488
+ })() })));
486
489
  } }) })] }));
487
490
  }
488
491
  export const Cascader = forwardRef(CascaderFC);
@@ -40,6 +40,7 @@ export interface CascaderProps<V extends React.Key, T extends CascaderItem<V>> e
40
40
  };
41
41
  inputRef?: React.ForwardedRef<HTMLInputElement>;
42
42
  inputRender?: CloneHTMLElement;
43
+ popupRender?: (el: React.ReactElement) => React.ReactNode;
43
44
  onModelChange?: (value: any, origin: any) => void;
44
45
  onVisibleChange?: (visible: boolean) => void;
45
46
  onSearch?: (value: string) => void;
@@ -16,6 +16,7 @@ export declare const CLASSES: {
16
16
  cascader__icon: string;
17
17
  cascader__arrow: string;
18
18
  'cascader-popup': string;
19
+ 'cascader-popup__content': string;
19
20
  'cascader-popup__loading': string;
20
21
  'cascader-popup__loading--empty': string;
21
22
  cascader__list: string;
package/cascader/vars.js CHANGED
@@ -16,6 +16,7 @@ export const CLASSES = {
16
16
  cascader__icon: '^cascader__icon',
17
17
  cascader__arrow: '^cascader__arrow',
18
18
  'cascader-popup': '^cascader-popup',
19
+ 'cascader-popup__content': '^cascader-popup__content',
19
20
  'cascader-popup__loading': '^cascader-popup__loading',
20
21
  'cascader-popup__loading--empty': '^cascader-popup__loading--empty',
21
22
  cascader__list: '^cascader__list',
@@ -18,7 +18,7 @@ import { getVerticalSidePosition, mergeCS } from '../utils';
18
18
  import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../vars';
19
19
  function DropdownFC(props, ref) {
20
20
  var _a;
21
- const _b = useComponentProps('Dropdown', props), { children, styleOverrides, styleProvider, list, visible: visibleProp, defaultVisible, trigger = 'hover', placement: placementProp = 'bottom-right', placementFixed = false, arrow = false, escClosable = true, zIndex: zIndexProp, onVisibleChange, afterVisibleChange, onClick } = _b, restProps = __rest(_b, ["children", "styleOverrides", "styleProvider", "list", "visible", "defaultVisible", "trigger", "placement", "placementFixed", "arrow", "escClosable", "zIndex", "onVisibleChange", "afterVisibleChange", "onClick"]);
21
+ const _b = useComponentProps('Dropdown', props), { children, styleOverrides, styleProvider, list, visible: visibleProp, defaultVisible, trigger = 'hover', placement: placementProp = 'bottom-right', placementFixed = false, arrow = false, escClosable = true, zIndex: zIndexProp, popupRender, onVisibleChange, afterVisibleChange, onClick } = _b, restProps = __rest(_b, ["children", "styleOverrides", "styleProvider", "list", "visible", "defaultVisible", "trigger", "placement", "placementFixed", "arrow", "escClosable", "zIndex", "popupRender", "onVisibleChange", "afterVisibleChange", "onClick"]);
22
22
  const namespace = useNamespace();
23
23
  const { t } = useTranslation();
24
24
  const styled = useStyled(CLASSES, { dropdown: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.dropdown, 'dropdown-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['dropdown-popup'] }, styleOverrides);
@@ -372,7 +372,10 @@ function DropdownFC(props, ref) {
372
372
  preventBlur(e);
373
373
  }, children: renderPopup(_jsxs("div", Object.assign({}, mergeCS(styled('dropdown-popup'), {
374
374
  style: Object.assign({ zIndex }, transitionStyle),
375
- }), { ref: popupRef, children: [_jsx("ul", Object.assign({}, styled('dropdown__list'), { ref: ulRef, id: id, tabIndex: -1, role: "menu", "aria-labelledby": triggerId, "aria-activedescendant": isUndefined(focusId) ? undefined : getItemId(focusId), children: list.length === 0 ? _jsx("div", Object.assign({}, styled('dropdown__empty'), { children: t('No Data') })) : nodes })), arrow && _jsx("div", Object.assign({}, styled('dropdown__arrow')))] }))) })));
375
+ }), { ref: popupRef, children: [(() => {
376
+ const el = (_jsx("ul", Object.assign({}, styled('dropdown__list'), { ref: ulRef, id: id, tabIndex: -1, role: "menu", "aria-labelledby": triggerId, "aria-activedescendant": isUndefined(focusId) ? undefined : getItemId(focusId), children: list.length === 0 ? _jsx("div", Object.assign({}, styled('dropdown__empty'), { children: t('No Data') })) : nodes })));
377
+ return popupRender ? popupRender(el) : el;
378
+ })(), arrow && _jsx("div", Object.assign({}, styled('dropdown__arrow')))] }))) })));
376
379
  } }) })] }));
377
380
  } }));
378
381
  }
@@ -25,6 +25,7 @@ export interface DropdownProps<ID extends React.Key, T extends DropdownItem<ID>>
25
25
  arrow?: boolean;
26
26
  escClosable?: boolean;
27
27
  zIndex?: number | string;
28
+ popupRender?: (el: React.ReactElement) => React.ReactNode;
28
29
  onVisibleChange?: (visible: boolean) => void;
29
30
  afterVisibleChange?: (visible: boolean) => void;
30
31
  onClick?: (id: ID, origin: T) => void | false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laser-ui/components",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "React components.",
5
5
  "keywords": [
6
6
  "ui",
@@ -26,8 +26,8 @@
26
26
  "module": "./index.js",
27
27
  "types": "./index.d.ts",
28
28
  "dependencies": {
29
- "@laser-ui/hooks": "0.4.0",
30
- "@laser-ui/utils": "0.4.0",
29
+ "@laser-ui/hooks": "0.5.0",
30
+ "@laser-ui/utils": "0.5.0",
31
31
  "@material-design-icons/svg": "^0.14.12",
32
32
  "jss": "^10.10.0",
33
33
  "jss-preset-default": "^10.10.0",
@@ -45,5 +45,5 @@
45
45
  "access": "public",
46
46
  "directory": "../../dist/libs/components"
47
47
  },
48
- "gitHead": "434cf3de2a91e6557cf77801eda230c46e137ec9"
48
+ "gitHead": "0c9f6009f6ad197c8870046b52277485a5217747"
49
49
  }
package/root/Root.js CHANGED
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEvent, useRefExtra } from '@laser-ui/hooks';
3
3
  import { isString, set } from 'lodash';
4
4
  import { useStore } from 'rcl-store';
@@ -7,10 +7,32 @@ import { ROOT_DATA, RootContext, Store } from './vars';
7
7
  import dayjs from '../dayjs';
8
8
  import { Portal } from '../internal/portal';
9
9
  import resources from '../resources.json';
10
+ function WindowSize() {
11
+ const windowSizeRef = useRef(null);
12
+ useEffect(() => {
13
+ if (windowSizeRef.current) {
14
+ const observer = new ResizeObserver((entries) => {
15
+ const entry = entries[0];
16
+ ROOT_DATA.windowSize = { width: entry.contentRect.width, height: entry.contentRect.height };
17
+ });
18
+ observer.observe(windowSizeRef.current);
19
+ return () => {
20
+ observer.disconnect();
21
+ };
22
+ }
23
+ });
24
+ return (_jsx("div", { ref: windowSizeRef, style: {
25
+ position: 'fixed',
26
+ top: 0,
27
+ right: 0,
28
+ bottom: 0,
29
+ left: 0,
30
+ pointerEvents: 'none',
31
+ } }));
32
+ }
10
33
  export function Root(props) {
11
34
  const { context: contextProp, children } = props;
12
35
  const windowRef = useRefExtra(() => window);
13
- const windowSizeRef = useRef(null);
14
36
  const [{ dialogs }] = useStore(Store, ['dialogs']);
15
37
  useEvent(windowRef, 'click', (e) => {
16
38
  // Check if click by keydown
@@ -25,18 +47,6 @@ export function Root(props) {
25
47
  }
26
48
  }
27
49
  }, { capture: true });
28
- useEffect(() => {
29
- if (windowSizeRef.current) {
30
- const observer = new ResizeObserver(() => {
31
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
32
- ROOT_DATA.windowSize = { width: windowSizeRef.current.clientWidth, height: windowSizeRef.current.clientHeight };
33
- });
34
- observer.observe(windowSizeRef.current);
35
- return () => {
36
- observer.disconnect();
37
- };
38
- }
39
- });
40
50
  const context = useMemo(() => {
41
51
  var _a, _b;
42
52
  const { i18n } = contextProp !== null && contextProp !== void 0 ? contextProp : {};
@@ -74,12 +84,5 @@ export function Root(props) {
74
84
  default:
75
85
  break;
76
86
  }
77
- return (_jsxs(RootContext.Provider, { value: context, children: [children, dialogs.map(({ type, key, props }) => createElement(type, Object.assign({ key }, props))), _jsx(Portal, { selector: () => document.body, children: _jsx("div", { ref: windowSizeRef, style: {
78
- position: 'fixed',
79
- top: 0,
80
- right: 0,
81
- bottom: 0,
82
- left: 0,
83
- pointerEvents: 'none',
84
- } }) })] }));
87
+ return (_jsxs(_Fragment, { children: [_jsxs(RootContext.Provider, { value: context, children: [children, dialogs.map(({ type, key, props }) => createElement(type, Object.assign({ key }, props)))] }), _jsx(Portal, { selector: () => document.body, children: _jsx(WindowSize, {}) })] }));
85
88
  }
package/select/Select.js CHANGED
@@ -25,7 +25,7 @@ import { getVerticalSidePosition, isPrintableCharacter, mergeCS } from '../utils
25
25
  import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../vars';
26
26
  import { VirtualScroll } from '../virtual-scroll';
27
27
  function SelectFC(props, ref) {
28
- const _a = useComponentProps('Select', props), { styleOverrides, styleProvider, formControl, list: listProp, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, monospaced = true, virtual = false, escClosable = true, customItem, customSelected, customSearch, createItem, inputRef: inputRefProp, inputRender, onModelChange, onVisibleChange, onSearch, onClear, onCreateItem, onScrollBottom, afterVisibleChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "clearable", "loading", "size", "disabled", "monospaced", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "createItem", "inputRef", "inputRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onCreateItem", "onScrollBottom", "afterVisibleChange"]);
28
+ const _a = useComponentProps('Select', props), { styleOverrides, styleProvider, formControl, list: listProp, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, monospaced = true, virtual = false, escClosable = true, customItem, customSelected, customSearch, createItem, inputRef: inputRefProp, inputRender, popupRender, onModelChange, onVisibleChange, onSearch, onClear, onCreateItem, onScrollBottom, afterVisibleChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "clearable", "loading", "size", "disabled", "monospaced", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "createItem", "inputRef", "inputRender", "popupRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onCreateItem", "onScrollBottom", "afterVisibleChange"]);
29
29
  const namespace = useNamespace();
30
30
  const styled = useStyled(CLASSES, { select: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.select, 'select-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['select-popup'] }, styleOverrides);
31
31
  const sheet = useJSS();
@@ -490,44 +490,47 @@ function SelectFC(props, ref) {
490
490
  default:
491
491
  break;
492
492
  }
493
- return (_jsxs("div", Object.assign({}, mergeCS(styled('select-popup'), {
493
+ return (_jsx("div", Object.assign({}, mergeCS(styled('select-popup'), {
494
494
  style: Object.assign({ zIndex }, transitionStyle),
495
495
  }), { ref: popupRef, onMouseDown: (e) => {
496
496
  preventBlur(e);
497
497
  }, onMouseUp: (e) => {
498
498
  preventBlur(e);
499
- }, children: [loading && (_jsx("div", Object.assign({}, styled('select-popup__loading', {
500
- 'select-popup__loading--empty': list.length === 0,
501
- }), { children: _jsx(Icon, { children: _jsx(CircularProgress, {}) }) }))), loading && list.length === 0 ? null : (_jsx(VirtualScroll, Object.assign({}, vsProps, { ref: vsRef, enable: virtual !== false, listSize: 264, listPadding: 4, itemRender: (item, index, props, ancestry, children) => {
502
- const { label: itemLabel, value: itemValue, disabled: itemDisabled } = item;
503
- const node = customItem ? customItem(item) : itemLabel;
504
- if (children) {
505
- return (_createElement("ul", Object.assign({}, styled('select__option-group'), { key: itemValue, role: "group", "aria-labelledby": getItemId(itemValue) }),
506
- _createElement("li", Object.assign({}, styled('select__option-group-label'), { key: itemValue, id: getItemId(itemValue), role: "presentation" }),
507
- _jsx("div", Object.assign({}, styled('select__option-content'), { children: node }))),
508
- children));
509
- }
510
- let isSelected = false;
511
- if (multiple) {
512
- isSelected = selected.has(itemValue);
513
- }
514
- else {
515
- isSelected = selected === itemValue;
516
- }
517
- return (_createElement("li", Object.assign({}, mergeCS(styled('select__option', {
518
- 'select__option.is-selected': !multiple && isSelected,
519
- 'select__option.is-disabled': itemDisabled,
520
- }), { style: { paddingLeft: ancestry.length === 0 ? undefined : 12 + 8 } }), props, { key: itemValue, id: getItemId(itemValue), title: (item[IS_CREATED] ? t('Create') + ' ' : '') + itemLabel, role: "option", "aria-selected": isSelected, "aria-disabled": itemDisabled, onClick: () => {
521
- if (item[IS_CREATED]) {
522
- handleCreateItem(item);
499
+ }, children: (() => {
500
+ const el = (_jsxs("div", Object.assign({}, styled('select-popup__content'), { children: [loading && (_jsx("div", Object.assign({}, styled('select-popup__loading', {
501
+ 'select-popup__loading--empty': list.length === 0,
502
+ }), { children: _jsx(Icon, { children: _jsx(CircularProgress, {}) }) }))), loading && list.length === 0 ? null : (_jsx(VirtualScroll, Object.assign({}, vsProps, { ref: vsRef, enable: virtual !== false, listSize: 264, listPadding: 4, itemRender: (item, index, props, ancestry, children) => {
503
+ const { label: itemLabel, value: itemValue, disabled: itemDisabled } = item;
504
+ const node = customItem ? customItem(item) : itemLabel;
505
+ if (children) {
506
+ return (_createElement("ul", Object.assign({}, styled('select__option-group'), { key: itemValue, role: "group", "aria-labelledby": getItemId(itemValue) }),
507
+ _createElement("li", Object.assign({}, styled('select__option-group-label'), { key: itemValue, id: getItemId(itemValue), role: "presentation" }),
508
+ _jsx("div", Object.assign({}, styled('select__option-content'), { children: node }))),
509
+ children));
523
510
  }
524
- changeItemFocused(item);
525
- changeSelectedByClick(itemValue);
526
- } }),
527
- focusVisible && (itemFocused === null || itemFocused === void 0 ? void 0 : itemFocused.value) === itemValue && _jsx("div", { className: `${namespace}-focus-outline` }),
528
- item[IS_CREATED] ? (_jsx("div", Object.assign({}, styled('select__option-prefix'), { children: _jsx(Icon, { theme: "primary", children: _jsx(AddOutlined, {}) }) }))) : multiple ? (_jsx("div", Object.assign({}, styled('select__option-prefix'), { children: _jsx(Checkbox, { model: isSelected, disabled: itemDisabled }) }))) : null,
529
- _jsx("div", Object.assign({}, styled('select__option-content'), { children: node }))));
530
- }, itemFocused: itemFocused === null || itemFocused === void 0 ? void 0 : itemFocused.value, itemEmptyRender: () => (_jsx("li", Object.assign({}, mergeCS(styled('select__empty'), { style: { paddingLeft: 12 + 8 } }), { children: _jsx("div", Object.assign({}, styled('select__option-content'), { children: t('No Data') })) }))), itemInAriaSetsize: (item) => !item.children, placeholder: "li", onScrollEnd: onScrollBottom, children: (vsList, onScroll) => (_jsx("ul", Object.assign({}, styled('select__list'), { ref: listRef, id: listId, tabIndex: -1, role: "listbox", "aria-multiselectable": multiple, "aria-activedescendant": isUndefined(itemFocused) ? undefined : getItemId(itemFocused.value), onScroll: onScroll, children: list.length === 0 ? _jsx(Empty, { style: { padding: '12px 0' }, image: Empty.SIMPLE_IMG }) : vsList }))) })))] })));
511
+ let isSelected = false;
512
+ if (multiple) {
513
+ isSelected = selected.has(itemValue);
514
+ }
515
+ else {
516
+ isSelected = selected === itemValue;
517
+ }
518
+ return (_createElement("li", Object.assign({}, mergeCS(styled('select__option', {
519
+ 'select__option.is-selected': !multiple && isSelected,
520
+ 'select__option.is-disabled': itemDisabled,
521
+ }), { style: { paddingLeft: ancestry.length === 0 ? undefined : 12 + 8 } }), props, { key: itemValue, id: getItemId(itemValue), title: (item[IS_CREATED] ? t('Create') + ' ' : '') + itemLabel, role: "option", "aria-selected": isSelected, "aria-disabled": itemDisabled, onClick: () => {
522
+ if (item[IS_CREATED]) {
523
+ handleCreateItem(item);
524
+ }
525
+ changeItemFocused(item);
526
+ changeSelectedByClick(itemValue);
527
+ } }),
528
+ focusVisible && (itemFocused === null || itemFocused === void 0 ? void 0 : itemFocused.value) === itemValue && _jsx("div", { className: `${namespace}-focus-outline` }),
529
+ item[IS_CREATED] ? (_jsx("div", Object.assign({}, styled('select__option-prefix'), { children: _jsx(Icon, { theme: "primary", children: _jsx(AddOutlined, {}) }) }))) : multiple ? (_jsx("div", Object.assign({}, styled('select__option-prefix'), { children: _jsx(Checkbox, { model: isSelected, disabled: itemDisabled }) }))) : null,
530
+ _jsx("div", Object.assign({}, styled('select__option-content'), { children: node }))));
531
+ }, itemFocused: itemFocused === null || itemFocused === void 0 ? void 0 : itemFocused.value, itemEmptyRender: () => (_jsx("li", Object.assign({}, mergeCS(styled('select__empty'), { style: { paddingLeft: 12 + 8 } }), { children: _jsx("div", Object.assign({}, styled('select__option-content'), { children: t('No Data') })) }))), itemInAriaSetsize: (item) => !item.children, placeholder: "li", onScrollEnd: onScrollBottom, children: (vsList, onScroll) => (_jsx("ul", Object.assign({}, styled('select__list'), { ref: listRef, id: listId, tabIndex: -1, role: "listbox", "aria-multiselectable": multiple, "aria-activedescendant": isUndefined(itemFocused) ? undefined : getItemId(itemFocused.value), onScroll: onScroll, children: list.length === 0 ? _jsx(Empty, { style: { padding: '12px 0' }, image: Empty.SIMPLE_IMG }) : vsList }))) })))] })));
532
+ return popupRender ? popupRender(el) : el;
533
+ })() })));
531
534
  } }) })] }));
532
535
  }
533
536
  export const Select = forwardRef(SelectFC);
package/select/types.d.ts CHANGED
@@ -40,6 +40,7 @@ export interface SelectProps<V extends React.Key, T extends SelectItem<V>> exten
40
40
  createItem?: (value: string) => T | undefined;
41
41
  inputRef?: React.ForwardedRef<HTMLInputElement>;
42
42
  inputRender?: CloneHTMLElement;
43
+ popupRender?: (el: React.ReactElement) => React.ReactNode;
43
44
  onModelChange?: (value: any, origin: any) => void;
44
45
  onVisibleChange?: (visible: boolean) => void;
45
46
  onSearch?: (value: string) => void;
package/select/vars.d.ts CHANGED
@@ -16,6 +16,7 @@ export declare const CLASSES: {
16
16
  select__icon: string;
17
17
  select__arrow: string;
18
18
  'select-popup': string;
19
+ 'select-popup__content': string;
19
20
  'select-popup__loading': string;
20
21
  'select-popup__loading--empty': string;
21
22
  select__list: string;
package/select/vars.js CHANGED
@@ -16,6 +16,7 @@ export const CLASSES = {
16
16
  select__icon: '^select__icon',
17
17
  select__arrow: '^select__arrow',
18
18
  'select-popup': '^select-popup',
19
+ 'select-popup__content': '^select-popup__content',
19
20
  'select-popup__loading': '^select-popup__loading',
20
21
  'select-popup__loading--empty': '^select-popup__loading--empty',
21
22
  select__list: '^select__list',
@@ -26,7 +26,7 @@ import { TREE_NODE_KEY } from '../tree/vars';
26
26
  import { getVerticalSidePosition, isPrintableCharacter, mergeCS } from '../utils';
27
27
  import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../vars';
28
28
  function TreeSelectFC(props, ref) {
29
- const _a = useComponentProps('TreeSelect', props), { styleOverrides, styleProvider, formControl, list, model, defaultModel, expands: expandsProp, defaultExpands, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, onlyLeafSelectable = true, showLine = false, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, virtual = false, escClosable = true, customItem, customSelected, customSearch, inputRef: inputRefProp, inputRender, onModelChange, onFirstExpand, onExpandsChange, onVisibleChange, onSearch, onClear, afterVisibleChange, onScrollBottom } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "expands", "defaultExpands", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "onlyLeafSelectable", "showLine", "clearable", "loading", "size", "disabled", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "inputRef", "inputRender", "onModelChange", "onFirstExpand", "onExpandsChange", "onVisibleChange", "onSearch", "onClear", "afterVisibleChange", "onScrollBottom"]);
29
+ const _a = useComponentProps('TreeSelect', props), { styleOverrides, styleProvider, formControl, list, model, defaultModel, expands: expandsProp, defaultExpands, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, onlyLeafSelectable = true, showLine = false, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, virtual = false, escClosable = true, customItem, customSelected, customSearch, inputRef: inputRefProp, inputRender, popupRender, onModelChange, onFirstExpand, onExpandsChange, onVisibleChange, onSearch, onClear, afterVisibleChange, onScrollBottom } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "expands", "defaultExpands", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "onlyLeafSelectable", "showLine", "clearable", "loading", "size", "disabled", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "inputRef", "inputRender", "popupRender", "onModelChange", "onFirstExpand", "onExpandsChange", "onVisibleChange", "onSearch", "onClear", "afterVisibleChange", "onScrollBottom"]);
30
30
  const namespace = useNamespace();
31
31
  const styled = useStyled(CLASSES, {
32
32
  'tree-select': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['tree-select'],
@@ -493,18 +493,21 @@ function TreeSelectFC(props, ref) {
493
493
  default:
494
494
  break;
495
495
  }
496
- return (_jsxs("div", Object.assign({}, mergeCS(styled('tree-select-popup'), {
496
+ return (_jsx("div", Object.assign({}, mergeCS(styled('tree-select-popup'), {
497
497
  style: Object.assign({ zIndex }, transitionStyle),
498
498
  }), { ref: popupRef, onMouseDown: (e) => {
499
499
  preventBlur(e);
500
500
  }, onMouseUp: (e) => {
501
501
  preventBlur(e);
502
- }, children: [loading && (_jsx("div", Object.assign({}, styled('tree-select-popup__loading', {
503
- 'tree-select-popup__loading--empty': isEmpty,
504
- }), { children: _jsx(Icon, { children: _jsx(CircularProgress, {}) }) }))), loading && isEmpty ? null : hasSearch ? (_jsx(TreeSelectSearchPanel, { ref: focusRef, namespace: namespace, styled: styled, id: listId, list: searchList, customItem: customItem, itemId: getItemId, itemFocused: itemFocusedWithSearch, multiple: multiple, onlyLeafSelectable: onlyLeafSelectable, virtual: virtual, focusVisible: focusVisible, onClick: (item) => {
505
- setItemFocusedWithSearch(item);
506
- changeSelectedByClickWithSearch(item);
507
- } })) : (_jsx(TreePanel, { style: { maxHeight: 264, padding: '4px 0' }, ref: focusRef, id: listId, namespace: namespace, styled: styled, list: nodes, itemId: getItemId, itemSelected: !multiple && hasSelected ? nodesMap.get(selected) : undefined, itemFocused: itemFocusedWithoutSearch, expands: expands, customItem: customItem, showLine: showLine, multiple: multiple, onlyLeafSelectable: onlyLeafSelectable, disabled: false, virtual: virtual === false ? undefined : { listSize: 264, listPadding: 4, itemSize: isNumber(virtual) ? virtual : 32 }, focusVisible: focusVisible, onNodeFocus: setItemFocusedWithoutSearch, onNodeExpand: handleExpand, onNodeClick: changeSelectedByClickWithoutSearch, onScrollBottom: onScrollBottom }))] })));
502
+ }, children: (() => {
503
+ const el = (_jsxs("div", Object.assign({}, styled('tree-select-popup__content'), { children: [loading && (_jsx("div", Object.assign({}, styled('tree-select-popup__loading', {
504
+ 'tree-select-popup__loading--empty': isEmpty,
505
+ }), { children: _jsx(Icon, { children: _jsx(CircularProgress, {}) }) }))), loading && isEmpty ? null : hasSearch ? (_jsx(TreeSelectSearchPanel, { ref: focusRef, namespace: namespace, styled: styled, id: listId, list: searchList, customItem: customItem, itemId: getItemId, itemFocused: itemFocusedWithSearch, multiple: multiple, onlyLeafSelectable: onlyLeafSelectable, virtual: virtual, focusVisible: focusVisible, onClick: (item) => {
506
+ setItemFocusedWithSearch(item);
507
+ changeSelectedByClickWithSearch(item);
508
+ } })) : (_jsx(TreePanel, { style: { maxHeight: 264, padding: '4px 0' }, ref: focusRef, id: listId, namespace: namespace, styled: styled, list: nodes, itemId: getItemId, itemSelected: !multiple && hasSelected ? nodesMap.get(selected) : undefined, itemFocused: itemFocusedWithoutSearch, expands: expands, customItem: customItem, showLine: showLine, multiple: multiple, onlyLeafSelectable: onlyLeafSelectable, disabled: false, virtual: virtual === false ? undefined : { listSize: 264, listPadding: 4, itemSize: isNumber(virtual) ? virtual : 32 }, focusVisible: focusVisible, onNodeFocus: setItemFocusedWithoutSearch, onNodeExpand: handleExpand, onNodeClick: changeSelectedByClickWithoutSearch, onScrollBottom: onScrollBottom }))] })));
509
+ return popupRender ? popupRender(el) : el;
510
+ })() })));
508
511
  } }) })] }));
509
512
  }
510
513
  export const TreeSelect = forwardRef(TreeSelectFC);
@@ -37,6 +37,7 @@ export interface TreeSelectProps<V extends React.Key, T extends TreeItem<V>> ext
37
37
  };
38
38
  inputRef?: React.ForwardedRef<HTMLInputElement>;
39
39
  inputRender?: CloneHTMLElement;
40
+ popupRender?: (el: React.ReactElement) => React.ReactNode;
40
41
  onModelChange?: (value: any, origin: any) => void;
41
42
  onFirstExpand?: (value: V, origin: T) => void;
42
43
  onExpandsChange?: (values: V[], origins: T[]) => void;
@@ -16,6 +16,7 @@ export declare const CLASSES: {
16
16
  'tree-select__icon': string;
17
17
  'tree-select__arrow': string;
18
18
  'tree-select-popup': string;
19
+ 'tree-select-popup__content': string;
19
20
  'tree-select-popup__loading': string;
20
21
  'tree-select-popup__loading--empty': string;
21
22
  tree: string;
@@ -16,6 +16,7 @@ export const CLASSES = {
16
16
  'tree-select__icon': '^tree-select__icon',
17
17
  'tree-select__arrow': '^tree-select__arrow',
18
18
  'tree-select-popup': '^tree-select-popup',
19
+ 'tree-select-popup__content': '^tree-select-popup__content',
19
20
  'tree-select-popup__loading': '^tree-select-popup__loading',
20
21
  'tree-select-popup__loading--empty': '^tree-select-popup__loading--empty',
21
22
  tree: '^tree',