@quadrats/react 1.0.0 → 1.1.1
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/card/components/Card.js +83 -75
- package/card/index.cjs.js +82 -74
- package/carousel/components/Carousel.js +32 -28
- package/carousel/index.cjs.js +32 -28
- package/components/Tooltip/index.js +5 -2
- package/components/index.cjs.js +5 -2
- package/core/components/Quadrats.js +5 -2
- package/core/contexts/modal/CarouselModal/CarouselModal.js +14 -17
- package/embed/renderers/base/components/BaseEmbedElement.js +51 -43
- package/embed/renderers/base/index.cjs.js +50 -42
- package/image/components/Image.js +34 -26
- package/image/createReactImage.js +1 -1
- package/image/index.cjs.js +34 -26
- package/index.cjs.js +19 -19
- package/package.json +4 -4
- package/table/components/ColumnDragButton.d.ts +10 -0
- package/table/components/ColumnDragButton.js +41 -0
- package/table/components/RowDragButton.d.ts +10 -0
- package/table/components/RowDragButton.js +42 -0
- package/table/components/Table.d.ts +9 -0
- package/table/components/Table.js +236 -0
- package/table/components/TableBody.d.ts +5 -0
- package/table/components/TableBody.js +8 -0
- package/table/components/TableCell.d.ts +5 -0
- package/table/components/TableCell.js +297 -0
- package/table/components/TableDragLayer.d.ts +6 -0
- package/table/components/TableDragLayer.js +89 -0
- package/table/components/TableHeader.d.ts +5 -0
- package/table/components/TableHeader.js +13 -0
- package/table/components/TableMain.d.ts +5 -0
- package/table/components/TableMain.js +233 -0
- package/table/components/TableRow.d.ts +5 -0
- package/table/components/TableRow.js +8 -0
- package/table/components/TableTitle.d.ts +5 -0
- package/table/components/TableTitle.js +18 -0
- package/table/contexts/TableActionsContext.d.ts +3 -0
- package/table/contexts/TableActionsContext.js +5 -0
- package/table/contexts/TableDragContext.d.ts +26 -0
- package/table/contexts/TableDragContext.js +26 -0
- package/table/contexts/TableHeaderContext.d.ts +2 -0
- package/table/contexts/TableHeaderContext.js +7 -0
- package/table/contexts/TableMetadataContext.d.ts +3 -0
- package/table/contexts/TableMetadataContext.js +5 -0
- package/table/contexts/TableScrollContext.d.ts +2 -0
- package/table/contexts/TableScrollContext.js +9 -0
- package/table/contexts/TableStateContext.d.ts +3 -0
- package/table/contexts/TableStateContext.js +5 -0
- package/table/createReactTable.d.ts +4 -0
- package/table/createReactTable.js +297 -0
- package/table/defaultRenderTableElements.d.ts +2 -0
- package/table/defaultRenderTableElements.js +20 -0
- package/table/hooks/useColumnResize.d.ts +12 -0
- package/table/hooks/useColumnResize.js +168 -0
- package/table/hooks/useTableActions.d.ts +27 -0
- package/table/hooks/useTableActions.js +1092 -0
- package/table/hooks/useTableActionsContext.d.ts +1 -0
- package/table/hooks/useTableActionsContext.js +12 -0
- package/table/hooks/useTableCell.d.ts +16 -0
- package/table/hooks/useTableCell.js +166 -0
- package/table/hooks/useTableCellToolbarActions.d.ts +34 -0
- package/table/hooks/useTableCellToolbarActions.js +526 -0
- package/table/hooks/useTableMetadata.d.ts +1 -0
- package/table/hooks/useTableMetadata.js +12 -0
- package/table/hooks/useTableStateContext.d.ts +1 -0
- package/table/hooks/useTableStateContext.js +12 -0
- package/table/hooks/useTableStates.d.ts +18 -0
- package/table/hooks/useTableStates.js +14 -0
- package/table/index.cjs.js +4002 -0
- package/table/index.d.ts +16 -0
- package/table/index.js +27 -0
- package/table/jsx-serializer/components/Table.d.ts +3 -0
- package/table/jsx-serializer/components/Table.js +7 -0
- package/table/jsx-serializer/components/TableBody.d.ts +3 -0
- package/table/jsx-serializer/components/TableBody.js +7 -0
- package/table/jsx-serializer/components/TableCell.d.ts +5 -0
- package/table/jsx-serializer/components/TableCell.js +33 -0
- package/table/jsx-serializer/components/TableHeader.d.ts +3 -0
- package/table/jsx-serializer/components/TableHeader.js +10 -0
- package/table/jsx-serializer/components/TableMain.d.ts +6 -0
- package/table/jsx-serializer/components/TableMain.js +18 -0
- package/table/jsx-serializer/components/TableRow.d.ts +3 -0
- package/table/jsx-serializer/components/TableRow.js +7 -0
- package/table/jsx-serializer/components/TableTitle.d.ts +3 -0
- package/table/jsx-serializer/components/TableTitle.js +7 -0
- package/table/jsx-serializer/contexts/TableHeaderContext.d.ts +1 -0
- package/table/jsx-serializer/contexts/TableHeaderContext.js +5 -0
- package/table/jsx-serializer/contexts/TableScrollContext.d.ts +2 -0
- package/table/jsx-serializer/contexts/TableScrollContext.js +7 -0
- package/table/jsx-serializer/createJsxSerializeTable.d.ts +5 -0
- package/table/jsx-serializer/createJsxSerializeTable.js +113 -0
- package/table/jsx-serializer/defaultRenderTableElements.d.ts +2 -0
- package/table/jsx-serializer/defaultRenderTableElements.js +20 -0
- package/table/jsx-serializer/index.cjs.js +195 -0
- package/table/jsx-serializer/index.d.ts +3 -0
- package/table/jsx-serializer/index.js +2 -0
- package/table/jsx-serializer/package.json +7 -0
- package/table/jsx-serializer/typings.d.ts +12 -0
- package/table/package.json +10 -0
- package/table/table.css +1 -0
- package/table/table.scss +428 -0
- package/table/toolbar/TableToolbarIcon.d.ts +8 -0
- package/table/toolbar/TableToolbarIcon.js +12 -0
- package/table/toolbar/index.cjs.js +24 -0
- package/table/toolbar/index.d.ts +2 -0
- package/table/toolbar/index.js +2 -0
- package/table/toolbar/package.json +7 -0
- package/table/toolbar/useTableTool.d.ts +4 -0
- package/table/toolbar/useTableTool.js +13 -0
- package/table/typings.d.ts +68 -0
- package/table/utils/helper.d.ts +186 -0
- package/table/utils/helper.js +799 -0
- package/toolbar/components/InlineToolbar.d.ts +12 -11
- package/toolbar/components/InlineToolbar.js +23 -19
- package/toolbar/components/Toolbar.js +2 -2
- package/toolbar/index.cjs.js +24 -21
- package/toolbar/toolbar.css +1 -1
- package/toolbar/toolbar.scss +4 -1
- package/utils/index.cjs.js +7 -1
- package/utils/removePreviousElement.js +7 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { TableHeaderContext } from '../contexts/TableHeaderContext.js';
|
|
4
|
+
|
|
5
|
+
function TableHeader(props) {
|
|
6
|
+
const { attributes, children, element } = props;
|
|
7
|
+
const tableHeaderContextValue = useMemo(() => ({ isHeader: true }), []);
|
|
8
|
+
const hasAnyRowPinned = element.children.some((child) => child.children.every((cell) => cell.pinned));
|
|
9
|
+
return (React.createElement(TableHeaderContext.Provider, { value: tableHeaderContextValue },
|
|
10
|
+
React.createElement("thead", Object.assign({}, attributes, { className: clsx('qdr-table__header', { 'qdr-table__header--pinned': hasAnyRowPinned }) }), children)));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { TableHeader as default };
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import React, { useRef, useState, useMemo, useEffect, useCallback } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useModal, useSlateStatic, ReactEditor } from '@quadrats/react';
|
|
4
|
+
import { Icon } from '@quadrats/react/components';
|
|
5
|
+
import { AlignLeft, AlignRight, AlignCenter, Copy, Trash, Plus } from '@quadrats/icons';
|
|
6
|
+
import { useTableActionsContext } from '../hooks/useTableActionsContext.js';
|
|
7
|
+
import { useTableMetadata } from '../hooks/useTableMetadata.js';
|
|
8
|
+
import { useTableStateContext } from '../hooks/useTableStateContext.js';
|
|
9
|
+
import { useTableDragContext } from '../contexts/TableDragContext.js';
|
|
10
|
+
import { InlineToolbar, ToolbarGroupIcon, ToolbarIcon } from '@quadrats/react/toolbar';
|
|
11
|
+
import { Transforms } from 'slate';
|
|
12
|
+
import { calculateTableMinWidth, columnWidthToCSS } from '@quadrats/common/table';
|
|
13
|
+
import { TableScrollContext } from '../contexts/TableScrollContext.js';
|
|
14
|
+
import { useTableCellAlign, useTableCellAlignStatus } from '../hooks/useTableCell.js';
|
|
15
|
+
import { getTableElements, getColumnWidths } from '../utils/helper.js';
|
|
16
|
+
import { TableDragLayer } from './TableDragLayer.js';
|
|
17
|
+
|
|
18
|
+
function TableMain(props) {
|
|
19
|
+
const { attributes, children } = props;
|
|
20
|
+
const { setConfirmModalConfig } = useModal();
|
|
21
|
+
const editor = useSlateStatic();
|
|
22
|
+
const { addColumn, addRow, addColumnAndRow } = useTableActionsContext();
|
|
23
|
+
const { isReachMaximumColumns, isReachMaximumRows, tableElement } = useTableMetadata();
|
|
24
|
+
const { tableSelectedOn, setTableSelectedOn } = useTableStateContext();
|
|
25
|
+
const { dragState } = useTableDragContext();
|
|
26
|
+
// Table align functions
|
|
27
|
+
const setAlign = useTableCellAlign(tableElement, editor);
|
|
28
|
+
const getAlign = useTableCellAlignStatus(tableElement, editor);
|
|
29
|
+
const tablePath = ReactEditor.findPath(editor, tableElement);
|
|
30
|
+
const scrollRef = useRef(null);
|
|
31
|
+
const tableRef = useRef(null);
|
|
32
|
+
const [scrollTop, setScrollTop] = useState(0);
|
|
33
|
+
const [scrollLeft, setScrollLeft] = useState(0);
|
|
34
|
+
const [tableWidth, setTableWidth] = useState(0);
|
|
35
|
+
const scrollUpdateTimerRef = useRef(null);
|
|
36
|
+
const isUpdatingScrollRef = useRef(false); // 標記是否正在更新滾動位置
|
|
37
|
+
const previousColumnWidthsRef = useRef(''); // 追蹤 columnWidths 的變化
|
|
38
|
+
// sizing
|
|
39
|
+
const { tableBodyElement } = getTableElements(tableElement);
|
|
40
|
+
const firstRowCells = tableBodyElement === null || tableBodyElement === void 0 ? void 0 : tableBodyElement.children[0].children;
|
|
41
|
+
// 獲取欄位寬度(傳入 tableWidth 以支援混合模式)
|
|
42
|
+
const columnWidths = useMemo(() => getColumnWidths(tableElement, tableWidth), [tableElement, tableWidth]);
|
|
43
|
+
// 計算 table 的最小寬度
|
|
44
|
+
const tableMinWidth = useMemo(() => calculateTableMinWidth(columnWidths), [columnWidths]);
|
|
45
|
+
// 監聽 table 寬度變化
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const { current: table } = tableRef;
|
|
48
|
+
if (!table)
|
|
49
|
+
return;
|
|
50
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
setTableWidth(entry.contentRect.width);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
resizeObserver.observe(table);
|
|
56
|
+
// 初始化寬度
|
|
57
|
+
setTableWidth(table.getBoundingClientRect().width);
|
|
58
|
+
return () => {
|
|
59
|
+
resizeObserver.disconnect();
|
|
60
|
+
};
|
|
61
|
+
}, []);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const { current: scrollContainer } = scrollRef;
|
|
64
|
+
if (!scrollContainer)
|
|
65
|
+
return;
|
|
66
|
+
const handleScroll = () => {
|
|
67
|
+
setScrollTop(scrollContainer.scrollTop);
|
|
68
|
+
setScrollLeft(scrollContainer.scrollLeft);
|
|
69
|
+
// 如果正在更新滾動位置,不要觸發 Slate 更新
|
|
70
|
+
if (isUpdatingScrollRef.current) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// 如果正在拖曳,不要觸發 Slate 更新(避免 transform 導致事件遺失)
|
|
74
|
+
if (dragState) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
// 使用 debounce 來減少 Slate 更新頻率
|
|
78
|
+
if (scrollUpdateTimerRef.current) {
|
|
79
|
+
clearTimeout(scrollUpdateTimerRef.current);
|
|
80
|
+
}
|
|
81
|
+
scrollUpdateTimerRef.current = setTimeout(() => {
|
|
82
|
+
// 更新 tableElement 的 scrollPosition
|
|
83
|
+
const tablePath = ReactEditor.findPath(editor, tableElement);
|
|
84
|
+
Transforms.setNodes(editor, {
|
|
85
|
+
scrollPosition: {
|
|
86
|
+
scrollLeft: scrollContainer.scrollLeft,
|
|
87
|
+
scrollTop: scrollContainer.scrollTop,
|
|
88
|
+
},
|
|
89
|
+
}, { at: tablePath });
|
|
90
|
+
}, 300); // 300ms debounce
|
|
91
|
+
};
|
|
92
|
+
scrollContainer.addEventListener('scroll', handleScroll, false);
|
|
93
|
+
return () => {
|
|
94
|
+
scrollContainer.removeEventListener('scroll', handleScroll, false);
|
|
95
|
+
if (scrollUpdateTimerRef.current) {
|
|
96
|
+
clearTimeout(scrollUpdateTimerRef.current);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}, [editor, tableElement, dragState]);
|
|
100
|
+
// 只在 columnWidths 改變時恢復滾動位置
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
const { current: scrollContainer } = scrollRef;
|
|
103
|
+
if (!scrollContainer || !tableElement.scrollPosition)
|
|
104
|
+
return;
|
|
105
|
+
// 檢查 columnWidths 是否真的改變了
|
|
106
|
+
const currentColumnWidthsStr = JSON.stringify(columnWidths);
|
|
107
|
+
if (previousColumnWidthsRef.current !== currentColumnWidthsStr) {
|
|
108
|
+
previousColumnWidthsRef.current = currentColumnWidthsStr;
|
|
109
|
+
// 標記正在更新,避免觸發 handleScroll
|
|
110
|
+
isUpdatingScrollRef.current = true;
|
|
111
|
+
// 使用 requestAnimationFrame 確保 DOM 已更新
|
|
112
|
+
requestAnimationFrame(() => {
|
|
113
|
+
var _a, _b, _c, _d;
|
|
114
|
+
scrollContainer.scrollLeft = (_b = (_a = tableElement.scrollPosition) === null || _a === void 0 ? void 0 : _a.scrollLeft) !== null && _b !== void 0 ? _b : 0;
|
|
115
|
+
scrollContainer.scrollTop = (_d = (_c = tableElement.scrollPosition) === null || _c === void 0 ? void 0 : _c.scrollTop) !== null && _d !== void 0 ? _d : 0;
|
|
116
|
+
// 重置標記
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
isUpdatingScrollRef.current = false;
|
|
119
|
+
}, 100);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}, [columnWidths, tableElement.scrollPosition]);
|
|
123
|
+
const scrollContextValue = useMemo(() => ({ scrollTop, scrollLeft, scrollRef }), [scrollTop, scrollLeft, scrollRef]);
|
|
124
|
+
// 複製 Table 功能
|
|
125
|
+
const copyTable = useCallback(() => {
|
|
126
|
+
try {
|
|
127
|
+
const clonedTable = JSON.parse(JSON.stringify(tableElement));
|
|
128
|
+
// 找到當前 table 的父節點路徑
|
|
129
|
+
const tableParentPath = tablePath.slice(0, -1);
|
|
130
|
+
const tableIndex = tablePath[tablePath.length - 1];
|
|
131
|
+
// 在當前 table 之後插入複製的 table
|
|
132
|
+
Transforms.insertNodes(editor, clonedTable, {
|
|
133
|
+
at: [...tableParentPath, tableIndex + 1],
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error('Failed to copy table:', error);
|
|
138
|
+
}
|
|
139
|
+
}, [editor, tableElement, tablePath]);
|
|
140
|
+
// 獲取當前 table 的 align 狀態
|
|
141
|
+
const currentTableAlign = getAlign('table');
|
|
142
|
+
// 根據當前 table align 狀態選擇對應的 icon
|
|
143
|
+
const getCurrentTableAlignIcon = useCallback(() => {
|
|
144
|
+
switch (currentTableAlign) {
|
|
145
|
+
case 'left':
|
|
146
|
+
return AlignLeft;
|
|
147
|
+
case 'center':
|
|
148
|
+
return AlignCenter;
|
|
149
|
+
case 'right':
|
|
150
|
+
return AlignRight;
|
|
151
|
+
default:
|
|
152
|
+
return AlignLeft;
|
|
153
|
+
}
|
|
154
|
+
}, [currentTableAlign]);
|
|
155
|
+
return (React.createElement("div", { className: clsx('qdr-table__mainWrapper', {
|
|
156
|
+
'qdr-table__mainWrapper--selected': (tableSelectedOn === null || tableSelectedOn === void 0 ? void 0 : tableSelectedOn.region) === 'table',
|
|
157
|
+
}) },
|
|
158
|
+
React.createElement(InlineToolbar, { className: "qdr-table__table-toolbar", onClickAway: (tableSelectedOn === null || tableSelectedOn === void 0 ? void 0 : tableSelectedOn.region) === 'table' ? () => setTableSelectedOn(undefined) : undefined, iconGroups: [
|
|
159
|
+
{
|
|
160
|
+
icons: [
|
|
161
|
+
{
|
|
162
|
+
icon: Copy,
|
|
163
|
+
onClick: () => {
|
|
164
|
+
copyTable();
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
React.createElement(ToolbarGroupIcon, { key: "table-align-change", icon: getCurrentTableAlignIcon() },
|
|
168
|
+
React.createElement(ToolbarIcon, { icon: AlignLeft, onClick: () => {
|
|
169
|
+
setAlign('left', 'table');
|
|
170
|
+
} }),
|
|
171
|
+
React.createElement(ToolbarIcon, { icon: AlignCenter, onClick: () => {
|
|
172
|
+
setAlign('center', 'table');
|
|
173
|
+
} }),
|
|
174
|
+
React.createElement(ToolbarIcon, { icon: AlignRight, onClick: () => {
|
|
175
|
+
setAlign('right', 'table');
|
|
176
|
+
} })),
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
icons: [
|
|
181
|
+
{
|
|
182
|
+
icon: Trash,
|
|
183
|
+
className: 'qdr-table__delete',
|
|
184
|
+
onClick: () => {
|
|
185
|
+
setConfirmModalConfig({
|
|
186
|
+
title: '刪除表格',
|
|
187
|
+
content: '是否確認刪除此表格?刪除後將立即移除,且此操作無法復原。',
|
|
188
|
+
confirmText: '刪除表格',
|
|
189
|
+
onConfirm: () => {
|
|
190
|
+
Transforms.removeNodes(editor, { at: tablePath });
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
] }),
|
|
198
|
+
React.createElement("div", { ref: scrollRef, className: "qdr-table__scrollContainer" },
|
|
199
|
+
React.createElement(TableScrollContext.Provider, { value: scrollContextValue },
|
|
200
|
+
React.createElement("table", Object.assign({}, attributes, { ref: (node) => {
|
|
201
|
+
// 合併兩個 refs
|
|
202
|
+
tableRef.current = node;
|
|
203
|
+
if (typeof attributes.ref === 'function') {
|
|
204
|
+
attributes.ref(node);
|
|
205
|
+
}
|
|
206
|
+
else if (attributes.ref) {
|
|
207
|
+
attributes.ref.current = node;
|
|
208
|
+
}
|
|
209
|
+
}, className: "qdr-table__main", style: {
|
|
210
|
+
minWidth: tableMinWidth,
|
|
211
|
+
} }),
|
|
212
|
+
React.createElement("colgroup", null, columnWidths.map((width, index) => (React.createElement("col", { key: index, style: {
|
|
213
|
+
width: columnWidthToCSS(width),
|
|
214
|
+
minWidth: columnWidthToCSS(width),
|
|
215
|
+
} })))),
|
|
216
|
+
children)),
|
|
217
|
+
React.createElement(TableDragLayer, { scrollRef: scrollRef })),
|
|
218
|
+
React.createElement("div", { className: "qdr-table__size-indicators" }, firstRowCells === null || firstRowCells === void 0 ? void 0 : firstRowCells.map((cell, colIndex) => (React.createElement("div", { key: colIndex, className: "qdr-table__size-indicator", style: {
|
|
219
|
+
width: columnWidthToCSS(columnWidths[colIndex]),
|
|
220
|
+
minWidth: columnWidthToCSS(columnWidths[colIndex]),
|
|
221
|
+
transform: cell.pinned ? 'none' : `translateX(-${scrollLeft}px)`,
|
|
222
|
+
zIndex: cell.pinned ? 2 : 1,
|
|
223
|
+
} },
|
|
224
|
+
React.createElement("div", { className: "qdr-table__size" }, columnWidthToCSS(columnWidths[colIndex])))))),
|
|
225
|
+
isReachMaximumColumns ? null : (React.createElement("button", { type: "button", onClick: () => addColumn(), title: "Add Column", className: "qdr-table__add-column" },
|
|
226
|
+
React.createElement(Icon, { icon: Plus, width: 20, height: 20, className: "qdr-table__btn-icon" }))),
|
|
227
|
+
isReachMaximumRows ? null : (React.createElement("button", { type: "button", onClick: () => addRow(), title: "Add Row", className: "qdr-table__add-row" },
|
|
228
|
+
React.createElement(Icon, { icon: Plus, width: 20, height: 20, className: "qdr-table__btn-icon" }))),
|
|
229
|
+
isReachMaximumColumns || isReachMaximumRows ? null : (React.createElement("button", { type: "button", onClick: addColumnAndRow, title: "Add Column and Row", className: "qdr-table__add-both" },
|
|
230
|
+
React.createElement(Icon, { icon: Plus, width: 20, height: 20, className: "qdr-table__btn-icon" })))));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export { TableMain as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { Editor, Path } from '@quadrats/core';
|
|
3
|
+
import { useComposition, useQuadrats, ReactEditor } from '@quadrats/react';
|
|
4
|
+
|
|
5
|
+
function TableTitle(props) {
|
|
6
|
+
const { compositionPath } = useComposition();
|
|
7
|
+
const { attributes, children, element } = props;
|
|
8
|
+
const editor = useQuadrats();
|
|
9
|
+
const path = ReactEditor.findPath(editor, element);
|
|
10
|
+
const text = Editor.string(editor, path);
|
|
11
|
+
const isEmpty = !text;
|
|
12
|
+
const composing = useMemo(() => Path.equals(compositionPath, path), [compositionPath, path]);
|
|
13
|
+
return (React.createElement("h3", Object.assign({}, attributes, { className: "qdr-table__title" }),
|
|
14
|
+
children,
|
|
15
|
+
isEmpty && !composing && (React.createElement("span", { className: "qdr-table__title__placeholder", contentEditable: false }, "\u8ACB\u8F38\u5165\u8868\u683C\u6A19\u984C"))));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { TableTitle as default };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TableContextType } from '../typings';
|
|
2
|
+
export type TableActionsContextType = Pick<TableContextType, 'addColumn' | 'addRow' | 'addColumnAndRow' | 'deleteRow' | 'deleteColumn' | 'moveRowToBody' | 'moveRowToHeader' | 'unsetColumnAsTitle' | 'setColumnAsTitle' | 'pinColumn' | 'unpinColumn' | 'pinRow' | 'unpinRow' | 'moveOrSwapRow' | 'moveOrSwapColumn'>;
|
|
3
|
+
export declare const TableActionsContext: import("react").Context<TableActionsContextType | undefined>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
interface RowDragState {
|
|
3
|
+
type: 'row';
|
|
4
|
+
rowIndex: number;
|
|
5
|
+
isInHeader: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface ColumnDragState {
|
|
8
|
+
type: 'column';
|
|
9
|
+
columnIndex: number;
|
|
10
|
+
isTitle: boolean;
|
|
11
|
+
}
|
|
12
|
+
type DragState = RowDragState | ColumnDragState | null;
|
|
13
|
+
type DragDirection = 'up' | 'down' | 'left' | 'right' | null;
|
|
14
|
+
interface TableDragContextValue {
|
|
15
|
+
dragState: DragState;
|
|
16
|
+
setDragState: Dispatch<SetStateAction<DragState>>;
|
|
17
|
+
dropTargetIndex: number | null;
|
|
18
|
+
setDropTargetIndex: Dispatch<SetStateAction<number | null>>;
|
|
19
|
+
dragDirection: DragDirection;
|
|
20
|
+
setDragDirection: Dispatch<SetStateAction<DragDirection>>;
|
|
21
|
+
}
|
|
22
|
+
export declare const TableDragProvider: React.FC<{
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
}>;
|
|
25
|
+
export declare const useTableDragContext: () => TableDragContextValue;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { createContext, useContext, useState, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
const TableDragContext = createContext(null);
|
|
4
|
+
const TableDragProvider = ({ children }) => {
|
|
5
|
+
const [dragState, setDragState] = useState(null);
|
|
6
|
+
const [dropTargetIndex, setDropTargetIndex] = useState(null);
|
|
7
|
+
const [dragDirection, setDragDirection] = useState(null);
|
|
8
|
+
const value = useMemo(() => ({
|
|
9
|
+
dragState,
|
|
10
|
+
setDragState,
|
|
11
|
+
dropTargetIndex,
|
|
12
|
+
setDropTargetIndex,
|
|
13
|
+
dragDirection,
|
|
14
|
+
setDragDirection,
|
|
15
|
+
}), [dragState, dropTargetIndex, dragDirection]);
|
|
16
|
+
return React.createElement(TableDragContext.Provider, { value: value }, children);
|
|
17
|
+
};
|
|
18
|
+
const useTableDragContext = () => {
|
|
19
|
+
const context = useContext(TableDragContext);
|
|
20
|
+
if (!context) {
|
|
21
|
+
throw new Error('useTableDragContext must be used within TableDragProvider');
|
|
22
|
+
}
|
|
23
|
+
return context;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { TableDragProvider, useTableDragContext };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TableContextType } from '../typings';
|
|
2
|
+
export type TableMetadataContextType = Pick<TableContextType, 'tableElement' | 'columnCount' | 'rowCount' | 'portalContainerRef' | 'isReachMaximumColumns' | 'isReachMaximumRows' | 'isReachMinimumNormalColumns' | 'isReachMinimumBodyRows' | 'pinnedColumns' | 'pinnedRows' | 'cellPositions' | 'isColumnPinned' | 'isRowPinned'>;
|
|
3
|
+
export declare const TableMetadataContext: import("react").Context<TableMetadataContextType | undefined>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TableContextType } from '../typings';
|
|
2
|
+
export type TableStateContextType = Pick<TableContextType, 'tableSelectedOn' | 'setTableSelectedOn' | 'tableHoveredOn' | 'setTableHoveredOn'>;
|
|
3
|
+
export declare const TableStateContext: import("react").Context<TableStateContextType | undefined>;
|