Side panel
Customizing Resize Panel
Build your own Sizes panel with presets and unit-aware inputs
How to set your own default page sizes?
You can make your own panel from scratch and define new Sizes section. For example:
import React, { useState, useEffect } from 'react';
import { observer } from 'mobx-react-lite';
import {
Button,
NumericInput,
Select,
SelectTrigger,
SelectContent,
SelectItem,
SelectValue,
} from 'polotno/primitives';
import { pxToUnitRounded, unitToPx } from 'polotno/utils/unit';
const MIN_PX = 10;
const PRESETS = [
{ label: 'IG Post', w: 1080, h: 1080, unit: 'px' },
{ label: 'IG Story', w: 1080, h: 1920, unit: 'px' },
{ label: 'Full HD', w: 1920, h: 1080, unit: 'px' },
{ label: 'A4', w: 21, h: 29.7, unit: 'cm' },
{ label: 'Letter', w: 8.5, h: 11, unit: 'in' },
];
export const ResizePanel = observer(({ store }) => {
const [w, setW] = useState(0);
const [h, setH] = useState(0);
useEffect(() => {
setW(
pxToUnitRounded({ px: store.width, unit: store.unit, dpi: store.dpi })
);
setH(
pxToUnitRounded({ px: store.height, unit: store.unit, dpi: store.dpi })
);
}, [store.width, store.height, store.unit, store.dpi]);
const applyResize = (unitW = w, unitH = h) => {
const widthPx = unitToPx({
unitVal: unitW,
unit: store.unit,
dpi: store.dpi,
});
const heightPx = unitToPx({
unitVal: unitH,
unit: store.unit,
dpi: store.dpi,
});
if (widthPx >= MIN_PX && heightPx >= MIN_PX)
store.setSize(widthPx, heightPx, true);
};
const Row = ({ children }) => (
<div
style={{
display: 'flex',
alignItems: 'center',
gap: 8,
marginBottom: 10,
}}
>
{children}
</div>
);
return (
<div style={{ padding: 16, overflowY: 'auto', maxHeight: '100%' }}>
<Row>
<div style={{ width: 60 }}>Width</div>
<NumericInput value={w} onValueChange={setW} min={1} />
</Row>
<Row>
<div style={{ width: 60 }}>Height</div>
<NumericInput value={h} onValueChange={setH} min={1} />
</Row>
<Row>
<div style={{ width: 60 }}>Units</div>
<Select
value={store.unit}
onValueChange={(unit) => store.setUnit({ unit, dpi: store.dpi })}
>
<SelectTrigger style={{ width: '100%' }}>
<SelectValue />
</SelectTrigger>
<SelectContent>
{['px', 'cm', 'in'].map((u) => (
<SelectItem key={u} value={u}>
{u}
</SelectItem>
))}
</SelectContent>
</Select>
</Row>
<Button
onClick={() => applyResize()}
style={{ width: '100%', marginBottom: 16 }}
>
Resize
</Button>
{/* preset buttons, one per row */}
{PRESETS.map(({ label, w: pw, h: ph, unit }) => (
<Button
key={label}
style={{ width: '100%', height: 60, marginBottom: 8 }}
onClick={() => {
store.setUnit({ unit, dpi: store.dpi });
applyResize(pw, ph);
}}
>
{label}
<span style={{ fontSize: '0.75em', marginLeft: 6, opacity: 0.7 }}>
{pw}×{ph} {unit}
</span>
</Button>
))}
</div>
);
});