mirror of https://github.com/penpot/penpot.git
244 lines
6.3 KiB
TypeScript
244 lines
6.3 KiB
TypeScript
import { GridLayout } from '@penpot/plugin-types';
|
|
import { PluginMessageEvent, TablePluginEvent } from './app/model';
|
|
|
|
penpot.ui.open('TABLE PLUGIN', `?theme=${penpot.theme}`, {
|
|
width: 280,
|
|
height: 610,
|
|
});
|
|
|
|
penpot.ui.onMessage<PluginMessageEvent>((message) => {
|
|
pluginData(message);
|
|
|
|
if (message.type === 'table') {
|
|
let numRows = 0;
|
|
let numCols = 0;
|
|
if (message.content.type === 'import' && message.content.import) {
|
|
numRows = message.content.import.length;
|
|
numCols = message.content.import[0].length;
|
|
} else if (message.content.new) {
|
|
numRows = message.content.new.row;
|
|
numCols = message.content.new.column;
|
|
}
|
|
|
|
const board = penpot.createBoard();
|
|
board.name = 'Table';
|
|
|
|
const viewport = penpot.viewport;
|
|
board.x = viewport.center.x - 150;
|
|
board.y = viewport.center.y - 200;
|
|
board.resize(numCols * 160, numRows * 50);
|
|
board.borderRadius = 8;
|
|
|
|
// create grid
|
|
const grid = board.addGridLayout();
|
|
|
|
for (let i = 0; i < numRows; i++) {
|
|
grid.addRow('flex', 1);
|
|
}
|
|
|
|
for (let i = 0; i < numCols; i++) {
|
|
grid.addColumn('flex', 1);
|
|
}
|
|
|
|
grid.alignItems = 'center';
|
|
grid.justifyItems = 'start';
|
|
grid.justifyContent = 'stretch';
|
|
grid.alignContent = 'stretch';
|
|
|
|
// create text
|
|
for (let row = 0; row < numRows; row++) {
|
|
for (let col = 0; col < numCols; col++) {
|
|
if (numRows * numCols >= 25) {
|
|
createGroupCell(grid, numRows, numCols, row, col, message);
|
|
} else {
|
|
createFlexCell(grid, numRows, numCols, row, col, message);
|
|
}
|
|
}
|
|
}
|
|
penpot.closePlugin();
|
|
}
|
|
});
|
|
|
|
function createGroupCell(
|
|
grid: GridLayout,
|
|
numRows: number,
|
|
numCols: number,
|
|
row: number,
|
|
col: number,
|
|
message: TablePluginEvent,
|
|
) {
|
|
const bg = penpot.createRectangle();
|
|
bg.x = 0;
|
|
bg.y = 0;
|
|
bg.resize(100, 100);
|
|
|
|
if (col === 0 && row === 0) {
|
|
bg.borderRadiusTopLeft = 8;
|
|
} else if (col === 0 && row === numRows - 1) {
|
|
bg.borderRadiusBottomRight = 8;
|
|
} else if (col === numCols - 1 && row === 0) {
|
|
bg.borderRadiusTopRight = 8;
|
|
} else if (col === numCols - 1 && row === numRows - 1) {
|
|
bg.borderRadiusBottomRight = 8;
|
|
}
|
|
|
|
if (message.content.options.alternateRows && !(row % 2)) {
|
|
bg.fills = [{ fillColor: '#f8f9fc' }];
|
|
} else {
|
|
bg.fills = [{ fillColor: '#ffffff' }];
|
|
}
|
|
|
|
if (
|
|
(message.content.options.filledHeaderRow && row === 0) ||
|
|
(message.content.options.filledHeaderColumn && col === 0)
|
|
) {
|
|
bg.fills = [{ fillColor: '#d9dfea' }];
|
|
}
|
|
|
|
if (message.content.options.borders) {
|
|
bg.strokes = [
|
|
{
|
|
strokeColor: '#d4dadc',
|
|
strokeStyle: 'solid',
|
|
strokeWidth: 0.5,
|
|
strokeAlignment: 'center',
|
|
},
|
|
];
|
|
}
|
|
|
|
let text;
|
|
if (message.content.type === 'import' && message.content.import) {
|
|
text = penpot.createText(message.content.import[row][col]);
|
|
} else if (message.content.new) {
|
|
text = row === 0 ? penpot.createText('Header') : penpot.createText('Cell');
|
|
}
|
|
|
|
if (text) {
|
|
text.x = 20;
|
|
text.y = 10;
|
|
text.resize(60, 80);
|
|
text.verticalAlign = 'center';
|
|
text.growType = 'auto-height';
|
|
text.fontFamily = 'Work Sans';
|
|
text.fontId = 'gfont-work-sans';
|
|
text.fontVariantId = row === 0 ? '500' : 'regular';
|
|
text.fontSize = '12';
|
|
text.fontWeight = row === 0 ? '500' : '400';
|
|
|
|
const group = penpot.group([bg, text]);
|
|
if (group) {
|
|
text.constraintsHorizontal = 'leftright';
|
|
text.constraintsVertical = 'topbottom';
|
|
|
|
grid.appendChild(group, row + 1, col + 1);
|
|
if (group.layoutChild) {
|
|
group.layoutChild.horizontalSizing = 'fill';
|
|
group.layoutChild.verticalSizing = 'fill';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function createFlexCell(
|
|
grid: GridLayout,
|
|
numRows: number,
|
|
numCols: number,
|
|
row: number,
|
|
col: number,
|
|
message: TablePluginEvent,
|
|
) {
|
|
const board = penpot.createBoard();
|
|
|
|
if (col === 0 && row === 0) {
|
|
board.borderRadiusTopLeft = 8;
|
|
} else if (col === 0 && row === numRows - 1) {
|
|
board.borderRadiusBottomRight = 8;
|
|
} else if (col === numCols - 1 && row === 0) {
|
|
board.borderRadiusTopRight = 8;
|
|
} else if (col === numCols - 1 && row === numRows - 1) {
|
|
board.borderRadiusBottomRight = 8;
|
|
}
|
|
|
|
grid.appendChild(board, row + 1, col + 1);
|
|
|
|
if (board.layoutChild) {
|
|
board.layoutChild.horizontalSizing = 'fill';
|
|
board.layoutChild.verticalSizing = 'fill';
|
|
}
|
|
|
|
if (message.content.options.alternateRows && !(row % 2)) {
|
|
board.fills = [{ fillColor: '#f8f9fc' }];
|
|
}
|
|
|
|
if (
|
|
(message.content.options.filledHeaderRow && row === 0) ||
|
|
(message.content.options.filledHeaderColumn && col === 0)
|
|
) {
|
|
board.fills = [{ fillColor: '#d9dfea' }];
|
|
}
|
|
|
|
if (message.content.options.borders) {
|
|
board.strokes = [
|
|
{
|
|
strokeColor: '#d4dadc',
|
|
strokeStyle: 'solid',
|
|
strokeWidth: 0.5,
|
|
strokeAlignment: 'center',
|
|
},
|
|
];
|
|
}
|
|
|
|
const flex = board.addFlexLayout();
|
|
flex.alignItems = 'center';
|
|
flex.justifyContent = 'start';
|
|
flex.verticalPadding = 10;
|
|
flex.horizontalPadding = 20;
|
|
|
|
let text;
|
|
if (message.content.type === 'import' && message.content.import) {
|
|
text = penpot.createText(message.content.import[row][col]);
|
|
} else if (message.content.new) {
|
|
text = row === 0 ? penpot.createText('Header') : penpot.createText('Cell');
|
|
}
|
|
|
|
if (text) {
|
|
text.growType = 'auto-height';
|
|
text.fontFamily = 'Work Sans';
|
|
text.fontId = 'gfont-work-sans';
|
|
text.fontVariantId = row === 0 ? '500' : 'regular';
|
|
text.fontSize = '12';
|
|
text.fontWeight = row === 0 ? '500' : '400';
|
|
board.appendChild(text);
|
|
if (text.layoutChild) {
|
|
text.layoutChild.horizontalSizing = 'fill';
|
|
text.layoutChild.verticalSizing = 'fix';
|
|
}
|
|
}
|
|
}
|
|
|
|
function pluginData(message: PluginMessageEvent) {
|
|
if (message.type === 'tableconfig') {
|
|
const { type, options } = message.content;
|
|
const page = penpot.currentPage;
|
|
|
|
if (type === 'save') {
|
|
page?.setPluginData('table-plugin', JSON.stringify(options));
|
|
} else if (message.content.type === 'retrieve') {
|
|
const data = page?.getPluginData('table-plugin');
|
|
const options = data ? JSON.parse(data) : null;
|
|
|
|
sendMessage({
|
|
type: 'tableconfig',
|
|
content: {
|
|
type: 'retrieve',
|
|
options,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function sendMessage(message: PluginMessageEvent) {
|
|
penpot.ui.sendMessage(message);
|
|
}
|