-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Plugin to generate table with customizable header and body cells - Generate table with any header and body cells - Update data using CSV data
- Loading branch information
Showing
53 changed files
with
3,112 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"typescript.tsdk": "node_modules/typescript/lib" | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Generic Table Generator | ||
|
||
Generate table with any header and body cells | ||
|
||
![Generate table screenshot](./docs/generate-table-screenshot.png) | ||
|
||
Update data using CSV data | ||
|
||
![Update data screenshot](./docs/update-table-data-screenshot.png) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,15 @@ | ||
{ | ||
"name": "Table Generator", | ||
"id": "1250025074199810777", | ||
"api": "1.0.0", | ||
"editorType": ["figma"], | ||
"permissions": [], | ||
"main": "dist/code.js", | ||
"ui": "dist/index.html", | ||
"relaunchButtons": [ | ||
{ | ||
"command": "edit-table", | ||
"name": "Edit table" | ||
} | ||
] | ||
} |
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,50 @@ | ||
{ | ||
"name": "figma-table-generator", | ||
"version": "0.0.1", | ||
"description": "Table Generator Figma Plugin", | ||
"main": "dist/code.js", | ||
"scripts": { | ||
"test": "jest", | ||
"tsc": "npm run tsc:main && npm run tsc:ui && npm run tsc:tests", | ||
"tsc:main": "tsc --noEmit -p plugin-src", | ||
"tsc:ui": "tsc --noEmit -p ui-src", | ||
"tsc:tests": "tsc --noEmit -p plugin-src/__tests__", | ||
"tsc:watch": "concurrently -n widget,iframe,tests \"npm run tsc:main -- --watch --preserveWatchOutput\" \"npm run tsc:ui -- --watch --preserveWatchOutput\" \"npm run tsc:tests -- --watch --preserveWatchOutput\"", | ||
"build": "npm run build:ui && npm run build:main -- --minify", | ||
"build:main": "esbuild plugin-src/code.ts --bundle --outfile=dist/code.js --target=es6", | ||
"build:ui": "npx vite build --minify esbuild --emptyOutDir=false", | ||
"build:watch": "concurrently -n widget,iframe \"npm run build:main -- --watch\" \"npm run build:ui -- --watch\"", | ||
"dev": "concurrently -n tsc,build,vite 'npm:tsc:watch' 'npm:build:watch' 'vite'" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/jpmorganchase/Figma-Plugins-and-Widgets.git" | ||
}, | ||
"keywords": [ | ||
"figma-plugin" | ||
], | ||
"author": "JPMC", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/jpmorganchase/Figma-Plugins-and-Widgets/issues" | ||
}, | ||
"homepage": "https://github.com/jpmorganchase/Figma-Plugins-and-Widgets#readme", | ||
"dependencies": { | ||
"@salt-ds/core": "^1.7.1", | ||
"@salt-ds/icons": "^1.3.1", | ||
"@salt-ds/lab": "^1.0.0-alpha.9", | ||
"@salt-ds/theme": "^1.5.0", | ||
"papaparse": "^5.3.2", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0" | ||
}, | ||
"devDependencies": { | ||
"@types/papaparse": "^5.3.7" | ||
}, | ||
"jest": { | ||
"projects": [ | ||
"ui-src/jest.config.js", | ||
"plugin-src/jest.config.js" | ||
] | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
packages/table-generator/plugin-src/__tests__/tsconfig.json
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,17 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es6", | ||
"lib": ["es6"], | ||
"strict": true, | ||
"skipLibCheck": true, | ||
"types": ["jest", "plugin-typings"], | ||
"typeRoots": [ | ||
"../../../../node_modules/@figma", | ||
"../../../../node_modules/@jest", | ||
"../../../../node_modules/@types" | ||
], | ||
"esModuleInterop": true, | ||
"moduleResolution": "node" | ||
}, | ||
"include": ["./**/*.ts"] | ||
} |
61 changes: 61 additions & 0 deletions
61
packages/table-generator/plugin-src/__tests__/utils/clientStorage.spec.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { | ||
readUISetting, | ||
sendUISettingToUI, | ||
setUiSetting, | ||
} from "../../utils/clientStorage"; | ||
|
||
describe("sendUISettingToUI", () => { | ||
test("sends message to UI", () => { | ||
const postMessageSpy = jest.spyOn(figma.ui, "postMessage"); | ||
const testSetting = { | ||
syncCsvHeader: true, | ||
autoPopulateCsvColumns: true, | ||
}; | ||
sendUISettingToUI(testSetting); | ||
expect(postMessageSpy).toBeCalledWith( | ||
expect.objectContaining({ | ||
setting: testSetting, | ||
type: "read-data-table-setting-result", | ||
}) | ||
); | ||
}); | ||
}); | ||
|
||
describe("readUISetting", () => { | ||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
test("default settings to false when first launch", async () => { | ||
jest.spyOn(figma.clientStorage, "keysAsync").mockResolvedValue([]); | ||
expect(await readUISetting()).toEqual({ | ||
syncCsvHeader: false, | ||
autoPopulateCsvColumns: false, | ||
}); | ||
}); | ||
test("reads setting correctly when value set before", async () => { | ||
jest | ||
.spyOn(figma.clientStorage, "keysAsync") | ||
.mockResolvedValue(["SYNC_CSV_HEADER", "AUTO_POPULATE_CSV_COLUMNS"]); | ||
jest.spyOn(figma.clientStorage, "getAsync").mockResolvedValue(true); | ||
expect(await readUISetting()).toEqual({ | ||
autoPopulateCsvColumns: true, | ||
syncCsvHeader: true, | ||
}); | ||
}); | ||
}); | ||
|
||
describe("setUiSetting", () => { | ||
test("set setting correctly", async () => { | ||
const mockStore: any = {}; | ||
jest | ||
.spyOn(figma.clientStorage, "setAsync") | ||
.mockImplementation(async (key, value) => { | ||
mockStore[key] = value; | ||
}); | ||
await setUiSetting({ syncCsvHeader: false, autoPopulateCsvColumns: true }); | ||
expect(mockStore).toEqual({ | ||
SYNC_CSV_HEADER: false, | ||
AUTO_POPULATE_CSV_COLUMNS: true, | ||
}); | ||
}); | ||
}); |
27 changes: 27 additions & 0 deletions
27
packages/table-generator/plugin-src/__tests__/utils/data-interface.spec.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { getPreferredTextInChild } from "../../utils/data-interface"; | ||
|
||
describe("getPreferredTextInChild", () => { | ||
test("returns empty string when no nested TextNode", () => { | ||
const actual = getPreferredTextInChild({ children: [] } as any); | ||
expect(actual).toBe(""); | ||
}); | ||
|
||
test("returns content when there is only one nested TextNode", () => { | ||
const actual = getPreferredTextInChild({ | ||
children: [ | ||
{ type: "TEXT", visible: true, characters: "ABC", name: "Any" }, | ||
], | ||
} as any); | ||
expect(actual).toBe("ABC"); | ||
}); | ||
|
||
test("returns content with preferred name when there are more than one nested TextNode", () => { | ||
const actual = getPreferredTextInChild({ | ||
children: [ | ||
{ type: "TEXT", visible: true, characters: "ABC", name: "Any" }, | ||
{ type: "TEXT", visible: true, characters: "XYZ", name: "Cell" }, | ||
], | ||
} as any); | ||
expect(actual).toBe("XYZ"); | ||
}); | ||
}); |
71 changes: 71 additions & 0 deletions
71
packages/table-generator/plugin-src/__tests__/utils/generate-table.spec.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { updateColumn } from "../../utils/generate-table"; | ||
|
||
describe("updateColumn", () => { | ||
test("not adding or removing when config rows stays the same", () => { | ||
const mockRemove = jest.fn(); | ||
const mockAppendChild = jest.fn(); | ||
const mockColumn = { | ||
type: "FRAME", | ||
appendChild: mockAppendChild, | ||
children: [ | ||
{ type: "INSTANCE", remove: mockRemove }, // header | ||
{ type: "INSTANCE", remove: mockRemove }, // cell 1 | ||
], | ||
} as any; | ||
|
||
const mockComponent = { | ||
type: "COMPONENT", | ||
createInstance: () => ({ type: "INSTANCE", layoutAlign: "INHERIT" }), | ||
} as any; | ||
|
||
updateColumn(mockColumn, 1, mockComponent); | ||
expect(mockAppendChild).not.toBeCalled(); | ||
expect(mockRemove).not.toBeCalled(); | ||
}); | ||
|
||
test("removes excess cells when new config has less rows", () => { | ||
const mockRemove = jest.fn(); | ||
const mockAppendChild = jest.fn(); | ||
const mockColumn = { | ||
type: "FRAME", | ||
appendChild: mockAppendChild, | ||
children: [ | ||
{ type: "INSTANCE", remove: mockRemove }, // header | ||
{ type: "INSTANCE", remove: mockRemove }, // cell 1 | ||
{ type: "INSTANCE", remove: mockRemove }, // cell 2 | ||
{ type: "INSTANCE", remove: mockRemove }, // cell 3 | ||
], | ||
} as any; | ||
|
||
const mockComponent = { | ||
type: "COMPONENT", | ||
createInstance: () => ({ type: "INSTANCE", layoutAlign: "INHERIT" }), | ||
} as any; | ||
|
||
updateColumn(mockColumn, 1, mockComponent); | ||
expect(mockAppendChild).not.toBeCalled(); | ||
expect(mockRemove).toBeCalledTimes(2); | ||
}); | ||
|
||
test("adds missing cells when new config has more rows", () => { | ||
const mockRemove = jest.fn(); | ||
const mockAppendChild = jest.fn(); | ||
const mockColumn = { | ||
type: "FRAME", | ||
appendChild: mockAppendChild, | ||
children: [ | ||
{ type: "INSTANCE", remove: mockRemove }, // header | ||
{ type: "INSTANCE", remove: mockRemove }, // cell 1 | ||
], | ||
} as any; | ||
|
||
const mockComponent = { | ||
type: "COMPONENT", | ||
createInstance: () => ({ type: "INSTANCE", layoutAlign: "INHERIT" }), | ||
} as any; | ||
|
||
updateColumn(mockColumn, 3, mockComponent); | ||
expect(mockAppendChild).toBeCalledTimes(2); | ||
expect(mockRemove).not.toBeCalled(); | ||
}); | ||
}); |
10 changes: 10 additions & 0 deletions
10
packages/table-generator/plugin-src/__tests__/utils/relaunch.spec.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { setRelaunchButton } from "../../utils/relaunch"; | ||
|
||
describe("setRelaunchButton", () => { | ||
test("sets relaunch data with empty string", () => { | ||
const mockSet = jest.fn(); | ||
setRelaunchButton({ setRelaunchData: mockSet } as any); | ||
|
||
expect(mockSet).toBeCalledWith({ "edit-table": "" }); | ||
}); | ||
}); |
Oops, something went wrong.