mirror of
https://github.com/ruilisi/fortune-sheet.git
synced 2025-01-09 04:07:33 +08:00
fix: selection style overflow when acrossing freeze line
Rework of https://github.com/ruilisi/fortune-sheet/pull/320
This commit is contained in:
parent
a417df231f
commit
3c05925a23
@ -1,5 +1,5 @@
|
||||
import _, { isPlainObject } from "lodash";
|
||||
import type { Sheet as SheetType, Selection, Freezen, Range } from "../types";
|
||||
import type { Sheet as SheetType, Freezen, Range } from "../types";
|
||||
import { Context, getFlowdata } from "../context";
|
||||
import {
|
||||
getCellValue,
|
||||
@ -2197,34 +2197,21 @@ export function selectAll(ctx: Context) {
|
||||
normalizeSelection(ctx, ctx.luckysheet_select_save);
|
||||
}
|
||||
|
||||
export function getSelectionStyle(
|
||||
export function fixRowStyleOverflowInFreeze(
|
||||
ctx: Context,
|
||||
selection: Selection,
|
||||
r1: number,
|
||||
r2: number,
|
||||
freeze: Freezen | undefined
|
||||
): {
|
||||
left: number | undefined;
|
||||
top: number | undefined;
|
||||
width: number | undefined;
|
||||
height: number | undefined;
|
||||
display: string;
|
||||
backgroundColor?: string;
|
||||
top?: number;
|
||||
height?: number;
|
||||
display?: string;
|
||||
} {
|
||||
const ret = {
|
||||
left: selection.left_move,
|
||||
top: selection.top_move,
|
||||
width: selection.width_move,
|
||||
height: selection.height_move,
|
||||
display: "block",
|
||||
};
|
||||
if (!freeze) return ret;
|
||||
if (!freeze) return {};
|
||||
|
||||
const ret: ReturnType<typeof fixRowStyleOverflowInFreeze> = {};
|
||||
const { scrollTop } = ctx;
|
||||
const { scrollLeft } = ctx;
|
||||
|
||||
const freezenverticaldata = freeze?.vertical?.freezenverticaldata;
|
||||
const freezenhorizontaldata = freeze?.horizontal?.freezenhorizontaldata;
|
||||
|
||||
const obj = selection;
|
||||
const freezenhorizontaldata = freeze.horizontal?.freezenhorizontaldata;
|
||||
|
||||
let rangeshow = true;
|
||||
|
||||
@ -2233,9 +2220,6 @@ export function getSelectionStyle(
|
||||
const freezen_rowindex = freezenhorizontaldata[1];
|
||||
const offTop = scrollTop - freezenhorizontaldata[2];
|
||||
|
||||
const r1 = obj.row[0];
|
||||
const r2 = obj.row[1];
|
||||
|
||||
const row = ctx.visibledatarow[r2];
|
||||
const row_pre = r1 - 1 === -1 ? 0 : ctx.visibledatarow[r1 - 1];
|
||||
|
||||
@ -2266,14 +2250,35 @@ export function getSelectionStyle(
|
||||
}
|
||||
}
|
||||
|
||||
if (!rangeshow) {
|
||||
ret.display = "none";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function fixColumnStyleOverflowInFreeze(
|
||||
ctx: Context,
|
||||
c1: number,
|
||||
c2: number,
|
||||
freeze: Freezen | undefined
|
||||
): {
|
||||
left?: number;
|
||||
width?: number;
|
||||
display?: string;
|
||||
} {
|
||||
if (!freeze) return {};
|
||||
|
||||
const ret: ReturnType<typeof fixColumnStyleOverflowInFreeze> = {};
|
||||
const { scrollLeft } = ctx;
|
||||
const freezenverticaldata = freeze.vertical?.freezenverticaldata;
|
||||
|
||||
let rangeshow = true;
|
||||
|
||||
if (freezenverticaldata != null) {
|
||||
const freezenLeft = freezenverticaldata[0];
|
||||
const freezen_colindex = freezenverticaldata[1];
|
||||
const offLeft = scrollLeft - freezenverticaldata[2];
|
||||
|
||||
const c1 = obj.column[0];
|
||||
const c2 = obj.column[1];
|
||||
|
||||
const col = ctx.visibledatacolumn[c2];
|
||||
const col_pre = c1 - 1 === -1 ? 0 : ctx.visibledatacolumn[c1 - 1];
|
||||
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
handleContextMenu,
|
||||
isAllowEdit,
|
||||
getFlowdata,
|
||||
fixColumnStyleOverflowInFreeze,
|
||||
} from "@fortune-sheet/core";
|
||||
import _ from "lodash";
|
||||
import React, {
|
||||
@ -27,9 +28,10 @@ const ColumnHeader: React.FC = () => {
|
||||
const [hoverLocation, setHoverLocation] = useState({
|
||||
col: -1,
|
||||
col_pre: -1,
|
||||
col_index: -1,
|
||||
});
|
||||
const [selectedLocation, setSelectedLocation] = useState<
|
||||
{ col: number; col_pre: number }[]
|
||||
{ col: number; col_pre: number; c1: number; c2: number }[]
|
||||
>([]);
|
||||
const allowEditRef = useRef<boolean>(true);
|
||||
|
||||
@ -43,9 +45,9 @@ const ColumnHeader: React.FC = () => {
|
||||
containerRef.current!.getBoundingClientRect().left +
|
||||
containerRef.current!.scrollLeft;
|
||||
const col_location = colLocation(x, context.visibledatacolumn);
|
||||
const [col_pre, col] = col_location;
|
||||
if (col_pre !== hoverLocation.col_pre || col !== hoverLocation.col) {
|
||||
setHoverLocation({ col_pre, col });
|
||||
const [col_pre, col, col_index] = col_location;
|
||||
if (col_index !== hoverLocation.col_index) {
|
||||
setHoverLocation({ col_pre, col, col_index });
|
||||
}
|
||||
const flowdata = getFlowdata(context);
|
||||
if (!_.isNil(flowdata))
|
||||
@ -58,7 +60,7 @@ const ColumnHeader: React.FC = () => {
|
||||
},
|
||||
]);
|
||||
},
|
||||
[context, hoverLocation.col, hoverLocation.col_pre]
|
||||
[context, hoverLocation.col_index]
|
||||
);
|
||||
|
||||
const onMouseDown = useCallback(
|
||||
@ -82,7 +84,7 @@ const ColumnHeader: React.FC = () => {
|
||||
if (context.luckysheet_cols_change_size) {
|
||||
return;
|
||||
}
|
||||
setHoverLocation({ col: -1, col_pre: -1 });
|
||||
setHoverLocation({ col: -1, col_pre: -1, col_index: -1 });
|
||||
}, [context.luckysheet_cols_change_size]);
|
||||
|
||||
const onColSizeHandleMouseDown = useCallback(
|
||||
@ -131,14 +133,15 @@ const ColumnHeader: React.FC = () => {
|
||||
columnTitleMap = selectTitlesMap(columnTitleMap, c1, c2);
|
||||
}
|
||||
const columnTitleRange = selectTitlesRange(columnTitleMap);
|
||||
const selects: { col: number; col_pre: number }[] = [];
|
||||
const selects: { col: number; col_pre: number; c1: number; c2: number }[] =
|
||||
[];
|
||||
for (let j = 0; j < columnTitleRange.length; j += 1) {
|
||||
const c1 = columnTitleRange[j][0];
|
||||
const c2 = columnTitleRange[j][columnTitleRange[j].length - 1];
|
||||
const col = colLocationByIndex(c2, context.visibledatacolumn)[1];
|
||||
const col_pre = colLocationByIndex(c1, context.visibledatacolumn)[0];
|
||||
if (_.isNumber(col) && _.isNumber(col_pre)) {
|
||||
selects.push({ col, col_pre });
|
||||
selects.push({ col, col_pre, c1, c2 });
|
||||
}
|
||||
}
|
||||
setSelectedLocation(selects);
|
||||
@ -170,16 +173,22 @@ const ColumnHeader: React.FC = () => {
|
||||
opacity: context.luckysheet_cols_change_size ? 1 : 0,
|
||||
}}
|
||||
/>
|
||||
{!context.luckysheet_cols_change_size &&
|
||||
hoverLocation.col >= 0 &&
|
||||
hoverLocation.col_pre >= 0 ? (
|
||||
{!context.luckysheet_cols_change_size && hoverLocation.col_index >= 0 ? (
|
||||
<div
|
||||
className="fortune-col-header-hover"
|
||||
style={{
|
||||
left: hoverLocation.col_pre,
|
||||
width: hoverLocation.col - hoverLocation.col_pre - 1,
|
||||
display: "block",
|
||||
}}
|
||||
style={_.assign(
|
||||
{
|
||||
left: hoverLocation.col_pre,
|
||||
width: hoverLocation.col - hoverLocation.col_pre - 1,
|
||||
display: "block",
|
||||
},
|
||||
fixColumnStyleOverflowInFreeze(
|
||||
context,
|
||||
hoverLocation.col_index,
|
||||
hoverLocation.col_index,
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
)
|
||||
)}
|
||||
>
|
||||
{allowEditRef.current && (
|
||||
<span
|
||||
@ -199,16 +208,24 @@ const ColumnHeader: React.FC = () => {
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
{selectedLocation.map(({ col, col_pre }, i) => (
|
||||
{selectedLocation.map(({ col, col_pre, c1, c2 }, i) => (
|
||||
<div
|
||||
className="fortune-col-header-selected"
|
||||
key={i}
|
||||
style={{
|
||||
left: col_pre,
|
||||
width: col - col_pre - 1,
|
||||
display: "block",
|
||||
backgroundColor: "rgba(76, 76, 76, 0.1)",
|
||||
}}
|
||||
style={_.assign(
|
||||
{
|
||||
left: col_pre,
|
||||
width: col - col_pre - 1,
|
||||
display: "block",
|
||||
backgroundColor: "rgba(76, 76, 76, 0.1)",
|
||||
},
|
||||
fixColumnStyleOverflowInFreeze(
|
||||
context,
|
||||
c1,
|
||||
c2,
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
)
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
{/* placeholder to overflow the container, making the container scrollable */}
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
handleContextMenu,
|
||||
handleRowHeaderMouseDown,
|
||||
handleRowSizeHandleMouseDown,
|
||||
fixRowStyleOverflowInFreeze,
|
||||
} from "@fortune-sheet/core";
|
||||
import _ from "lodash";
|
||||
import React, {
|
||||
@ -24,9 +25,10 @@ const RowHeader: React.FC = () => {
|
||||
const [hoverLocation, setHoverLocation] = useState({
|
||||
row: -1,
|
||||
row_pre: -1,
|
||||
row_index: -1,
|
||||
});
|
||||
const [selectedLocation, setSelectedLocation] = useState<
|
||||
{ row: number; row_pre: number }[]
|
||||
{ row: number; row_pre: number; r1: number; r2: number }[]
|
||||
>([]);
|
||||
|
||||
const onMouseMove = useCallback(
|
||||
@ -39,9 +41,9 @@ const RowHeader: React.FC = () => {
|
||||
containerRef.current!.getBoundingClientRect().top +
|
||||
containerRef.current!.scrollTop;
|
||||
const row_location = rowLocation(y, context.visibledatarow);
|
||||
const [row_pre, row] = row_location;
|
||||
const [row_pre, row, row_index] = row_location;
|
||||
if (row_pre !== hoverLocation.row_pre || row !== hoverLocation.row) {
|
||||
setHoverLocation({ row_pre, row });
|
||||
setHoverLocation({ row_pre, row, row_index });
|
||||
}
|
||||
},
|
||||
[
|
||||
@ -73,7 +75,7 @@ const RowHeader: React.FC = () => {
|
||||
if (context.luckysheet_rows_change_size) {
|
||||
return;
|
||||
}
|
||||
setHoverLocation({ row: -1, row_pre: -1 });
|
||||
setHoverLocation({ row: -1, row_pre: -1, row_index: -1 });
|
||||
}, [context.luckysheet_rows_change_size]);
|
||||
|
||||
const onRowSizeHandleMouseDown = useCallback(
|
||||
@ -120,14 +122,15 @@ const RowHeader: React.FC = () => {
|
||||
rowTitleMap = selectTitlesMap(rowTitleMap, r1, r2);
|
||||
}
|
||||
const rowTitleRange = selectTitlesRange(rowTitleMap);
|
||||
const selects: { row: number; row_pre: number }[] = [];
|
||||
const selects: { row: number; row_pre: number; r1: number; r2: number }[] =
|
||||
[];
|
||||
for (let i = 0; i < rowTitleRange.length; i += 1) {
|
||||
const r1 = rowTitleRange[i][0];
|
||||
const r2 = rowTitleRange[i][rowTitleRange[i].length - 1];
|
||||
const row = rowLocationByIndex(r2, context.visibledatarow)[1];
|
||||
const row_pre = rowLocationByIndex(r1, context.visibledatarow)[0];
|
||||
if (_.isNumber(row_pre) && _.isNumber(row)) {
|
||||
selects.push({ row, row_pre });
|
||||
selects.push({ row, row_pre, r1, r2 });
|
||||
}
|
||||
}
|
||||
setSelectedLocation(selects);
|
||||
@ -159,26 +162,42 @@ const RowHeader: React.FC = () => {
|
||||
opacity: context.luckysheet_rows_change_size ? 1 : 0,
|
||||
}}
|
||||
/>
|
||||
{hoverLocation.row >= 0 && hoverLocation.row_pre >= 0 ? (
|
||||
{!context.luckysheet_rows_change_size && hoverLocation.row_index >= 0 ? (
|
||||
<div
|
||||
className="fortune-row-header-hover"
|
||||
style={{
|
||||
top: hoverLocation.row_pre,
|
||||
height: hoverLocation.row - hoverLocation.row_pre - 1,
|
||||
display: "block",
|
||||
}}
|
||||
style={_.assign(
|
||||
{
|
||||
top: hoverLocation.row_pre,
|
||||
height: hoverLocation.row - hoverLocation.row_pre - 1,
|
||||
display: "block",
|
||||
},
|
||||
fixRowStyleOverflowInFreeze(
|
||||
context,
|
||||
hoverLocation.row_index,
|
||||
hoverLocation.row_index,
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
)
|
||||
)}
|
||||
/>
|
||||
) : null}
|
||||
{selectedLocation.map(({ row, row_pre }, i) => (
|
||||
{selectedLocation.map(({ row, row_pre, r1, r2 }, i) => (
|
||||
<div
|
||||
className="fortune-row-header-selected"
|
||||
key={i}
|
||||
style={{
|
||||
top: row_pre,
|
||||
height: row - row_pre - 1,
|
||||
display: "block",
|
||||
backgroundColor: "rgba(76, 76, 76, 0.1)",
|
||||
}}
|
||||
style={_.assign(
|
||||
{
|
||||
top: row_pre,
|
||||
height: row - row_pre - 1,
|
||||
display: "block",
|
||||
backgroundColor: "rgba(76, 76, 76, 0.1)",
|
||||
},
|
||||
fixRowStyleOverflowInFreeze(
|
||||
context,
|
||||
r1,
|
||||
r2,
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
)
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
{/* placeholder to overflow the container, making the container scrollable */}
|
||||
|
@ -16,7 +16,6 @@ import {
|
||||
handleOverlayMouseMove,
|
||||
handleOverlayMouseUp,
|
||||
selectAll,
|
||||
getSelectionStyle,
|
||||
handleOverlayTouchEnd,
|
||||
handleOverlayTouchMove,
|
||||
handleOverlayTouchStart,
|
||||
@ -29,6 +28,8 @@ import {
|
||||
onCellsMoveStart,
|
||||
insertRowCol,
|
||||
getSheetIndex,
|
||||
fixRowStyleOverflowInFreeze,
|
||||
fixColumnStyleOverflowInFreeze,
|
||||
} from "@fortune-sheet/core";
|
||||
import _ from "lodash";
|
||||
import WorkbookContext, { SetContextOptions } from "../../context";
|
||||
@ -482,13 +483,30 @@ const SheetOverlay: React.FC = () => {
|
||||
className="luckysheet-cell-selected-focus"
|
||||
style={
|
||||
(context.luckysheet_select_save?.length ?? 0) > 0
|
||||
? {
|
||||
display: "block",
|
||||
left: _.last(context.luckysheet_select_save)?.left,
|
||||
width: _.last(context.luckysheet_select_save)?.width,
|
||||
top: _.last(context.luckysheet_select_save)?.top,
|
||||
height: _.last(context.luckysheet_select_save)?.height,
|
||||
}
|
||||
? (() => {
|
||||
const selection = _.last(context.luckysheet_select_save)!;
|
||||
return _.assign(
|
||||
{
|
||||
left: selection.left,
|
||||
top: selection.top,
|
||||
width: selection.width,
|
||||
height: selection.height,
|
||||
display: "block",
|
||||
},
|
||||
fixRowStyleOverflowInFreeze(
|
||||
context,
|
||||
selection.row_focus || 0,
|
||||
selection.row_focus || 0,
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
),
|
||||
fixColumnStyleOverflowInFreeze(
|
||||
context,
|
||||
selection.column_focus || 0,
|
||||
selection.column_focus || 0,
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
)
|
||||
);
|
||||
})()
|
||||
: {}
|
||||
}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
@ -543,10 +561,26 @@ const SheetOverlay: React.FC = () => {
|
||||
key={index}
|
||||
id="luckysheet-cell-selected"
|
||||
className="luckysheet-cell-selected"
|
||||
style={getSelectionStyle(
|
||||
context,
|
||||
selection,
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
style={_.assign(
|
||||
{
|
||||
left: selection.left_move,
|
||||
top: selection.top_move,
|
||||
width: selection.width_move,
|
||||
height: selection.height_move,
|
||||
display: "block",
|
||||
},
|
||||
fixRowStyleOverflowInFreeze(
|
||||
context,
|
||||
selection.row[0],
|
||||
selection.row[1],
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
),
|
||||
fixColumnStyleOverflowInFreeze(
|
||||
context,
|
||||
selection.column[0],
|
||||
selection.column[1],
|
||||
refs.globalCache.freezen?.[context.currentSheetId]
|
||||
)
|
||||
)}
|
||||
onMouseDown={(e) => {
|
||||
e.stopPropagation();
|
||||
|
Loading…
Reference in New Issue
Block a user