@skygraph/react 0.5.2 → 0.6.4
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/README.md +70 -70
- package/dist/{Table-BmesoMje.d.ts → Table-CAay8MmA.d.ts} +8 -1
- package/dist/{Table-CpKMOH2x.d.cts → Table-CMKo6Pc3.d.cts} +8 -1
- package/dist/{chunk-ZJF6SJLP.js → chunk-45YW5VSP.js} +44 -10
- package/dist/chunk-45YW5VSP.js.map +1 -0
- package/dist/{chunk-NXB3VAVF.js → chunk-7AA2JPZB.js} +148 -61
- package/dist/chunk-7AA2JPZB.js.map +1 -0
- package/dist/{chunk-Z5UGF7EO.js → chunk-EFDB2ENB.js} +87 -25
- package/dist/chunk-EFDB2ENB.js.map +1 -0
- package/dist/{chunk-UO6VJC3C.js → chunk-KGFFQGCM.js} +3 -3
- package/dist/{chunk-FSV73JI4.js → chunk-PEX2UTNG.js} +2 -2
- package/dist/chunk-VLRLCHEL.js +184 -0
- package/dist/chunk-VLRLCHEL.js.map +1 -0
- package/dist/{chunk-MLEBVELO.js → chunk-Y6XZ5TLD.js} +93 -47
- package/dist/chunk-Y6XZ5TLD.js.map +1 -0
- package/dist/{chunk-GJDDPZH7.js → chunk-ZJC2QUWA.js} +12 -12
- package/dist/chunk-ZJC2QUWA.js.map +1 -0
- package/dist/datagrid.cjs +76 -21
- package/dist/datagrid.cjs.map +1 -1
- package/dist/datagrid.js +3 -3
- package/dist/devtools.cjs +11 -11
- package/dist/devtools.cjs.map +1 -1
- package/dist/devtools.js +1 -1
- package/dist/form.cjs +168 -86
- package/dist/form.cjs.map +1 -1
- package/dist/form.d.cts +1 -1
- package/dist/form.d.ts +1 -1
- package/dist/form.js +3 -3
- package/dist/index.cjs +1549 -1021
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +157 -7
- package/dist/index.d.ts +157 -7
- package/dist/index.js +444 -231
- package/dist/index.js.map +1 -1
- package/dist/table.cjs +344 -221
- package/dist/table.cjs.map +1 -1
- package/dist/table.d.cts +1 -1
- package/dist/table.d.ts +1 -1
- package/dist/table.js +4 -4
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.js +3 -3
- package/package.json +2 -2
- package/dist/chunk-2OCEO636.js +0 -91
- package/dist/chunk-2OCEO636.js.map +0 -1
- package/dist/chunk-GJDDPZH7.js.map +0 -1
- package/dist/chunk-MLEBVELO.js.map +0 -1
- package/dist/chunk-NXB3VAVF.js.map +0 -1
- package/dist/chunk-Z5UGF7EO.js.map +0 -1
- package/dist/chunk-ZJF6SJLP.js.map +0 -1
- /package/dist/{chunk-UO6VJC3C.js.map → chunk-KGFFQGCM.js.map} +0 -0
- /package/dist/{chunk-FSV73JI4.js.map → chunk-PEX2UTNG.js.map} +0 -0
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Checkbox
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PEX2UTNG.js";
|
|
4
4
|
import {
|
|
5
5
|
Spin
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VLRLCHEL.js";
|
|
7
7
|
import {
|
|
8
8
|
useVirtualScroll
|
|
9
9
|
} from "./chunk-SEQI65CF.js";
|
|
10
10
|
|
|
11
11
|
// src/components/complex/DataGrid/DataGrid.tsx
|
|
12
|
-
import React, {
|
|
12
|
+
import React, {
|
|
13
|
+
forwardRef,
|
|
14
|
+
useImperativeHandle,
|
|
15
|
+
useCallback as useCallback2,
|
|
16
|
+
useRef as useRef2,
|
|
17
|
+
useMemo,
|
|
18
|
+
useState as useState2
|
|
19
|
+
} from "react";
|
|
13
20
|
|
|
14
21
|
// src/components/complex/DataGrid/useDataGridState.ts
|
|
15
22
|
import { useState, useCallback, useRef } from "react";
|
|
@@ -289,7 +296,11 @@ function DataGridInner(props, ref) {
|
|
|
289
296
|
} = state;
|
|
290
297
|
const [ctxMenu, setCtxMenu] = useState2(null);
|
|
291
298
|
const [dragOverCol, setDragOverCol] = useState2(null);
|
|
292
|
-
const {
|
|
299
|
+
const {
|
|
300
|
+
range,
|
|
301
|
+
containerRef: scrollRef,
|
|
302
|
+
scrollToIndex
|
|
303
|
+
} = useVirtualScroll({
|
|
293
304
|
itemCount: data.length,
|
|
294
305
|
itemHeight: rowHeight,
|
|
295
306
|
overscan
|
|
@@ -301,18 +312,9 @@ function DataGridInner(props, ref) {
|
|
|
301
312
|
},
|
|
302
313
|
[rowKey]
|
|
303
314
|
);
|
|
304
|
-
const frozenLeft = useMemo(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
);
|
|
308
|
-
const frozenRight = useMemo(
|
|
309
|
-
() => columns.filter((c) => c.frozen === "right"),
|
|
310
|
-
[columns]
|
|
311
|
-
);
|
|
312
|
-
const scrollable = useMemo(
|
|
313
|
-
() => columns.filter((c) => !c.frozen),
|
|
314
|
-
[columns]
|
|
315
|
-
);
|
|
315
|
+
const frozenLeft = useMemo(() => columns.filter((c) => c.frozen === "left"), [columns]);
|
|
316
|
+
const frozenRight = useMemo(() => columns.filter((c) => c.frozen === "right"), [columns]);
|
|
317
|
+
const scrollable = useMemo(() => columns.filter((c) => !c.frozen), [columns]);
|
|
316
318
|
const orderedColumns = useMemo(() => {
|
|
317
319
|
const base = [...frozenLeft, ...scrollable, ...frozenRight];
|
|
318
320
|
if (!columnOrder) return base;
|
|
@@ -624,7 +626,14 @@ function DataGridInner(props, ref) {
|
|
|
624
626
|
{
|
|
625
627
|
ref: containerRef,
|
|
626
628
|
className: rootCls,
|
|
627
|
-
style: {
|
|
629
|
+
style: {
|
|
630
|
+
width,
|
|
631
|
+
height,
|
|
632
|
+
display: "flex",
|
|
633
|
+
flexDirection: "column",
|
|
634
|
+
position: "relative",
|
|
635
|
+
...style
|
|
636
|
+
},
|
|
628
637
|
onKeyDown: handleKeyDown,
|
|
629
638
|
tabIndex: 0,
|
|
630
639
|
role: "grid",
|
|
@@ -647,7 +656,13 @@ function DataGridInner(props, ref) {
|
|
|
647
656
|
"div",
|
|
648
657
|
{
|
|
649
658
|
className: `${cls.headerCell} ${cls.selectionCell}`,
|
|
650
|
-
style: {
|
|
659
|
+
style: {
|
|
660
|
+
width: SELECTION_COL_WIDTH,
|
|
661
|
+
minWidth: SELECTION_COL_WIDTH,
|
|
662
|
+
display: "flex",
|
|
663
|
+
alignItems: "center",
|
|
664
|
+
justifyContent: "center"
|
|
665
|
+
},
|
|
651
666
|
role: "columnheader",
|
|
652
667
|
children: /* @__PURE__ */ jsx(
|
|
653
668
|
Checkbox,
|
|
@@ -663,7 +678,14 @@ function DataGridInner(props, ref) {
|
|
|
663
678
|
"div",
|
|
664
679
|
{
|
|
665
680
|
className: `${cls.headerCell} ${cls.rowNumberCell}`,
|
|
666
|
-
style: {
|
|
681
|
+
style: {
|
|
682
|
+
width: ROW_NUMBER_COL_WIDTH,
|
|
683
|
+
minWidth: ROW_NUMBER_COL_WIDTH,
|
|
684
|
+
display: "flex",
|
|
685
|
+
alignItems: "center",
|
|
686
|
+
justifyContent: "center",
|
|
687
|
+
userSelect: "none"
|
|
688
|
+
},
|
|
667
689
|
role: "columnheader",
|
|
668
690
|
children: "#"
|
|
669
691
|
}
|
|
@@ -774,7 +796,13 @@ function DataGridInner(props, ref) {
|
|
|
774
796
|
"div",
|
|
775
797
|
{
|
|
776
798
|
className: `${cls.cell} ${cls.selectionCell}`,
|
|
777
|
-
style: {
|
|
799
|
+
style: {
|
|
800
|
+
width: SELECTION_COL_WIDTH,
|
|
801
|
+
minWidth: SELECTION_COL_WIDTH,
|
|
802
|
+
display: "flex",
|
|
803
|
+
alignItems: "center",
|
|
804
|
+
justifyContent: "center"
|
|
805
|
+
},
|
|
778
806
|
onClick: (e) => e.stopPropagation(),
|
|
779
807
|
children: /* @__PURE__ */ jsx(
|
|
780
808
|
Checkbox,
|
|
@@ -789,7 +817,14 @@ function DataGridInner(props, ref) {
|
|
|
789
817
|
"div",
|
|
790
818
|
{
|
|
791
819
|
className: `${cls.cell} ${cls.rowNumberCell}`,
|
|
792
|
-
style: {
|
|
820
|
+
style: {
|
|
821
|
+
width: ROW_NUMBER_COL_WIDTH,
|
|
822
|
+
minWidth: ROW_NUMBER_COL_WIDTH,
|
|
823
|
+
display: "flex",
|
|
824
|
+
alignItems: "center",
|
|
825
|
+
justifyContent: "center",
|
|
826
|
+
color: "var(--sg-color-text-tertiary, #999)"
|
|
827
|
+
},
|
|
793
828
|
children: vi.index + 1
|
|
794
829
|
}
|
|
795
830
|
),
|
|
@@ -807,8 +842,20 @@ function DataGridInner(props, ref) {
|
|
|
807
842
|
className: `${cls.summaryRow} ${sr.className ?? ""}`,
|
|
808
843
|
style: { display: "flex", height: rowHeight },
|
|
809
844
|
children: [
|
|
810
|
-
rowSelection && /* @__PURE__ */ jsx(
|
|
811
|
-
|
|
845
|
+
rowSelection && /* @__PURE__ */ jsx(
|
|
846
|
+
"div",
|
|
847
|
+
{
|
|
848
|
+
className: `${cls.summaryCell}`,
|
|
849
|
+
style: { width: SELECTION_COL_WIDTH, minWidth: SELECTION_COL_WIDTH }
|
|
850
|
+
}
|
|
851
|
+
),
|
|
852
|
+
showRowNumber && /* @__PURE__ */ jsx(
|
|
853
|
+
"div",
|
|
854
|
+
{
|
|
855
|
+
className: `${cls.summaryCell}`,
|
|
856
|
+
style: { width: ROW_NUMBER_COL_WIDTH, minWidth: ROW_NUMBER_COL_WIDTH }
|
|
857
|
+
}
|
|
858
|
+
),
|
|
812
859
|
orderedColumns.map((col) => /* @__PURE__ */ jsx(
|
|
813
860
|
"div",
|
|
814
861
|
{
|
|
@@ -834,7 +881,22 @@ function DataGridInner(props, ref) {
|
|
|
834
881
|
onClose: () => setCtxMenu(null)
|
|
835
882
|
}
|
|
836
883
|
),
|
|
837
|
-
loading && /* @__PURE__ */ jsx(
|
|
884
|
+
loading && /* @__PURE__ */ jsx(
|
|
885
|
+
"div",
|
|
886
|
+
{
|
|
887
|
+
className: cls.loading,
|
|
888
|
+
style: {
|
|
889
|
+
position: "absolute",
|
|
890
|
+
inset: 0,
|
|
891
|
+
display: "flex",
|
|
892
|
+
alignItems: "center",
|
|
893
|
+
justifyContent: "center",
|
|
894
|
+
background: "rgba(255,255,255,0.6)",
|
|
895
|
+
zIndex: 10
|
|
896
|
+
},
|
|
897
|
+
children: /* @__PURE__ */ jsx(Spin, { size: "large" })
|
|
898
|
+
}
|
|
899
|
+
)
|
|
838
900
|
]
|
|
839
901
|
}
|
|
840
902
|
);
|
|
@@ -844,4 +906,4 @@ var DataGrid = forwardRef(DataGridInner);
|
|
|
844
906
|
export {
|
|
845
907
|
DataGrid
|
|
846
908
|
};
|
|
847
|
-
//# sourceMappingURL=chunk-
|
|
909
|
+
//# sourceMappingURL=chunk-EFDB2ENB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/complex/DataGrid/DataGrid.tsx","../src/components/complex/DataGrid/useDataGridState.ts"],"sourcesContent":["import React, {\n forwardRef,\n useImperativeHandle,\n useCallback,\n useRef,\n useMemo,\n useState,\n} from 'react'\nimport { useVirtualScroll } from '../../../hooks/useVirtualScroll'\nimport { Spin } from '../../ui/Spin'\nimport { Checkbox } from '../../ui/Checkbox'\nimport { useDataGridState } from './useDataGridState'\nimport type {\n DataGridProps,\n DataGridRef,\n CellPosition,\n CellValue,\n DataGridColumn,\n CellEditorProps,\n DataGridContextMenuItem,\n} from './types'\n\nconst cls = {\n root: 'sg-datagrid',\n header: 'sg-datagrid-header',\n headerCell: 'sg-datagrid-header-cell',\n body: 'sg-datagrid-body',\n row: 'sg-datagrid-row',\n rowEven: 'sg-datagrid-row--even',\n rowOdd: 'sg-datagrid-row--odd',\n rowHoverable: 'sg-datagrid-row--hoverable',\n rowSelected: 'sg-datagrid-row--selected',\n cell: 'sg-datagrid-cell',\n cellActive: 'sg-datagrid-cell--active',\n cellEditing: 'sg-datagrid-cell--editing',\n cellSelected: 'sg-datagrid-cell--selected',\n frozen: 'sg-datagrid-cell--frozen',\n sortable: 'sg-datagrid-header-cell--sortable',\n sortAsc: 'sg-datagrid-header-cell--asc',\n sortDesc: 'sg-datagrid-header-cell--desc',\n resizer: 'sg-datagrid-resizer',\n empty: 'sg-datagrid-empty',\n summary: 'sg-datagrid-summary',\n summaryRow: 'sg-datagrid-summary-row',\n summaryCell: 'sg-datagrid-summary-cell',\n contextMenu: 'sg-datagrid-context-menu',\n contextMenuItem: 'sg-datagrid-context-menu-item',\n contextMenuDanger: 'sg-datagrid-context-menu-item--danger',\n contextMenuDisabled: 'sg-datagrid-context-menu-item--disabled',\n contextMenuDivider: 'sg-datagrid-context-menu-divider',\n loading: 'sg-datagrid-loading',\n selectionCell: 'sg-datagrid-selection-cell',\n rowNumberCell: 'sg-datagrid-row-number-cell',\n headerDragOver: 'sg-datagrid-header-cell--drag-over',\n}\n\nconst SELECTION_COL_WIDTH = 40\nconst ROW_NUMBER_COL_WIDTH = 48\n\nfunction DefaultEditor({ value, onChange, onCommit, onCancel }: CellEditorProps) {\n return (\n <input\n autoFocus\n defaultValue={value == null ? '' : String(value)}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onCommit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') onCommit()\n if (e.key === 'Escape') onCancel()\n }}\n style={{\n width: '100%',\n height: '100%',\n border: 'none',\n outline: 'none',\n padding: '0 8px',\n background: 'transparent',\n font: 'inherit',\n }}\n />\n )\n}\n\nfunction isCellInRange(\n row: number,\n col: number,\n range: { start: CellPosition; end: CellPosition } | null,\n): boolean {\n if (!range) return false\n const minRow = Math.min(range.start.row, range.end.row)\n const maxRow = Math.max(range.start.row, range.end.row)\n const minCol = Math.min(range.start.col, range.end.col)\n const maxCol = Math.max(range.start.col, range.end.col)\n return row >= minRow && row <= maxRow && col >= minCol && col <= maxCol\n}\n\nfunction ContextMenuPopup({\n items,\n position,\n onClose,\n}: {\n items: DataGridContextMenuItem[]\n position: { x: number; y: number }\n onClose: () => void\n}) {\n const ref = useRef<HTMLDivElement>(null)\n\n React.useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) onClose()\n }\n document.addEventListener('mousedown', handler)\n return () => document.removeEventListener('mousedown', handler)\n }, [onClose])\n\n // Only the coordinates are runtime-computed; visuals (z-index, padding,\n // colours, hover, danger/disabled state) live in\n // `packages/styles/components/context-menu.css` under\n // `.sg-datagrid-context-menu*`.\n return (\n <div\n ref={ref}\n className={cls.contextMenu}\n style={{ position: 'fixed', top: position.y, left: position.x }}\n >\n {items.map((item) =>\n item.divider ? (\n <div key={item.key} className={cls.contextMenuDivider} />\n ) : (\n <div\n key={item.key}\n className={[\n cls.contextMenuItem,\n item.danger ? cls.contextMenuDanger : '',\n item.disabled ? cls.contextMenuDisabled : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => {\n if (!item.disabled) {\n item.onClick()\n onClose()\n }\n }}\n >\n {item.label}\n </div>\n ),\n )}\n </div>\n )\n}\n\nfunction DataGridInner<R extends Record<string, unknown>>(\n props: DataGridProps<R>,\n ref: React.ForwardedRef<DataGridRef>,\n) {\n const {\n columns,\n data,\n rowKey,\n rowHeight = 36,\n headerHeight = 40,\n width = '100%',\n height = 400,\n className,\n style,\n onCellEdit,\n sortColumn,\n sortDirection,\n onSort,\n onCopy,\n onPaste,\n overscan = 5,\n locale,\n rowSelection,\n selectedRows,\n onSelectedRowsChange,\n striped,\n highlightOnHover = true,\n showRowNumber,\n summaryRows,\n cellClassName,\n cellStyle: cellStyleFn,\n columnReorder,\n onColumnOrderChange,\n onContextMenu,\n onRowClick,\n onRowDoubleClick,\n rowClassName,\n loading,\n emptyContent,\n } = props\n\n const containerRef = useRef<HTMLDivElement>(null)\n\n const state = useDataGridState(columns, data)\n const {\n activeCell,\n setActiveCell,\n editingCell,\n startEditing,\n stopEditing,\n editValueRef,\n selection,\n navigate,\n resizeColumn,\n getColumnWidth,\n columnOrder,\n reorderColumns,\n dragColumnRef,\n } = state\n\n const [ctxMenu, setCtxMenu] = useState<{\n items: DataGridContextMenuItem[]\n position: { x: number; y: number }\n } | null>(null)\n\n const [dragOverCol, setDragOverCol] = useState<string | null>(null)\n\n const {\n range,\n containerRef: scrollRef,\n scrollToIndex,\n } = useVirtualScroll({\n itemCount: data.length,\n itemHeight: rowHeight,\n overscan,\n })\n\n const getRowKey = useCallback(\n (row: R, index: number): React.Key => {\n if (typeof rowKey === 'function') return rowKey(row, index)\n return row[rowKey] as React.Key\n },\n [rowKey],\n )\n\n const frozenLeft = useMemo(() => columns.filter((c) => c.frozen === 'left'), [columns])\n const frozenRight = useMemo(() => columns.filter((c) => c.frozen === 'right'), [columns])\n const scrollable = useMemo(() => columns.filter((c) => !c.frozen), [columns])\n\n const orderedColumns = useMemo(() => {\n const base = [...frozenLeft, ...scrollable, ...frozenRight]\n if (!columnOrder) return base\n const map = new Map(base.map((c) => [c.key, c]))\n const ordered: DataGridColumn<R>[] = []\n for (const key of columnOrder) {\n const col = map.get(key)\n if (col) ordered.push(col)\n }\n for (const col of base) {\n if (!columnOrder.includes(col.key)) ordered.push(col)\n }\n return ordered\n }, [frozenLeft, scrollable, frozenRight, columnOrder])\n\n const extraColsWidth =\n (rowSelection ? SELECTION_COL_WIDTH : 0) + (showRowNumber ? ROW_NUMBER_COL_WIDTH : 0)\n\n const totalWidth = useMemo(\n () => orderedColumns.reduce((sum, col) => sum + getColumnWidth(col.key), 0) + extraColsWidth,\n [orderedColumns, getColumnWidth, extraColsWidth],\n )\n\n const allSelected = useMemo(() => {\n if (!selectedRows || data.length === 0) return false\n return data.every((row, i) => selectedRows.has(getRowKey(row, i)))\n }, [selectedRows, data, getRowKey])\n\n const someSelected = useMemo(() => {\n if (!selectedRows || data.length === 0) return false\n const count = data.filter((row, i) => selectedRows.has(getRowKey(row, i))).length\n return count > 0 && count < data.length\n }, [selectedRows, data, getRowKey])\n\n const handleSelectAll = useCallback(() => {\n if (!onSelectedRowsChange) return\n if (allSelected) {\n onSelectedRowsChange(new Set())\n } else {\n const all = new Set<React.Key>(data.map((row, i) => getRowKey(row, i)))\n onSelectedRowsChange(all)\n }\n }, [allSelected, data, getRowKey, onSelectedRowsChange])\n\n const handleSelectRow = useCallback(\n (row: R, index: number) => {\n if (!onSelectedRowsChange || !selectedRows) return\n const key = getRowKey(row, index)\n const next = new Set(selectedRows)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n onSelectedRowsChange(next)\n },\n [getRowKey, onSelectedRowsChange, selectedRows],\n )\n\n const handleCellClick = useCallback(\n (rowIndex: number, colIndex: number) => {\n if (editingCell) {\n if (onCellEdit && editValueRef.current !== undefined) {\n onCellEdit(editingCell.row, orderedColumns[editingCell.col].key, editValueRef.current)\n }\n stopEditing()\n }\n setActiveCell({ row: rowIndex, col: colIndex })\n },\n [editingCell, onCellEdit, editValueRef, orderedColumns, stopEditing, setActiveCell],\n )\n\n const handleCellDoubleClick = useCallback(\n (rowIndex: number, colIndex: number) => {\n startEditing({ row: rowIndex, col: colIndex })\n },\n [startEditing],\n )\n\n const handleCommitEdit = useCallback(() => {\n if (editingCell && onCellEdit && editValueRef.current !== undefined) {\n onCellEdit(editingCell.row, orderedColumns[editingCell.col].key, editValueRef.current)\n }\n stopEditing()\n }, [editingCell, onCellEdit, editValueRef, orderedColumns, stopEditing])\n\n const handleCancelEdit = useCallback(() => {\n stopEditing()\n }, [stopEditing])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (!activeCell) return\n\n if (editingCell) return\n\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault()\n navigate(activeCell, 'up', e.shiftKey)\n break\n case 'ArrowDown':\n e.preventDefault()\n navigate(activeCell, 'down', e.shiftKey)\n break\n case 'ArrowLeft':\n e.preventDefault()\n navigate(activeCell, 'left', e.shiftKey)\n break\n case 'ArrowRight':\n e.preventDefault()\n navigate(activeCell, 'right', e.shiftKey)\n break\n case 'Enter':\n e.preventDefault()\n startEditing(activeCell)\n break\n case 'Tab':\n e.preventDefault()\n navigate(activeCell, e.shiftKey ? 'left' : 'right')\n break\n case 'Escape':\n setActiveCell(null)\n break\n case ' ':\n if (rowSelection && selectedRows) {\n e.preventDefault()\n const row = data[activeCell.row]\n if (row) handleSelectRow(row, activeCell.row)\n }\n break\n case 'a':\n if ((e.ctrlKey || e.metaKey) && rowSelection) {\n e.preventDefault()\n handleSelectAll()\n }\n break\n case 'c':\n if ((e.ctrlKey || e.metaKey) && onCopy) {\n e.preventDefault()\n const col = orderedColumns[activeCell.col]\n const val = data[activeCell.row]?.[col.key]\n onCopy(val == null ? '' : String(val))\n }\n break\n case 'v':\n if ((e.ctrlKey || e.metaKey) && onPaste) {\n e.preventDefault()\n navigator.clipboard?.readText().then((text) => {\n onPaste(text, activeCell)\n })\n }\n break\n }\n },\n [\n activeCell,\n editingCell,\n navigate,\n startEditing,\n setActiveCell,\n onCopy,\n onPaste,\n orderedColumns,\n data,\n rowSelection,\n selectedRows,\n handleSelectRow,\n handleSelectAll,\n ],\n )\n\n const handleSort = useCallback(\n (col: DataGridColumn<R>) => {\n if (!col.sortable || !onSort) return\n const dir = sortColumn === col.key && sortDirection === 'asc' ? 'desc' : 'asc'\n onSort(col.key, dir)\n },\n [sortColumn, sortDirection, onSort],\n )\n\n const handleCellContextMenu = useCallback(\n (e: React.MouseEvent, rowIndex: number, col: DataGridColumn<R>) => {\n if (!onContextMenu) return\n e.preventDefault()\n const row = data[rowIndex]\n if (!row) return\n const items = onContextMenu(rowIndex, col.key, row)\n if (items.length === 0) return\n setCtxMenu({ items, position: { x: e.clientX, y: e.clientY } })\n },\n [onContextMenu, data],\n )\n\n const handleHeaderDragStart = useCallback(\n (e: React.DragEvent, colKey: string) => {\n if (!columnReorder) return\n dragColumnRef.current = colKey\n e.dataTransfer.effectAllowed = 'move'\n },\n [columnReorder, dragColumnRef],\n )\n\n const handleHeaderDragOver = useCallback(\n (e: React.DragEvent, colKey: string) => {\n if (!columnReorder || !dragColumnRef.current) return\n e.preventDefault()\n setDragOverCol(colKey)\n },\n [columnReorder, dragColumnRef],\n )\n\n const handleHeaderDrop = useCallback(\n (e: React.DragEvent, colKey: string) => {\n e.preventDefault()\n if (!columnReorder || !dragColumnRef.current) return\n const newOrder = reorderColumns(dragColumnRef.current, colKey)\n dragColumnRef.current = null\n setDragOverCol(null)\n onColumnOrderChange?.(newOrder)\n },\n [columnReorder, dragColumnRef, reorderColumns, onColumnOrderChange],\n )\n\n const handleHeaderDragEnd = useCallback(() => {\n dragColumnRef.current = null\n setDragOverCol(null)\n }, [dragColumnRef])\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToRow: scrollToIndex,\n scrollToColumn: () => {},\n getActiveCell: () => activeCell,\n setActiveCell,\n }),\n [scrollToIndex, activeCell, setActiveCell],\n )\n\n const handleResizeStart = useCallback(\n (colKey: string, startX: number) => {\n const startWidth = getColumnWidth(colKey)\n\n const onMouseMove = (e: MouseEvent) => {\n const delta = e.clientX - startX\n resizeColumn(colKey, startWidth + delta)\n }\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n }\n document.addEventListener('mousemove', onMouseMove)\n document.addEventListener('mouseup', onMouseUp)\n },\n [getColumnWidth, resizeColumn],\n )\n\n const renderCell = useCallback(\n (row: R, rowIndex: number, col: DataGridColumn<R>, colIndex: number) => {\n const isActive = activeCell?.row === rowIndex && activeCell?.col === colIndex\n const isEditing = editingCell?.row === rowIndex && editingCell?.col === colIndex\n const isSelected = isCellInRange(rowIndex, colIndex, selection)\n\n const rawValue = col.formula ? col.formula(row) : (row[col.key] as CellValue)\n\n const extraClass = cellClassName?.(rawValue, row, rowIndex, col) ?? ''\n const extraStyle = cellStyleFn?.(rawValue, row, rowIndex, col)\n\n const cellClassNames = [\n cls.cell,\n isActive ? cls.cellActive : '',\n isEditing ? cls.cellEditing : '',\n isSelected ? cls.cellSelected : '',\n col.frozen ? cls.frozen : '',\n col.className ?? '',\n extraClass,\n ]\n .filter(Boolean)\n .join(' ')\n\n const baseCellStyle: React.CSSProperties = {\n width: getColumnWidth(col.key),\n minWidth: getColumnWidth(col.key),\n textAlign: col.align ?? 'left',\n ...extraStyle,\n }\n\n return (\n <div\n key={col.key}\n className={cellClassNames}\n style={baseCellStyle}\n onClick={() => handleCellClick(rowIndex, colIndex)}\n onDoubleClick={() => handleCellDoubleClick(rowIndex, colIndex)}\n onContextMenu={(e) => handleCellContextMenu(e, rowIndex, col)}\n role=\"gridcell\"\n aria-colindex={colIndex + 1 + (rowSelection ? 1 : 0) + (showRowNumber ? 1 : 0)}\n aria-selected={isActive || isSelected}\n >\n {isEditing ? (\n (col.editor ?? (DefaultEditor as (props: CellEditorProps<R>) => React.ReactNode))({\n value: rawValue,\n row,\n rowIndex,\n column: col,\n onChange: (v) => {\n editValueRef.current = v\n },\n onCommit: handleCommitEdit,\n onCancel: handleCancelEdit,\n })\n ) : col.render ? (\n col.render(rawValue, row, rowIndex)\n ) : (\n <span>{rawValue == null ? '' : String(rawValue)}</span>\n )}\n </div>\n )\n },\n [\n activeCell,\n editingCell,\n selection,\n getColumnWidth,\n handleCellClick,\n handleCellDoubleClick,\n handleCommitEdit,\n handleCancelEdit,\n editValueRef,\n cellClassName,\n cellStyleFn,\n handleCellContextMenu,\n rowSelection,\n showRowNumber,\n ],\n )\n\n const heightValue = typeof height === 'number' ? height : undefined\n const bodyHeight = heightValue ? heightValue - headerHeight : undefined\n\n const rootCls = [\n cls.root,\n striped ? 'sg-datagrid--striped' : '',\n loading ? 'sg-datagrid--loading' : '',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n ref={containerRef}\n className={rootCls}\n style={{\n width,\n height,\n display: 'flex',\n flexDirection: 'column',\n position: 'relative',\n ...style,\n }}\n onKeyDown={handleKeyDown}\n tabIndex={0}\n role=\"grid\"\n aria-rowcount={data.length}\n aria-colcount={orderedColumns.length}\n >\n {/* Header */}\n <div\n className={cls.header}\n style={{\n display: 'flex',\n height: headerHeight,\n minHeight: headerHeight,\n minWidth: totalWidth,\n }}\n role=\"row\"\n >\n {rowSelection && (\n <div\n className={`${cls.headerCell} ${cls.selectionCell}`}\n style={{\n width: SELECTION_COL_WIDTH,\n minWidth: SELECTION_COL_WIDTH,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n role=\"columnheader\"\n >\n <Checkbox\n checked={allSelected}\n indeterminate={someSelected}\n onChange={handleSelectAll}\n />\n </div>\n )}\n {showRowNumber && (\n <div\n className={`${cls.headerCell} ${cls.rowNumberCell}`}\n style={{\n width: ROW_NUMBER_COL_WIDTH,\n minWidth: ROW_NUMBER_COL_WIDTH,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n userSelect: 'none',\n }}\n role=\"columnheader\"\n >\n #\n </div>\n )}\n {orderedColumns.map((col) => {\n const isSorted = sortColumn === col.key\n const headerCls = [\n cls.headerCell,\n col.sortable ? cls.sortable : '',\n isSorted && sortDirection === 'asc' ? cls.sortAsc : '',\n isSorted && sortDirection === 'desc' ? cls.sortDesc : '',\n col.headerClassName ?? '',\n dragOverCol === col.key ? cls.headerDragOver : '',\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n key={col.key}\n className={headerCls}\n style={{\n width: getColumnWidth(col.key),\n minWidth: getColumnWidth(col.key),\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n padding: '0 8px',\n cursor: col.sortable ? 'pointer' : 'default',\n userSelect: 'none',\n }}\n onClick={() => handleSort(col)}\n draggable={!!columnReorder}\n onDragStart={(e) => handleHeaderDragStart(e, col.key)}\n onDragOver={(e) => handleHeaderDragOver(e, col.key)}\n onDrop={(e) => handleHeaderDrop(e, col.key)}\n onDragEnd={handleHeaderDragEnd}\n onDragLeave={() => setDragOverCol(null)}\n role=\"columnheader\"\n >\n {col.title}\n {isSorted && (\n <span style={{ marginLeft: 4, fontSize: 10 }}>\n {sortDirection === 'asc' ? '▲' : '▼'}\n </span>\n )}\n {col.resizable !== false && (\n <div\n className={cls.resizer}\n style={{\n position: 'absolute',\n right: 0,\n top: 0,\n bottom: 0,\n width: 4,\n cursor: 'col-resize',\n }}\n onMouseDown={(e) => {\n e.stopPropagation()\n handleResizeStart(col.key, e.clientX)\n }}\n />\n )}\n </div>\n )\n })}\n </div>\n\n {/* Body */}\n <div\n ref={scrollRef as React.RefObject<HTMLDivElement>}\n className={cls.body}\n style={{\n flex: 1,\n overflow: 'auto',\n position: 'relative',\n height: bodyHeight,\n }}\n >\n {data.length === 0 ? (\n <div className={cls.empty} style={{ padding: 24, textAlign: 'center' }}>\n {emptyContent ?? locale?.noData ?? 'No data'}\n </div>\n ) : (\n <div style={{ height: range.totalHeight, position: 'relative', minWidth: totalWidth }}>\n {range.visibleItems.map((vi) => {\n const row = data[vi.index]\n if (!row) return null\n const rKey = getRowKey(row, vi.index)\n const isRowSelected = selectedRows?.has(rKey) ?? false\n const rowExtraClass =\n typeof rowClassName === 'function'\n ? rowClassName(row, vi.index)\n : (rowClassName ?? '')\n\n const rowCls = [\n cls.row,\n striped ? (vi.index % 2 === 0 ? cls.rowEven : cls.rowOdd) : '',\n highlightOnHover ? cls.rowHoverable : '',\n isRowSelected ? cls.rowSelected : '',\n rowExtraClass,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n key={rKey}\n className={rowCls}\n style={{\n display: 'flex',\n position: 'absolute',\n top: vi.offsetTop,\n height: vi.height,\n width: '100%',\n }}\n role=\"row\"\n aria-rowindex={vi.index + 1}\n aria-selected={isRowSelected}\n onClick={() => onRowClick?.(row, vi.index)}\n onDoubleClick={() => onRowDoubleClick?.(row, vi.index)}\n >\n {rowSelection && (\n <div\n className={`${cls.cell} ${cls.selectionCell}`}\n style={{\n width: SELECTION_COL_WIDTH,\n minWidth: SELECTION_COL_WIDTH,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={isRowSelected}\n onChange={() => handleSelectRow(row, vi.index)}\n />\n </div>\n )}\n {showRowNumber && (\n <div\n className={`${cls.cell} ${cls.rowNumberCell}`}\n style={{\n width: ROW_NUMBER_COL_WIDTH,\n minWidth: ROW_NUMBER_COL_WIDTH,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'var(--sg-color-text-tertiary, #999)',\n }}\n >\n {vi.index + 1}\n </div>\n )}\n {orderedColumns.map((col, ci) => renderCell(row, vi.index, col, ci))}\n </div>\n )\n })}\n </div>\n )}\n </div>\n\n {/* Summary Footer */}\n {summaryRows && summaryRows.length > 0 && data.length > 0 && (\n <div className={cls.summary} style={{ minWidth: totalWidth }}>\n {summaryRows.map((sr, sri) => (\n <div\n key={sri}\n className={`${cls.summaryRow} ${sr.className ?? ''}`}\n style={{ display: 'flex', height: rowHeight }}\n >\n {rowSelection && (\n <div\n className={`${cls.summaryCell}`}\n style={{ width: SELECTION_COL_WIDTH, minWidth: SELECTION_COL_WIDTH }}\n />\n )}\n {showRowNumber && (\n <div\n className={`${cls.summaryCell}`}\n style={{ width: ROW_NUMBER_COL_WIDTH, minWidth: ROW_NUMBER_COL_WIDTH }}\n />\n )}\n {orderedColumns.map((col) => (\n <div\n key={col.key}\n className={cls.summaryCell}\n style={{\n width: getColumnWidth(col.key),\n minWidth: getColumnWidth(col.key),\n textAlign: col.align ?? 'left',\n }}\n >\n {sr.render(col.key, data)}\n </div>\n ))}\n </div>\n ))}\n </div>\n )}\n\n {/* Context Menu */}\n {ctxMenu && (\n <ContextMenuPopup\n items={ctxMenu.items}\n position={ctxMenu.position}\n onClose={() => setCtxMenu(null)}\n />\n )}\n\n {/* Loading */}\n {loading && (\n <div\n className={cls.loading}\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'rgba(255,255,255,0.6)',\n zIndex: 10,\n }}\n >\n <Spin size=\"large\" />\n </div>\n )}\n </div>\n )\n}\n\n/**\n * Virtualized table grid with sortable headers, resizable columns, inline editing,\n * row selection, striped rows, summary footer, context menu, column reorder, and clipboard hooks.\n */\nexport const DataGrid = forwardRef(DataGridInner) as <R extends Record<string, unknown>>(\n props: DataGridProps<R> & { ref?: React.Ref<DataGridRef> },\n) => React.ReactElement\n","import { useState, useCallback, useRef } from 'react'\nimport type { CellPosition, CellRange, CellValue, DataGridColumn } from './types'\n\n/**\n * Holds active cell, edit session, range selection, column width, and column order state for `DataGrid`.\n */\nexport function useDataGridState<R>(columns: DataGridColumn<R>[], data: R[]) {\n const [activeCell, setActiveCell] = useState<CellPosition | null>(null)\n const [editingCell, setEditingCell] = useState<CellPosition | null>(null)\n const [selection, setSelection] = useState<CellRange | null>(null)\n const [columnWidths, setColumnWidths] = useState<Map<string, number>>(() => {\n const map = new Map<string, number>()\n for (const col of columns) {\n if (col.width) map.set(col.key, col.width)\n }\n return map\n })\n const [columnOrder, setColumnOrder] = useState<string[] | null>(null)\n\n const editValueRef = useRef<CellValue>(undefined)\n const dragColumnRef = useRef<string | null>(null)\n\n const startEditing = useCallback(\n (pos: CellPosition) => {\n const col = columns[pos.col]\n if (!col) return\n\n const isEditable =\n typeof col.editable === 'function'\n ? col.editable(data[pos.row], pos.row)\n : col.editable !== false\n\n if (!isEditable) return\n\n editValueRef.current = (data[pos.row] as Record<string, unknown>)[col.key] as CellValue\n setEditingCell(pos)\n },\n [columns, data],\n )\n\n const stopEditing = useCallback(() => {\n setEditingCell(null)\n editValueRef.current = undefined\n }, [])\n\n const navigate = useCallback(\n (\n from: CellPosition,\n direction: 'up' | 'down' | 'left' | 'right',\n shiftKey = false,\n ): CellPosition => {\n let { row, col } = from\n switch (direction) {\n case 'up':\n row = Math.max(0, row - 1)\n break\n case 'down':\n row = Math.min(data.length - 1, row + 1)\n break\n case 'left':\n col = Math.max(0, col - 1)\n break\n case 'right':\n col = Math.min(columns.length - 1, col + 1)\n break\n }\n const next = { row, col }\n\n if (shiftKey) {\n setSelection((prev) => ({\n start: prev?.start ?? from,\n end: next,\n }))\n } else {\n setSelection(null)\n }\n\n setActiveCell(next)\n return next\n },\n [data.length, columns.length],\n )\n\n const resizeColumn = useCallback(\n (key: string, width: number) => {\n const col = columns.find((c) => c.key === key)\n const minW = col?.minWidth ?? 50\n const maxW = col?.maxWidth ?? Infinity\n const clamped = Math.max(minW, Math.min(maxW, width))\n setColumnWidths((prev) => new Map(prev).set(key, clamped))\n },\n [columns],\n )\n\n const getColumnWidth = useCallback(\n (key: string): number => {\n return columnWidths.get(key) ?? columns.find((c) => c.key === key)?.width ?? 120\n },\n [columnWidths, columns],\n )\n\n const reorderColumns = useCallback(\n (fromKey: string, toKey: string) => {\n const order = columnOrder ?? columns.map((c) => c.key)\n const fromIdx = order.indexOf(fromKey)\n const toIdx = order.indexOf(toKey)\n if (fromIdx === -1 || toIdx === -1 || fromIdx === toIdx) return order\n const next = [...order]\n const [moved] = next.splice(fromIdx, 1)\n next.splice(toIdx, 0, moved)\n setColumnOrder(next)\n return next\n },\n [columnOrder, columns],\n )\n\n return {\n activeCell,\n setActiveCell,\n editingCell,\n startEditing,\n stopEditing,\n editValueRef,\n selection,\n setSelection,\n navigate,\n resizeColumn,\n getColumnWidth,\n columnOrder,\n setColumnOrder,\n reorderColumns,\n dragColumnRef,\n }\n}\n"],"mappings":"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","names":["useCallback","useRef","useState","useRef","useState","useCallback"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Checkbox
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PEX2UTNG.js";
|
|
4
4
|
import {
|
|
5
5
|
Spin,
|
|
6
6
|
useConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VLRLCHEL.js";
|
|
8
8
|
|
|
9
9
|
// src/hooks/useTree.ts
|
|
10
10
|
import { useState, useCallback, useMemo } from "react";
|
|
@@ -1664,4 +1664,4 @@ export {
|
|
|
1664
1664
|
Tree,
|
|
1665
1665
|
TreeSelect
|
|
1666
1666
|
};
|
|
1667
|
-
//# sourceMappingURL=chunk-
|
|
1667
|
+
//# sourceMappingURL=chunk-KGFFQGCM.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Spin,
|
|
3
3
|
useConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VLRLCHEL.js";
|
|
5
5
|
|
|
6
6
|
// src/components/ui/Checkbox.tsx
|
|
7
7
|
import React from "react";
|
|
@@ -55,4 +55,4 @@ function Checkbox({
|
|
|
55
55
|
export {
|
|
56
56
|
Checkbox
|
|
57
57
|
};
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-PEX2UTNG.js.map
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// src/components/ConfigProvider.tsx
|
|
2
|
+
import { createContext, useContext, useMemo } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var SgConfigContext = createContext({});
|
|
5
|
+
var TOKEN_TO_CSS_VAR = {
|
|
6
|
+
colorPrimary: "--sg-color-primary",
|
|
7
|
+
colorSuccess: "--sg-color-success",
|
|
8
|
+
colorWarning: "--sg-color-warning",
|
|
9
|
+
colorError: "--sg-color-error",
|
|
10
|
+
colorText: "--sg-color-text",
|
|
11
|
+
colorBg: "--sg-color-bg",
|
|
12
|
+
colorBorder: "--sg-color-border",
|
|
13
|
+
borderRadius: "--sg-border-radius",
|
|
14
|
+
fontSize: "--sg-font-size",
|
|
15
|
+
fontFamily: "--sg-font-sans"
|
|
16
|
+
};
|
|
17
|
+
var PX_TOKENS = /* @__PURE__ */ new Set(["borderRadius", "fontSize"]);
|
|
18
|
+
function buildThemeVars(theme) {
|
|
19
|
+
const vars = {};
|
|
20
|
+
if (!theme) return vars;
|
|
21
|
+
if (theme.token) {
|
|
22
|
+
for (const key of Object.keys(theme.token)) {
|
|
23
|
+
const value = theme.token[key];
|
|
24
|
+
if (value == null) continue;
|
|
25
|
+
const cssVar = TOKEN_TO_CSS_VAR[key];
|
|
26
|
+
if (!cssVar) continue;
|
|
27
|
+
vars[cssVar] = typeof value === "number" && PX_TOKENS.has(key) ? `${value}px` : String(value);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (theme.cssVars) {
|
|
31
|
+
for (const [name, value] of Object.entries(theme.cssVars)) {
|
|
32
|
+
if (value == null) continue;
|
|
33
|
+
vars[name.startsWith("--") ? name : `--${name}`] = String(value);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return vars;
|
|
37
|
+
}
|
|
38
|
+
function mergeTheme(parent, child) {
|
|
39
|
+
if (!parent) return child;
|
|
40
|
+
if (!child) return parent;
|
|
41
|
+
return {
|
|
42
|
+
mode: child.mode ?? parent.mode,
|
|
43
|
+
token: { ...parent.token, ...child.token },
|
|
44
|
+
cssVars: { ...parent.cssVars, ...child.cssVars }
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function ConfigProvider({ children, ...config }) {
|
|
48
|
+
const parent = useContext(SgConfigContext);
|
|
49
|
+
const merged = useMemo(
|
|
50
|
+
() => ({
|
|
51
|
+
size: config.size ?? parent.size,
|
|
52
|
+
disabled: config.disabled ?? parent.disabled,
|
|
53
|
+
bordered: config.bordered ?? parent.bordered,
|
|
54
|
+
direction: config.direction ?? parent.direction,
|
|
55
|
+
locale: config.locale ? parent.locale ? { ...parent.locale, ...config.locale } : config.locale : parent.locale,
|
|
56
|
+
theme: mergeTheme(parent.theme, config.theme),
|
|
57
|
+
getPopupContainer: config.getPopupContainer ?? parent.getPopupContainer,
|
|
58
|
+
getTargetContainer: config.getTargetContainer ?? parent.getTargetContainer,
|
|
59
|
+
renderEmpty: config.renderEmpty ?? parent.renderEmpty,
|
|
60
|
+
csp: config.csp ?? parent.csp
|
|
61
|
+
}),
|
|
62
|
+
[
|
|
63
|
+
config.size,
|
|
64
|
+
config.disabled,
|
|
65
|
+
config.bordered,
|
|
66
|
+
config.direction,
|
|
67
|
+
config.locale,
|
|
68
|
+
config.theme,
|
|
69
|
+
config.getPopupContainer,
|
|
70
|
+
config.getTargetContainer,
|
|
71
|
+
config.renderEmpty,
|
|
72
|
+
config.csp,
|
|
73
|
+
parent
|
|
74
|
+
]
|
|
75
|
+
);
|
|
76
|
+
const ownVars = useMemo(() => buildThemeVars(config.theme), [config.theme]);
|
|
77
|
+
const mode = config.theme?.mode;
|
|
78
|
+
const direction = config.direction;
|
|
79
|
+
const needsScope = Boolean(direction || mode || Object.keys(ownVars).length > 0);
|
|
80
|
+
const content = needsScope ? /* @__PURE__ */ jsx(
|
|
81
|
+
"div",
|
|
82
|
+
{
|
|
83
|
+
className: "sg-config-provider",
|
|
84
|
+
style: { display: "contents", ...ownVars },
|
|
85
|
+
dir: direction,
|
|
86
|
+
"data-sg-theme": mode,
|
|
87
|
+
children
|
|
88
|
+
}
|
|
89
|
+
) : children;
|
|
90
|
+
return /* @__PURE__ */ jsx(SgConfigContext.Provider, { value: merged, children: content });
|
|
91
|
+
}
|
|
92
|
+
function useConfig() {
|
|
93
|
+
return useContext(SgConfigContext);
|
|
94
|
+
}
|
|
95
|
+
function useConfigWithDefaults(props, defaults) {
|
|
96
|
+
const config = useContext(SgConfigContext);
|
|
97
|
+
return useMemo(() => {
|
|
98
|
+
const resolvedSize = props.size ?? config.size ?? defaults.size ?? "middle";
|
|
99
|
+
const resolvedDisabled = props.disabled ?? config.disabled ?? defaults.disabled ?? false;
|
|
100
|
+
const resolvedDirection = props.direction ?? config.direction ?? defaults.direction ?? "ltr";
|
|
101
|
+
return { ...props, resolvedSize, resolvedDisabled, resolvedDirection };
|
|
102
|
+
}, [
|
|
103
|
+
props,
|
|
104
|
+
config.size,
|
|
105
|
+
config.disabled,
|
|
106
|
+
config.direction,
|
|
107
|
+
defaults.size,
|
|
108
|
+
defaults.disabled,
|
|
109
|
+
defaults.direction
|
|
110
|
+
]);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/components/ui/Spin.tsx
|
|
114
|
+
import React2 from "react";
|
|
115
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
116
|
+
function Spin({
|
|
117
|
+
spinning = true,
|
|
118
|
+
size: sizeProp,
|
|
119
|
+
delay,
|
|
120
|
+
tip,
|
|
121
|
+
fullscreen,
|
|
122
|
+
indicator,
|
|
123
|
+
children,
|
|
124
|
+
className,
|
|
125
|
+
style,
|
|
126
|
+
unstyled
|
|
127
|
+
}) {
|
|
128
|
+
const config = useConfig();
|
|
129
|
+
const resolvedSize = sizeProp ?? config.size ?? "middle";
|
|
130
|
+
const [visible, setVisible] = React2.useState(delay ? false : spinning);
|
|
131
|
+
React2.useEffect(() => {
|
|
132
|
+
if (!delay) {
|
|
133
|
+
setVisible(spinning);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (spinning) {
|
|
137
|
+
const timer = setTimeout(() => setVisible(true), delay);
|
|
138
|
+
return () => clearTimeout(timer);
|
|
139
|
+
}
|
|
140
|
+
setVisible(false);
|
|
141
|
+
}, [spinning, delay]);
|
|
142
|
+
if (!visible && !children) return null;
|
|
143
|
+
if (!visible && children) return /* @__PURE__ */ jsx2(Fragment, { children });
|
|
144
|
+
const spinSizeClass = resolvedSize === "middle" ? "default" : resolvedSize;
|
|
145
|
+
const spinClasses = unstyled ? className ?? "" : ["sg-spin", `sg-spin-${spinSizeClass}`, className].filter(Boolean).join(" ");
|
|
146
|
+
const spinElement = indicator ?? /* @__PURE__ */ jsx2(
|
|
147
|
+
"span",
|
|
148
|
+
{
|
|
149
|
+
className: spinClasses,
|
|
150
|
+
style,
|
|
151
|
+
role: "status",
|
|
152
|
+
"aria-live": "polite",
|
|
153
|
+
"aria-label": config.locale?.spin?.loading ?? "Loading"
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
if (fullscreen) {
|
|
157
|
+
return /* @__PURE__ */ jsx2("div", { className: unstyled ? "" : "sg-spin-fullscreen", children: /* @__PURE__ */ jsxs("div", { className: unstyled ? "" : "sg-spin-fullscreen-inner", children: [
|
|
158
|
+
spinElement,
|
|
159
|
+
tip && /* @__PURE__ */ jsx2("div", { className: unstyled ? "" : "sg-spin-tip", children: tip })
|
|
160
|
+
] }) });
|
|
161
|
+
}
|
|
162
|
+
if (!children) {
|
|
163
|
+
return /* @__PURE__ */ jsxs("span", { className: unstyled ? "" : "sg-spin-standalone", style, children: [
|
|
164
|
+
spinElement,
|
|
165
|
+
tip && /* @__PURE__ */ jsx2("div", { className: unstyled ? "" : "sg-spin-tip", children: tip })
|
|
166
|
+
] });
|
|
167
|
+
}
|
|
168
|
+
return /* @__PURE__ */ jsxs("div", { className: unstyled ? "" : "sg-spin-container", style, children: [
|
|
169
|
+
/* @__PURE__ */ jsxs("div", { className: unstyled ? "" : "sg-spin-overlay", children: [
|
|
170
|
+
spinElement,
|
|
171
|
+
tip && /* @__PURE__ */ jsx2("div", { className: unstyled ? "" : "sg-spin-tip", children: tip })
|
|
172
|
+
] }),
|
|
173
|
+
/* @__PURE__ */ jsx2("div", { className: visible ? unstyled ? "" : "sg-spin-blur" : "", children })
|
|
174
|
+
] });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
buildThemeVars,
|
|
179
|
+
ConfigProvider,
|
|
180
|
+
useConfig,
|
|
181
|
+
useConfigWithDefaults,
|
|
182
|
+
Spin
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=chunk-VLRLCHEL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ConfigProvider.tsx","../src/components/ui/Spin.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from 'react'\nimport type { SizeType, SgLocale } from '../types'\n\n/** Text/layout direction shared by descendant components. */\nexport type Direction = 'ltr' | 'rtl'\n\n/**\n * Friendly design-token overrides. Each entry is mapped to a `--sg-*` CSS\n * custom property and emitted onto a `display: contents` scope wrapper, so\n * overrides cascade to every descendant without affecting layout.\n *\n * Numeric values for length-like tokens (`borderRadius`, `fontSize`) are\n * suffixed with `px`; everything else is emitted verbatim.\n */\nexport interface SgThemeToken {\n /** Brand / primary color → `--sg-color-primary`. */\n colorPrimary?: string\n /** Success color → `--sg-color-success`. */\n colorSuccess?: string\n /** Warning color → `--sg-color-warning`. */\n colorWarning?: string\n /** Error / danger color → `--sg-color-error`. */\n colorError?: string\n /** Base text color → `--sg-color-text`. */\n colorText?: string\n /** Base background color → `--sg-color-bg`. */\n colorBg?: string\n /** Base border color → `--sg-color-border`. */\n colorBorder?: string\n /** Base corner radius → `--sg-border-radius` (number ⇒ px). */\n borderRadius?: number | string\n /** Base font size → `--sg-font-size` (number ⇒ px). */\n fontSize?: number | string\n /** Base font family → `--sg-font-sans`. */\n fontFamily?: string\n}\n\n/**\n * Theme configuration. Combines a built-in light/dark preset (`mode`),\n * friendly token overrides (`token`), and an escape hatch for raw CSS\n * variables (`cssVars`). All three are applied to a scope wrapper.\n */\nexport interface ThemeConfig {\n /** Built-in palette preset applied via `data-sg-theme`. */\n mode?: 'light' | 'dark'\n /** Friendly token overrides mapped to `--sg-*` variables. */\n token?: SgThemeToken\n /** Raw CSS variable overrides (full names, e.g. `{ '--sg-color-link': '#f50' }`). */\n cssVars?: Record<string, string>\n}\n\n/** Content-Security-Policy options for runtime-injected styles. */\nexport interface CSPConfig {\n /** `nonce` attribute applied to dynamically created `<style>` tags. */\n nonce?: string\n}\n\n/** Customizes the empty state rendered by data components (`Empty`, `Table`, …). */\nexport type RenderEmptyHandler = (componentName?: string) => React.ReactNode\n\n/**\n * Global Skygraph component configuration merged through React context.\n *\n * По `prefixCls`: сознательно НЕ входит в публичный API до реализации\n * (вариант A в `docs/styling-plan.md`, фаза 4). На практике все корневые классы\n * имеют стабильный префикс `.sg-*`; если нужна изоляция — используйте изолированный\n * скоуп на хосте (шадоу-рут/отдельный контейнер со своими токенами).\n */\nexport interface SgConfig {\n /** Default size token for nested components. */\n size?: SizeType\n /** Disables interactions for nested components when true. */\n disabled?: boolean\n /** Enables bordered styling for nested components when true. */\n bordered?: boolean\n /** Text / layout direction (`ltr` by default) applied via the `dir` attribute. */\n direction?: Direction\n /** Locale messages shallow-merged with the parent provider when set. */\n locale?: SgLocale\n /** Theme preset + token overrides applied to a scope wrapper. */\n theme?: ThemeConfig\n /**\n * Returns the mount node for popups (dropdowns, tooltips, pickers). Defaults\n * to `document.body` in consumers. Useful to keep overlays inside a scrolling\n * or scoped container.\n */\n getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement\n /** Returns the scroll/target container for affix-like positioning. */\n getTargetContainer?: () => HTMLElement\n /** Global override for the default empty state. */\n renderEmpty?: RenderEmptyHandler\n /** Content-Security-Policy options for injected styles. */\n csp?: CSPConfig\n}\n\nconst SgConfigContext = createContext<SgConfig>({})\n\n/** Props for `ConfigProvider`, extending `SgConfig` with React children. */\nexport interface ConfigProviderProps extends SgConfig {\n /** Tree of components that consume merged configuration from this provider. */\n children: React.ReactNode\n}\n\n/** Maps friendly token names to their `--sg-*` CSS variable. */\nconst TOKEN_TO_CSS_VAR: Record<keyof SgThemeToken, string> = {\n colorPrimary: '--sg-color-primary',\n colorSuccess: '--sg-color-success',\n colorWarning: '--sg-color-warning',\n colorError: '--sg-color-error',\n colorText: '--sg-color-text',\n colorBg: '--sg-color-bg',\n colorBorder: '--sg-color-border',\n borderRadius: '--sg-border-radius',\n fontSize: '--sg-font-size',\n fontFamily: '--sg-font-sans',\n}\n\n/** Token keys whose numeric values should be emitted as `px` lengths. */\nconst PX_TOKENS = new Set<keyof SgThemeToken>(['borderRadius', 'fontSize'])\n\n/** Builds a CSS-variable map from a theme's `token` + `cssVars`. */\nexport function buildThemeVars(theme?: ThemeConfig): Record<string, string> {\n const vars: Record<string, string> = {}\n if (!theme) return vars\n if (theme.token) {\n for (const key of Object.keys(theme.token) as Array<keyof SgThemeToken>) {\n const value = theme.token[key]\n if (value == null) continue\n const cssVar = TOKEN_TO_CSS_VAR[key]\n if (!cssVar) continue\n vars[cssVar] = typeof value === 'number' && PX_TOKENS.has(key) ? `${value}px` : String(value)\n }\n }\n if (theme.cssVars) {\n for (const [name, value] of Object.entries(theme.cssVars)) {\n if (value == null) continue\n vars[name.startsWith('--') ? name : `--${name}`] = String(value)\n }\n }\n return vars\n}\n\n/** Shallow-merges a parent and child theme (`token` / `cssVars` merged key-wise). */\nfunction mergeTheme(parent?: ThemeConfig, child?: ThemeConfig): ThemeConfig | undefined {\n if (!parent) return child\n if (!child) return parent\n return {\n mode: child.mode ?? parent.mode,\n token: { ...parent.token, ...child.token },\n cssVars: { ...parent.cssVars, ...child.cssVars },\n }\n}\n\n/**\n * Merges Skygraph configuration with any parent provider and exposes it via context.\n * Descendants read values through `useConfig` or `useConfigWithDefaults`.\n *\n * When `theme` or `direction` is set, children are wrapped in a `display: contents`\n * element that carries the `dir`/`data-sg-theme` attributes and CSS variables, so\n * the scope inherits without introducing an extra layout box.\n */\nexport function ConfigProvider({ children, ...config }: ConfigProviderProps) {\n const parent = useContext(SgConfigContext)\n\n const merged = useMemo<SgConfig>(\n () => ({\n size: config.size ?? parent.size,\n disabled: config.disabled ?? parent.disabled,\n bordered: config.bordered ?? parent.bordered,\n direction: config.direction ?? parent.direction,\n locale: config.locale\n ? parent.locale\n ? { ...parent.locale, ...config.locale }\n : config.locale\n : parent.locale,\n theme: mergeTheme(parent.theme, config.theme),\n getPopupContainer: config.getPopupContainer ?? parent.getPopupContainer,\n getTargetContainer: config.getTargetContainer ?? parent.getTargetContainer,\n renderEmpty: config.renderEmpty ?? parent.renderEmpty,\n csp: config.csp ?? parent.csp,\n }),\n [\n config.size,\n config.disabled,\n config.bordered,\n config.direction,\n config.locale,\n config.theme,\n config.getPopupContainer,\n config.getTargetContainer,\n config.renderEmpty,\n config.csp,\n parent,\n ],\n )\n\n // Only the *own* props are emitted to the DOM scope; CSS variables and the\n // `dir` attribute cascade to descendants, so nested providers stay correct.\n const ownVars = useMemo(() => buildThemeVars(config.theme), [config.theme])\n const mode = config.theme?.mode\n const direction = config.direction\n const needsScope = Boolean(direction || mode || Object.keys(ownVars).length > 0)\n\n const content = needsScope ? (\n <div\n className=\"sg-config-provider\"\n style={{ display: 'contents', ...ownVars } as React.CSSProperties}\n dir={direction}\n data-sg-theme={mode}\n >\n {children}\n </div>\n ) : (\n children\n )\n\n return <SgConfigContext.Provider value={merged}>{content}</SgConfigContext.Provider>\n}\n\n/** Returns the merged `SgConfig` from the nearest ancestor `ConfigProvider`. */\nexport function useConfig(): SgConfig {\n return useContext(SgConfigContext)\n}\n\n/**\n * Resolves effective `size`, `disabled`, and `direction` from props, context,\n * and explicit defaults. Returns the original props plus the resolved values.\n */\nexport function useConfigWithDefaults<T extends Record<string, unknown>>(\n props: T,\n defaults: { size?: SizeType; disabled?: boolean; bordered?: boolean; direction?: Direction },\n): T & { resolvedSize: SizeType; resolvedDisabled: boolean; resolvedDirection: Direction } {\n const config = useContext(SgConfigContext)\n\n return useMemo(() => {\n const resolvedSize =\n ((props as Record<string, unknown>).size as SizeType | undefined) ??\n config.size ??\n defaults.size ??\n 'middle'\n const resolvedDisabled =\n ((props as Record<string, unknown>).disabled as boolean | undefined) ??\n config.disabled ??\n defaults.disabled ??\n false\n const resolvedDirection =\n ((props as Record<string, unknown>).direction as Direction | undefined) ??\n config.direction ??\n defaults.direction ??\n 'ltr'\n\n return { ...props, resolvedSize, resolvedDisabled, resolvedDirection }\n }, [\n props,\n config.size,\n config.disabled,\n config.direction,\n defaults.size,\n defaults.disabled,\n defaults.direction,\n ])\n}\n","import React from 'react'\nimport { useConfig } from '../ConfigProvider'\nimport type { BaseComponentProps, SizableProps } from '../../types'\n\n/** Props for loading spinner, overlay, and optional content blur. */\nexport interface SpinProps extends BaseComponentProps, SizableProps {\n /** When `true`, shows the loading state (subject to `delay`). @default true */\n spinning?: boolean\n /** Milliseconds to wait before showing the spinner after `spinning` becomes true. */\n delay?: number\n /** Optional text below the indicator. */\n tip?: string\n /** When `true`, covers the viewport instead of inline or wrapping children. */\n fullscreen?: boolean\n /** Custom spinner node; defaults to a styled status element. */\n indicator?: React.ReactNode\n /** When set, shows an overlay with blur on this content while loading. */\n children?: React.ReactNode\n}\n\n/**\n * Loading indicator with optional delay, tip, fullscreen mode, and child overlay.\n */\nexport function Spin({\n spinning = true,\n size: sizeProp,\n delay,\n tip,\n fullscreen,\n indicator,\n children,\n className,\n style,\n unstyled,\n}: SpinProps) {\n const config = useConfig()\n const resolvedSize = sizeProp ?? config.size ?? 'middle'\n\n const [visible, setVisible] = React.useState(delay ? false : spinning)\n\n React.useEffect(() => {\n if (!delay) {\n setVisible(spinning)\n return\n }\n\n if (spinning) {\n const timer = setTimeout(() => setVisible(true), delay)\n return () => clearTimeout(timer)\n }\n\n setVisible(false)\n }, [spinning, delay])\n\n if (!visible && !children) return null\n if (!visible && children) return <>{children}</>\n\n const spinSizeClass = resolvedSize === 'middle' ? 'default' : resolvedSize\n const spinClasses = unstyled\n ? (className ?? '')\n : ['sg-spin', `sg-spin-${spinSizeClass}`, className].filter(Boolean).join(' ')\n\n const spinElement = indicator ?? (\n <span\n className={spinClasses}\n style={style}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={config.locale?.spin?.loading ?? 'Loading'}\n />\n )\n\n if (fullscreen) {\n return (\n <div className={unstyled ? '' : 'sg-spin-fullscreen'}>\n <div className={unstyled ? '' : 'sg-spin-fullscreen-inner'}>\n {spinElement}\n {tip && <div className={unstyled ? '' : 'sg-spin-tip'}>{tip}</div>}\n </div>\n </div>\n )\n }\n\n if (!children) {\n return (\n <span className={unstyled ? '' : 'sg-spin-standalone'} style={style}>\n {spinElement}\n {tip && <div className={unstyled ? '' : 'sg-spin-tip'}>{tip}</div>}\n </span>\n )\n }\n\n return (\n <div className={unstyled ? '' : 'sg-spin-container'} style={style}>\n <div className={unstyled ? '' : 'sg-spin-overlay'}>\n {spinElement}\n {tip && <div className={unstyled ? '' : 'sg-spin-tip'}>{tip}</div>}\n </div>\n <div className={visible ? (unstyled ? '' : 'sg-spin-blur') : ''}>{children}</div>\n </div>\n )\n}\n"],"mappings":"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","names":["React","jsx","React"]}
|