diff --git a/.eslintrc.json b/.eslintrc.json
index 2060b64..45baed2 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -4,9 +4,6 @@
"plugin:react/recommended",
"plugin:prettier/recommended"
],
- "ecmaFeatures": {
- "experimentalObjectRestSpread": true
- },
"env": {
"browser": true,
"es6": true,
diff --git a/README.md b/README.md
index cbb9c5f..59c2c61 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,8 @@ The plugin's name is based on Dutch graphic designer [Wim Crouwel](https://en.wi
## Features
- Create an unlimited amount of layout grids with varying dimensions, columns, gutters, and margins
-- Build grids and overlay them upon any object: artboards, rectangles, polygons, text, etc.
+- Construct grids with columns or rows or both
+- Produce grids as rectangle fills or gridlines or both
+- Build grids that fit into any object: artboards, rectangles, polygons, text, etc.
- Use auto-calculations to make sure your grids hold your desired structure while still being valid
- Support for grid construction using decimals
-- Produce grids as rectangle fills or gridlines or both
diff --git a/package.json b/package.json
index aa05b93..f759009 100644
--- a/package.json
+++ b/package.json
@@ -13,8 +13,12 @@
"watch": "nodemon -w src -e js,jsx,css -w webpack.config.js -x yarn build"
},
"devDependencies": {
+ "@babel/core": "^7.9.6",
+ "@babel/plugin-transform-react-jsx": "^7.10.1",
+ "babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.0.0",
+ "css-loader": "^3.5.3",
"eslint": "^7.0.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-jest": "^23.13.1",
@@ -24,19 +28,14 @@
"jest": "^26.0.1",
"nodemon": "^2.0.4",
"prettier": "^2.0.5",
+ "style-loader": "^1.2.1",
"webpack": "^4.43.0",
- "webpack-cli": "^3.3.11"
+ "webpack-cli": "^3.3.11",
+ "yarn": "^1.22.4"
},
"dependencies": {
- "@babel/core": "^7.9.6",
- "babel-core": "^6.26.3",
- "babel-loader": "^8.1.0",
- "babel-plugin-transform-react-jsx": "^6.24.1",
- "css-loader": "^3.5.3",
"prop-types": "^15.7.2",
"react": "^16.13.1",
- "react-dom": "^16.13.1",
- "style-loader": "^1.2.1",
- "yarn": "^1.22.4"
+ "react-dom": "^16.13.1"
}
}
diff --git a/src/components/Panel.jsx b/src/components/Panel.jsx
index 5229c53..5093778 100644
--- a/src/components/Panel.jsx
+++ b/src/components/Panel.jsx
@@ -24,6 +24,8 @@ const Panel = ({ selectionAmount, validSelection }) => {
const [boundType, setBoundType] = useState('path')
const [canvasWidth, setCanvasWidth] = useState('')
const [canvasHeight, setCanvasHeight] = useState('')
+
+ const [createCols, setCreateCols] = useState(true)
const [cols, setCols] = useState('')
const [gutterWidth, setGutterWidth] = useState(0)
const [colWidth, setColWidth] = useState('')
@@ -32,6 +34,15 @@ const Panel = ({ selectionAmount, validSelection }) => {
const [bottomMargin, setBottomMargin] = useState(0)
const [leftMargin, setLeftMargin] = useState(0)
+ const [createRows, setCreateRows] = useState(true)
+ const [rows, setRows] = useState('')
+ const [gutterHeight, setGutterHeight] = useState(0)
+ const [rowHeight, setRowHeight] = useState('')
+ const [rowTopMargin, setRowTopMargin] = useState(0)
+ const [rowRightMargin, setRowRightMargin] = useState(0)
+ const [rowBottomMargin, setRowBottomMargin] = useState(0)
+ const [rowLeftMargin, setRowLeftMargin] = useState(0)
+
const [colWidthsSum, setColWidthsSum] = useState('N/A')
const [gridHeight, setGridHeight] = useState('N/A')
const [gridWidth, setGridWidth] = useState('N/A')
@@ -39,18 +50,25 @@ const Panel = ({ selectionAmount, validSelection }) => {
const [topBottomMarginsSum, setTopBottomMarginsSum] = useState(0)
const [rightLeftMarginsSum, setRightLeftMarginsSum] = useState(0)
+ const [rowHeightsSum, setRowHeightsSum] = useState('N/A')
+ const [rowGridHeight, setRowGridHeight] = useState('N/A')
+ const [rowGridWidth, setRowGridWidth] = useState('N/A')
+ const [gutterHeightsSum, setGutterHeightsSum] = useState('N/A')
+ const [rowTopBottomMarginsSum, setRowTopBottomMarginsSum] = useState(0)
+ const [rowRightLeftMarginsSum, setRowRightLeftMarginsSum] = useState(0)
+
const [drawFields, setDrawFields] = useState(true)
const [drawGridlines, setDrawGridlines] = useState(true)
- const [isCalcReady, setIsCalcReady] = useState(false)
+ const [isColCalcReady, setIsColCalcReady] = useState(false)
+ const [isRowCalcReady, setIsRowCalcReady] = useState(false)
- const calcState = {
+ const colCalcState = {
+ floorVals,
canvasHeight,
canvasWidth,
cols,
colWidth,
- floorVals,
- gridHeight,
gutterWidth,
topMargin,
rightMargin,
@@ -58,23 +76,36 @@ const Panel = ({ selectionAmount, validSelection }) => {
leftMargin,
}
+ const rowCalcState = {
+ floorVals,
+ canvasHeight: canvasWidth,
+ canvasWidth: canvasHeight,
+ cols: rows,
+ colWidth: rowHeight,
+ gutterWidth: gutterHeight,
+ topMargin: rowTopMargin,
+ rightMargin: rowRightMargin,
+ bottomMargin: rowBottomMargin,
+ leftMargin: rowLeftMargin,
+ }
+
/**
- * Reset stats on panel UI.
+ * Reset column stats on panel UI.
*/
- const resetStats = () => {
+ const resetColStats = () => {
setColWidthsSum('N/A')
setGridHeight('N/A')
setGridWidth('N/A')
setGutterWidthsSum('N/A')
setTopBottomMarginsSum(0)
setRightLeftMarginsSum(0)
- setIsCalcReady(false)
+ setIsColCalcReady(false)
}
/**
- * Reset form & stats on panel UI.
+ * Reset column form & stats on panel UI.
*/
- const resetForm = () => {
+ const resetColForm = () => {
setFloorVals(true)
setCols('')
setGutterWidth(0)
@@ -83,20 +114,75 @@ const Panel = ({ selectionAmount, validSelection }) => {
setRightMargin(0)
setBottomMargin(0)
setLeftMargin(0)
+ resetColStats()
+ }
+
+ /**
+ * Reset row stats on panel UI.
+ */
+ const resetRowStats = () => {
+ setRowHeightsSum('N/A')
+ setRowGridHeight('N/A')
+ setRowGridWidth('N/A')
+ setGutterHeightsSum('N/A')
+ setRowTopBottomMarginsSum(0)
+ setRowRightLeftMarginsSum(0)
+ setIsRowCalcReady(false)
+ }
+
+ /**
+ * Reset row form & stats on panel UI.
+ */
+ const resetRowForm = () => {
+ setFloorVals(true)
+ setRows('')
+ setGutterHeight(0)
+ setRowHeight('')
+ setRowTopMargin(0)
+ setRowRightMargin(0)
+ setRowBottomMargin(0)
+ setRowLeftMargin(0)
+ resetRowStats()
+ }
+
+ /**
+ * Reset form & stats on panel UI.
+ */
+ const resetForm = () => {
+ setFloorVals(true)
setDrawFields(true)
setDrawGridlines(true)
- resetStats()
+
+ setCols('')
+ setGutterWidth(0)
+ setColWidth('')
+ setTopMargin(0)
+ setRightMargin(0)
+ setBottomMargin(0)
+ setLeftMargin(0)
+
+ setRows('')
+ setGutterHeight(0)
+ setRowHeight('')
+ setRowTopMargin(0)
+ setRowRightMargin(0)
+ setRowBottomMargin(0)
+ setRowLeftMargin(0)
+
+ resetColStats()
+ resetRowStats()
}
/**
- * Set form to calcState values.
+ * Set form to column calcState values.
+ * @param {Object} calcState State for calculations
*/
const setForm = (calcState) => {
+ setFloorVals(calcState.floorVals)
setCanvasWidth(calcState.canvasWidth)
setCanvasHeight(calcState.canvasHeight)
setCols(calcState.cols)
setColWidth(calcState.colWidth)
- setFloorVals(calcState.floorVals)
setGutterWidth(calcState.gutterWidth)
setTopMargin(calcState.topMargin)
setRightMargin(calcState.rightMargin)
@@ -105,9 +191,29 @@ const Panel = ({ selectionAmount, validSelection }) => {
}
/**
- * Attempt calculations for column width.
+ * Set form to rowCalcState values.
+ * @param {Object} calcState State for calculations
*/
- const attemptColWidthCalc = () => {
+ const setRowForm = (calcState) => {
+ setFloorVals(calcState.floorVals)
+ setCanvasWidth(calcState.canvasHeight)
+ setCanvasHeight(calcState.canvasWidth)
+ setRows(calcState.cols)
+ setRowHeight(calcState.colWidth)
+ setGutterHeight(calcState.gutterWidth)
+ setRowTopMargin(calcState.topMargin)
+ setRowRightMargin(calcState.rightMargin)
+ setRowBottomMargin(calcState.bottomMargin)
+ setRowLeftMargin(calcState.leftMargin)
+ }
+
+ /**
+ * Validates calcState for calcColWidth. If validation is successful, calcColWidth is called.
+ * @param {Object} calcState State for calculations
+ * @param {boolean} [updateLeftMargin=false] Flag to control update for left margin. By default it is set to false, so the right margin will be updated.
+ * @returns {Object|null} If a final successful calculation occurred, it will be returned, otherwise it will return null
+ */
+ const validateAndCalcColWidth = (calcState, updateLeftMargin = false) => {
let finalResult
// Clean inputs to possible values
// May not be enough inputs for calculations though
@@ -118,7 +224,7 @@ const Panel = ({ selectionAmount, validSelection }) => {
if (canCalcColWidth) {
// calcColWidth is possible
- const results = calcColWidth(calcState, [
+ const results = calcColWidth(calcState, updateLeftMargin, [
'rightLeftMargins',
'cols',
'gutterWidth',
@@ -129,39 +235,25 @@ const Panel = ({ selectionAmount, validSelection }) => {
if (Array.isArray(results) && results.length > 0) {
finalResult = results[results.length - 1]
}
- }
-
- if (
- finalResult &&
- Array.isArray(finalResult.errs) &&
- finalResult.errs.length === 0
- ) {
- // Final result was successful
- setColWidthsSum(finalResult.colWidthsSum)
- setGridWidth(finalResult.gridWidth)
- setGutterWidthsSum(finalResult.gutterWidthsSum)
- setRightLeftMarginsSum(finalResult.rightLeftMarginsSum)
- // Calculate grid height
- const calcGridHeightResult = calcGridHeight(calcState)
- setGridHeight(calcState.gridHeight)
- setTopBottomMarginsSum(calcGridHeightResult.topBottomMarginsSum)
- setIsCalcReady(true)
- }
+ if (
+ finalResult &&
+ Array.isArray(finalResult.errs) &&
+ finalResult.errs.length === 0
+ ) {
+ return finalResult
+ }
- if (!canCalcColWidth || !finalResult) {
- // Not possible to run calcColWidth or final result failed
- resetStats()
+ return null
}
-
- // Update form UI to reflect input value changes
- setForm(calcState)
}
/**
- * Attempt calculations for gutter width.
+ * Validates calcState for calcGutterWidth. If validation is successful, calcGutterWidth is called.
+ * @param {Object} calcState State for calculations
+ * @returns {Object|null} If a final successful calculation occurred, it will be returned, otherwise it will return null
*/
- const attemptGutterWidthCalc = () => {
+ const validateAndCalcGutterWidth = (calcState) => {
let finalResult
// Clean inputs to possible values
// May not be enough inputs for calculations though
@@ -172,7 +264,7 @@ const Panel = ({ selectionAmount, validSelection }) => {
if (canCalcGutterWidth) {
// calcGutterWidth is possible
- const results = calcGutterWidth(calcState, [
+ const results = calcGutterWidth(calcState, false, [
'rightLeftMargins',
'cols',
'colWidth',
@@ -190,22 +282,61 @@ const Panel = ({ selectionAmount, validSelection }) => {
Array.isArray(finalResult.errs) &&
finalResult.errs.length === 0
) {
+ return finalResult
+ }
+
+ return null
+ }
+
+ /**
+ * Attempt calculations for column width.
+ * @param {Object} calcState State for calculations
+ * @param {boolean} [updateLeftMargin=false] Flag to control update for left margin. By default it is set to false, so the right margin will be updated.
+ */
+ const attemptColWidthCalc = (calcState, updateLeftMargin = false) => {
+ const result = validateAndCalcColWidth(calcState, updateLeftMargin)
+
+ if (result) {
// Final result was successful
- setColWidthsSum(finalResult.colWidthsSum)
- setGridWidth(finalResult.gridWidth)
- setGutterWidthsSum(finalResult.gutterWidthsSum)
- setRightLeftMarginsSum(finalResult.rightLeftMarginsSum)
+ setColWidthsSum(result.colWidthsSum)
+ setGridWidth(result.gridWidth)
+ setGutterWidthsSum(result.gutterWidthsSum)
+ setRightLeftMarginsSum(result.rightLeftMarginsSum)
// Calculate grid height
const calcGridHeightResult = calcGridHeight(calcState)
- setGridHeight(calcState.gridHeight)
+ setGridHeight(calcGridHeightResult.gridHeight)
setTopBottomMarginsSum(calcGridHeightResult.topBottomMarginsSum)
- setIsCalcReady(true)
+ setIsColCalcReady(true)
+ } else {
+ resetColStats()
}
- if (!canCalcGutterWidth || !finalResult) {
- // Not possible to run calcColWidth or final result failed
- resetStats()
+ // Update form UI to reflect input value changes
+ setForm(calcState)
+ }
+
+ /**
+ * Attempt calculations for gutter width.
+ * @param {Object} calcState State for calculations
+ */
+ const attemptGutterWidthCalc = (calcState) => {
+ const result = validateAndCalcGutterWidth(calcState)
+
+ if (result) {
+ // Final result was successful
+ setColWidthsSum(result.colWidthsSum)
+ setGridWidth(result.gridWidth)
+ setGutterWidthsSum(result.gutterWidthsSum)
+ setRightLeftMarginsSum(result.rightLeftMarginsSum)
+
+ // Calculate grid height
+ const calcGridHeightResult = calcGridHeight(calcState)
+ setGridHeight(calcGridHeightResult.gridHeight)
+ setTopBottomMarginsSum(calcGridHeightResult.topBottomMarginsSum)
+ setIsColCalcReady(true)
+ } else {
+ resetColStats()
}
// Update form UI to reflect input value changes
@@ -213,9 +344,10 @@ const Panel = ({ selectionAmount, validSelection }) => {
}
/**
- * Attempt calculations for top bottom margins.
+ * Attempt calculations for column grid height.
+ * @param {Object} calcState State for calculations
*/
- const attemptGridHeightCalc = () => {
+ const attemptGridHeightCalc = (calcState) => {
// Clean inputs to possible values
// May not be enough inputs for calculations though
validateInputs(calcState)
@@ -237,14 +369,103 @@ const Panel = ({ selectionAmount, validSelection }) => {
topBottomMarginsSum: result.topBottomMarginsSum,
})
) {
- // Previous calculation was valid, so set isCalcReady to true
- setIsCalcReady(true)
+ // Previous calculation was valid, so set isColCalcReady to true
+ setIsColCalcReady(true)
}
}
setForm(calcState)
}
+ /**
+ * Attempt calculations for row height.
+ * @param {Object} calcState State for calculations
+ * @param {boolean} [updateLeftMargin=true] Flag to control update for left margin. By default it is set to true, so the left margin will be updated.
+ */
+ const attemptRowHeightCalc = (calcState, updateLeftMargin = true) => {
+ const result = validateAndCalcColWidth(calcState, updateLeftMargin)
+
+ if (result) {
+ // Final result was successful
+ setRowHeightsSum(result.colWidthsSum)
+ setRowGridWidth(result.gridWidth)
+ setGutterHeightsSum(result.gutterWidthsSum)
+ setRowRightLeftMarginsSum(result.rightLeftMarginsSum)
+
+ // Calculate grid height
+ const calcGridHeightResult = calcGridHeight(calcState)
+ setRowGridHeight(calcGridHeightResult.gridHeight)
+ setRowTopBottomMarginsSum(calcGridHeightResult.topBottomMarginsSum)
+ setIsRowCalcReady(true)
+ } else {
+ resetRowStats()
+ }
+
+ // Update form UI to reflect input value changes
+ setRowForm(calcState)
+ }
+
+ /**
+ * Attempt calculations for gutter height.
+ * @param {Object} calcState State for calculations
+ */
+ const attemptGutterHeightCalc = (calcState) => {
+ const result = validateAndCalcGutterWidth(calcState)
+
+ if (result) {
+ // Final result was successful
+ setRowHeightsSum(result.colWidthsSum)
+ setRowGridWidth(result.gridWidth)
+ setGutterHeightsSum(result.gutterWidthsSum)
+ setRowRightLeftMarginsSum(result.rightLeftMarginsSum)
+
+ // Calculate grid height
+ const calcGridHeightResult = calcGridHeight(calcState)
+ setRowGridHeight(calcGridHeightResult.gridHeight)
+ setRowTopBottomMarginsSum(calcGridHeightResult.topBottomMarginsSum)
+ setIsRowCalcReady(true)
+ } else {
+ resetRowStats()
+ }
+
+ // Update form UI to reflect input value changes
+ setRowForm(calcState)
+ }
+
+ /**
+ * Attempt calculations for row grid height.
+ * @param {Object} calcState State for calculations
+ */
+ const attemptRowGridHeightCalc = (calcState) => {
+ // Clean inputs to possible values
+ // May not be enough inputs for calculations though
+ validateInputs(calcState)
+
+ if (validateColWidthCalc(calcState) || validateGutterWidthCalc(calcState)) {
+ // If calcColWidth or calcGutterWidth is possible, run calcGridHeight
+ const result = calcGridHeight(calcState)
+
+ setRowGridHeight(result.gridHeight)
+ setRowTopBottomMarginsSum(result.topBottomMarginsSum)
+
+ if (
+ validateStats({
+ colWidthsSum: rowHeightsSum,
+ gutterWidthsSum: gutterHeightsSum,
+ gridWidth: rowGridWidth,
+ gridHeight: result.gridHeight,
+ rightLeftMarginsSum: rowRightLeftMarginsSum,
+ topBottomMarginsSum: result.topBottomMarginsSum,
+ })
+ ) {
+ // Previous calculation was valid, so set isRowCalcReady to true
+ setIsRowCalcReady(true)
+ }
+ }
+
+ setRowForm(calcState)
+ }
+
/**
* Handle bound type change.
* @param {*} evt
@@ -285,25 +506,31 @@ const Panel = ({ selectionAmount, validSelection }) => {
if (canvasType === 'auto' && validSelection && validSelection.guid) {
if (boundType === 'draw') {
// Bound type is "draw"
- calcState.canvasWidth = validSelection.globalDrawBounds.width
- calcState.canvasHeight = validSelection.globalDrawBounds.height
+ colCalcState.canvasWidth = validSelection.globalDrawBounds.width
+ colCalcState.canvasHeight = validSelection.globalDrawBounds.height
+ rowCalcState.canvasWidth = validSelection.globalDrawBounds.height
+ rowCalcState.canvasHeight = validSelection.globalDrawBounds.width
} else {
// Assume bound type is "path"
- calcState.canvasWidth = validSelection.globalBounds.width
- calcState.canvasHeight = validSelection.globalBounds.height
+ colCalcState.canvasWidth = validSelection.globalBounds.width
+ colCalcState.canvasHeight = validSelection.globalBounds.height
+ rowCalcState.canvasWidth = validSelection.globalBounds.height
+ rowCalcState.canvasHeight = validSelection.globalBounds.width
}
- if (calcState.canvasWidth !== canvasWidth) {
- setCanvasWidth(calcState.canvasWidth)
+ if (colCalcState.canvasWidth !== canvasWidth) {
+ setCanvasWidth(colCalcState.canvasWidth)
}
- if (calcState.canvasHeight !== canvasHeight) {
- setCanvasHeight(calcState.canvasHeight)
+ if (colCalcState.canvasHeight !== canvasHeight) {
+ setCanvasHeight(colCalcState.canvasHeight)
}
} else {
// Use manual canvas values
- calcState.canvasWidth = canvasWidth
- calcState.canvasHeight = canvasHeight
+ colCalcState.canvasWidth = canvasWidth
+ colCalcState.canvasHeight = canvasHeight
+ rowCalcState.canvasWidth = canvasHeight
+ rowCalcState.canvasHeight = canvasWidth
}
let content
@@ -317,6 +544,16 @@ const Panel = ({ selectionAmount, validSelection }) => {
checked={floorVals}
onChange={(evt) => {
setFloorVals(evt.target.checked)
+ colCalcState.floorVals = evt.target.checked
+ rowCalcState.floorVals = evt.target.checked
+
+ if (createCols) {
+ attemptColWidthCalc(colCalcState)
+ }
+
+ if (createRows) {
+ attemptRowHeightCalc(rowCalcState)
+ }
}}
uxp-quiet="true"
/>
@@ -339,7 +576,6 @@ const Panel = ({ selectionAmount, validSelection }) => {
-
+
+
-