@canlooks/can-ui 0.0.204 → 0.0.206

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.
Files changed (51) hide show
  1. package/dist/cjs/components/autocomplete/autocomplete.js +6 -1
  2. package/dist/cjs/components/curd/curd.js +1 -0
  3. package/dist/cjs/components/curd/curd.style.d.ts +1 -0
  4. package/dist/cjs/components/curd/curd.style.js +2 -1
  5. package/dist/cjs/components/curd/curdColumnConfig.js +3 -2
  6. package/dist/cjs/components/curd/curdColumnConfig.style.js +3 -12
  7. package/dist/cjs/components/dataGrid/dataGrid.d.ts +2 -1
  8. package/dist/cjs/components/dataGrid/dataGrid.js +7 -2
  9. package/dist/cjs/components/dataGrid/dataGrid.style.js +27 -16
  10. package/dist/cjs/components/dataGrid/dataGridHead.d.ts +2 -1
  11. package/dist/cjs/components/dataGrid/dataGridHead.js +2 -2
  12. package/dist/cjs/components/dataGrid/dataGridRows.js +5 -3
  13. package/dist/cjs/components/dataGrid/stickyRow.d.ts +5 -0
  14. package/dist/cjs/components/dataGrid/stickyRow.js +28 -0
  15. package/dist/cjs/components/popper/popper.js +67 -67
  16. package/dist/cjs/components/select/select.js +10 -1
  17. package/dist/cjs/components/selectedList/selectedItem.js +2 -1
  18. package/dist/cjs/components/selectedList/selectedList.js +6 -1
  19. package/dist/cjs/components/selectionContext/selectionHook.js +6 -1
  20. package/dist/cjs/components/table/table.style.js +1 -1
  21. package/dist/cjs/components/table/tableSticky.js +3 -1
  22. package/dist/cjs/components/table/tableSticky.style.js +1 -1
  23. package/dist/cjs/utils/dataGrid.js +6 -1
  24. package/dist/cjs/utils/dnd.d.ts +1 -0
  25. package/dist/cjs/utils/dnd.js +12 -9
  26. package/dist/esm/components/autocomplete/autocomplete.js +6 -1
  27. package/dist/esm/components/curd/curd.js +1 -0
  28. package/dist/esm/components/curd/curd.style.d.ts +1 -0
  29. package/dist/esm/components/curd/curd.style.js +2 -1
  30. package/dist/esm/components/curd/curdColumnConfig.js +3 -2
  31. package/dist/esm/components/curd/curdColumnConfig.style.js +3 -12
  32. package/dist/esm/components/dataGrid/dataGrid.d.ts +2 -1
  33. package/dist/esm/components/dataGrid/dataGrid.js +8 -3
  34. package/dist/esm/components/dataGrid/dataGrid.style.js +27 -16
  35. package/dist/esm/components/dataGrid/dataGridHead.d.ts +2 -1
  36. package/dist/esm/components/dataGrid/dataGridHead.js +2 -2
  37. package/dist/esm/components/dataGrid/dataGridRows.js +5 -3
  38. package/dist/esm/components/dataGrid/stickyRow.d.ts +5 -0
  39. package/dist/esm/components/dataGrid/stickyRow.js +25 -0
  40. package/dist/esm/components/popper/popper.js +67 -67
  41. package/dist/esm/components/select/select.js +10 -1
  42. package/dist/esm/components/selectedList/selectedItem.js +2 -1
  43. package/dist/esm/components/selectedList/selectedList.js +7 -2
  44. package/dist/esm/components/selectionContext/selectionHook.js +6 -1
  45. package/dist/esm/components/table/table.style.js +1 -1
  46. package/dist/esm/components/table/tableSticky.js +3 -1
  47. package/dist/esm/components/table/tableSticky.style.js +1 -1
  48. package/dist/esm/utils/dataGrid.js +6 -1
  49. package/dist/esm/utils/dnd.d.ts +1 -0
  50. package/dist/esm/utils/dnd.js +12 -9
  51. package/package.json +1 -1
@@ -48,7 +48,12 @@ exports.Autocomplete = (0, react_1.memo)(({ children, loading, options, loadOpti
48
48
  actualOptions?.forEach(opt => {
49
49
  if (opt && typeof opt === 'object') {
50
50
  const key = opt[primaryKey];
51
- !(0, utils_1.isUnset)(key) && map.set(key, opt);
51
+ if (!(0, utils_1.isUnset)(key)) {
52
+ if (map.has(key)) {
53
+ console.warn(`[@canlooks/can-ui/<Autocomple/>] option key "${key}" was duplicated`);
54
+ }
55
+ map.set(key, opt);
56
+ }
52
57
  }
53
58
  });
54
59
  return map;
@@ -97,6 +97,7 @@ exports.Curd = (0, react_1.memo)((props) => {
97
97
  const controlColumn = {
98
98
  key: utils_1.CONTROL_COLUMN_KEY,
99
99
  title: controlColumnTitle,
100
+ className: curd_style_1.classes.controlColumn,
100
101
  render(row) {
101
102
  const _updatable = typeof updatable === 'function' ? updatable(row) : updatable;
102
103
  const _deletable = typeof deletable === 'function' ? deletable(row) : deletable;
@@ -14,6 +14,7 @@ export declare const classes: {
14
14
  toolbarLeft: string;
15
15
  toolbarRight: string;
16
16
  card: string;
17
+ controlColumn: string;
17
18
  dialogTitle: string;
18
19
  copyButton: string;
19
20
  } & {
@@ -20,6 +20,7 @@ exports.classes = (0, utils_1.defineInnerClasses)('curd', [
20
20
  'toolbarRight',
21
21
  'divider',
22
22
  'card',
23
+ 'controlColumn',
23
24
  'control',
24
25
  'dialogTitle',
25
26
  'copyButton'
@@ -32,7 +33,7 @@ exports.style = (0, utils_1.defineCss)(({ spacing, text, background, borderRadiu
32
33
  min-height: 0;
33
34
  display: flex;
34
35
  flex-direction: column;
35
-
36
+
36
37
  .${exports.classes.filterForm} {
37
38
  min-height: 0;
38
39
  display: flex;
@@ -13,6 +13,7 @@ const utils_1 = require("../../utils");
13
13
  const icon_1 = require("../icon");
14
14
  const faGear_1 = require("@fortawesome/free-solid-svg-icons/faGear");
15
15
  const react_2 = require("@dnd-kit/react");
16
+ const tooltip_1 = require("../tooltip");
16
17
  exports.CurdColumnConfig = (0, react_1.memo)((props) => {
17
18
  const dragEndHandler = e => {
18
19
  const newColumns = (0, utils_1.onDndDragEnd)(e, props.columns || [], '_key');
@@ -41,12 +42,12 @@ const CurdColumnConfigContent = (0, react_1.memo)(({ columns, innerVisible, setI
41
42
  ? [...o, key]
42
43
  : o.filter(k => k !== key));
43
44
  };
44
- return ((0, jsx_runtime_1.jsx)(bubble_1.Bubble, { placement: "bottomRight", trigger: ['hover', 'click'], ...columnConfigBubbleProps, css: curdColumnConfig_style_1.style, open: open, onOpenChange: openChangeHandler, content: (0, jsx_runtime_1.jsxs)("div", { className: curdColumnConfig_style_1.classes.content, children: [(0, jsx_runtime_1.jsxs)("div", { className: curdColumnConfig_style_1.classes.title, children: [(0, jsx_runtime_1.jsx)("div", { className: curdColumnConfig_style_1.classes.titleText, children: "\u5217\u8BBE\u7F6E" }), (0, jsx_runtime_1.jsx)("div", { className: curdColumnConfig_style_1.classes.description, children: "\u62D6\u62FD\u8C03\u6574\u987A\u5E8F" })] }), columns?.map((col, i) => {
45
+ return ((0, jsx_runtime_1.jsx)(bubble_1.Bubble, { placement: "bottomRight", trigger: "click", ...columnConfigBubbleProps, css: curdColumnConfig_style_1.style, open: open, onOpenChange: openChangeHandler, content: (0, jsx_runtime_1.jsxs)("div", { className: curdColumnConfig_style_1.classes.content, children: [(0, jsx_runtime_1.jsxs)("div", { className: curdColumnConfig_style_1.classes.title, children: [(0, jsx_runtime_1.jsx)("div", { className: curdColumnConfig_style_1.classes.titleText, children: "\u5217\u8BBE\u7F6E" }), (0, jsx_runtime_1.jsx)("div", { className: curdColumnConfig_style_1.classes.description, children: "\u62D6\u62FD\u8C03\u6574\u987A\u5E8F" })] }), columns?.map((col, i) => {
45
46
  const id = col._key;
46
47
  const checked = !(0, utils_1.isUnset)(id) && (!visibleSet || visibleSet.has(id));
47
48
  return ((0, jsx_runtime_1.jsx)(sortableItem_1.SortableItem, { id: id ?? i, index: i, component: menuItem_1.MenuItem, className: curdColumnConfig_style_1.classes.item, prefix: (0, jsx_runtime_1.jsx)(checkbox_1.Checkbox, { className: curdColumnConfig_style_1.classes.checkbox, checked: checked, onChange: e => {
48
49
  e.stopPropagation();
49
50
  toggleVisible(id, e.target.checked);
50
51
  } }), onClick: () => toggleVisible(id, !checked), label: col.titleText ?? col.title, noStyle: true }, id ?? i));
51
- })] }), autoClose: false, children: (0, jsx_runtime_1.jsx)(button_1.Button, { shape: "circular", variant: "text", color: "text.secondary", children: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faGear_1.faGear }) }) }));
52
+ })] }), autoClose: false, children: (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { title: "\u5217\u8BBE\u7F6E", clickToClose: true, children: (0, jsx_runtime_1.jsx)(button_1.Button, { shape: "circular", variant: "text", color: "text.secondary", children: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faGear_1.faGear }) }) }) }));
52
53
  });
@@ -21,25 +21,16 @@ exports.style = (0, utils_1.defineCss)(({ spacing, text }) => (0, react_1.css) `
21
21
  align-items: center;
22
22
  justify-content: space-between;
23
23
  padding: ${spacing[3]}px;
24
-
24
+
25
25
  .${exports.classes.titleText} {
26
26
  font-weight: bold;
27
27
  }
28
-
28
+
29
29
  .${exports.classes.description} {
30
30
  color: ${text.disabled};
31
31
  }
32
32
  }
33
-
34
- .${exports.classes.item} {
35
- cursor: pointer;
36
-
37
- &[data-dragging=true] {
38
- position: relative;
39
- z-index: 1;
40
- }
41
- }
42
-
33
+
43
34
  .${exports.classes.checkbox} {
44
35
  display: flex;
45
36
  margin-right: ${spacing[1]}px;
@@ -1,4 +1,4 @@
1
- import React, { ComponentProps, ReactElement, ReactNode } from 'react';
1
+ import React, { ComponentProps, ReactElement, ReactNode, RefObject } from 'react';
2
2
  import { DivProps, Id, Obj, SlotsAndProps, ToRequired } from '../../types';
3
3
  import { SelectionContextProps } from '../selectionContext';
4
4
  import { PaginationProps } from '../pagination';
@@ -136,6 +136,7 @@ interface IDataGridContext<R extends RowType = RowType> extends ToRequired<DataG
136
136
  expandedSet: Set<Id>;
137
137
  flattedColumns: (symbol | ColumnType<R>)[] | undefined;
138
138
  toggleExpanded(key: Id): void;
139
+ theadRef: RefObject<HTMLTableSectionElement | null>;
139
140
  }
140
141
  export declare function useDataGridContext<R extends RowType>(): IDataGridContext<R>;
141
142
  export declare const DataGrid: {
@@ -130,13 +130,18 @@ exports.DataGrid = (0, react_1.memo)(({ slots, slotProps, columns, rows, rowProp
130
130
  const { page, pageSize } = _paginationProps;
131
131
  return orderedRows?.slice((page - 1) * pageSize, page * pageSize);
132
132
  }, [orderedRows, _paginationProps.page, _paginationProps.pageSize, paginatable]);
133
+ /**
134
+ * ---------------------------------------------------------------
135
+ * 渲染
136
+ */
137
+ const theadRef = (0, react_1.useRef)(null);
133
138
  const { container: Container = table_1.TableContainer } = slots || {};
134
139
  const { container: containerProps } = slotProps || {};
135
140
  const renderedContent = ((0, jsx_runtime_1.jsx)(columnResize_1.ColumnResizeContext, { columnResizable: columnResizable, children: ({ scrollerRef, tableRef }) => (0, jsx_runtime_1.jsxs)(Container, { ...(0, utils_1.mergeComponentProps)(containerProps, {
136
141
  ref: scrollerRef,
137
142
  className: dataGrid_style_1.classes.container
138
- }), children: [(0, jsx_runtime_1.jsx)(table_1.Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: (0, utils_1.cloneRef)(tableProps?.ref, tableRef), children: (0, jsx_runtime_1.jsxs)(selectionContext_1.SelectionContext, { options: rows, primaryKey: primaryKey, childrenKey: childrenKey !== null ? childrenKey : void 0, relation: relation, integration: integration, disabled: !selectable, multiple: multiple, defaultValue: defaultValue, value: value, onChange: onChange, onToggle: onToggle, children: [(0, jsx_runtime_1.jsx)(dataGridHead_1.DataGridHead, { rows: rows, flattedColumns: flattedColumns, completedColumns: completedColumns, primaryKey: primaryKey, allowSelectAll: allowSelectAll, columnResizable: columnResizable, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler, filterBubbleProps: filterBubbleProps, onFilterClick: onFilterClick }), (0, jsx_runtime_1.jsx)("tbody", { children: (0, jsx_runtime_1.jsx)(DataGridContext, { value: (0, react_1.useMemo)(() => ({
139
- slots, slotProps,
143
+ }), children: [(0, jsx_runtime_1.jsx)(table_1.Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: (0, utils_1.cloneRef)(tableProps?.ref, tableRef), children: (0, jsx_runtime_1.jsxs)(selectionContext_1.SelectionContext, { options: rows, primaryKey: primaryKey, childrenKey: childrenKey !== null ? childrenKey : void 0, relation: relation, integration: integration, disabled: !selectable, multiple: multiple, defaultValue: defaultValue, value: value, onChange: onChange, onToggle: onToggle, children: [(0, jsx_runtime_1.jsx)(dataGridHead_1.DataGridHead, { ref: theadRef, rows: rows, flattedColumns: flattedColumns, completedColumns: completedColumns, primaryKey: primaryKey, allowSelectAll: allowSelectAll, columnResizable: columnResizable, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler, filterBubbleProps: filterBubbleProps, onFilterClick: onFilterClick }), (0, jsx_runtime_1.jsx)("tbody", { children: (0, jsx_runtime_1.jsx)(DataGridContext, { value: (0, react_1.useMemo)(() => ({
144
+ slots, slotProps, theadRef,
140
145
  rowProps, primaryKey, childrenKey, clickRowToSelect, indent, renderExpandIcon,
141
146
  expandedSet, flattedColumns, toggleExpanded
142
147
  }), [
@@ -92,25 +92,36 @@ exports.style = (0, utils_1.defineCss)(({ spacing, mode, gray, text, colors, eas
92
92
  }
93
93
  }
94
94
  }
95
+
96
+ tr {
97
+ position: relative;
98
+ z-index: 2;
99
+
100
+ &[data-expanded=true] {
101
+ position: sticky;
102
+ z-index: 1;
103
+ }
104
+
105
+ &.${exports.classes.sub} {
106
+ z-index: 0;
107
+ background-color: ${gray(mode === 'light' ? .02 : .22)};
95
108
 
96
- tr.${exports.classes.sub} {
97
- background-color: ${gray(mode === 'light' ? .02 : .22)};
98
-
99
- td.${exports.classes.subTd} {
100
- padding: 0;
101
- border: none;
109
+ td.${exports.classes.subTd} {
110
+ padding: 0;
111
+ border: none;
102
112
 
103
- .${exports.classes.children} {
104
- padding: ${spacing[4]}px ${spacing[5]}px;
105
- border-bottom: 1px solid ${gray(mode === 'light' ? .12 : .32)};
113
+ .${exports.classes.children} {
114
+ padding: ${spacing[4]}px ${spacing[5]}px;
115
+ border-bottom: 1px solid ${gray(mode === 'light' ? .12 : .32)};
106
116
 
107
- thead, tfoot {
108
- z-index: 3;
109
- }
117
+ thead, tfoot {
118
+ z-index: 5;
119
+ }
110
120
 
111
- th, td {
112
- &[data-sticky=left], &[data-sticky=right] {
113
- z-index: 2;
121
+ th, td {
122
+ &[data-sticky=left], &[data-sticky=right] {
123
+ z-index: 4;
124
+ }
114
125
  }
115
126
  }
116
127
  }
@@ -157,7 +168,7 @@ exports.style = (0, utils_1.defineCss)(({ spacing, mode, gray, text, colors, eas
157
168
  position: absolute;
158
169
  top: 0;
159
170
  right: -4px;
160
- z-index: 1;
171
+ z-index: 3;
161
172
  }
162
173
 
163
174
  th:last-of-type {
@@ -1,7 +1,8 @@
1
- import { ReactElement } from 'react';
1
+ import { ReactElement, RefObject } from 'react';
2
2
  import { ColumnType, DataGridProps, RowType } from './dataGrid';
3
3
  import { Id } from '../../types';
4
4
  interface DataGridHeadProps<R extends RowType, V extends Id = Id> extends Required<Pick<DataGridProps<R, V>, 'primaryKey' | 'orderType' | 'onOrderChange' | 'allowSelectAll' | 'columnResizable'>> {
5
+ ref: RefObject<HTMLTableSectionElement | null>;
5
6
  rows: R[] | undefined;
6
7
  orderColumn: Id | undefined;
7
8
  flattedColumns: (symbol | ColumnType<R>)[] | undefined;
@@ -18,7 +18,7 @@ const bubble_1 = require("../bubble");
18
18
  const filterBubbleContent_1 = require("./filterBubbleContent");
19
19
  const form_1 = require("../form");
20
20
  const utils_1 = require("../../utils");
21
- exports.DataGridHead = (0, react_2.memo)(({ allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, filterBubbleProps, onFilterClick }) => {
21
+ exports.DataGridHead = (0, react_2.memo)(({ ref, allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, filterBubbleProps, onFilterClick }) => {
22
22
  const { multiple, setValue, selectionStatus } = (0, selectionContext_1.useSelectionContext)();
23
23
  const allSelectionStatus = (0, react_2.useMemo)(() => {
24
24
  if (multiple && allowSelectAll) {
@@ -116,5 +116,5 @@ exports.DataGridHead = (0, react_2.memo)(({ allowSelectAll, columnResizable, fla
116
116
  ];
117
117
  }) }, i));
118
118
  });
119
- return (0, jsx_runtime_1.jsx)("thead", { children: renderedHead });
119
+ return (0, jsx_runtime_1.jsx)("thead", { ref: ref, children: renderedHead });
120
120
  });
@@ -16,10 +16,11 @@ const icon_1 = require("../icon");
16
16
  const faMinusSquare_1 = require("@fortawesome/free-regular-svg-icons/faMinusSquare");
17
17
  const faPlusSquare_1 = require("@fortawesome/free-regular-svg-icons/faPlusSquare");
18
18
  const dataGrid_style_1 = require("./dataGrid.style");
19
+ const stickyRow_1 = require("./stickyRow");
19
20
  exports.DataGridRows = (0, react_2.memo)(({ rows, _level = 0 }) => {
20
21
  const { multiple, toggleSelected, selectionStatus } = (0, selectionContext_1.useSelectionContext)();
21
22
  const { slots, slotProps, rowProps, primaryKey, childrenKey, clickRowToSelect, indent, renderExpandIcon, expandedSet, flattedColumns, toggleExpanded } = (0, dataGrid_1.useDataGridContext)();
22
- const { tr: Tr = 'tr' } = slots || {};
23
+ const { tr: Tr = stickyRow_1.StickyRow } = slots || {};
23
24
  const { tr: TrProps } = slotProps || {};
24
25
  return rows?.flatMap((row, i, arr) => {
25
26
  const trKey = row[primaryKey];
@@ -37,8 +38,9 @@ exports.DataGridRows = (0, react_2.memo)(({ rows, _level = 0 }) => {
37
38
  className: (0, utils_1.clsx)(_rowProps, _level > 0 && dataGrid_style_1.classes.sub),
38
39
  onClick() {
39
40
  clickRowToSelect && toggleSelected(trKey);
40
- }
41
- }), key: trKey, "data-selected": status === 2 }, flattedColumns?.flatMap((col, j) => {
41
+ },
42
+ sticky: currentExpanded
43
+ }), key: trKey, "data-selected": status === 2, "data-expanded": currentExpanded }, flattedColumns?.flatMap((col, j) => {
42
44
  if (typeof col === 'symbol') {
43
45
  if (col === dataGrid_1.DataGrid.EXPAND_COLUMN) {
44
46
  expandableIndex = j;
@@ -0,0 +1,5 @@
1
+ import { ComponentProps } from 'react';
2
+ export interface StickyRowProps extends ComponentProps<'tr'> {
3
+ sticky?: boolean;
4
+ }
5
+ export declare function StickyRow({ sticky, ...props }: StickyRowProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StickyRow = StickyRow;
4
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const dataGrid_1 = require("./dataGrid");
7
+ const utils_1 = require("../../utils");
8
+ function StickyRow({ sticky, ...props }) {
9
+ const [offset, setOffset] = (0, react_1.useState)(0);
10
+ const { theadRef } = (0, dataGrid_1.useDataGridContext)();
11
+ (0, react_1.useEffect)(() => {
12
+ if (!sticky || !theadRef.current) {
13
+ return;
14
+ }
15
+ const resizeObserver = new ResizeObserver(() => {
16
+ setOffset(theadRef.current.offsetHeight);
17
+ });
18
+ resizeObserver.observe(theadRef.current);
19
+ return () => {
20
+ resizeObserver.disconnect();
21
+ };
22
+ }, [sticky]);
23
+ return ((0, jsx_runtime_1.jsx)("tr", { ...(0, utils_1.mergeComponentProps)(props, {
24
+ ...sticky && {
25
+ style: { top: offset }
26
+ }
27
+ }) }));
28
+ }
@@ -9,18 +9,56 @@ const clickAway_1 = require("../clickAway");
9
9
  const popper_style_1 = require("./popper.style");
10
10
  const popperContext_1 = require("./popperContext");
11
11
  const theme_1 = require("../theme");
12
- const getAttemptOrder = (placement) => {
13
- const order = ['top', 'bottom', 'left', 'right', 'topLeft', 'topRight', 'rightTop', 'rightBottom', 'bottomRight', 'bottomLeft', 'leftBottom', 'leftTop'];
14
- const index = order.indexOf(placement);
15
- if (index > -1) {
16
- return [
17
- placement,
18
- ...order.slice(index + 1),
19
- ...order.slice(0, index),
20
- placement
21
- ];
12
+ const defaultAttemptOrder = ['top', 'bottom', 'left', 'right', 'topLeft', 'topRight', 'rightTop', 'rightBottom', 'bottomRight', 'bottomLeft', 'leftBottom', 'leftTop'];
13
+ const contextMenuOrder = [
14
+ 'bottomRight',
15
+ 'rightBottom',
16
+ 'bottomLeft',
17
+ 'leftBottom',
18
+ 'topLeft',
19
+ 'leftTop',
20
+ 'topRight',
21
+ 'rightTop'
22
+ ];
23
+ const getAttemptOrder = (startPlacement, contextMenu, sizeAdaptable, callback) => {
24
+ if (contextMenu) {
25
+ const startIndex = Math.max(contextMenuOrder.indexOf(startPlacement), 0);
26
+ for (let i = 0; i <= contextMenuOrder.length + 1; i += 2) {
27
+ const index = (startIndex + i) % contextMenuOrder.length;
28
+ if (callback(contextMenuOrder[index]) === false) {
29
+ break;
30
+ }
31
+ }
32
+ }
33
+ else {
34
+ let order = defaultAttemptOrder;
35
+ let startIndex;
36
+ if (sizeAdaptable) {
37
+ switch (startPlacement) {
38
+ case 'top':
39
+ order = [startPlacement, 'bottom', startPlacement];
40
+ break;
41
+ case 'bottom':
42
+ order = [startPlacement, 'top', startPlacement];
43
+ break;
44
+ case 'left':
45
+ order = [startPlacement, 'right', startPlacement];
46
+ break;
47
+ case 'right':
48
+ order = [startPlacement, 'left', startPlacement];
49
+ }
50
+ startIndex = 0;
51
+ }
52
+ else {
53
+ startIndex = Math.max(order.indexOf(startPlacement), 0);
54
+ }
55
+ for (let i = 0; i <= order.length; i++) {
56
+ const index = (startIndex + i) % order.length;
57
+ if (callback(order[index]) === false) {
58
+ break;
59
+ }
60
+ }
22
61
  }
23
- return order;
24
62
  };
25
63
  const splitPlacement = {
26
64
  top: ['top'],
@@ -141,33 +179,6 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
141
179
  const mouseY = contextMenuEvent.current.clientY - containerRect.top;
142
180
  attempt = placement => {
143
181
  switch (placement) {
144
- case 'topLeft':
145
- case 'leftTop':
146
- top = void 0;
147
- bottom = -mouseY;
148
- left = void 0;
149
- right = containerRect.width - mouseX;
150
- originX = '100%';
151
- originY = '100%';
152
- break;
153
- case 'topRight':
154
- case 'rightTop':
155
- top = void 0;
156
- bottom = -mouseY;
157
- left = mouseX;
158
- right = void 0;
159
- originX = '0%';
160
- originY = '100%';
161
- break;
162
- case 'bottomLeft':
163
- case 'leftBottom':
164
- top = mouseY;
165
- bottom = void 0;
166
- left = void 0;
167
- right = containerRect.width - mouseX;
168
- originX = '100%';
169
- originY = '0%';
170
- break;
171
182
  case 'bottomRight':
172
183
  case 'rightBottom':
173
184
  top = mouseY;
@@ -177,37 +188,32 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
177
188
  originX = '0%';
178
189
  originY = '0%';
179
190
  break;
180
- case 'top':
181
- top = mouseY - popperHeight;
182
- bottom = void 0;
183
- left = mouseX - popperWidth / 2;
184
- right = void 0;
185
- originX = '50%';
186
- originY = '100%';
187
- break;
188
- case 'bottom':
191
+ case 'bottomLeft':
192
+ case 'leftBottom':
189
193
  top = mouseY;
190
194
  bottom = void 0;
191
- left = mouseX - popperWidth / 2;
192
- right = void 0;
193
- originX = '50%';
195
+ left = void 0;
196
+ right = containerRect.width - mouseX;
197
+ originX = '100%';
194
198
  originY = '0%';
195
199
  break;
196
- case 'left':
197
- top = mouseY - popperHeight / 2;
198
- bottom = void 0;
199
- left = mouseX - popperWidth;
200
- right = void 0;
200
+ case 'topLeft':
201
+ case 'leftTop':
202
+ top = void 0;
203
+ bottom = -mouseY;
204
+ left = void 0;
205
+ right = containerRect.width - mouseX;
201
206
  originX = '100%';
202
- originY = '50%';
207
+ originY = '100%';
203
208
  break;
204
- case 'right':
205
- top = mouseY - popperHeight / 2;
206
- bottom = void 0;
209
+ case 'topRight':
210
+ case 'rightTop':
211
+ top = void 0;
212
+ bottom = -mouseY;
207
213
  left = mouseX;
208
214
  right = void 0;
209
215
  originX = '0%';
210
- originY = '50%';
216
+ originY = '100%';
211
217
  }
212
218
  popperEl.style.top = typeof top === 'undefined' ? '' : top + 'px';
213
219
  popperEl.style.bottom = typeof bottom === 'undefined' ? '' : bottom + 'px';
@@ -311,13 +317,7 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
311
317
  else {
312
318
  popperEl.style.transition = 'none';
313
319
  popperEl.style.transform = 'scale(1)';
314
- const attemptOrder = getAttemptOrder(placement);
315
- for (let i = 0; i < attemptOrder.length; i++) {
316
- const t = attempt(attemptOrder[i]);
317
- if (t === false) {
318
- break;
319
- }
320
- }
320
+ getAttemptOrder(placement, !!contextMenuEvent.current, sizeAdaptable, attempt);
321
321
  }
322
322
  beforeOpen?.();
323
323
  placeA.current = pA;
@@ -7,6 +7,7 @@ const selectBase_1 = require("../selectBase");
7
7
  const optionsBase_1 = require("../optionsBase");
8
8
  const menuItem_1 = require("../menuItem");
9
9
  const selectionContext_1 = require("../selectionContext");
10
+ const utils_1 = require("../../utils");
10
11
  exports.Select = (0, react_1.memo)(({ children,
11
12
  // 从SelectableProps继承
12
13
  multiple = false, // 同时转发至<SelectBase/>
@@ -19,7 +20,15 @@ showCheckbox = multiple, loading = false, options, labelKey = 'label', primaryKe
19
20
  const optionsMap = (0, react_1.useMemo)(() => {
20
21
  const map = new Map();
21
22
  optionsArr?.forEach(opt => {
22
- opt && typeof opt === 'object' && map.set(opt[primaryKey], opt);
23
+ if (opt && typeof opt === 'object') {
24
+ const key = opt[primaryKey];
25
+ if (!(0, utils_1.isUnset)(key)) {
26
+ if (map.has(key)) {
27
+ console.warn(`[@canlooks/can-ui/<Select/>] option key "${key}" was duplicated`);
28
+ }
29
+ map.set(opt[primaryKey], opt);
30
+ }
31
+ }
23
32
  });
24
33
  return map;
25
34
  }, [optionsArr, primaryKey]);
@@ -7,6 +7,7 @@ const utils_1 = require("../../utils");
7
7
  const react_1 = require("react");
8
8
  const transitionBase_1 = require("../transitionBase");
9
9
  const selectedList_style_1 = require("./selectedList.style");
10
+ const sortableItem_1 = require("../sortableItem");
10
11
  function SelectedItem({ value, index, itemProps, onClose, ...props }) {
11
12
  const [alertProps, setAlertProps] = (0, utils_1.useSyncState)();
12
13
  const [loading, requestFn] = (0, utils_1.useLoading)(async () => {
@@ -17,5 +18,5 @@ function SelectedItem({ value, index, itemProps, onClose, ...props }) {
17
18
  alertProps.current?.onClose?.(e);
18
19
  onClose?.(value, index);
19
20
  };
20
- return ((0, jsx_runtime_1.jsx)(transitionBase_1.Collapse, { ...props, className: selectedList_style_1.classes.option, children: (0, jsx_runtime_1.jsx)(alert_1.Alert, { closable: true, color: "info", showIcon: false, ...alertProps.current, className: (0, utils_1.clsx)(selectedList_style_1.classes.optionWrap, alertProps.current?.className), onClose: closeHandler, loading: loading.current }) }));
21
+ return ((0, jsx_runtime_1.jsx)(transitionBase_1.Collapse, { ...props, className: selectedList_style_1.classes.option, children: (0, jsx_runtime_1.jsx)(sortableItem_1.SortableItem, { component: alert_1.Alert, id: value, index: index, closable: true, color: "info", showIcon: false, ...alertProps.current, className: (0, utils_1.clsx)(selectedList_style_1.classes.optionWrap, alertProps.current?.className), onClose: closeHandler, loading: loading.current }) }));
21
22
  }
@@ -8,6 +8,7 @@ const selectedList_style_1 = require("./selectedList.style");
8
8
  const react_transition_group_1 = require("react-transition-group");
9
9
  const selectionContext_1 = require("../selectionContext");
10
10
  const selectedItem_1 = require("./selectedItem");
11
+ const react_2 = require("@dnd-kit/react");
11
12
  exports.SelectedList = (0, react_1.memo)(({ value, itemProps, onClose, ...props }) => {
12
13
  const { value: innerValue, setValue: setInnerValue } = (0, selectionContext_1.useSelectionContext)();
13
14
  const arr = (0, utils_1.toArray)(value || innerValue);
@@ -15,5 +16,9 @@ exports.SelectedList = (0, react_1.memo)(({ value, itemProps, onClose, ...props
15
16
  onClose?.(v, i);
16
17
  setInnerValue?.(arr?.filter(_v => _v !== v));
17
18
  };
18
- return ((0, jsx_runtime_1.jsx)(react_transition_group_1.TransitionGroup, { ...props, css: selectedList_style_1.style, className: (0, utils_1.clsx)(selectedList_style_1.classes.root, props.className), children: arr?.map((v, i) => (0, jsx_runtime_1.jsx)(selectedItem_1.SelectedItem, { value: v, index: i, itemProps: itemProps, onClose: closeHandler }, v)) }));
19
+ const dragEndHandler = e => {
20
+ const newValue = (0, utils_1.onDndDragEnd)(e, arr);
21
+ newValue && setInnerValue(newValue);
22
+ };
23
+ return ((0, jsx_runtime_1.jsx)(react_2.DragDropProvider, { sensors: utils_1.defaultSensors, onDragEnd: dragEndHandler, children: (0, jsx_runtime_1.jsx)(react_transition_group_1.TransitionGroup, { ...props, css: selectedList_style_1.style, className: (0, utils_1.clsx)(selectedList_style_1.classes.root, props.className), children: arr?.map((v, i) => (0, jsx_runtime_1.jsx)(selectedItem_1.SelectedItem, { value: v, index: i, itemProps: itemProps, onClose: closeHandler }, v)) }) }));
19
24
  });
@@ -32,7 +32,12 @@ function useSelection({ ...props }) {
32
32
  item._parentId = parentId;
33
33
  item._isLast = i === arr.length - 1;
34
34
  const id = item[props.primaryKey];
35
- !(0, utils_1.isUnset)(id) && map.set(id, item);
35
+ if (!(0, utils_1.isUnset)(id)) {
36
+ if (map.has(id)) {
37
+ console.warn(`[@canlooks/can-ui/<SelectionContext/>] option key "${id}" was duplicated`);
38
+ }
39
+ map.set(id, item);
40
+ }
36
41
  fn(item[props.childrenKey], id);
37
42
  });
38
43
  };
@@ -20,7 +20,7 @@ exports.style = (0, utils_1.defineCss)(({ mode, spacing, gray, divider, backgrou
20
20
 
21
21
  thead, tfoot {
22
22
  position: sticky;
23
- z-index: 5;
23
+ z-index: 7;
24
24
 
25
25
  th, td {
26
26
  background-color: ${headerBg};
@@ -73,7 +73,9 @@ function useStickyCellProps({ sticky, ...props }) {
73
73
  ref: innerRef,
74
74
  css: tableSticky_style_1.style,
75
75
  className: table_style_1.classes.cell,
76
- style: sticky && { [sticky]: offset },
76
+ ...sticky && {
77
+ style: { [sticky]: offset }
78
+ },
77
79
  'data-sticky': sticky
78
80
  });
79
81
  }
@@ -11,7 +11,7 @@ exports.style = (0, utils_1.defineCss)(({ easing }) => (0, react_1.css) `
11
11
  &[data-sticky=left], &[data-sticky=right] {
12
12
  overflow: visible;
13
13
  position: sticky;
14
- z-index: 4;
14
+ z-index: 6;
15
15
 
16
16
  &::after {
17
17
  content: '';
@@ -26,7 +26,12 @@ function useColumnMap(columns) {
26
26
  columns?.forEach((col, i) => {
27
27
  if (typeof col !== 'symbol') {
28
28
  const _key = setDefaultColumnKey(col, i);
29
- !(0, utils_1.isUnset)(_key) && map.set(_key, col);
29
+ if (!(0, utils_1.isUnset)(_key)) {
30
+ if (map.has(_key)) {
31
+ console.warn(`[@canlooks/can-ui/<DataGrid/>] column key "${_key}" was duplicated`);
32
+ }
33
+ map.set(_key, col);
34
+ }
30
35
  }
31
36
  });
32
37
  return map;
@@ -13,6 +13,7 @@ export declare const defaultSensors: Customizable<Sensors>;
13
13
  * @param primaryKey 索引用的主键,默认为`id`
14
14
  * @return 返回新的数组,但如果顺序未改变,会得到null
15
15
  */
16
+ export declare function onDndDragEnd<T>({ operation }: Parameters<DragDropEvents<any, any, any>['dragend']>[0], items: T[]): T[] | null;
16
17
  export declare function onDndDragEnd<T extends Obj>({ operation }: Parameters<DragDropEvents<any, any, any>['dragend']>[0], items: T[], primaryKey?: keyof T): T[] | null;
17
18
  export declare function arrayMove<T>(array: T[], from: number, to: number): T[];
18
19
  /**
@@ -21,20 +21,23 @@ const defaultSensors = defaults => [
21
21
  })
22
22
  ];
23
23
  exports.defaultSensors = defaultSensors;
24
- /**
25
- * <DragDropProvider>组件通用的onDragEnd方法
26
- * @param e 事件
27
- * @param items 传入需要排序的数组
28
- * @param primaryKey 索引用的主键,默认为`id`
29
- * @return 返回新的数组,但如果顺序未改变,会得到null
30
- */
31
24
  function onDndDragEnd({ operation }, items, primaryKey = 'id') {
32
25
  const { source, target, canceled } = operation;
33
26
  if (!source || !target || canceled) {
34
27
  return null;
35
28
  }
36
- const sourceIndex = items.findIndex(item => item[primaryKey] === source.id);
37
- const targetIndex = items.findIndex(item => item[primaryKey] === target.id);
29
+ const sourceIndex = items.findIndex(item => {
30
+ if (typeof item === 'object' && item !== null) {
31
+ return item[primaryKey] === source.id;
32
+ }
33
+ return item === source.id;
34
+ });
35
+ const targetIndex = items.findIndex(item => {
36
+ if (typeof item === 'object' && item !== null) {
37
+ return item[primaryKey] === target.id;
38
+ }
39
+ return item === target.id;
40
+ });
38
41
  if (sourceIndex === -1 || targetIndex === -1) {
39
42
  if (typeof source.initialIndex === 'number' && typeof source.index === 'number') {
40
43
  const from = source.initialIndex;