UNPKG

figma-gridgen

Version:

Utilizes built-in Figma rectangles, lines, and texts to generate tables with neatly organized layers

904 lines (876 loc) 103 kB
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/code.ts"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./src/code.ts": /*!*********************!*\ !*** ./src/code.ts ***! \*********************/ /*! no exports provided */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _generators_generators__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./generators/generators */ "./src/generators/generators.ts"); /* harmony import */ var _utils_figma__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/figma */ "./src/utils/figma.ts"); /* harmony import */ var _models_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./models/constants */ "./src/models/constants.ts"); // This shows the HTML page in "ui.html". _utils_figma__WEBPACK_IMPORTED_MODULE_1__["showUI"](__html__, _models_constants__WEBPACK_IMPORTED_MODULE_2__["showUIOptions"]); // Generate available font options and load saved states let promise = [ _utils_figma__WEBPACK_IMPORTED_MODULE_1__["listAvailableFontsAsync"](), _utils_figma__WEBPACK_IMPORTED_MODULE_1__["getStorageData"]("create-table" /* CREATE */), ]; Promise.all(promise).then(results => { const msg = {}; const fonts = results[0]; const createMessage = results[1]; let fontOptions = {}; let previousFont = ""; fonts.forEach(font => { if (font.fontName.family !== previousFont) { fontOptions[font.fontName.family] = [font.fontName.style]; previousFont = font.fontName.family; } else { fontOptions[font.fontName.family].push(font.fontName.style); } }); msg.fontOptions = fontOptions; msg.createMessage = createMessage; figma.ui.postMessage(msg); figma.ui.show(); }); // Calls to "parent.postMessage" from within the HTML page will trigger this // callback. The callback will be passed the "pluginMessage" property of the // posted message. figma.ui.onmessage = msg => { processMessage(msg); }; function processMessage(message) { if (message.type === "create-table" /* CREATE */) { /* Generate Background */ const oddRowBackgroundGroup = Object(_generators_generators__WEBPACK_IMPORTED_MODULE_0__["generateRowBackground"])("Odd" /* ODD */, message.rows, message.rowHeight, message.columnWidth * message.columns, message.alternateBackgrounds, message.header, message.primarybackgroundColor, message.stripedbackgroundColor, message.referenceCoordinates); const rowBackgroundNode = [oddRowBackgroundGroup]; if ((message.header && message.rows > 2) || (!message.header && message.rows > 1)) { const evenRowBackgroundGroup = Object(_generators_generators__WEBPACK_IMPORTED_MODULE_0__["generateRowBackground"])("Even" /* EVEN */, message.rows, message.rowHeight, message.columnWidth * message.columns, message.alternateBackgrounds, message.header, message.primarybackgroundColor, message.stripedbackgroundColor, message.referenceCoordinates); rowBackgroundNode.push(evenRowBackgroundGroup); } const rowBackgroundGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_1__["groupNodes"](rowBackgroundNode, figma.currentPage); rowBackgroundGroup.name = "Row Background"; /* Generate Texts */ const columnTextsGroup = Object(_generators_generators__WEBPACK_IMPORTED_MODULE_0__["generateTableTexts"])(message.rows, message.rowHeight, message.columns, message.columnWidth, message.tableFontFamily, message.tableFontStyle, message.tableFontSize, message.header, message.referenceCoordinates); /* Generate Headers */ const tableHeaderGroup = Object(_generators_generators__WEBPACK_IMPORTED_MODULE_0__["generateTableHeader"])(message.rows, message.rowHeight, message.columns, message.columnWidth, message.header, message.headerHeight, message.headerFontFamily, message.headerFontStyle, message.headerFontSize, message.floatingFilter, message.floatingFilterHeight, message.primarybackgroundColor, message.referenceCoordinates); /* Generate Borders */ const verticalLinesGroup = Object(_generators_generators__WEBPACK_IMPORTED_MODULE_0__["generateBorders"])("Vertical" /* VERTICAL */, message.borders, message.columns, message.columnWidth, message.rows, message.rowHeight, message.header, message.headerHeight, message.borderColor, message.referenceCoordinates); const horizontalLinesGroup = Object(_generators_generators__WEBPACK_IMPORTED_MODULE_0__["generateBorders"])("Horizontal" /* HORIZONTAL */, message.borders, message.rows, message.rowHeight, message.columns, message.columnWidth, message.header, message.headerHeight, message.borderColor, message.referenceCoordinates); const borderLinesNode = [verticalLinesGroup, horizontalLinesGroup]; const borderLinesGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_1__["groupNodes"](borderLinesNode, figma.currentPage); borderLinesGroup.name = "Borders"; /* Sort Group Nodes */ const tableGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_1__["groupNodes"]([rowBackgroundGroup], figma.currentPage); tableGroup.appendChild(columnTextsGroup); if (tableHeaderGroup !== null) { tableGroup.appendChild(tableHeaderGroup); } tableGroup.appendChild(borderLinesGroup); tableGroup.name = "Table"; figma.currentPage.selection = [tableGroup]; figma.viewport.scrollAndZoomIntoView([tableGroup]); /* Save Message to Client Storage */ Object(_generators_generators__WEBPACK_IMPORTED_MODULE_0__["saveMessage"])("create-table" /* CREATE */, message); return null; } } /***/ }), /***/ "./src/generators/generators.ts": /*!**************************************!*\ !*** ./src/generators/generators.ts ***! \**************************************/ /*! exports provided: generateBorders, generateRowBackground, generateTableTexts, generateTableHeader, saveMessage */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateBorders", function() { return generateBorders; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateRowBackground", function() { return generateRowBackground; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateTableTexts", function() { return generateTableTexts; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateTableHeader", function() { return generateTableHeader; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "saveMessage", function() { return saveMessage; }); /* harmony import */ var _utils_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/utils */ "./src/utils/utils.ts"); /* harmony import */ var _models_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../models/constants */ "./src/models/constants.ts"); /* harmony import */ var _utils_figma__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/figma */ "./src/utils/figma.ts"); var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; /* Check if Font is Loaded */ let isTableFontLoaded = false; let isHeaderFontLoaded = false; /* Check if Data is Save */ let isDataSaved = false; function generateBorders(borderType, visible = true, borderCount, borderSpacing, borderWidthMultiplier, borderWidthIndividual, header, headerHeight, borderColor, referenceCoordinates) { const linesNode = []; let borderWidth; if (header) { if (borderType === "Vertical" /* VERTICAL */) { borderWidth = (borderWidthMultiplier - 1) * borderWidthIndividual + headerHeight; } else { borderCount -= 1; borderWidth = borderWidthMultiplier * borderWidthIndividual; } } else { borderWidth = borderWidthMultiplier * borderWidthIndividual; } const lineStrokesColor = borderColor.match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i) === null ? _utils_utils__WEBPACK_IMPORTED_MODULE_0__["hexToRgb"](_models_constants__WEBPACK_IMPORTED_MODULE_1__["defaultBorderColor"]) : _utils_utils__WEBPACK_IMPORTED_MODULE_0__["hexToRgb"](borderColor); for (let i = 0; i < borderCount + 1; i++) { const line = figma.createLine(); const lineStrokes = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["clone"](line.strokes); lineStrokes[0].color.r = lineStrokesColor.r / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; lineStrokes[0].color.g = lineStrokesColor.g / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; lineStrokes[0].color.b = lineStrokesColor.b / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; line.strokes = lineStrokes; if (borderType === "Vertical" /* VERTICAL */) { line.rotation = 90 /* QUARTER */; line.x = referenceCoordinates.x + i * borderSpacing; line.y = referenceCoordinates.y; } else { line.x = referenceCoordinates.x; line.y = referenceCoordinates.y - i * borderSpacing; } line.resize(borderWidth, 0); linesNode.push(line); } // create top line if header is included if (header && borderType === "Horizontal" /* HORIZONTAL */) { const line = figma.createLine(); const lineStrokes = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["clone"](line.strokes); lineStrokes[0].color.r = lineStrokesColor.r / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; lineStrokes[0].color.g = lineStrokesColor.g / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; lineStrokes[0].color.b = lineStrokesColor.b / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; line.strokes = lineStrokes; line.resize(borderWidth, 0); line.x = referenceCoordinates.x; line.y = referenceCoordinates.y - headerHeight - borderCount * borderSpacing; linesNode.push(line); } const linesGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_2__["groupNodes"](linesNode, _utils_figma__WEBPACK_IMPORTED_MODULE_2__["getCurrentPage"]()); if (!visible) { linesGroup.visible = false; } linesGroup.name = borderType; return linesGroup; } function generateRowBackground(rowBackgroundType, rowCount, rowHeight, rowWidth, alternateBackgrounds, header, primaryBackgroundColor, stripedBackgroundColor, referenceCoordinates) { const rowBackgroundNode = []; const rowSpacing = rowHeight * 2; let computedRowCount = 0; let startingPoint = 0; if (header) { rowCount -= 1; } if (rowBackgroundType === "Odd" /* ODD */) { computedRowCount = Math.round(rowCount / 2); startingPoint = referenceCoordinates.y - rowHeight; } else { computedRowCount = Math.floor(rowCount / 2); startingPoint = referenceCoordinates.y - rowSpacing; } for (let i = 0; i < computedRowCount; i++) { const background = figma.createRectangle(); const backgroundFills = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["clone"](background.fills); let backgroundFillsColor; if (alternateBackgrounds) { if ((rowCount % 2 === 0 && rowBackgroundType === "Odd" /* ODD */) || (rowCount % 2 !== 0 && rowBackgroundType === "Even" /* EVEN */)) { backgroundFillsColor = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["hexToRgb"](stripedBackgroundColor); } else { backgroundFillsColor = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["hexToRgb"](primaryBackgroundColor); } } else { backgroundFillsColor = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["hexToRgb"](primaryBackgroundColor); } backgroundFills[0].color.r = backgroundFillsColor.r / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; backgroundFills[0].color.g = backgroundFillsColor.g / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; backgroundFills[0].color.b = backgroundFillsColor.b / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; background.fills = backgroundFills; background.resize(rowWidth, rowHeight); background.y = startingPoint - i * rowSpacing; rowBackgroundNode.push(background); } const rowBackgroundGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_2__["groupNodes"](rowBackgroundNode, _utils_figma__WEBPACK_IMPORTED_MODULE_2__["getCurrentPage"]()); rowBackgroundGroup.name = rowBackgroundType; return rowBackgroundGroup; } function generateTableTexts(rowCount, rowHeight, columnCount, columnWidth, tableFontFamily, tableFontStyle, tableFontSize, header, referenceCoordinates) { const tableTextsNode = []; const tableFontName = { family: tableFontFamily, style: tableFontStyle, }; if (header) { rowCount -= 1; } const textMargin = { x: 5, y: 5 }; for (let i = 0; i < columnCount; i++) { const columnTextsNode = []; const columnTextsStartingPosition = referenceCoordinates.x + i * columnWidth + textMargin.x; for (let j = 0; j < rowCount; j++) { const text = figma.createText(); text.name = "Row " + (rowCount - j); text.x = columnTextsStartingPosition; text.y = referenceCoordinates.y + textMargin.y - (j + 1) * rowHeight; columnTextsNode.push(text); } const columnTextsGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_2__["groupNodes"](columnTextsNode, _utils_figma__WEBPACK_IMPORTED_MODULE_2__["getCurrentPage"]()); columnTextsGroup.name = "Column " + (i + 1); tableTextsNode.push(columnTextsGroup); } const tableTextsGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_2__["groupNodes"](tableTextsNode, _utils_figma__WEBPACK_IMPORTED_MODULE_2__["getCurrentPage"]()); const allTextsNodesGenerated = tableTextsGroup.findAll(node => node.type === "TEXT"); _utils_figma__WEBPACK_IMPORTED_MODULE_2__["loadNodeFont"](tableFontName).then(() => { for (let textNode of allTextsNodesGenerated) { const text = textNode; text.fontName = tableFontName; text.fontSize = tableFontSize; text.characters = _models_constants__WEBPACK_IMPORTED_MODULE_1__["sampleText"]; text.textAlignVertical = "CENTER" /* CENTER */; text.resize(columnWidth - 1 - 2 * textMargin.x, rowHeight - 2 * textMargin.y); } isTableFontLoaded = true; onPromiseResolved(header); }); tableTextsGroup.name = "Table Texts"; return tableTextsGroup; } function generateTableHeader(rowCount, rowHeight, columnCount, columnWidth, header, headerHeight, headerFontFamily, headerFontStyle, headerFontSize, floatingFilter, floatingFilterHeight, primaryBackgroundColor, referenceCoordinates) { if (header) { // Background const tableHeaderNode = []; const tableHeaderFontName = { family: headerFontFamily, style: headerFontStyle }; const rowWidth = columnWidth * columnCount; const background = figma.createRectangle(); const backgroundFills = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["clone"](background.fills); const backgroundFillsColor = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["hexToRgb"](primaryBackgroundColor); backgroundFills[0].color.r = backgroundFillsColor.r / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; backgroundFills[0].color.g = backgroundFillsColor.g / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; backgroundFills[0].color.b = backgroundFillsColor.b / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; background.fills = backgroundFills; background.resize(rowWidth, headerHeight); background.y = referenceCoordinates.y - headerHeight - (rowCount - 1) * rowHeight; background.name = "Header Background"; tableHeaderNode.push(background); // Texts const tableHeaderTextsNode = []; const textHeight = floatingFilter ? headerHeight - floatingFilterHeight : headerHeight; const headerTextMargin = { x: 5, y: 5 }; for (let i = 0; i < columnCount; i++) { const columnTextsStartingPosition = referenceCoordinates.x + i * columnWidth + headerTextMargin.x; const text = figma.createText(); text.name = "Column Header " + (i + 1); text.x = columnTextsStartingPosition; text.y = referenceCoordinates.y - headerHeight + headerTextMargin.y - (rowCount - 1) * rowHeight; tableHeaderTextsNode.push(text); } const tableHeaderTextsGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_2__["groupNodes"](tableHeaderTextsNode, _utils_figma__WEBPACK_IMPORTED_MODULE_2__["getCurrentPage"]()); const allTextsNodesGenerated = tableHeaderTextsGroup.findAll(node => node.type === "TEXT"); _utils_figma__WEBPACK_IMPORTED_MODULE_2__["loadNodeFont"](tableHeaderFontName).then(() => { isHeaderFontLoaded = true; for (let textNode of allTextsNodesGenerated) { const text = textNode; text.fontName = tableHeaderFontName; text.fontSize = headerFontSize; text.characters = _models_constants__WEBPACK_IMPORTED_MODULE_1__["sampleText"].toUpperCase(); text.textAlignVertical = "CENTER" /* CENTER */; text.resize(columnWidth - 1 - 2 * headerTextMargin.x, textHeight - 2 * headerTextMargin.y); } onPromiseResolved(header); }); tableHeaderTextsGroup.name = "Column Headers"; tableHeaderNode.push(tableHeaderTextsGroup); // Floating Filters if (floatingFilter) { const floatingFiltersNode = []; const floatingFilterMargin = { x: 5, y: 5 }; for (let i = 0; i < columnCount; i++) { const columnFloatingFiltersStartingPosition = referenceCoordinates.x + i * columnWidth + floatingFilterMargin.x; const floatingFilter = figma.createRectangle(); const floatingFilterFills = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["clone"](floatingFilter.fills); const floatingFilterFillsColor = _utils_utils__WEBPACK_IMPORTED_MODULE_0__["hexToRgb"]("#FFFFFF" /* WHITE */); floatingFilterFills[0].color.r = floatingFilterFillsColor.r / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; floatingFilterFills[0].color.g = floatingFilterFillsColor.g / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; floatingFilterFills[0].color.b = floatingFilterFillsColor.b / _models_constants__WEBPACK_IMPORTED_MODULE_1__["maxRGB"]; floatingFilter.fills = floatingFilterFills; floatingFilter.name = "Floating Filter Placeholder" + (i + 1); floatingFilter.resize(columnWidth - 1 - 2 * floatingFilterMargin.x, floatingFilterHeight - 2 * floatingFilterMargin.y); floatingFilter.x = columnFloatingFiltersStartingPosition; floatingFilter.y = referenceCoordinates.y - floatingFilterHeight + floatingFilterMargin.y - (rowCount - 1) * rowHeight; floatingFiltersNode.push(floatingFilter); } const tableFloatingFiltersGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_2__["groupNodes"](floatingFiltersNode, _utils_figma__WEBPACK_IMPORTED_MODULE_2__["getCurrentPage"]()); tableFloatingFiltersGroup.name = "Floating Filters"; tableHeaderNode.push(tableFloatingFiltersGroup); } const tableHeaderGroup = _utils_figma__WEBPACK_IMPORTED_MODULE_2__["groupNodes"](tableHeaderNode, _utils_figma__WEBPACK_IMPORTED_MODULE_2__["getCurrentPage"]()); tableHeaderGroup.name = "Table Header"; return tableHeaderGroup; } else { return null; } } function saveMessage(key, value) { return __awaiter(this, void 0, void 0, function* () { _utils_figma__WEBPACK_IMPORTED_MODULE_2__["setStorageData"](key, value).then(() => { isDataSaved = true; onPromiseResolved(value.header); }); }); } // Getter function for font load status function onPromiseResolved(header) { if (isDataSaved && isTableFontLoaded && (isHeaderFontLoaded || !header)) { /* Notify Success to User */ _utils_figma__WEBPACK_IMPORTED_MODULE_2__["notify"]("👍 Table successfully generated. Install GridMod to modify it easily!", 2400); _utils_figma__WEBPACK_IMPORTED_MODULE_2__["closePlugin"](); } } /***/ }), /***/ "./src/models/constants.ts": /*!*********************************!*\ !*** ./src/models/constants.ts ***! \*********************************/ /*! exports provided: showUIOptions, defaultBorderColor, maxRGB, sampleText, defaultInputsForModes, CheckboxInputIds, maxDimensionInPixels, maxNumberOfRowsOrColumns, inputsAffectedByMode, genericInputs, inputIds */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "showUIOptions", function() { return showUIOptions; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultBorderColor", function() { return defaultBorderColor; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maxRGB", function() { return maxRGB; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sampleText", function() { return sampleText; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultInputsForModes", function() { return defaultInputsForModes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CheckboxInputIds", function() { return CheckboxInputIds; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maxDimensionInPixels", function() { return maxDimensionInPixels; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maxNumberOfRowsOrColumns", function() { return maxNumberOfRowsOrColumns; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "inputsAffectedByMode", function() { return inputsAffectedByMode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "genericInputs", function() { return genericInputs; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "inputIds", function() { return inputIds; }); const showUIOptions = { width: 300, height: 625, visible: false, }; const defaultBorderColor = "#C7C7C7" /* GREY_C7 */; const maxRGB = 255; const sampleText = "Sample"; const defaultInputsForModes = { // first on list is the default selected "count-and-table-size": ["tableWidth", "tableHeight", "columns", "rows"], "count-and-cell-size": ["columns", "rows", "columnWidth", "rowHeight"], "cell-and-table-size": ["tableWidth", "tableHeight", "columnWidth", "rowHeight"], }; var CheckboxInputIds; (function (CheckboxInputIds) { CheckboxInputIds["HEADER"] = "header"; CheckboxInputIds["FLOATING_FILTER"] = "floatingFilter"; CheckboxInputIds["ALTERNATE_BACKGROUNDS"] = "alternateBackgrounds"; CheckboxInputIds["BORDERS"] = "borders"; })(CheckboxInputIds || (CheckboxInputIds = {})); const maxDimensionInPixels = 5000; const maxNumberOfRowsOrColumns = 100; const inputsAffectedByMode = { tableWidth: "1024" /* TABLE_WIDTH */, tableHeight: "768" /* TABLE_HEIGHT */, columns: "5" /* COLUMNS */, rows: "8" /* ROWS */, columnWidth: "100" /* COLUMN_WIDTH */, rowHeight: "30" /* ROW_HEIGHT */, }; const genericInputs = { primarybackgroundColor: "#F7F7F7" /* GREY_F7 */, tableFontFamily: "Roboto" /* OVERALL_FONT_NAME_FAMILY */, tableFontStyle: "Regular" /* OVERALL_FONT_NAME_STYLE */, tableFontSize: "12" /* OVERALL_FONT_SIZE */, header: "" /* CHECKBOX */, headerHeight: "60" /* HEADER_HEIGHT */, headerFontFamily: "Roboto" /* OVERALL_FONT_NAME_FAMILY */, headerFontStyle: "Regular" /* OVERALL_FONT_NAME_STYLE */, headerFontSize: "12" /* OVERALL_FONT_SIZE */, floatingFilter: "" /* CHECKBOX */, floatingFilterHeight: "30" /* FLOATING_FILTER_HEIGHT */, alternateBackgrounds: "" /* CHECKBOX */, stripedbackgroundColor: "#FFFFFF" /* WHITE */, borders: "" /* CHECKBOX */, borderColor: "#C7C7C7" /* GREY_C7 */, }; const inputIds = { tableWidth: 0 /* NUMBER */, tableHeight: 0 /* NUMBER */, columns: 0 /* NUMBER */, rows: 0 /* NUMBER */, primarybackgroundColor: 2 /* STRING */, tableFontFamily: 2 /* STRING */, tableFontStyle: 2 /* STRING */, tableFontSize: 0 /* NUMBER */, columnWidth: 0 /* NUMBER */, rowHeight: 0 /* NUMBER */, header: 1 /* BOOLEAN */, headerHeight: 0 /* NUMBER */, headerFontFamily: 2 /* STRING */, headerFontStyle: 2 /* STRING */, headerFontSize: 0 /* NUMBER */, floatingFilter: 1 /* BOOLEAN */, floatingFilterHeight: 0 /* NUMBER */, alternateBackgrounds: 1 /* BOOLEAN */, stripedbackgroundColor: 2 /* STRING */, borders: 1 /* BOOLEAN */, borderColor: 2 /* STRING */, }; /***/ }), /***/ "./src/utils/figma.ts": /*!****************************!*\ !*** ./src/utils/figma.ts ***! \****************************/ /*! exports provided: notify, showUI, closePlugin, loadNodeFont, listAvailableFontsAsync, getStorageData, setStorageData, groupNodes, getCurrentPage, getSelection, setSelection, scrollAndZoomIntoView */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "notify", function() { return notify; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "showUI", function() { return showUI; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "closePlugin", function() { return closePlugin; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadNodeFont", function() { return loadNodeFont; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "listAvailableFontsAsync", function() { return listAvailableFontsAsync; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getStorageData", function() { return getStorageData; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setStorageData", function() { return setStorageData; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "groupNodes", function() { return groupNodes; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCurrentPage", function() { return getCurrentPage; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSelection", function() { return getSelection; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setSelection", function() { return setSelection; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scrollAndZoomIntoView", function() { return scrollAndZoomIntoView; }); var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; function notify(message, timeout) { return figma.notify(message, { timeout: timeout }); } function showUI(html, showUIOptions) { return figma.showUI(html, showUIOptions); } function closePlugin() { return figma.closePlugin(); } /* Fonts Util */ // Function to load selected font function loadNodeFont(fontName) { return __awaiter(this, void 0, void 0, function* () { yield figma.loadFontAsync(fontName).catch(error => console.error(error)); }); } // Function to list all available fonts on Figma function listAvailableFontsAsync() { return __awaiter(this, void 0, void 0, function* () { return yield figma.listAvailableFontsAsync().catch(error => { console.error(error); return null; }); }); } /* Client Storage */ function getStorageData(key) { return __awaiter(this, void 0, void 0, function* () { return yield figma.clientStorage.getAsync(key).catch(error => { console.error(error); return null; }); }); } function setStorageData(key, value) { return __awaiter(this, void 0, void 0, function* () { yield figma.clientStorage.setAsync(key, value).catch(error => console.error(error)); }); } /* Figma API Function Abstraction */ function groupNodes(nodes, parent) { return figma.group(nodes, parent); } function getCurrentPage() { return figma.currentPage; } function getSelection() { return getCurrentPage().selection; } function setSelection(node) { figma.currentPage.selection = node; return null; } function scrollAndZoomIntoView(node) { figma.viewport.scrollAndZoomIntoView(node); return null; } /***/ }), /***/ "./src/utils/utils.ts": /*!****************************!*\ !*** ./src/utils/utils.ts ***! \****************************/ /*! exports provided: clone, hexToRgb, getHTMLElementById, getHTMLInputElementById, getActiveMode, resetInvalidInput, getValue, validateInput, processInputToMessage, toggleEditable, constructFontFamilyOptions, constructFontStyleOptions */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clone", function() { return clone; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hexToRgb", function() { return hexToRgb; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHTMLElementById", function() { return getHTMLElementById; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHTMLInputElementById", function() { return getHTMLInputElementById; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getActiveMode", function() { return getActiveMode; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resetInvalidInput", function() { return resetInvalidInput; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getValue", function() { return getValue; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "validateInput", function() { return validateInput; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "processInputToMessage", function() { return processInputToMessage; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toggleEditable", function() { return toggleEditable; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "constructFontFamilyOptions", function() { return constructFontFamilyOptions; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "constructFontStyleOptions", function() { return constructFontStyleOptions; }); /* harmony import */ var _models_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../models/constants */ "./src/models/constants.ts"); /* Clone function taken from Figma Plugin API example */ function clone(val) { const type = typeof val; if (val === null) { return null; } else if (type === "undefined" || type === "number" || type === "string" || type === "boolean") { return val; } else if (type === "object") { if (val instanceof Array) { return val.map(x => clone(x)); } else if (val instanceof Uint8Array) { return new Uint8Array(val); } else { let o = {}; for (const key in val) { o[key] = clone(val[key]); } return o; } } throw "unknown"; } /* HEX to RGB Conversion */ function hexToRgb(hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16), } : null; } /* HTML Elements */ // Select generic HTML Element function getHTMLElementById(htmlElement) { return document.getElementById(htmlElement); } // Select Input Element function getHTMLInputElementById(htmlElement) { return document.getElementById(htmlElement); } // Get active mode function getActiveMode() { return getValue("count-and-table-size" /* COUNT_AND_TABLE_SIZE */, 1 /* BOOLEAN */) ? "count-and-table-size" /* COUNT_AND_TABLE_SIZE */ : getValue("count-and-cell-size" /* COUNT_AND_CELL_SIZE */, 1 /* BOOLEAN */) ? "count-and-cell-size" /* COUNT_AND_CELL_SIZE */ : "cell-and-table-size" /* CELL_AND_TABLE_SIZE */; } // Reset Invalid CSS function resetInvalidInput() { const inputList = Object.keys(_models_constants__WEBPACK_IMPORTED_MODULE_0__["inputsAffectedByMode"]); for (let input of inputList) { getHTMLElementById(input).classList.remove("invalid"); } } // Set Invalid CSS by List function setInvalidInputs(mode) { const inputList = _models_constants__WEBPACK_IMPORTED_MODULE_0__["defaultInputsForModes"][mode]; for (let input of inputList) { getHTMLElementById(input).classList.add("invalid"); } } /* Extract Inputs */ function getValue(htmlTagId, inputType) { const input = getHTMLInputElementById(htmlTagId); switch (inputType) { case 0 /* NUMBER */: return parseInt(input.value, 10) ? parseInt(input.value, 10) : 0; case 1 /* BOOLEAN */: return input.checked; case 2 /* STRING */: return input.value; } } /* Validate User Input */ function validateInput(mode, columns, rows, columnWidth, rowHeight, hasHeader, hasFloatingFilter) { let validInput = true; // reset invalid CSS and validators resetInvalidInput(); getHTMLElementById("validValidator").classList.add("show"); getHTMLElementById("negativeValidator").classList.remove("show"); getHTMLElementById("minimumRowsValidator").classList.remove("show"); getHTMLElementById("constraintValidator").classList.remove("show"); // negative and invalid value check let inputsToValidate = _models_constants__WEBPACK_IMPORTED_MODULE_0__["defaultInputsForModes"][mode].concat(["tableFontSize"]); if (hasHeader) { inputsToValidate = inputsToValidate.concat(["headerHeight", "headerFontSize"]); } if (hasFloatingFilter) { inputsToValidate = inputsToValidate.concat(["floatingFilterHeight"]); } for (let input of inputsToValidate) { const inputValue = getValue(input, 0 /* NUMBER */); if (!inputValue || inputValue < 1) { getHTMLInputElementById(input).classList.add("invalid"); getHTMLElementById("validValidator").classList.remove("show"); getHTMLElementById("negativeValidator").classList.add("show"); getHTMLElementById("minimumRowsValidator").classList.remove("show"); getHTMLElementById("constraintValidator").classList.remove("show"); validInput = false; } } // limit check if (validInput) { if ((!hasHeader && rows < 1) || (hasHeader && rows < 2)) { setInvalidInputs(mode); getHTMLElementById("validValidator").classList.remove("show"); getHTMLElementById("negativeValidator").classList.remove("show"); getHTMLElementById("minimumRowsValidator").classList.add("show"); getHTMLElementById("constraintValidator").classList.remove("show"); validInput = false; } else if (columns * columnWidth > _models_constants__WEBPACK_IMPORTED_MODULE_0__["maxDimensionInPixels"] || rows * rowHeight > _models_constants__WEBPACK_IMPORTED_MODULE_0__["maxDimensionInPixels"] || columns > _models_constants__WEBPACK_IMPORTED_MODULE_0__["maxNumberOfRowsOrColumns"] || rows > _models_constants__WEBPACK_IMPORTED_MODULE_0__["maxNumberOfRowsOrColumns"]) { setInvalidInputs(mode); getHTMLElementById("validValidator").classList.remove("show"); getHTMLElementById("negativeValidator").classList.remove("show"); getHTMLElementById("minimumRowsValidator").classList.remove("show"); getHTMLElementById("constraintValidator").classList.add("show"); validInput = false; } } getHTMLInputElementById(_models_constants__WEBPACK_IMPORTED_MODULE_0__["defaultInputsForModes"][mode][0]).select(); return validInput; } /* Process Input */ function processInputToMessage() { // Selected Mode const mode = getActiveMode(); // PluginMessage Creation const createMessage = { type: "create-table" /* CREATE */, mode: mode }; // Table Font Info Object.keys(_models_constants__WEBPACK_IMPORTED_MODULE_0__["inputIds"]).forEach(id => { createMessage[id] = getValue(id, _models_constants__WEBPACK_IMPORTED_MODULE_0__["inputIds"][id]); }); // Constraints Processing createMessage.referenceCoordinates = { x: 0, y: 0 }; switch (mode) { case "count-and-table-size" /* COUNT_AND_TABLE_SIZE */: createMessage.columnWidth = createMessage.tableWidth / createMessage.columns; createMessage.rowHeight = (createMessage.tableHeight - createMessage.headerHeight) / createMessage.rows; break; case "cell-and-table-size" /* CELL_AND_TABLE_SIZE */: createMessage.columns = Math.floor(createMessage.tableWidth / createMessage.columnWidth); createMessage.rows = createMessage.headerHeight > 0 ? Math.floor((createMessage.tableHeight - createMessage.headerHeight) / createMessage.rowHeight + 1) : Math.floor((createMessage.tableHeight - createMessage.headerHeight) / createMessage.rowHeight); createMessage.referenceCoordinates.y = createMessage.tableHeight % createMessage.rowHeight; break; default: break; } // Validation const validWithinLimits = validateInput(mode, createMessage.columns, createMessage.rows, createMessage.columnWidth, createMessage.rowHeight, createMessage.header, createMessage.floatingFilter); if (validWithinLimits) { parent.postMessage({ pluginMessage: createMessage, }, "*"); } else { // Enable create button and hide loader getHTMLInputElementById("create").disabled = false; getHTMLElementById("lds").classList.remove("is-visible"); } } /* Toggle HTML Input Editability */ // Generic function function toggleEditable(htmlTagType, htmlTagId, isPrerequisiteSelected, defaultValue) { let htmlTagById; // Get HTML tag based on type switch (htmlTagType) { case "input" /* INPUT */: htmlTagById = getHTMLInputElementById(htmlTagId); break; case "select" /* SELECT */: htmlTagById = getHTMLElementById(htmlTagId); break; default: break; } // Unchecked any checkbox inputs if (htmlTagById.checked) { htmlTagById.checked = false; } // If input has to be enabled if (isPrerequisiteSelected) { htmlTagById.disabled = false; switch (htmlTagType) { // Populate default value for textboxes case "input" /* INPUT */: htmlTagById.value = defaultValue; break; // Populate options for select case "select" /* SELECT */: htmlTagById.innerHTML = defaultValue; break; default: break; } } else { htmlTagById.disabled = true; htmlTagById.value = "N.A." /* DISABLED */; } // TODO put these somewhere else? getHTMLInputElementById("stripedPickerButton").disabled = getHTMLInputElementById("stripedbackgroundColor").disabled; getHTMLInputElementById("borderPickerButton").disabled = getHTMLInputElementById("borderColor").disabled; return null; } /* Construct Font Options */ // Font family function constructFontFamilyOptions(pluginFontOptions) { let fontFamilyOptionsHTML = ""; Object.keys(pluginFontOptions).forEach(fontFamily => { fontFamilyOptionsHTML += `<option value="${fontFamily}" />`; }); return fontFamilyOptionsHTML; } // Font style function constructFontStyleOptions(pluginFontOptions, selectedFontFamily, selectedFontStyle) { let fontStyleOptionsHTML = ""; pluginFontOptions[selectedFontFamily].forEach(fontStyle => { const selected = fontStyle === selectedFontStyle ? "selected" : fontStyle === "Regular" /* OVERALL_FONT_NAME_STYLE */ && !selectedFontStyle ? "selected" : ""; fontStyleOptionsHTML += `<option value="${fontStyle}" ${selected}>${fontStyle}</option>`; }); return fontStyleOptionsHTML; } /***/ }) /******/ }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvZGUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2dlbmVyYXRvcnMvZ2VuZXJhdG9ycy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvbW9kZWxzL2NvbnN0YW50cy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvdXRpbHMvZmlnbWEudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3V0aWxzL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7UUFBQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTs7O1FBR0E7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLDBDQUEwQyxnQ0FBZ0M7UUFDMUU7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSx3REFBd0Qsa0JBQWtCO1FBQzFFO1FBQ0EsaURBQWlELGNBQWM7UUFDL0Q7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBLHlDQUF5QyxpQ0FBaUM7UUFDMUUsZ0hBQWdILG1CQUFtQixFQUFFO1FBQ3JJO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0EsMkJBQTJCLDBCQUEwQixFQUFFO1FBQ3ZELGlDQUFpQyxlQUFlO1FBQ2hEO1FBQ0E7UUFDQTs7UUFFQTtRQUNBLHNEQUFzRCwrREFBK0Q7O1FBRXJIO1FBQ0E7OztRQUdBO1FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNsRkE7QUFBQTtBQUFBO0FBQUE7QUFBd0k7QUFDakc7QUFDUztBQUNoRDtBQUNBLG1EQUFZLFdBQVcsK0RBQXVCO0FBQzlDO0FBQ0E7QUFDQSxJQUFJLG9FQUE2QjtBQUNqQyxJQUFJLDJEQUFvQjtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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