@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 @@
|
|
|
1
|
+
export declare function useTableActionsContext(): import("../contexts/TableActionsContext").TableActionsContextType;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import { TableActionsContext } from '../contexts/TableActionsContext.js';
|
|
3
|
+
|
|
4
|
+
function useTableActionsContext() {
|
|
5
|
+
const context = useContext(TableActionsContext);
|
|
6
|
+
if (!context) {
|
|
7
|
+
throw new Error('useTableActionsContext must be used within a TableActionsContext.Provider');
|
|
8
|
+
}
|
|
9
|
+
return context;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { useTableActionsContext };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TableElement } from '@quadrats/common/table';
|
|
2
|
+
import { QuadratsReactEditor } from '@quadrats/react';
|
|
3
|
+
import { AlignValue } from '@quadrats/common/align';
|
|
4
|
+
/** 檢查 table cell 是否在 focused 狀態 */
|
|
5
|
+
export declare function useTableCellFocused(element: TableElement, editor: QuadratsReactEditor): boolean;
|
|
6
|
+
/** 取得 table cell 在 table 裡的 columnIndex 及 rowIndex */
|
|
7
|
+
export declare function useTableCellPosition(element: TableElement, _editor: QuadratsReactEditor): {
|
|
8
|
+
columnIndex: number;
|
|
9
|
+
rowIndex: number;
|
|
10
|
+
};
|
|
11
|
+
/** 轉換 paragraph, order list, un-order list */
|
|
12
|
+
export declare function useTableCellTransformContent(element: TableElement, editor: QuadratsReactEditor): (elementType: string) => void;
|
|
13
|
+
/** 設定 column 或 table 的 align */
|
|
14
|
+
export declare function useTableCellAlign(tableElement: TableElement, editor: QuadratsReactEditor): (alignValue: AlignValue, scope: "table" | "column", columnIndex?: number) => void;
|
|
15
|
+
/** 獲取 column 或 table 的 align 狀態 */
|
|
16
|
+
export declare function useTableCellAlignStatus(tableElement: TableElement, editor: QuadratsReactEditor): (scope: "table" | "column", columnIndex?: number) => AlignValue;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { usePreviousValue } from '@quadrats/react/utils';
|
|
2
|
+
import { Editor, Range, Node, Element, Transforms, PARAGRAPH_TYPE } from '@quadrats/core';
|
|
3
|
+
import { useCallback, useMemo, useEffect } from 'react';
|
|
4
|
+
import { ReactEditor, useFocused } from 'slate-react';
|
|
5
|
+
import { useTableStateContext } from './useTableStateContext.js';
|
|
6
|
+
import { useTableMetadata } from './useTableMetadata.js';
|
|
7
|
+
import { createList, LIST_TYPES } from '@quadrats/common/list';
|
|
8
|
+
import { getTableStructure, collectCells, setAlignForCells, getAlignFromCells } from '../utils/helper.js';
|
|
9
|
+
|
|
10
|
+
/** 檢查 table cell 是否在 focused 狀態 */
|
|
11
|
+
function useTableCellFocused(element, editor) {
|
|
12
|
+
const { tableSelectedOn, setTableHoveredOn, setTableSelectedOn } = useTableStateContext();
|
|
13
|
+
const cellPath = ReactEditor.findPath(editor, element);
|
|
14
|
+
const focused = useFocused();
|
|
15
|
+
const isCellFocused = useMemo(() => {
|
|
16
|
+
if (!focused || !editor.selection || (tableSelectedOn === null || tableSelectedOn === void 0 ? void 0 : tableSelectedOn.region))
|
|
17
|
+
return false;
|
|
18
|
+
const isSelectionCollapsed = Range.isCollapsed(editor.selection);
|
|
19
|
+
if (!isSelectionCollapsed)
|
|
20
|
+
return false;
|
|
21
|
+
const selectionPath = editor.selection.anchor.path;
|
|
22
|
+
return selectionPath.slice(0, cellPath.length).every((segment, index) => segment === cellPath[index]);
|
|
23
|
+
}, [focused, editor.selection, cellPath, tableSelectedOn]);
|
|
24
|
+
const isPreviousCellFocused = usePreviousValue(isCellFocused);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (isCellFocused) {
|
|
27
|
+
setTableHoveredOn(undefined);
|
|
28
|
+
}
|
|
29
|
+
if (isCellFocused && !isPreviousCellFocused) {
|
|
30
|
+
setTableSelectedOn(undefined);
|
|
31
|
+
}
|
|
32
|
+
}, [isCellFocused, isPreviousCellFocused, setTableSelectedOn, setTableHoveredOn]);
|
|
33
|
+
return isCellFocused;
|
|
34
|
+
}
|
|
35
|
+
/** 取得 table cell 在 table 裡的 columnIndex 及 rowIndex */
|
|
36
|
+
function useTableCellPosition(element, _editor) {
|
|
37
|
+
const { cellPositions } = useTableMetadata();
|
|
38
|
+
const cellPosition = useMemo(() => {
|
|
39
|
+
const position = cellPositions.get(element);
|
|
40
|
+
if (position) {
|
|
41
|
+
return position;
|
|
42
|
+
}
|
|
43
|
+
return { columnIndex: -1, rowIndex: -1 };
|
|
44
|
+
}, [cellPositions, element]);
|
|
45
|
+
return cellPosition;
|
|
46
|
+
}
|
|
47
|
+
/** 轉換 paragraph, order list, un-order list */
|
|
48
|
+
function useTableCellTransformContent(element, editor) {
|
|
49
|
+
const splitContentByNewlines = useCallback((cellPath) => {
|
|
50
|
+
try {
|
|
51
|
+
const cellNode = Node.get(editor, cellPath);
|
|
52
|
+
if (!Element.isElement(cellNode))
|
|
53
|
+
return false;
|
|
54
|
+
let hasChanges = false;
|
|
55
|
+
const nodesToProcess = [...cellNode.children];
|
|
56
|
+
// Process each content node in reverse order to maintain indices
|
|
57
|
+
for (let contentIndex = nodesToProcess.length - 1; contentIndex >= 0; contentIndex--) {
|
|
58
|
+
const contentNode = nodesToProcess[contentIndex];
|
|
59
|
+
if (Element.isElement(contentNode)) {
|
|
60
|
+
const textContent = Node.string(contentNode);
|
|
61
|
+
if (textContent.includes('\n')) {
|
|
62
|
+
const contentPath = [...cellPath, contentIndex];
|
|
63
|
+
// Verify the path is still valid
|
|
64
|
+
try {
|
|
65
|
+
const currentNode = Node.get(editor, contentPath);
|
|
66
|
+
if (!currentNode)
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
catch (_a) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Split by newlines and filter out empty strings
|
|
73
|
+
const lines = textContent.split('\n').filter((line) => line.trim() !== '');
|
|
74
|
+
if (lines.length > 1) {
|
|
75
|
+
hasChanges = true;
|
|
76
|
+
// Use Editor.withoutNormalizing to batch operations
|
|
77
|
+
Editor.withoutNormalizing(editor, () => {
|
|
78
|
+
Transforms.removeNodes(editor, { at: contentPath });
|
|
79
|
+
lines.forEach((line, lineIndex) => {
|
|
80
|
+
const newParagraph = {
|
|
81
|
+
type: PARAGRAPH_TYPE,
|
|
82
|
+
children: [{ text: line.trim() }],
|
|
83
|
+
};
|
|
84
|
+
Transforms.insertNodes(editor, newParagraph, {
|
|
85
|
+
at: [...cellPath, contentIndex + lineIndex],
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return hasChanges;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.warn('Failed to split content by newlines:', error);
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}, [editor]);
|
|
100
|
+
const transformCellContent = useCallback((elementType) => {
|
|
101
|
+
try {
|
|
102
|
+
const cellPath = ReactEditor.findPath(editor, element);
|
|
103
|
+
const listHelper = createList();
|
|
104
|
+
if (elementType === LIST_TYPES.ol || elementType === LIST_TYPES.ul) {
|
|
105
|
+
/** 將 paragraph 的換行符號轉換成 list item */
|
|
106
|
+
const wasSplit = splitContentByNewlines(cellPath);
|
|
107
|
+
if (wasSplit) {
|
|
108
|
+
Editor.normalize(editor, { force: true });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// 選擇整個儲存格內容
|
|
112
|
+
const cellStartPoint = Editor.start(editor, cellPath);
|
|
113
|
+
const cellEndPoint = Editor.end(editor, cellPath);
|
|
114
|
+
Transforms.select(editor, { anchor: cellStartPoint, focus: cellEndPoint });
|
|
115
|
+
if (elementType === LIST_TYPES.ol || elementType === LIST_TYPES.ul) {
|
|
116
|
+
listHelper.toggleList(editor, elementType, PARAGRAPH_TYPE);
|
|
117
|
+
}
|
|
118
|
+
else if (elementType === PARAGRAPH_TYPE) {
|
|
119
|
+
const cellNode = Node.get(editor, cellPath);
|
|
120
|
+
if (Element.isElement(cellNode)) {
|
|
121
|
+
const currentListElement = cellNode.children.find((child) => Element.isElement(child) && [LIST_TYPES.ol, LIST_TYPES.ul].includes(child.type));
|
|
122
|
+
if (currentListElement && Element.isElement(currentListElement)) {
|
|
123
|
+
listHelper.toggleList(editor, currentListElement.type, PARAGRAPH_TYPE);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// 因為底層結構改變了,取消選取以避免錯誤
|
|
128
|
+
Transforms.deselect(editor);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.warn('Failed to transform cell content:', error);
|
|
132
|
+
}
|
|
133
|
+
}, [editor, element, splitContentByNewlines]);
|
|
134
|
+
return transformCellContent;
|
|
135
|
+
}
|
|
136
|
+
/** 設定 column 或 table 的 align */
|
|
137
|
+
function useTableCellAlign(tableElement, editor) {
|
|
138
|
+
const setAlign = useCallback((alignValue, scope, columnIndex) => {
|
|
139
|
+
const tableStructure = getTableStructure(editor, tableElement);
|
|
140
|
+
if (!tableStructure) {
|
|
141
|
+
console.warn('Failed to get table structure');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// 使用 helper 函數收集 cells
|
|
145
|
+
const cells = collectCells(tableStructure, scope, columnIndex);
|
|
146
|
+
// 使用 helper 函數設定 align
|
|
147
|
+
Editor.withoutNormalizing(editor, () => {
|
|
148
|
+
setAlignForCells(editor, cells, alignValue);
|
|
149
|
+
});
|
|
150
|
+
}, [editor, tableElement]);
|
|
151
|
+
return setAlign;
|
|
152
|
+
}
|
|
153
|
+
/** 獲取 column 或 table 的 align 狀態 */
|
|
154
|
+
function useTableCellAlignStatus(tableElement, editor) {
|
|
155
|
+
const getAlign = useCallback((scope, columnIndex) => {
|
|
156
|
+
const tableStructure = getTableStructure(editor, tableElement);
|
|
157
|
+
if (!tableStructure) {
|
|
158
|
+
return 'left';
|
|
159
|
+
}
|
|
160
|
+
const cells = collectCells(tableStructure, scope, columnIndex);
|
|
161
|
+
return getAlignFromCells(cells);
|
|
162
|
+
}, [editor, tableElement]);
|
|
163
|
+
return getAlign;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { useTableCellAlign, useTableCellAlignStatus, useTableCellFocused, useTableCellPosition, useTableCellTransformContent };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TableElement } from '@quadrats/common/table';
|
|
3
|
+
interface Position {
|
|
4
|
+
columnIndex: number;
|
|
5
|
+
rowIndex: number;
|
|
6
|
+
}
|
|
7
|
+
interface UseTableCellToolbarActionsParams {
|
|
8
|
+
element: TableElement;
|
|
9
|
+
cellPosition: Position;
|
|
10
|
+
isHeader: boolean;
|
|
11
|
+
transformCellContent: (type: string) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 將所有與 toolbar icons 相關的邏輯集中管理
|
|
15
|
+
*/
|
|
16
|
+
export declare function useTableCellToolbarActions({ element, cellPosition, isHeader, transformCellContent, }: UseTableCellToolbarActionsParams): {
|
|
17
|
+
focusToolbarIconGroups: ({
|
|
18
|
+
icons: React.JSX.Element[];
|
|
19
|
+
} | {
|
|
20
|
+
icons: {
|
|
21
|
+
icon: import("@quadrats/icons").IconDefinition;
|
|
22
|
+
onClick: () => void;
|
|
23
|
+
}[];
|
|
24
|
+
})[];
|
|
25
|
+
inlineToolbarIconGroups: ({
|
|
26
|
+
icons: {
|
|
27
|
+
icon: import("@quadrats/icons").IconDefinition;
|
|
28
|
+
onClick: () => void;
|
|
29
|
+
}[];
|
|
30
|
+
} | {
|
|
31
|
+
icons: React.JSX.Element[];
|
|
32
|
+
})[];
|
|
33
|
+
};
|
|
34
|
+
export {};
|