-
Notifications
You must be signed in to change notification settings - Fork 171
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
**Problem:** The strategy controls were wrapped in `controlForStrategyMemoized` which [defeats Vite's HMR.](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react#consistent-components-exports) **Fix:** Move all the component internals into a dedicated file which doesn't export other functions to prevent breaking the rules of hmr. **Commit Details:** - Moved all grid control components and their helper code into `grid-controls-components` - `grid-controls` now imports these components - No code was changed, only moved I verified that with this change, HMR started working! ## Bonus At @liady 's suggestion, I added `eslint-plugin-react-refresh` to the list of our ESLint rules. It is not rock solid, but definitely helps in remembering that there _are_ rules for HMR / Fast Refresh to work correctly.
- Loading branch information
1 parent
5eb72f0
commit d366ed5
Showing
24 changed files
with
820 additions
and
466 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
editor/src/components/canvas/canvas-strategies/strategies/grid-rearrange-move-strategy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
206 changes: 206 additions & 0 deletions
206
editor/src/components/canvas/controls/grid-controls-for-strategies.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/** @jsxRuntime classic */ | ||
/** @jsx jsx */ | ||
import type { Sides } from 'utopia-api/core' | ||
import type { ElementPath } from 'utopia-shared/src/types' | ||
import { isStaticGridRepeat, printGridAutoOrTemplateBase } from '../../inspector/common/css-utils' | ||
import { MetadataUtils } from '../../../core/model/element-metadata-utils' | ||
import { mapDropNulls } from '../../../core/shared/array-utils' | ||
import * as EP from '../../../core/shared/element-path' | ||
import type { ElementInstanceMetadata } from '../../../core/shared/element-template' | ||
import { type GridAutoOrTemplateBase } from '../../../core/shared/element-template' | ||
import type { CanvasRectangle } from '../../../core/shared/math-utils' | ||
import { isFiniteRectangle } from '../../../core/shared/math-utils' | ||
import { assertNever } from '../../../core/shared/utils' | ||
import { Substores, useEditorState } from '../../editor/store/store-hook' | ||
import type { | ||
ControlWithProps, | ||
WhenToShowControl, | ||
} from '../canvas-strategies/canvas-strategy-types' | ||
import { controlForStrategyMemoized } from '../canvas-strategies/canvas-strategy-types' | ||
import type { GridResizeEdge } from '../canvas-strategies/interaction-state' | ||
import type { EdgePosition } from '../canvas-types' | ||
import { | ||
CSSCursor, | ||
EdgePositionBottom, | ||
EdgePositionLeft, | ||
EdgePositionRight, | ||
EdgePositionTop, | ||
} from '../canvas-types' | ||
import { | ||
GridControlsComponent, | ||
GridResizeControlsComponent, | ||
GridRowColumnResizingControlsComponent, | ||
} from './grid-controls' | ||
|
||
export const GridCellTestId = (elementPath: ElementPath) => `grid-cell-${EP.toString(elementPath)}` | ||
|
||
function getCellsCount(template: GridAutoOrTemplateBase | null): number { | ||
if (template == null) { | ||
return 0 | ||
} | ||
|
||
switch (template.type) { | ||
case 'DIMENSIONS': | ||
return template.dimensions.reduce((acc, cur) => { | ||
return acc + (isStaticGridRepeat(cur) ? cur.times : 1) | ||
}, 0) | ||
case 'FALLBACK': | ||
return 0 | ||
default: | ||
assertNever(template) | ||
} | ||
} | ||
|
||
export function getNullableAutoOrTemplateBaseString( | ||
template: GridAutoOrTemplateBase | null, | ||
): string | undefined { | ||
if (template == null) { | ||
return undefined | ||
} else { | ||
return printGridAutoOrTemplateBase(template) | ||
} | ||
} | ||
|
||
export type GridData = { | ||
elementPath: ElementPath | ||
frame: CanvasRectangle | ||
gridTemplateColumns: GridAutoOrTemplateBase | null | ||
gridTemplateRows: GridAutoOrTemplateBase | null | ||
gridTemplateColumnsFromProps: GridAutoOrTemplateBase | null | ||
gridTemplateRowsFromProps: GridAutoOrTemplateBase | null | ||
gap: number | null | ||
justifyContent: string | null | ||
alignContent: string | null | ||
rowGap: number | null | ||
columnGap: number | null | ||
padding: Sides | ||
rows: number | ||
columns: number | ||
cells: number | ||
metadata: ElementInstanceMetadata | ||
} | ||
|
||
export function useGridData(elementPaths: ElementPath[]): GridData[] { | ||
const grids = useEditorState( | ||
Substores.metadata, | ||
(store) => { | ||
return mapDropNulls((view) => { | ||
const element = MetadataUtils.findElementByElementPath(store.editor.jsxMetadata, view) | ||
|
||
const targetGridContainer = MetadataUtils.isGridLayoutedContainer(element) ? element : null | ||
|
||
if ( | ||
targetGridContainer == null || | ||
targetGridContainer.globalFrame == null || | ||
!isFiniteRectangle(targetGridContainer.globalFrame) | ||
) { | ||
return null | ||
} | ||
|
||
const gap = targetGridContainer.specialSizeMeasurements.gap | ||
const rowGap = targetGridContainer.specialSizeMeasurements.rowGap | ||
const columnGap = targetGridContainer.specialSizeMeasurements.columnGap | ||
const padding = targetGridContainer.specialSizeMeasurements.padding | ||
|
||
const gridTemplateColumns = | ||
targetGridContainer.specialSizeMeasurements.containerGridProperties.gridTemplateColumns | ||
const gridTemplateRows = | ||
targetGridContainer.specialSizeMeasurements.containerGridProperties.gridTemplateRows | ||
const gridTemplateColumnsFromProps = | ||
targetGridContainer.specialSizeMeasurements.containerGridPropertiesFromProps | ||
.gridTemplateColumns | ||
const gridTemplateRowsFromProps = | ||
targetGridContainer.specialSizeMeasurements.containerGridPropertiesFromProps | ||
.gridTemplateRows | ||
|
||
const columns = getCellsCount( | ||
targetGridContainer.specialSizeMeasurements.containerGridProperties.gridTemplateColumns, | ||
) | ||
const rows = getCellsCount( | ||
targetGridContainer.specialSizeMeasurements.containerGridProperties.gridTemplateRows, | ||
) | ||
|
||
return { | ||
elementPath: targetGridContainer.elementPath, | ||
metadata: targetGridContainer, | ||
frame: targetGridContainer.globalFrame, | ||
gridTemplateColumns: gridTemplateColumns, | ||
gridTemplateRows: gridTemplateRows, | ||
gridTemplateColumnsFromProps: gridTemplateColumnsFromProps, | ||
gridTemplateRowsFromProps: gridTemplateRowsFromProps, | ||
gap: gap, | ||
rowGap: rowGap, | ||
columnGap: columnGap, | ||
justifyContent: targetGridContainer.specialSizeMeasurements.justifyContent, | ||
alignContent: targetGridContainer.specialSizeMeasurements.alignContent, | ||
padding: padding, | ||
rows: rows, | ||
columns: columns, | ||
cells: rows * columns, | ||
} | ||
}, elementPaths) | ||
}, | ||
'useGridData', | ||
) | ||
|
||
return grids | ||
} | ||
|
||
interface GridRowColumnResizingControlsProps { | ||
target: ElementPath | ||
} | ||
|
||
export const GridRowColumnResizingControls = | ||
controlForStrategyMemoized<GridRowColumnResizingControlsProps>( | ||
GridRowColumnResizingControlsComponent, | ||
) | ||
|
||
export const GridControlsKey = (gridPath: ElementPath) => `grid-controls-${EP.toString(gridPath)}` | ||
|
||
export interface GridControlProps { | ||
grid: GridData | ||
} | ||
|
||
export interface GridControlsProps { | ||
targets: ElementPath[] | ||
} | ||
|
||
export const GridControls = controlForStrategyMemoized<GridControlsProps>(GridControlsComponent) | ||
|
||
export const GridResizeEdgeTestId = (edge: GridResizeEdge) => `grid-resize-edge-${edge}` | ||
|
||
interface GridResizeControlProps { | ||
target: ElementPath | ||
} | ||
|
||
export const GridResizeControls = controlForStrategyMemoized<GridResizeControlProps>( | ||
GridResizeControlsComponent, | ||
) | ||
|
||
export function gridEdgeToEdgePosition(edge: GridResizeEdge): EdgePosition { | ||
switch (edge) { | ||
case 'column-end': | ||
return EdgePositionRight | ||
case 'column-start': | ||
return EdgePositionLeft | ||
case 'row-end': | ||
return EdgePositionBottom | ||
case 'row-start': | ||
return EdgePositionTop | ||
default: | ||
assertNever(edge) | ||
} | ||
} | ||
|
||
export function controlsForGridPlaceholders( | ||
gridPath: ElementPath, | ||
whenToShow: WhenToShowControl = 'always-visible', | ||
): ControlWithProps<any> { | ||
return { | ||
control: GridControls, | ||
props: { targets: [gridPath] }, | ||
key: GridControlsKey(gridPath), | ||
show: whenToShow, | ||
priority: 'bottom', | ||
} | ||
} |
Oops, something went wrong.