Skip to content

Commit

Permalink
Merge branch 'v5/revise-stories' into v5/build-next-proj
Browse files Browse the repository at this point in the history
  • Loading branch information
webloopbox committed Oct 15, 2024
2 parents 60359d0 + 78b446c commit fb82a9d
Show file tree
Hide file tree
Showing 39 changed files with 1,906 additions and 1,886 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"lib": "npm run dev --prefix reactgrid",
"lib-build": "npm run build --prefix reactgrid",
"lib-test": "npm run test --prefix reactgrid",
"website": "npm run dev --prefix website"
"website": "npm run dev --prefix website",
"website-build": "npm run build --prefix website"
},
"name": "reactgrid-monorepo",
"version": "5.0.0",
Expand All @@ -18,4 +19,4 @@
"devDependencies": {
"@types/lodash.clonedeep": "^4.5.9"
}
}
}
22 changes: 13 additions & 9 deletions reactgrid/lib/behaviors/ColumnReorderBehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { scrollTowardsSticky } from "../utils/scrollTowardsSticky.ts";
import { getHiddenFocusTargetLocation } from "../utils/getHiddenFocusTargetLocation.ts";
import { isCellInPane } from "../utils/isCellInPane.ts";
import { checkColumnHasSpannedCell } from "../utils/checkColumnHasSpannedCell.ts";
import { getTheme } from "../utils/getTheme.ts";
import { getNumberFromPixelString } from "../utils/getNumberFromPixelValueString.ts";

const devEnvironment = isDevEnvironment();

Expand Down Expand Up @@ -51,7 +53,7 @@ export const ColumnReorderBehavior: Behavior = {
const hiddenFocusTarget = document.activeElement;
if (!hiddenFocusTarget) return store;

const { rowIndex, colIndex } = getHiddenFocusTargetLocation(hiddenFocusTarget);
const { rowIndex, colIndex } = getHiddenFocusTargetLocation(store.id, hiddenFocusTarget);
if (rowIndex === -1 || colIndex === -1) return store;

return {
Expand Down Expand Up @@ -122,6 +124,8 @@ const handlePointerMove = (

let shadowPosition = event.clientX - gridWrapperRectLeft - mouseToCellLeftBorderDistanceX;

const gapWidth = getNumberFromPixelString(getTheme(store).gap.width || 0);

// Use client rect instead of event.clientY to determine shadow position,
// This allows for accurate positioning even when the cursor is not hovering directly over the cell container.
const element = getCellContainerFromPoint(event.clientX, cellContainer.getBoundingClientRect().top);
Expand Down Expand Up @@ -260,7 +264,7 @@ const handlePointerMove = (

if (isCellInPane(store, leftCell, "TopLeft")) {
if (store.selectedArea.endColIdx <= store.paneRanges.Left.endColIdx) {
linePosition = leftCellContainer.offsetLeft;
linePosition = leftCellContainer.offsetLeft - gapWidth;
} else if (destinationEndColIdx <= store.paneRanges.Left.endColIdx) {
let colSpannedCellRight;

Expand All @@ -280,7 +284,7 @@ const handlePointerMove = (
(!colSpannedCellLeft && !colSpannedCellRight) ||
(colSpannedCellLeft && destinationEndColIdx === store.paneRanges.Left.endColIdx)
) {
linePosition = leftCellContainer.offsetLeft;
linePosition = leftCellContainer.offsetLeft - gapWidth;
}
} else {
let colSpannedCellRight;
Expand All @@ -298,20 +302,20 @@ const handlePointerMove = (
);

if (!colSpannedCellLeft && !colSpannedCellRight) {
linePosition = leftCellContainer.offsetLeft;
linePosition = leftCellContainer.offsetLeft - gapWidth;
}
}
} else if (store.selectedArea.endColIdx > store.paneRanges.TopRight.startColIdx) {
if (destinationColIdx >= store.paneRanges.TopRight.startColIdx) {
linePosition = leftCellContainer.offsetLeft;
linePosition = leftCellContainer.offsetLeft - gapWidth;
} else if (destinationEndColIdx > store.paneRanges.TopRight.startColIdx) {
const colSpannedCell = checkColumnHasSpannedCell(
store,
store.selectedArea.endColIdx - (destinationEndColIdx - store.paneRanges.TopRight.startColIdx)
);

if (!colSpannedCell) {
linePosition = leftCellContainer.offsetLeft;
linePosition = leftCellContainer.offsetLeft - gapWidth;
}
} else {
const colSpannedCell = checkColumnHasSpannedCell(
Expand All @@ -324,11 +328,11 @@ const handlePointerMove = (
("originColIndex" in colSpannedCell &&
colSpannedCell.originColIndex - selectedAreaColQuantity === store.paneRanges.TopRight.startColIdx)
) {
linePosition = leftCellContainer.offsetLeft;
linePosition = leftCellContainer.offsetLeft - gapWidth;
}
}
} else {
linePosition = leftCellContainer.offsetLeft;
linePosition = leftCellContainer.offsetLeft - gapWidth;
}
}
}
Expand Down Expand Up @@ -362,7 +366,7 @@ const handlePointerUp = (
// Prevent triggering the resize behavior when a column is selected twice without moving the pointer
if (!initialMouseXPos) return { ...store, currentBehavior: store.getBehavior("Default") };

if (!store.linePosition) {
if (!store.linePosition === undefined) {
initialMouseXPos = 0;

if (!initialMouseXPos)
Expand Down
8 changes: 4 additions & 4 deletions reactgrid/lib/behaviors/DefaultBehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const DefaultBehavior = (): Behavior => ({

if (shouldChangeFocusLocation) {
if (focusingCell?.isFocusable !== false) {
getHiddenTargetFocusByIdx(rowIndex, colIndex)?.focus({ preventScroll: true });
getHiddenTargetFocusByIdx(store.id, rowIndex, colIndex)?.focus({ preventScroll: true });
}

return {
Expand All @@ -126,7 +126,7 @@ export const DefaultBehavior = (): Behavior => ({
const hiddenFocusTarget = document.activeElement;
if (!hiddenFocusTarget) return store;

const { rowIndex, colIndex } = getHiddenFocusTargetLocation(hiddenFocusTarget);
const { rowIndex, colIndex } = getHiddenFocusTargetLocation(store.id, hiddenFocusTarget);
if (rowIndex === -1 || colIndex === -1) return store;

return {
Expand Down Expand Up @@ -222,7 +222,7 @@ export const DefaultBehavior = (): Behavior => ({
if (shouldChangeFocusLocation) {
if (shouldSelectEntireColumn || shouldSelectEntireRow) {
if (touchedCell?.isFocusable !== false) {
getHiddenTargetFocusByIdx(rowIndex, colIndex)?.focus({ preventScroll: true });
getHiddenTargetFocusByIdx(store.id, rowIndex, colIndex)?.focus({ preventScroll: true });
}

return {
Expand Down Expand Up @@ -292,7 +292,7 @@ export const DefaultBehavior = (): Behavior => ({

if (prevCell.rowIndex === currCell.rowIndex && prevCell.colIndex === currCell.colIndex) {
if (!shouldSelectEntireColumn && focusedCell?.isFocusable !== false) {
getHiddenTargetFocusByIdx(rowIndex, colIndex)?.focus({ preventScroll: true });
getHiddenTargetFocusByIdx(store.id, rowIndex, colIndex)?.focus({ preventScroll: true });
}

if (!shouldSelectEntireColumn && !shouldSelectEntireRow) {
Expand Down
2 changes: 1 addition & 1 deletion reactgrid/lib/behaviors/RowReorderBehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const RowReorderBehavior: Behavior = {
const hiddenFocusTarget = document.activeElement;
if (!hiddenFocusTarget) return store;

const { rowIndex, colIndex } = getHiddenFocusTargetLocation(hiddenFocusTarget);
const { rowIndex, colIndex } = getHiddenFocusTargetLocation(store.id, hiddenFocusTarget);
if (rowIndex === -1 || colIndex === -1) return store;

return {
Expand Down
12 changes: 9 additions & 3 deletions reactgrid/lib/cellTemplates/NumberCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ export const NumberCell: FC<NumberCellProps> = ({

const isValid = validator ? validator(Number(initialValue)) : true;

const getFormattedValue = () => {
if (hideZero && initialValue === 0) return "";
// display the formatted value or error message
const getFormattedValue = (): string => {
if (Number.isNaN(Number(initialValue)) || (hideZero && initialValue === 0)) return "";
if (format) return format.format(initialValue);
if (!isValid && errorMessage) return errorMessage;

// show the value as a string without any formatting
return initialValueStr;
};

Expand All @@ -51,7 +54,10 @@ export const NumberCell: FC<NumberCellProps> = ({
<CellWrapper
onTouchEnd={handleDoubleTouch}
onStringValueRequested={() => initialValueStr}
onStringValueReceived={(v) => onValueChanged?.(Number(v))}
onStringValueReceived={(v) => {
const numValue = Number(v);
onValueChanged?.(isNaN(numValue) ? 0 : numValue);
}}
style={style}
onDoubleClick={() => {
if (ctx.isFocused) {
Expand Down
6 changes: 3 additions & 3 deletions reactgrid/lib/components/HiddenFocusTarget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useReactGridId } from "./ReactGridIdProvider";
import { getHiddenTargetFocusByIdx } from "../utils/getHiddenTargetFocusByIdx";

const HiddenFocusTarget = ({ rowIdx, colIdx }: { colIdx: number; rowIdx: number }) => {
const id = useReactGridId();
const changedFocusedLocation = useReactGridStore(id, (store) => store.changedFocusedLocation);
const storeId = useReactGridId();
const changedFocusedLocation = useReactGridStore(storeId, (store) => store.changedFocusedLocation);

useEffect(() => {
if (changedFocusedLocation) {
getHiddenTargetFocusByIdx(changedFocusedLocation.rowIndex, changedFocusedLocation.colIndex)?.focus();
getHiddenTargetFocusByIdx(storeId, changedFocusedLocation.rowIndex, changedFocusedLocation.colIndex)?.focus();
}
}, [changedFocusedLocation]);

Expand Down
4 changes: 2 additions & 2 deletions reactgrid/lib/components/PartialArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ export const PartialArea: FC<PartialAreaProps> = React.memo(
display: "flex",
justifyContent: "center",
alignItems: "center",
right: -15,
bottom: -15,
right: `calc(-${theme.gap.width} - 15px)`,
bottom: `calc(-${theme.gap.width} - 15px)`,
width: 30,
height: 30,
pointerEvents: "auto",
Expand Down
2 changes: 1 addition & 1 deletion reactgrid/lib/components/ReactGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const ReactGrid: FC<ReactGridProps> = ({
stickyLeftColumns={stickyLeftColumns ?? 0}
stickyRightColumns={stickyRightColumns ?? 0}
/>
{linePosition && <Line />}
{linePosition !== undefined && <Line />}
{isReorderBehavior(currentBehavior.id) && <Shadow />}
</GridWrapper>
</ErrorBoundary>
Expand Down
2 changes: 1 addition & 1 deletion reactgrid/lib/hooks/useInitialFocusLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const useInitialFocusLocation = (
console.error("The provided 'initialFocusLocation' is invalid as it targets !");
}

getHiddenTargetFocusByIdx(rowIndex, colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, rowIndex, colIndex)?.focus();
}
}, []);
};
1 change: 1 addition & 0 deletions reactgrid/lib/types/ReactGridStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { RGTheme } from "./RGTheme.ts";
import { CellsLookup } from "./PublicModel.ts";

export interface ReactGridStoreProps {
id: string;
rows: Row[];
columns: Column[];

Expand Down
28 changes: 14 additions & 14 deletions reactgrid/lib/utils/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getCellArea } from "./getCellArea.ts";

export const moveFocusUp = (store: ReactGridStore, currentFocus: FocusedCell): Partial<ReactGridStore> => {
if (currentFocus.rowIndex === 0) {
getHiddenTargetFocusByIdx(currentFocus.rowIndex, currentFocus.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, currentFocus.rowIndex, currentFocus.colIndex)?.focus();
return store;
}

Expand All @@ -39,7 +39,7 @@ export const moveFocusUp = (store: ReactGridStore, currentFocus: FocusedCell): P

handlePaneOverlap(store, rowIndex, colIndex, scrollableParent);

getHiddenTargetFocusByIdx(originCell.rowIndex, originCell.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, originCell.rowIndex, originCell.colIndex)?.focus();

return {
selectedArea: EMPTY_AREA,
Expand All @@ -52,7 +52,7 @@ export const moveFocusUp = (store: ReactGridStore, currentFocus: FocusedCell): P

export const moveFocusRight = (store: ReactGridStore, currentFocus: FocusedCell) => {
if (currentFocus.colIndex === store.columns.length - 1) {
getHiddenTargetFocusByIdx(currentFocus.rowIndex, currentFocus.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, currentFocus.rowIndex, currentFocus.colIndex)?.focus();
return store;
}

Expand Down Expand Up @@ -83,7 +83,7 @@ export const moveFocusRight = (store: ReactGridStore, currentFocus: FocusedCell)

handlePaneOverlap(store, rowIndex, colIndex, scrollableParent);

getHiddenTargetFocusByIdx(originCell.rowIndex, originCell.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, originCell.rowIndex, originCell.colIndex)?.focus();

return {
selectedArea: EMPTY_AREA,
Expand All @@ -96,14 +96,14 @@ export const moveFocusRight = (store: ReactGridStore, currentFocus: FocusedCell)

export const moveFocusDown = (store: ReactGridStore, currentFocus: FocusedCell) => {
if (currentFocus.rowIndex === store.rows.length - 1) {
getHiddenTargetFocusByIdx(currentFocus.rowIndex, currentFocus.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, currentFocus.rowIndex, currentFocus.colIndex)?.focus();
return store;
}

const cellArea = getCellArea(store, currentFocus);

if (cellArea.endRowIdx === store.rows.length) {
getHiddenTargetFocusByIdx(currentFocus.rowIndex, currentFocus.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, currentFocus.rowIndex, currentFocus.colIndex)?.focus();
return store;
}

Expand All @@ -130,7 +130,7 @@ export const moveFocusDown = (store: ReactGridStore, currentFocus: FocusedCell)

handlePaneOverlap(store, rowIndex, colIndex, scrollableParent);

getHiddenTargetFocusByIdx(originCell.rowIndex, originCell.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, originCell.rowIndex, originCell.colIndex)?.focus();

return {
selectedArea: EMPTY_AREA,
Expand All @@ -143,7 +143,7 @@ export const moveFocusDown = (store: ReactGridStore, currentFocus: FocusedCell)

export const moveFocusLeft = (store: ReactGridStore, currentFocus: FocusedCell) => {
if (currentFocus.colIndex === 0) {
getHiddenTargetFocusByIdx(currentFocus.rowIndex, currentFocus.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, currentFocus.rowIndex, currentFocus.colIndex)?.focus();
return store;
}

Expand All @@ -170,7 +170,7 @@ export const moveFocusLeft = (store: ReactGridStore, currentFocus: FocusedCell)

handlePaneOverlap(store, rowIndex, colIndex, scrollableParent);

getHiddenTargetFocusByIdx(originCell.rowIndex, originCell.colIndex)?.focus();
getHiddenTargetFocusByIdx(store.id, originCell.rowIndex, originCell.colIndex)?.focus();

return {
selectedArea: EMPTY_AREA,
Expand Down Expand Up @@ -214,7 +214,7 @@ export const moveFocusInsideSelectedRange = (
nextPossibleLocation?.isFocusable === false
);

getHiddenTargetFocusByIdx(rowIdx, colIdx)?.focus();
getHiddenTargetFocusByIdx(store.id, rowIdx, colIdx)?.focus();

return store;
}
Expand Down Expand Up @@ -246,7 +246,7 @@ export const moveFocusInsideSelectedRange = (
nextPossibleLocation?.isFocusable === false
);

getHiddenTargetFocusByIdx(rowIdx, colIdx)?.focus();
getHiddenTargetFocusByIdx(store.id, rowIdx, colIdx)?.focus();

return store;
}
Expand Down Expand Up @@ -278,7 +278,7 @@ export const moveFocusInsideSelectedRange = (
nextPossibleLocation?.isFocusable === false
);

getHiddenTargetFocusByIdx(rowIdx, colIdx)?.focus();
getHiddenTargetFocusByIdx(store.id, rowIdx, colIdx)?.focus();

return store;
}
Expand All @@ -290,7 +290,7 @@ export const moveFocusInsideSelectedRange = (
let nextPossibleLocation = store.getCellOrSpanMemberByIndexes(rowIdx, colIdx);

if (rowIdx === 0) {
getHiddenTargetFocusByIdx(rowIdx, colIdx)?.focus();
getHiddenTargetFocusByIdx(store.id, rowIdx, colIdx)?.focus();
return store;
}

Expand All @@ -317,7 +317,7 @@ export const moveFocusInsideSelectedRange = (

emitEvent("focuschange", { currentFocus });

getHiddenTargetFocusByIdx(rowIdx, colIdx)?.focus();
getHiddenTargetFocusByIdx(store.id, rowIdx, colIdx)?.focus();

return store;
}
Expand Down
8 changes: 7 additions & 1 deletion reactgrid/lib/utils/getHiddenFocusTargetLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { IndexedLocation } from "../types/InternalModel";
* @param targetElement The element from which to extract row and column indexes.
* @returns An object containing the row and column indexes, or null if they cannot be extracted.
*/
export const getHiddenFocusTargetLocation = (targetElement: Element): IndexedLocation => {
export const getHiddenFocusTargetLocation = (storeId: string, targetElement: Element): IndexedLocation => {
const container = document.getElementById(`ReactGrid-${storeId}`);

if (!container || !container.contains(targetElement)) {
return { rowIndex: -1, colIndex: -1 };
}

const classList = targetElement.className.split(" ");
let rowIndex: number | null = null;
let colIndex: number | null = null;
Expand Down
9 changes: 7 additions & 2 deletions reactgrid/lib/utils/getHiddenTargetFocusByIdx.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
export const getHiddenTargetFocusByIdx = (rowIdx: number, colIdx: number) => {
export const getHiddenTargetFocusByIdx = (storeId: string, rowIdx: number, colIdx: number) => {
const container = document.getElementById(`ReactGrid-${storeId}`);

if (!container) return null;

const className = `rgHiddenFocusTarget rgFocusRowIdx-${rowIdx} rgFocusColIdx-${colIdx}`;

const elements = document.getElementsByClassName(className);
const elements = container.getElementsByClassName(className);

if (elements.length > 0) {
return elements[0] as HTMLInputElement;
}
return null;
};
Loading

0 comments on commit fb82a9d

Please sign in to comment.