@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.
- package/dist/cjs/components/autocomplete/autocomplete.js +6 -1
- package/dist/cjs/components/curd/curd.js +1 -0
- package/dist/cjs/components/curd/curd.style.d.ts +1 -0
- package/dist/cjs/components/curd/curd.style.js +2 -1
- package/dist/cjs/components/curd/curdColumnConfig.js +3 -2
- package/dist/cjs/components/curd/curdColumnConfig.style.js +3 -12
- package/dist/cjs/components/dataGrid/dataGrid.d.ts +2 -1
- package/dist/cjs/components/dataGrid/dataGrid.js +7 -2
- package/dist/cjs/components/dataGrid/dataGrid.style.js +27 -16
- package/dist/cjs/components/dataGrid/dataGridHead.d.ts +2 -1
- package/dist/cjs/components/dataGrid/dataGridHead.js +2 -2
- package/dist/cjs/components/dataGrid/dataGridRows.js +5 -3
- package/dist/cjs/components/dataGrid/stickyRow.d.ts +5 -0
- package/dist/cjs/components/dataGrid/stickyRow.js +28 -0
- package/dist/cjs/components/popper/popper.js +67 -67
- package/dist/cjs/components/select/select.js +10 -1
- package/dist/cjs/components/selectedList/selectedItem.js +2 -1
- package/dist/cjs/components/selectedList/selectedList.js +6 -1
- package/dist/cjs/components/selectionContext/selectionHook.js +6 -1
- package/dist/cjs/components/table/table.style.js +1 -1
- package/dist/cjs/components/table/tableSticky.js +3 -1
- package/dist/cjs/components/table/tableSticky.style.js +1 -1
- package/dist/cjs/utils/dataGrid.js +6 -1
- package/dist/cjs/utils/dnd.d.ts +1 -0
- package/dist/cjs/utils/dnd.js +12 -9
- package/dist/esm/components/autocomplete/autocomplete.js +6 -1
- package/dist/esm/components/curd/curd.js +1 -0
- package/dist/esm/components/curd/curd.style.d.ts +1 -0
- package/dist/esm/components/curd/curd.style.js +2 -1
- package/dist/esm/components/curd/curdColumnConfig.js +3 -2
- package/dist/esm/components/curd/curdColumnConfig.style.js +3 -12
- package/dist/esm/components/dataGrid/dataGrid.d.ts +2 -1
- package/dist/esm/components/dataGrid/dataGrid.js +8 -3
- package/dist/esm/components/dataGrid/dataGrid.style.js +27 -16
- package/dist/esm/components/dataGrid/dataGridHead.d.ts +2 -1
- package/dist/esm/components/dataGrid/dataGridHead.js +2 -2
- package/dist/esm/components/dataGrid/dataGridRows.js +5 -3
- package/dist/esm/components/dataGrid/stickyRow.d.ts +5 -0
- package/dist/esm/components/dataGrid/stickyRow.js +25 -0
- package/dist/esm/components/popper/popper.js +67 -67
- package/dist/esm/components/select/select.js +10 -1
- package/dist/esm/components/selectedList/selectedItem.js +2 -1
- package/dist/esm/components/selectedList/selectedList.js +7 -2
- package/dist/esm/components/selectionContext/selectionHook.js +6 -1
- package/dist/esm/components/table/table.style.js +1 -1
- package/dist/esm/components/table/tableSticky.js +3 -1
- package/dist/esm/components/table/tableSticky.style.js +1 -1
- package/dist/esm/utils/dataGrid.js +6 -1
- package/dist/esm/utils/dnd.d.ts +1 -0
- package/dist/esm/utils/dnd.js +12 -9
- package/package.json +1 -1
|
@@ -45,7 +45,12 @@ export const Autocomplete = memo(({ children, loading, options, loadOptions, pri
|
|
|
45
45
|
actualOptions?.forEach(opt => {
|
|
46
46
|
if (opt && typeof opt === 'object') {
|
|
47
47
|
const key = opt[primaryKey];
|
|
48
|
-
!isUnset(key)
|
|
48
|
+
if (!isUnset(key)) {
|
|
49
|
+
if (map.has(key)) {
|
|
50
|
+
console.warn(`[@canlooks/can-ui/<Autocomple/>] option key "${key}" was duplicated`);
|
|
51
|
+
}
|
|
52
|
+
map.set(key, opt);
|
|
53
|
+
}
|
|
49
54
|
}
|
|
50
55
|
});
|
|
51
56
|
return map;
|
|
@@ -94,6 +94,7 @@ export const Curd = memo((props) => {
|
|
|
94
94
|
const controlColumn = {
|
|
95
95
|
key: CONTROL_COLUMN_KEY,
|
|
96
96
|
title: controlColumnTitle,
|
|
97
|
+
className: classes.controlColumn,
|
|
97
98
|
render(row) {
|
|
98
99
|
const _updatable = typeof updatable === 'function' ? updatable(row) : updatable;
|
|
99
100
|
const _deletable = typeof deletable === 'function' ? deletable(row) : deletable;
|
|
@@ -17,6 +17,7 @@ export const classes = defineInnerClasses('curd', [
|
|
|
17
17
|
'toolbarRight',
|
|
18
18
|
'divider',
|
|
19
19
|
'card',
|
|
20
|
+
'controlColumn',
|
|
20
21
|
'control',
|
|
21
22
|
'dialogTitle',
|
|
22
23
|
'copyButton'
|
|
@@ -29,7 +30,7 @@ export const style = defineCss(({ spacing, text, background, borderRadius }) =>
|
|
|
29
30
|
min-height: 0;
|
|
30
31
|
display: flex;
|
|
31
32
|
flex-direction: column;
|
|
32
|
-
|
|
33
|
+
|
|
33
34
|
.${classes.filterForm} {
|
|
34
35
|
min-height: 0;
|
|
35
36
|
display: flex;
|
|
@@ -10,6 +10,7 @@ import { defaultSensors, isUnset, onDndDragEnd } from '../../utils/index.js';
|
|
|
10
10
|
import { Icon } from '../icon/index.js';
|
|
11
11
|
import { faGear } from '@fortawesome/free-solid-svg-icons/faGear';
|
|
12
12
|
import { DragDropProvider, useDragDropMonitor } from '@dnd-kit/react';
|
|
13
|
+
import { Tooltip } from '../tooltip/index.js';
|
|
13
14
|
export const CurdColumnConfig = memo((props) => {
|
|
14
15
|
const dragEndHandler = e => {
|
|
15
16
|
const newColumns = onDndDragEnd(e, props.columns || [], '_key');
|
|
@@ -38,12 +39,12 @@ const CurdColumnConfigContent = memo(({ columns, innerVisible, setInnerVisible,
|
|
|
38
39
|
? [...o, key]
|
|
39
40
|
: o.filter(k => k !== key));
|
|
40
41
|
};
|
|
41
|
-
return (_jsx(Bubble, { placement: "bottomRight", trigger:
|
|
42
|
+
return (_jsx(Bubble, { placement: "bottomRight", trigger: "click", ...columnConfigBubbleProps, css: style, open: open, onOpenChange: openChangeHandler, content: _jsxs("div", { className: classes.content, children: [_jsxs("div", { className: classes.title, children: [_jsx("div", { className: classes.titleText, children: "\u5217\u8BBE\u7F6E" }), _jsx("div", { className: classes.description, children: "\u62D6\u62FD\u8C03\u6574\u987A\u5E8F" })] }), columns?.map((col, i) => {
|
|
42
43
|
const id = col._key;
|
|
43
44
|
const checked = !isUnset(id) && (!visibleSet || visibleSet.has(id));
|
|
44
45
|
return (_jsx(SortableItem, { id: id ?? i, index: i, component: MenuItem, className: classes.item, prefix: _jsx(Checkbox, { className: classes.checkbox, checked: checked, onChange: e => {
|
|
45
46
|
e.stopPropagation();
|
|
46
47
|
toggleVisible(id, e.target.checked);
|
|
47
48
|
} }), onClick: () => toggleVisible(id, !checked), label: col.titleText ?? col.title, noStyle: true }, id ?? i));
|
|
48
|
-
})] }), autoClose: false, children: _jsx(Button, { shape: "circular", variant: "text", color: "text.secondary", children: _jsx(Icon, { icon: faGear }) }) }));
|
|
49
|
+
})] }), autoClose: false, children: _jsx(Tooltip, { title: "\u5217\u8BBE\u7F6E", clickToClose: true, children: _jsx(Button, { shape: "circular", variant: "text", color: "text.secondary", children: _jsx(Icon, { icon: faGear }) }) }) }));
|
|
49
50
|
});
|
|
@@ -18,25 +18,16 @@ export const style = defineCss(({ spacing, text }) => css `
|
|
|
18
18
|
align-items: center;
|
|
19
19
|
justify-content: space-between;
|
|
20
20
|
padding: ${spacing[3]}px;
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
.${classes.titleText} {
|
|
23
23
|
font-weight: bold;
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
.${classes.description} {
|
|
27
27
|
color: ${text.disabled};
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
.${classes.item} {
|
|
32
|
-
cursor: pointer;
|
|
33
|
-
|
|
34
|
-
&[data-dragging=true] {
|
|
35
|
-
position: relative;
|
|
36
|
-
z-index: 1;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
30
|
+
|
|
40
31
|
.${classes.checkbox} {
|
|
41
32
|
display: flex;
|
|
42
33
|
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.js';
|
|
3
3
|
import { SelectionContextProps } from '../selectionContext/index.js';
|
|
4
4
|
import { PaginationProps } from '../pagination/index.js';
|
|
@@ -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: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { createContext, memo, useCallback, useContext, useMemo, useState } from 'react';
|
|
2
|
+
import { createContext, memo, useCallback, useContext, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { classes, style } from './dataGrid.style.js';
|
|
4
4
|
import { SelectionContext, useSelectionContext } from '../selectionContext/index.js';
|
|
5
5
|
import { Pagination } from '../pagination/index.js';
|
|
@@ -126,13 +126,18 @@ export const DataGrid = memo(({ slots, slotProps, columns, rows, rowProps, prima
|
|
|
126
126
|
const { page, pageSize } = _paginationProps;
|
|
127
127
|
return orderedRows?.slice((page - 1) * pageSize, page * pageSize);
|
|
128
128
|
}, [orderedRows, _paginationProps.page, _paginationProps.pageSize, paginatable]);
|
|
129
|
+
/**
|
|
130
|
+
* ---------------------------------------------------------------
|
|
131
|
+
* 渲染
|
|
132
|
+
*/
|
|
133
|
+
const theadRef = useRef(null);
|
|
129
134
|
const { container: Container = TableContainer } = slots || {};
|
|
130
135
|
const { container: containerProps } = slotProps || {};
|
|
131
136
|
const renderedContent = (_jsx(ColumnResizeContext, { columnResizable: columnResizable, children: ({ scrollerRef, tableRef }) => _jsxs(Container, { ...mergeComponentProps(containerProps, {
|
|
132
137
|
ref: scrollerRef,
|
|
133
138
|
className: classes.container
|
|
134
|
-
}), children: [_jsx(Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: cloneRef(tableProps?.ref, tableRef), children: _jsxs(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: [_jsx(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 }), _jsx("tbody", { children: _jsx(DataGridContext, { value: useMemo(() => ({
|
|
135
|
-
slots, slotProps,
|
|
139
|
+
}), children: [_jsx(Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: cloneRef(tableProps?.ref, tableRef), children: _jsxs(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: [_jsx(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 }), _jsx("tbody", { children: _jsx(DataGridContext, { value: useMemo(() => ({
|
|
140
|
+
slots, slotProps, theadRef,
|
|
136
141
|
rowProps, primaryKey, childrenKey, clickRowToSelect, indent, renderExpandIcon,
|
|
137
142
|
expandedSet, flattedColumns, toggleExpanded
|
|
138
143
|
}), [
|
|
@@ -89,25 +89,36 @@ export const style = defineCss(({ spacing, mode, gray, text, colors, easing }) =
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
+
|
|
93
|
+
tr {
|
|
94
|
+
position: relative;
|
|
95
|
+
z-index: 2;
|
|
96
|
+
|
|
97
|
+
&[data-expanded=true] {
|
|
98
|
+
position: sticky;
|
|
99
|
+
z-index: 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&.${classes.sub} {
|
|
103
|
+
z-index: 0;
|
|
104
|
+
background-color: ${gray(mode === 'light' ? .02 : .22)};
|
|
92
105
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
td.${classes.subTd} {
|
|
97
|
-
padding: 0;
|
|
98
|
-
border: none;
|
|
106
|
+
td.${classes.subTd} {
|
|
107
|
+
padding: 0;
|
|
108
|
+
border: none;
|
|
99
109
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
.${classes.children} {
|
|
111
|
+
padding: ${spacing[4]}px ${spacing[5]}px;
|
|
112
|
+
border-bottom: 1px solid ${gray(mode === 'light' ? .12 : .32)};
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
thead, tfoot {
|
|
115
|
+
z-index: 5;
|
|
116
|
+
}
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
118
|
+
th, td {
|
|
119
|
+
&[data-sticky=left], &[data-sticky=right] {
|
|
120
|
+
z-index: 4;
|
|
121
|
+
}
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
124
|
}
|
|
@@ -154,7 +165,7 @@ export const style = defineCss(({ spacing, mode, gray, text, colors, easing }) =
|
|
|
154
165
|
position: absolute;
|
|
155
166
|
top: 0;
|
|
156
167
|
right: -4px;
|
|
157
|
-
z-index:
|
|
168
|
+
z-index: 3;
|
|
158
169
|
}
|
|
159
170
|
|
|
160
171
|
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.js';
|
|
3
3
|
import { Id } from '../../types.js';
|
|
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;
|
|
@@ -15,7 +15,7 @@ import { Bubble } from '../bubble/index.js';
|
|
|
15
15
|
import { FilterBubbleContent } from './filterBubbleContent.js';
|
|
16
16
|
import { useFormValueContext } from '../form/index.js';
|
|
17
17
|
import { isUnset, mergeComponentProps } from '../../utils/index.js';
|
|
18
|
-
export const DataGridHead = memo(({ allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, filterBubbleProps, onFilterClick }) => {
|
|
18
|
+
export const DataGridHead = memo(({ ref, allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, filterBubbleProps, onFilterClick }) => {
|
|
19
19
|
const { multiple, setValue, selectionStatus } = useSelectionContext();
|
|
20
20
|
const allSelectionStatus = useMemo(() => {
|
|
21
21
|
if (multiple && allowSelectAll) {
|
|
@@ -113,5 +113,5 @@ export const DataGridHead = memo(({ allowSelectAll, columnResizable, flattedColu
|
|
|
113
113
|
];
|
|
114
114
|
}) }, i));
|
|
115
115
|
});
|
|
116
|
-
return _jsx("thead", { children: renderedHead });
|
|
116
|
+
return _jsx("thead", { ref: ref, children: renderedHead });
|
|
117
117
|
});
|
|
@@ -13,10 +13,11 @@ import { Icon } from '../icon/index.js';
|
|
|
13
13
|
import { faMinusSquare } from '@fortawesome/free-regular-svg-icons/faMinusSquare';
|
|
14
14
|
import { faPlusSquare } from '@fortawesome/free-regular-svg-icons/faPlusSquare';
|
|
15
15
|
import { classes } from './dataGrid.style.js';
|
|
16
|
+
import { StickyRow } from './stickyRow.js';
|
|
16
17
|
export const DataGridRows = memo(({ rows, _level = 0 }) => {
|
|
17
18
|
const { multiple, toggleSelected, selectionStatus } = useSelectionContext();
|
|
18
19
|
const { slots, slotProps, rowProps, primaryKey, childrenKey, clickRowToSelect, indent, renderExpandIcon, expandedSet, flattedColumns, toggleExpanded } = useDataGridContext();
|
|
19
|
-
const { tr: Tr =
|
|
20
|
+
const { tr: Tr = StickyRow } = slots || {};
|
|
20
21
|
const { tr: TrProps } = slotProps || {};
|
|
21
22
|
return rows?.flatMap((row, i, arr) => {
|
|
22
23
|
const trKey = row[primaryKey];
|
|
@@ -34,8 +35,9 @@ export const DataGridRows = memo(({ rows, _level = 0 }) => {
|
|
|
34
35
|
className: clsx(_rowProps, _level > 0 && classes.sub),
|
|
35
36
|
onClick() {
|
|
36
37
|
clickRowToSelect && toggleSelected(trKey);
|
|
37
|
-
}
|
|
38
|
-
|
|
38
|
+
},
|
|
39
|
+
sticky: currentExpanded
|
|
40
|
+
}), key: trKey, "data-selected": status === 2, "data-expanded": currentExpanded }, flattedColumns?.flatMap((col, j) => {
|
|
39
41
|
if (typeof col === 'symbol') {
|
|
40
42
|
if (col === DataGrid.EXPAND_COLUMN) {
|
|
41
43
|
expandableIndex = j;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useDataGridContext } from './dataGrid.js';
|
|
4
|
+
import { mergeComponentProps } from '../../utils/index.js';
|
|
5
|
+
export function StickyRow({ sticky, ...props }) {
|
|
6
|
+
const [offset, setOffset] = useState(0);
|
|
7
|
+
const { theadRef } = useDataGridContext();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!sticky || !theadRef.current) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
13
|
+
setOffset(theadRef.current.offsetHeight);
|
|
14
|
+
});
|
|
15
|
+
resizeObserver.observe(theadRef.current);
|
|
16
|
+
return () => {
|
|
17
|
+
resizeObserver.disconnect();
|
|
18
|
+
};
|
|
19
|
+
}, [sticky]);
|
|
20
|
+
return (_jsx("tr", { ...mergeComponentProps(props, {
|
|
21
|
+
...sticky && {
|
|
22
|
+
style: { top: offset }
|
|
23
|
+
}
|
|
24
|
+
}) }));
|
|
25
|
+
}
|
|
@@ -6,18 +6,56 @@ import { ClickAway } from '../clickAway/index.js';
|
|
|
6
6
|
import { classes, style } from './popper.style.js';
|
|
7
7
|
import { PopperContext, usePopperContext } from './popperContext.js';
|
|
8
8
|
import { useTheme } from '../theme/index.js';
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
const defaultAttemptOrder = ['top', 'bottom', 'left', 'right', 'topLeft', 'topRight', 'rightTop', 'rightBottom', 'bottomRight', 'bottomLeft', 'leftBottom', 'leftTop'];
|
|
10
|
+
const contextMenuOrder = [
|
|
11
|
+
'bottomRight',
|
|
12
|
+
'rightBottom',
|
|
13
|
+
'bottomLeft',
|
|
14
|
+
'leftBottom',
|
|
15
|
+
'topLeft',
|
|
16
|
+
'leftTop',
|
|
17
|
+
'topRight',
|
|
18
|
+
'rightTop'
|
|
19
|
+
];
|
|
20
|
+
const getAttemptOrder = (startPlacement, contextMenu, sizeAdaptable, callback) => {
|
|
21
|
+
if (contextMenu) {
|
|
22
|
+
const startIndex = Math.max(contextMenuOrder.indexOf(startPlacement), 0);
|
|
23
|
+
for (let i = 0; i <= contextMenuOrder.length + 1; i += 2) {
|
|
24
|
+
const index = (startIndex + i) % contextMenuOrder.length;
|
|
25
|
+
if (callback(contextMenuOrder[index]) === false) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
let order = defaultAttemptOrder;
|
|
32
|
+
let startIndex;
|
|
33
|
+
if (sizeAdaptable) {
|
|
34
|
+
switch (startPlacement) {
|
|
35
|
+
case 'top':
|
|
36
|
+
order = [startPlacement, 'bottom', startPlacement];
|
|
37
|
+
break;
|
|
38
|
+
case 'bottom':
|
|
39
|
+
order = [startPlacement, 'top', startPlacement];
|
|
40
|
+
break;
|
|
41
|
+
case 'left':
|
|
42
|
+
order = [startPlacement, 'right', startPlacement];
|
|
43
|
+
break;
|
|
44
|
+
case 'right':
|
|
45
|
+
order = [startPlacement, 'left', startPlacement];
|
|
46
|
+
}
|
|
47
|
+
startIndex = 0;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
startIndex = Math.max(order.indexOf(startPlacement), 0);
|
|
51
|
+
}
|
|
52
|
+
for (let i = 0; i <= order.length; i++) {
|
|
53
|
+
const index = (startIndex + i) % order.length;
|
|
54
|
+
if (callback(order[index]) === false) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
19
58
|
}
|
|
20
|
-
return order;
|
|
21
59
|
};
|
|
22
60
|
const splitPlacement = {
|
|
23
61
|
top: ['top'],
|
|
@@ -138,33 +176,6 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
|
|
|
138
176
|
const mouseY = contextMenuEvent.current.clientY - containerRect.top;
|
|
139
177
|
attempt = placement => {
|
|
140
178
|
switch (placement) {
|
|
141
|
-
case 'topLeft':
|
|
142
|
-
case 'leftTop':
|
|
143
|
-
top = void 0;
|
|
144
|
-
bottom = -mouseY;
|
|
145
|
-
left = void 0;
|
|
146
|
-
right = containerRect.width - mouseX;
|
|
147
|
-
originX = '100%';
|
|
148
|
-
originY = '100%';
|
|
149
|
-
break;
|
|
150
|
-
case 'topRight':
|
|
151
|
-
case 'rightTop':
|
|
152
|
-
top = void 0;
|
|
153
|
-
bottom = -mouseY;
|
|
154
|
-
left = mouseX;
|
|
155
|
-
right = void 0;
|
|
156
|
-
originX = '0%';
|
|
157
|
-
originY = '100%';
|
|
158
|
-
break;
|
|
159
|
-
case 'bottomLeft':
|
|
160
|
-
case 'leftBottom':
|
|
161
|
-
top = mouseY;
|
|
162
|
-
bottom = void 0;
|
|
163
|
-
left = void 0;
|
|
164
|
-
right = containerRect.width - mouseX;
|
|
165
|
-
originX = '100%';
|
|
166
|
-
originY = '0%';
|
|
167
|
-
break;
|
|
168
179
|
case 'bottomRight':
|
|
169
180
|
case 'rightBottom':
|
|
170
181
|
top = mouseY;
|
|
@@ -174,37 +185,32 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
|
|
|
174
185
|
originX = '0%';
|
|
175
186
|
originY = '0%';
|
|
176
187
|
break;
|
|
177
|
-
case '
|
|
178
|
-
|
|
179
|
-
bottom = void 0;
|
|
180
|
-
left = mouseX - popperWidth / 2;
|
|
181
|
-
right = void 0;
|
|
182
|
-
originX = '50%';
|
|
183
|
-
originY = '100%';
|
|
184
|
-
break;
|
|
185
|
-
case 'bottom':
|
|
188
|
+
case 'bottomLeft':
|
|
189
|
+
case 'leftBottom':
|
|
186
190
|
top = mouseY;
|
|
187
191
|
bottom = void 0;
|
|
188
|
-
left =
|
|
189
|
-
right =
|
|
190
|
-
originX = '
|
|
192
|
+
left = void 0;
|
|
193
|
+
right = containerRect.width - mouseX;
|
|
194
|
+
originX = '100%';
|
|
191
195
|
originY = '0%';
|
|
192
196
|
break;
|
|
193
|
-
case '
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
197
|
+
case 'topLeft':
|
|
198
|
+
case 'leftTop':
|
|
199
|
+
top = void 0;
|
|
200
|
+
bottom = -mouseY;
|
|
201
|
+
left = void 0;
|
|
202
|
+
right = containerRect.width - mouseX;
|
|
198
203
|
originX = '100%';
|
|
199
|
-
originY = '
|
|
204
|
+
originY = '100%';
|
|
200
205
|
break;
|
|
201
|
-
case '
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
case 'topRight':
|
|
207
|
+
case 'rightTop':
|
|
208
|
+
top = void 0;
|
|
209
|
+
bottom = -mouseY;
|
|
204
210
|
left = mouseX;
|
|
205
211
|
right = void 0;
|
|
206
212
|
originX = '0%';
|
|
207
|
-
originY = '
|
|
213
|
+
originY = '100%';
|
|
208
214
|
}
|
|
209
215
|
popperEl.style.top = typeof top === 'undefined' ? '' : top + 'px';
|
|
210
216
|
popperEl.style.bottom = typeof bottom === 'undefined' ? '' : bottom + 'px';
|
|
@@ -308,13 +314,7 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
|
|
|
308
314
|
else {
|
|
309
315
|
popperEl.style.transition = 'none';
|
|
310
316
|
popperEl.style.transform = 'scale(1)';
|
|
311
|
-
|
|
312
|
-
for (let i = 0; i < attemptOrder.length; i++) {
|
|
313
|
-
const t = attempt(attemptOrder[i]);
|
|
314
|
-
if (t === false) {
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
317
|
+
getAttemptOrder(placement, !!contextMenuEvent.current, sizeAdaptable, attempt);
|
|
318
318
|
}
|
|
319
319
|
beforeOpen?.();
|
|
320
320
|
placeA.current = pA;
|
|
@@ -4,6 +4,7 @@ import { SelectBase } from '../selectBase/index.js';
|
|
|
4
4
|
import { OptionsBase } from '../optionsBase/index.js';
|
|
5
5
|
import { MenuItem } from '../menuItem/index.js';
|
|
6
6
|
import { useFlatSelection } from '../selectionContext/index.js';
|
|
7
|
+
import { isUnset } from '../../utils/index.js';
|
|
7
8
|
export const Select = memo(({ children,
|
|
8
9
|
// 从SelectableProps继承
|
|
9
10
|
multiple = false, // 同时转发至<SelectBase/>
|
|
@@ -16,7 +17,15 @@ showCheckbox = multiple, loading = false, options, labelKey = 'label', primaryKe
|
|
|
16
17
|
const optionsMap = useMemo(() => {
|
|
17
18
|
const map = new Map();
|
|
18
19
|
optionsArr?.forEach(opt => {
|
|
19
|
-
opt && typeof opt === 'object'
|
|
20
|
+
if (opt && typeof opt === 'object') {
|
|
21
|
+
const key = opt[primaryKey];
|
|
22
|
+
if (!isUnset(key)) {
|
|
23
|
+
if (map.has(key)) {
|
|
24
|
+
console.warn(`[@canlooks/can-ui/<Select/>] option key "${key}" was duplicated`);
|
|
25
|
+
}
|
|
26
|
+
map.set(opt[primaryKey], opt);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
20
29
|
});
|
|
21
30
|
return map;
|
|
22
31
|
}, [optionsArr, primaryKey]);
|
|
@@ -4,6 +4,7 @@ import { clsx, useLoading, useSyncState } from '../../utils/index.js';
|
|
|
4
4
|
import { useMemo } from 'react';
|
|
5
5
|
import { Collapse } from '../transitionBase/index.js';
|
|
6
6
|
import { classes } from './selectedList.style.js';
|
|
7
|
+
import { SortableItem } from '../sortableItem/index.js';
|
|
7
8
|
export function SelectedItem({ value, index, itemProps, onClose, ...props }) {
|
|
8
9
|
const [alertProps, setAlertProps] = useSyncState();
|
|
9
10
|
const [loading, requestFn] = useLoading(async () => {
|
|
@@ -14,5 +15,5 @@ export function SelectedItem({ value, index, itemProps, onClose, ...props }) {
|
|
|
14
15
|
alertProps.current?.onClose?.(e);
|
|
15
16
|
onClose?.(value, index);
|
|
16
17
|
};
|
|
17
|
-
return (_jsx(Collapse, { ...props, className: classes.option, children: _jsx(
|
|
18
|
+
return (_jsx(Collapse, { ...props, className: classes.option, children: _jsx(SortableItem, { component: Alert, id: value, index: index, closable: true, color: "info", showIcon: false, ...alertProps.current, className: clsx(classes.optionWrap, alertProps.current?.className), onClose: closeHandler, loading: loading.current }) }));
|
|
18
19
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
2
|
import { memo } from 'react';
|
|
3
|
-
import { clsx, toArray } from '../../utils/index.js';
|
|
3
|
+
import { clsx, defaultSensors, onDndDragEnd, toArray } from '../../utils/index.js';
|
|
4
4
|
import { classes, style } from './selectedList.style.js';
|
|
5
5
|
import { TransitionGroup } from 'react-transition-group';
|
|
6
6
|
import { useSelectionContext } from '../selectionContext/index.js';
|
|
7
7
|
import { SelectedItem } from './selectedItem.js';
|
|
8
|
+
import { DragDropProvider } from '@dnd-kit/react';
|
|
8
9
|
export const SelectedList = memo(({ value, itemProps, onClose, ...props }) => {
|
|
9
10
|
const { value: innerValue, setValue: setInnerValue } = useSelectionContext();
|
|
10
11
|
const arr = toArray(value || innerValue);
|
|
@@ -12,5 +13,9 @@ export const SelectedList = memo(({ value, itemProps, onClose, ...props }) => {
|
|
|
12
13
|
onClose?.(v, i);
|
|
13
14
|
setInnerValue?.(arr?.filter(_v => _v !== v));
|
|
14
15
|
};
|
|
15
|
-
|
|
16
|
+
const dragEndHandler = e => {
|
|
17
|
+
const newValue = onDndDragEnd(e, arr);
|
|
18
|
+
newValue && setInnerValue(newValue);
|
|
19
|
+
};
|
|
20
|
+
return (_jsx(DragDropProvider, { sensors: defaultSensors, onDragEnd: dragEndHandler, children: _jsx(TransitionGroup, { ...props, css: style, className: clsx(classes.root, props.className), children: arr?.map((v, i) => _jsx(SelectedItem, { value: v, index: i, itemProps: itemProps, onClose: closeHandler }, v)) }) }));
|
|
16
21
|
});
|
|
@@ -28,7 +28,12 @@ export function useSelection({ ...props }) {
|
|
|
28
28
|
item._parentId = parentId;
|
|
29
29
|
item._isLast = i === arr.length - 1;
|
|
30
30
|
const id = item[props.primaryKey];
|
|
31
|
-
!isUnset(id)
|
|
31
|
+
if (!isUnset(id)) {
|
|
32
|
+
if (map.has(id)) {
|
|
33
|
+
console.warn(`[@canlooks/can-ui/<SelectionContext/>] option key "${id}" was duplicated`);
|
|
34
|
+
}
|
|
35
|
+
map.set(id, item);
|
|
36
|
+
}
|
|
32
37
|
fn(item[props.childrenKey], id);
|
|
33
38
|
});
|
|
34
39
|
};
|
|
@@ -20,7 +20,12 @@ export function useColumnMap(columns) {
|
|
|
20
20
|
columns?.forEach((col, i) => {
|
|
21
21
|
if (typeof col !== 'symbol') {
|
|
22
22
|
const _key = setDefaultColumnKey(col, i);
|
|
23
|
-
!isUnset(_key)
|
|
23
|
+
if (!isUnset(_key)) {
|
|
24
|
+
if (map.has(_key)) {
|
|
25
|
+
console.warn(`[@canlooks/can-ui/<DataGrid/>] column key "${_key}" was duplicated`);
|
|
26
|
+
}
|
|
27
|
+
map.set(_key, col);
|
|
28
|
+
}
|
|
24
29
|
}
|
|
25
30
|
});
|
|
26
31
|
return map;
|
package/dist/esm/utils/dnd.d.ts
CHANGED
|
@@ -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
|
/**
|
package/dist/esm/utils/dnd.js
CHANGED
|
@@ -13,20 +13,23 @@ export const defaultSensors = defaults => [
|
|
|
13
13
|
]
|
|
14
14
|
})
|
|
15
15
|
];
|
|
16
|
-
/**
|
|
17
|
-
* <DragDropProvider>组件通用的onDragEnd方法
|
|
18
|
-
* @param e 事件
|
|
19
|
-
* @param items 传入需要排序的数组
|
|
20
|
-
* @param primaryKey 索引用的主键,默认为`id`
|
|
21
|
-
* @return 返回新的数组,但如果顺序未改变,会得到null
|
|
22
|
-
*/
|
|
23
16
|
export function onDndDragEnd({ operation }, items, primaryKey = 'id') {
|
|
24
17
|
const { source, target, canceled } = operation;
|
|
25
18
|
if (!source || !target || canceled) {
|
|
26
19
|
return null;
|
|
27
20
|
}
|
|
28
|
-
const sourceIndex = items.findIndex(item =>
|
|
29
|
-
|
|
21
|
+
const sourceIndex = items.findIndex(item => {
|
|
22
|
+
if (typeof item === 'object' && item !== null) {
|
|
23
|
+
return item[primaryKey] === source.id;
|
|
24
|
+
}
|
|
25
|
+
return item === source.id;
|
|
26
|
+
});
|
|
27
|
+
const targetIndex = items.findIndex(item => {
|
|
28
|
+
if (typeof item === 'object' && item !== null) {
|
|
29
|
+
return item[primaryKey] === target.id;
|
|
30
|
+
}
|
|
31
|
+
return item === target.id;
|
|
32
|
+
});
|
|
30
33
|
if (sourceIndex === -1 || targetIndex === -1) {
|
|
31
34
|
if (typeof source.initialIndex === 'number' && typeof source.index === 'number') {
|
|
32
35
|
const from = source.initialIndex;
|