├── .gitattributes ├── packages ├── anvil-embed-frame │ ├── .babelrc.js │ ├── .npmignore │ ├── test │ │ ├── mocha.js │ │ ├── .eslintrc.js │ │ └── src │ │ │ └── index.test.js │ ├── tsconfig.json │ ├── webpack.config.js │ ├── package.json │ ├── types │ │ └── index.d.ts │ ├── src │ │ └── index.js │ ├── CHANGELOG.md │ └── README.md ├── react-signature-frame │ ├── .babelrc.js │ ├── .npmignore │ ├── test │ │ ├── mocha.js │ │ ├── .eslintrc.js │ │ └── src │ │ │ ├── helpers.test.js │ │ │ └── index.test.js │ ├── types │ │ ├── helpers.d.ts.map │ │ ├── index.d.ts.map │ │ ├── helpers.d.ts │ │ └── index.d.ts │ ├── tsconfig.json │ ├── webpack.config.js │ ├── src │ │ ├── helpers.js │ │ └── index.js │ ├── package.json │ ├── README.md │ └── CHANGELOG.md └── react-signature-modal │ ├── .npmignore │ ├── types │ ├── react-signature-modal │ │ └── src │ │ │ ├── components │ │ │ ├── IconClose.d.ts.map │ │ │ └── IconClose.d.ts │ │ │ ├── index.d.ts.map │ │ │ └── index.d.ts │ └── react-signature-frame │ │ └── src │ │ ├── helpers.d.ts.map │ │ ├── index.d.ts.map │ │ ├── helpers.d.ts │ │ └── index.d.ts │ ├── src │ ├── components │ │ └── IconClose.js │ ├── styles.css │ └── index.js │ ├── tsconfig.json │ ├── webpack.config.js │ ├── package.json │ ├── README.md │ └── CHANGELOG.md ├── .gitignore ├── .prettierrc.js ├── .babelrc.js ├── test ├── bddSetup.js ├── mocha.js ├── environment.js └── domSetup.js ├── lerna.json ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── pull_request_template.md └── workflows │ └── lint.yml ├── changelog-template.hbs ├── LICENSE.md ├── package.json └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../.babelrc.js') 2 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | webpack.config.js 3 | *.tgz 4 | src 5 | -------------------------------------------------------------------------------- /packages/react-signature-frame/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../.babelrc.js') 2 | -------------------------------------------------------------------------------- /packages/react-signature-frame/.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | webpack.config.js 3 | *.tgz 4 | src 5 | -------------------------------------------------------------------------------- /packages/react-signature-modal/.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | webpack.config.js 3 | *.tgz 4 | src 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | node_modules 3 | *.log 4 | **/.DS_Store 5 | .env 6 | app.yaml 7 | lib 8 | dist 9 | *.tgz 10 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: "es5", 3 | tabWidth: 2, 4 | semi: false, 5 | singleQuote: true, 6 | }; 7 | -------------------------------------------------------------------------------- /.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "presets": [ 3 | ["@babel/preset-env", { "exclude": ["transform-regenerator"] }], 4 | "@babel/preset-react", 5 | ], 6 | } 7 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/test/mocha.js: -------------------------------------------------------------------------------- 1 | const parentMochaConfig = require('../../../test/mocha') 2 | 3 | module.exports = { 4 | ...parentMochaConfig, 5 | spec: './test/src/**/*.test.js', 6 | } 7 | -------------------------------------------------------------------------------- /packages/react-signature-frame/test/mocha.js: -------------------------------------------------------------------------------- 1 | const parentMochaConfig = require('../../../test/mocha') 2 | 3 | module.exports = { 4 | ...parentMochaConfig, 5 | spec: './test/src/**/*.test.js', 6 | } 7 | -------------------------------------------------------------------------------- /test/bddSetup.js: -------------------------------------------------------------------------------- 1 | const { get } = require('bdd-lazy-var/getter') 2 | 3 | // In order to get around eslint complaining for now: 4 | // https://github.com/stalniy/bdd-lazy-var/issues/56#issuecomment-639248242 5 | global.$ = get 6 | -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-modal/src/components/IconClose.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"IconClose.d.ts","sourceRoot":"","sources":["../../../../src/components/IconClose.js"],"names":[],"mappings":";AAGA;;;;gBAIC"} -------------------------------------------------------------------------------- /packages/react-signature-frame/types/helpers.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH;IAH6B,gBAAgB,GAAlC,OAAO;QA8BjB;AAED;;;;GAIG;AACH,8CAHW,QAAQ,OAWlB"} -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "command": { 6 | "publish" : { 7 | "registry": "https://registry.npmjs.org" 8 | } 9 | }, 10 | "version": "independent", 11 | "npmClient": "yarn", 12 | } 13 | -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-frame/src/helpers.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../react-signature-frame/src/helpers.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH;IAH6B,gBAAgB,GAAlC,OAAO;QA8BjB;AAED;;;;GAIG;AACH,8CAHW,QAAQ,OAWlB"} -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-modal/src/index.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.js"],"names":[],"mappings":";;;YAWU,OAAO;;;;;;qBAMP,SAAO,OAAO;;mBAEd,OAAO;;;;AAXjB;;;;;;;;;;;;;;GAcG;AAEH;;GAEG;AACH;IACE,wBAGC;IAED,sBAoDC;CACF"} -------------------------------------------------------------------------------- /packages/react-signature-frame/types/index.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";;;;;yBAYU,OAAO;;YAEP,MAAM,iBAAiB;;;;;;;;AAPjC;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH;IACE,wBAGC;IADC,gCAAkC;IAGpC,0BAIC;IAED,6BAEC;IAED;;;;OAIG;IACH;;;eAoBC;IAED,sBA4BC;CACF;;;QAGW,0BAAQ;QACD,iCAAQ;QAChB,yBAAQ"} -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-frame/src/index.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../react-signature-frame/src/index.js"],"names":[],"mappings":";;;;;yBAYU,OAAO;;YAEP,MAAM,iBAAiB;;;;;;;;AAPjC;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH;IACE,wBAGC;IADC,gCAAkC;IAGpC,0BAIC;IAED,6BAEC;IAED;;;;OAIG;IACH;;;eAoBC;IAED,sBA4BC;CACF;;;QAGW,0BAAQ;QACD,iCAAQ;QAChB,yBAAQ"} -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: [ 7 | 'plugin:react/recommended', 8 | 'nicenice', 9 | ], 10 | parserOptions: { 11 | ecmaFeatures: { 12 | jsx: true, 13 | }, 14 | ecmaVersion: 12, 15 | sourceType: 'module', 16 | "babelOptions": { 17 | "presets": ["@babel/preset-react"] 18 | }, 19 | }, 20 | rules: { 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /packages/react-signature-frame/types/helpers.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {String} searchStr 3 | * @param {Object} [options] 4 | * @param {boolean} [options.forceManualParse] 5 | * @returns {Object} 6 | */ 7 | export function parseURLParams(searchStr: string, options?: { 8 | forceManualParse?: boolean; 9 | }): any; 10 | /** 11 | * @param {Object} object 12 | * @param {String[]} keysToOmit 13 | * @returns {*} 14 | */ 15 | export function omit(object: any, keysToOmit: string[]): any; 16 | //# sourceMappingURL=helpers.d.ts.map -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-frame/src/helpers.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {String} searchStr 3 | * @param {Object} [options] 4 | * @param {boolean} [options.forceManualParse] 5 | * @returns {Object} 6 | */ 7 | export function parseURLParams(searchStr: string, options?: { 8 | forceManualParse?: boolean; 9 | }): any; 10 | /** 11 | * @param {Object} object 12 | * @param {String[]} keysToOmit 13 | * @returns {*} 14 | */ 15 | export function omit(object: any, keysToOmit: string[]): any; 16 | //# sourceMappingURL=helpers.d.ts.map -------------------------------------------------------------------------------- /test/mocha.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = { 4 | diff: true, 5 | delay: false, 6 | extension: ['js'], 7 | package: './package.json', 8 | slow: 75, 9 | timeout: 2000, 10 | spec: './test/src/**/*.test.js', 11 | require: [ 12 | '../../test/domSetup.js', 13 | // https://mochajs.org/#-require-module-r-module 14 | '@babel/register', 15 | '../../test/environment.js', 16 | ], 17 | file: '../../test/bddSetup.js', 18 | ui: 'bdd-lazy-var/getter', 19 | 'watch-files': [ 20 | './test/**/*.test.js', 21 | './src/**/*.js', 22 | ], 23 | 'watch-ignore': [], 24 | exit: true, 25 | } 26 | -------------------------------------------------------------------------------- /test/environment.js: -------------------------------------------------------------------------------- 1 | const sinon = require('sinon') 2 | const chai = require('chai') 3 | const sinonChai = require('sinon-chai') 4 | const chaiAsPromised = require('chai-as-promised') 5 | const chaiEnzyme = require('chai-enzyme') 6 | const enzyme = require('enzyme') 7 | const Adapter = require('@wojtekmaj/enzyme-adapter-react-17') 8 | 9 | enzyme.configure({ adapter: new Adapter() }) 10 | 11 | chai.use(sinonChai) 12 | chai.use(chaiAsPromised) 13 | chai.use(chaiEnzyme()) 14 | 15 | global.chai = chai 16 | global.sinon = sinon 17 | global.expect = chai.expect 18 | global.should = chai.should() 19 | global.mount = enzyme.mount 20 | global.render = enzyme.render 21 | global.shallow = enzyme.shallow 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /packages/react-signature-modal/src/components/IconClose.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | const IconClose = ({ width, height, ...others }) => ( 5 | 6 | 7 | 8 | ) 9 | 10 | IconClose.defaultProps = { 11 | width: 30, 12 | height: 30, 13 | } 14 | 15 | IconClose.propTypes = { 16 | width: PropTypes.number, 17 | height: PropTypes.number, 18 | } 19 | 20 | export default IconClose 21 | -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-modal/src/components/IconClose.d.ts: -------------------------------------------------------------------------------- 1 | export default IconClose; 2 | declare function IconClose({ width, height, ...others }: { 3 | [x: string]: any; 4 | width: any; 5 | height: any; 6 | }): JSX.Element; 7 | declare namespace IconClose { 8 | namespace defaultProps { 9 | const width: number; 10 | const height: number; 11 | } 12 | namespace propTypes { 13 | const width_1: PropTypes.Requireable; 14 | export { width_1 as width }; 15 | const height_1: PropTypes.Requireable; 16 | export { height_1 as height }; 17 | } 18 | } 19 | import PropTypes from "prop-types"; 20 | //# sourceMappingURL=IconClose.d.ts.map -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description of the change 2 | 3 | Description here -- be descriptive enough for another dev to have the full 4 | context of the problem and the solution. 5 | 6 | ## Type of change 7 | 8 | - [ ] Bug fix (non-breaking change that fixes an issue) 9 | - [ ] New feature (non-breaking change that adds functionality) 10 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 11 | 12 | ## Related issues 13 | 14 | Fixes 15 | 16 | ## Dev Checklist 17 | 18 | - [ ] The code changed/added as part of this pull request has been covered with tests 19 | - [ ] All tests related to the changed code pass in development 20 | - [ ] No previous tests unrelated to the changed code fail in development 21 | -------------------------------------------------------------------------------- /packages/react-signature-modal/src/styles.css: -------------------------------------------------------------------------------- 1 | #anvil-signature-modal { 2 | width: 80vw; 3 | height: 85vh; 4 | max-width: 1200px; 5 | border-style: none; 6 | } 7 | 8 | @media only screen and (max-width: 900px) { 9 | #anvil-signature-modal { 10 | width: 90vw; 11 | height: 90vh; 12 | } 13 | } 14 | 15 | @media only screen and (max-width: 500px) { 16 | #anvil-signature-modal { 17 | width: calc(100vw - 10px); 18 | height: 90vh; 19 | } 20 | } 21 | 22 | .anvil-modal { 23 | position: absolute; 24 | top: 50%; 25 | left: 50%; 26 | right: auto; 27 | bottom: auto; 28 | transform: translate(-50%, -50%); 29 | background: #fbfbfb; 30 | border: none; 31 | outline: none; 32 | padding: 0px; 33 | } 34 | 35 | .anvil-overlay { 36 | position: fixed; 37 | top: 0; 38 | left: 0; 39 | right: 0; 40 | bottom: 0; 41 | background: rgba(0, 0, 0, 0.3); 42 | } 43 | 44 | .anvil-delete-icon { 45 | cursor: pointer; 46 | position: fixed; 47 | top: 10px; 48 | right: 10px; 49 | } 50 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '../../../.eslintrc.js', 3 | env: { 4 | mocha: true, 5 | }, 6 | plugins: ['mocha'], 7 | rules: { 8 | 'mocha/no-exclusive-tests': 'error', 9 | }, 10 | globals: { 11 | expect: 'readonly', 12 | should: 'readonly', 13 | sinon: 'readonly', 14 | mount: 'readonly', 15 | render: 'readonly', 16 | shallow: 'readonly', 17 | //* ************************************************ 18 | // bdd-lazy-var 19 | // 20 | // In order to get around eslint complaining for now: 21 | // https://github.com/stalniy/bdd-lazy-var/issues/56#issuecomment-639248242 22 | $: 'readonly', 23 | its: 'readonly', 24 | def: 'readonly', 25 | subject: 'readonly', 26 | get: 'readonly', 27 | sharedExamplesFor: 'readonly', 28 | includeExamplesFor: 'readonly', 29 | itBehavesLike: 'readonly', 30 | is: 'readonly', 31 | // 32 | //* ************************************************ 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /packages/react-signature-frame/test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '../../../.eslintrc.js', 3 | env: { 4 | mocha: true, 5 | }, 6 | plugins: ['mocha'], 7 | rules: { 8 | 'mocha/no-exclusive-tests': 'error', 9 | }, 10 | globals: { 11 | expect: 'readonly', 12 | should: 'readonly', 13 | sinon: 'readonly', 14 | mount: 'readonly', 15 | render: 'readonly', 16 | shallow: 'readonly', 17 | //* ************************************************ 18 | // bdd-lazy-var 19 | // 20 | // In order to get around eslint complaining for now: 21 | // https://github.com/stalniy/bdd-lazy-var/issues/56#issuecomment-639248242 22 | $: 'readonly', 23 | its: 'readonly', 24 | def: 'readonly', 25 | subject: 'readonly', 26 | get: 'readonly', 27 | sharedExamplesFor: 'readonly', 28 | includeExamplesFor: 'readonly', 29 | itBehavesLike: 'readonly', 30 | is: 'readonly', 31 | // 32 | //* ************************************************ 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /changelog-template.hbs: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | {{#each releases}} 6 | {{#if href}} 7 | ## [{{title}}]({{href}}){{#if tag}} - {{isoDate}}{{/if}} 8 | {{else}} 9 | ## {{title}}{{#if tag}} - {{isoDate}}{{/if}} 10 | {{/if}} 11 | 12 | {{#if summary}} 13 | {{summary}} 14 | {{/if}} 15 | 16 | {{#if merges}} 17 | ### Merged 18 | 19 | {{#each merges}} 20 | - {{#if commit.breaking}}**Breaking change:** {{/if}}{{message}} {{#if href}}[`#{{id}}`]({{href}}){{/if}} 21 | {{/each}} 22 | {{/if}} 23 | 24 | {{#if fixes}} 25 | ### Fixed 26 | 27 | {{#each fixes}} 28 | - {{#if commit.breaking}}**Breaking change:** {{/if}}{{commit.subject}}{{#each fixes}} {{#if href}}[`#{{id}}`]({{href}}){{/if}}{{/each}} 29 | {{/each}} 30 | {{/if}} 31 | 32 | {{#commit-list commits heading='### Commits'}} 33 | - {{#if breaking}}**Breaking change:** {{/if}}{{subject}} {{#if href}}[`{{shorthash}}`]({{href}}){{/if}} 34 | {{/commit-list}} 35 | 36 | {{/each}} 37 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // Change this to match your project 3 | "include": [ 4 | "src/**/*" 5 | ], 6 | "compilerOptions": { 7 | "target": "es2021", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "lib": ["es2017", "dom"], 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "checkJs": true, 14 | "resolveJsonModule": true, 15 | // Tells TypeScript to read JS files, as 16 | // normally they are ignored as source files 17 | "allowJs": true, 18 | // Generate d.ts files 19 | "declaration": true, 20 | // This compiler run should 21 | // only output d.ts files 22 | "emitDeclarationOnly": true, 23 | // Types should go into this directory. 24 | // Removing this would place the .d.ts files 25 | // next to the .js files 26 | "outDir": "dist", 27 | // go to js file when using IDE functions like 28 | // "Go to Definition" in VSCode 29 | "declarationMap": true, 30 | "esModuleInterop": true, 31 | // Handle jsx 32 | "jsx": "preserve" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/react-signature-frame/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // Change this to match your project 3 | "include": [ 4 | "src/**/*" 5 | ], 6 | "compilerOptions": { 7 | "target": "es2021", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "lib": ["es2017", "dom"], 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "checkJs": true, 14 | "resolveJsonModule": true, 15 | // Tells TypeScript to read JS files, as 16 | // normally they are ignored as source files 17 | "allowJs": true, 18 | // Generate d.ts files 19 | "declaration": true, 20 | // This compiler run should 21 | // only output d.ts files 22 | "emitDeclarationOnly": true, 23 | // Types should go into this directory. 24 | // Removing this would place the .d.ts files 25 | // next to the .js files 26 | "outDir": "dist", 27 | // go to js file when using IDE functions like 28 | // "Go to Definition" in VSCode 29 | "declarationMap": true, 30 | "esModuleInterop": true, 31 | // Handle jsx 32 | "jsx": "preserve" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/react-signature-modal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // Change this to match your project 3 | "include": [ 4 | "src/**/*" 5 | ], 6 | "compilerOptions": { 7 | "target": "es2021", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "lib": ["es2017", "dom"], 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "checkJs": true, 14 | "resolveJsonModule": true, 15 | // Tells TypeScript to read JS files, as 16 | // normally they are ignored as source files 17 | "allowJs": true, 18 | // Generate d.ts files 19 | "declaration": true, 20 | // This compiler run should 21 | // only output d.ts files 22 | "emitDeclarationOnly": true, 23 | // Types should go into this directory. 24 | // Removing this would place the .d.ts files 25 | // next to the .js files 26 | "outDir": "dist", 27 | // go to js file when using IDE functions like 28 | // "Go to Definition" in VSCode 29 | "declarationMap": true, 30 | "esModuleInterop": true, 31 | // Handle jsx 32 | "jsx": "preserve" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Anvil Foundry, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /test/domSetup.js: -------------------------------------------------------------------------------- 1 | const { JSDOM } = require('jsdom') 2 | 3 | const jsdom = new JSDOM( 4 | '', 5 | // Without this `url` option, there will be the error: 6 | // "SecurityError: localStorage is not available for opaque origins" 7 | // This specifically comes from using the `rewire` package. 8 | // https://github.com/jsdom/jsdom/issues/2383#issuecomment-442199291 9 | { url: 'http://localhost' }, 10 | ) 11 | const { window } = jsdom 12 | 13 | function copyProps (src, target) { 14 | Object.defineProperties(target, { 15 | ...Object.getOwnPropertyDescriptors(src), 16 | ...Object.getOwnPropertyDescriptors(target), 17 | }) 18 | } 19 | 20 | global.window = window 21 | global.document = window.document 22 | global.navigator = { 23 | userAgent: 'node.js', 24 | platform: 'linux', // mac|windows|linux 25 | appName: 'A cool Anvil browser', // Arbitrary but must be defined 26 | } 27 | global.requestAnimationFrame = function (callback) { 28 | return setTimeout(callback, 0) 29 | } 30 | global.cancelAnimationFrame = function (id) { 31 | clearTimeout(id) 32 | } 33 | copyProps(window, global) 34 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | entry: path.resolve(__dirname, 'src', 'index.js'), 5 | output: { 6 | path: path.resolve(__dirname, 'dist'), 7 | filename: 'index.js', 8 | libraryTarget: 'commonjs2', 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.(js|jsx)$/, 14 | exclude: /(node_modules)/, 15 | use: { 16 | loader: 'babel-loader', 17 | options: { 18 | presets: ['@babel/preset-env', '@babel/preset-react'], 19 | plugins: ['@babel/plugin-proposal-class-properties'], 20 | }, 21 | }, 22 | }, 23 | ], 24 | }, 25 | resolve: { 26 | modules: [ 27 | path.join(__dirname, 'src'), 28 | __dirname, 29 | 'node_modules', 30 | ], 31 | extensions: ['*', '.js', '.jsx'], 32 | }, 33 | externals: { 34 | // Don't bundle react or react-dom 35 | react: { 36 | commonjs: 'react', 37 | commonjs2: 'react', 38 | amd: 'React', 39 | root: 'React', 40 | }, 41 | 'react-dom': { 42 | commonjs: 'react-dom', 43 | commonjs2: 'react-dom', 44 | amd: 'ReactDOM', 45 | root: 'ReactDOM', 46 | }, 47 | }, 48 | } 49 | -------------------------------------------------------------------------------- /packages/react-signature-frame/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | entry: path.resolve(__dirname, 'src', 'index.js'), 5 | output: { 6 | path: path.resolve(__dirname, 'dist'), 7 | filename: 'index.js', 8 | libraryTarget: 'commonjs2', 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.(js|jsx)$/, 14 | exclude: /(node_modules)/, 15 | use: { 16 | loader: 'babel-loader', 17 | options: { 18 | presets: ['@babel/preset-env', '@babel/preset-react'], 19 | plugins: ['@babel/plugin-proposal-class-properties'], 20 | }, 21 | }, 22 | }, 23 | { 24 | test: /\.css$/, 25 | exclude: /node_modules/, 26 | use: ['style-loader', 'css-loader'], 27 | }, 28 | ], 29 | }, 30 | resolve: { 31 | modules: [ 32 | path.join(__dirname, 'src'), 33 | __dirname, 34 | 'node_modules', 35 | ], 36 | extensions: ['*', '.js', '.jsx'], 37 | }, 38 | externals: { 39 | // Don't bundle react or react-dom 40 | react: { 41 | commonjs: 'react', 42 | commonjs2: 'react', 43 | amd: 'React', 44 | root: 'React', 45 | }, 46 | 'react-dom': { 47 | commonjs: 'react-dom', 48 | commonjs2: 'react-dom', 49 | amd: 'ReactDOM', 50 | root: 'ReactDOM', 51 | }, 52 | }, 53 | } 54 | -------------------------------------------------------------------------------- /packages/react-signature-modal/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | 4 | module.exports = { 5 | entry: path.resolve(__dirname, 'src', 'index.js'), 6 | output: { 7 | path: path.resolve(__dirname, 'dist'), 8 | filename: 'index.js', 9 | libraryTarget: 'commonjs2', 10 | }, 11 | plugins: [ 12 | new MiniCssExtractPlugin({ 13 | filename: 'styles.css', 14 | }), 15 | ], 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.(js|jsx)$/, 20 | exclude: /(node_modules)/, 21 | use: { 22 | loader: 'babel-loader', 23 | options: { 24 | presets: ['@babel/preset-env', '@babel/preset-react'], 25 | plugins: ['@babel/plugin-proposal-class-properties'], 26 | }, 27 | }, 28 | }, 29 | { 30 | test: /\.css$/, 31 | exclude: /node_modules/, 32 | use: [MiniCssExtractPlugin.loader, 'css-loader'], 33 | }, 34 | ], 35 | }, 36 | resolve: { 37 | modules: [ 38 | path.join(__dirname, 'src'), 39 | __dirname, 40 | 'node_modules', 41 | ], 42 | extensions: ['*', '.js', '.jsx'], 43 | }, 44 | externals: { 45 | // Don't bundle react or react-dom 46 | react: { 47 | commonjs: 'react', 48 | commonjs2: 'react', 49 | amd: 'React', 50 | root: 'React', 51 | }, 52 | 'react-dom': { 53 | commonjs: 'react-dom', 54 | commonjs2: 'react-dom', 55 | amd: 'ReactDOM', 56 | root: 'ReactDOM', 57 | }, 58 | }, 59 | } 60 | -------------------------------------------------------------------------------- /packages/react-signature-frame/src/helpers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {String} searchStr 3 | * @param {Object} [options] 4 | * @param {boolean} [options.forceManualParse] 5 | * @returns {Object} 6 | */ 7 | export function parseURLParams (searchStr, options = {}) { 8 | searchStr = searchStr || '' 9 | if (typeof searchStr !== 'string') return {} 10 | searchStr = searchStr.trim() 11 | 12 | let params = {} 13 | if (typeof URLSearchParams !== 'undefined' && !options?.forceManualParse) { 14 | const searchObj = new URLSearchParams(searchStr) 15 | /* @ts-ignore: TS2339 */ 16 | for (const paramEntry of searchObj.entries()) { 17 | const [key, value] = paramEntry 18 | params[key] = value 19 | } 20 | } else if (searchStr) { 21 | // IE does not support URLSearchParams, so this 22 | const parsableString = 23 | searchStr.indexOf('=') > -1 ? searchStr : searchStr + '=' 24 | try { 25 | params = JSON.parse( 26 | '{"' + 27 | parsableString 28 | .replace(/"/g, '\\"') 29 | .replace(/&/g, '","') 30 | .replace(/=/g, '":"') + 31 | '"}' 32 | ) 33 | } catch (e) { 34 | console.warn(e) 35 | console.warn('Could not parse params from', parsableString) 36 | } 37 | for (const key in params) { 38 | params[key] = decodeURIComponent(params[key].replace(/\+/g, '%20')) 39 | } 40 | } 41 | return params 42 | } 43 | 44 | /** 45 | * @param {Object} object 46 | * @param {String[]} keysToOmit 47 | * @returns {*} 48 | */ 49 | export function omit (object, keysToOmit) { 50 | const ret = { ...object } 51 | if (keysToOmit && keysToOmit.length) { 52 | for (const path of keysToOmit) { 53 | delete ret[path] 54 | } 55 | } 56 | return ret 57 | } 58 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Linting 2 | on: 3 | push: 4 | branches: [ main ] 5 | pull_request: 6 | branches: [ main ] 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | env: 11 | NODE_ENV: test 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: 20 17 | - uses: actions/cache@v4 18 | id: yarn-cache 19 | with: 20 | path: node_modules 21 | key: v1-${{ hashFiles('**/yarn.lock') }} 22 | restore-keys: | 23 | v1- 24 | - name: Install dependencies with yarn 25 | if: steps.yarn-cache.outputs.cache-hit != 'true' 26 | run: yarn install 27 | lint: 28 | runs-on: ubuntu-latest 29 | needs: build 30 | steps: 31 | - uses: actions/checkout@v4 32 | - uses: actions/setup-node@v1 33 | with: 34 | node-version: 20 35 | - uses: actions/cache@v4 36 | id: yarn-cache 37 | with: 38 | path: node_modules 39 | key: v1-${{ hashFiles('**/yarn.lock') }} 40 | restore-keys: | 41 | v1- 42 | - name: Run Linter 43 | if: steps.yarn-cache.outputs.cache-hit == 'true' 44 | run: yarn lint 45 | test: 46 | runs-on: ubuntu-latest 47 | needs: build 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: actions/setup-node@v1 51 | with: 52 | node-version: 20 53 | - uses: actions/cache@v4 54 | id: yarn-cache 55 | with: 56 | path: node_modules 57 | key: v1-${{ hashFiles('**/yarn.lock') }} 58 | restore-keys: | 59 | v1- 60 | - name: Run Tests 61 | if: steps.yarn-cache.outputs.cache-hit == 'true' 62 | run: yarn test 63 | -------------------------------------------------------------------------------- /packages/react-signature-frame/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@anvilco/react-signature-frame", 3 | "version": "1.9.2", 4 | "description": "The AnvilSignatureFrame React component for embedded Etch signatures", 5 | "author": "Anvil Foundry Inc.", 6 | "license": "MIT", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "build": "tsc && webpack --mode production", 11 | "build:changelog": "yarn auto-changelog", 12 | "clean": "rimraf dist", 13 | "clean:build": "yarn clean && yarn build", 14 | "prepack": "yarn clean:build", 15 | "pack": "yarn pack", 16 | "version": "yarn build:changelog && git add CHANGELOG.md", 17 | "test": "yarn mocha --config ./test/mocha.js" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/anvilco/react-ui.git" 22 | }, 23 | "homepage": "https://github.com/anvilco/react-ui#readme", 24 | "bugs": { 25 | "url": "https://github.com/anvilco/react-ui/issues", 26 | "email": "support@useanvil.com" 27 | }, 28 | "publishConfig": { 29 | "registry": "https://registry.npmjs.org", 30 | "@anvilco:registry": "https://registry.npmjs.org", 31 | "access": "public" 32 | }, 33 | "keywords": [ 34 | "signature", 35 | "documents", 36 | "pdf", 37 | "iframe" 38 | ], 39 | "devDependencies": { 40 | "@types/react": "^18.0.5", 41 | "prop-types": "^15.8.1", 42 | "react": "^16.0.0", 43 | "react-dom": "^16.0.0", 44 | "rimraf": "6.0.1", 45 | "typescript": "^4.6.3" 46 | }, 47 | "peerDependencies": { 48 | "prop-types": "^15.6.0", 49 | "react": ">=16", 50 | "react-dom": ">=16" 51 | }, 52 | "auto-changelog": { 53 | "output": "CHANGELOG.md", 54 | "template": "../../changelog-template.hbs", 55 | "unreleased": false, 56 | "commitLimit": true, 57 | "tagPrefix": "@anvilco/react-signature-frame@", 58 | "breakingPattern": "BREAKING CHANGE:" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@anvilco/anvil-embed-frame", 3 | "version": "2.2.2", 4 | "description": "The AnvilEmbedFrame React component for embedded Etch signatures and Workflows.", 5 | "author": "Anvil Foundry Inc.", 6 | "license": "MIT", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "build": "tsc && webpack --mode production", 11 | "build:changelog": "yarn auto-changelog", 12 | "clean": "rimraf dist", 13 | "clean:build": "yarn clean && yarn build", 14 | "prepack": "yarn clean:build", 15 | "pack": "yarn pack", 16 | "version": "yarn build:changelog && git add CHANGELOG.md", 17 | "test": "yarn mocha --config ./test/mocha.js", 18 | "watch": "nodemon --watch src --exec 'yarn build'" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/anvilco/react-ui.git" 23 | }, 24 | "homepage": "https://github.com/anvilco/react-ui#readme", 25 | "bugs": { 26 | "url": "https://github.com/anvilco/react-ui/issues", 27 | "email": "support@useanvil.com" 28 | }, 29 | "publishConfig": { 30 | "registry": "https://registry.npmjs.org", 31 | "@anvilco:registry": "https://registry.npmjs.org", 32 | "access": "public" 33 | }, 34 | "keywords": [ 35 | "signature", 36 | "documents", 37 | "pdf", 38 | "iframe", 39 | "workflow" 40 | ], 41 | "devDependencies": { 42 | "@types/react": "^18.2.22", 43 | "prop-types": "^15.8.1", 44 | "react": "^18.2.0", 45 | "react-dom": "^18.2.0", 46 | "rimraf": "6.0.1", 47 | "typescript": "^5.2.2" 48 | }, 49 | "peerDependencies": { 50 | "prop-types": "^15.6.0", 51 | "react": ">=16", 52 | "react-dom": ">=16" 53 | }, 54 | "auto-changelog": { 55 | "output": "CHANGELOG.md", 56 | "template": "../../changelog-template.hbs", 57 | "unreleased": false, 58 | "commitLimit": true, 59 | "tagPrefix": "@anvilco/anvil-embed-frame@", 60 | "breakingPattern": "BREAKING CHANGE:" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/types/index.d.ts: -------------------------------------------------------------------------------- 1 | export default AnvilEmbedFrame; 2 | export type Props = { 3 | iframeURL: string; 4 | onEvent: Function; 5 | anvilURL: string; 6 | enableDefaultStyles: boolean; 7 | scroll: string; 8 | style: object; 9 | className: string; 10 | }; 11 | /** 12 | * @typedef Props 13 | * @prop {String} iframeURL 14 | * @prop {Function} onEvent 15 | * @prop {String} anvilURL 16 | * @prop {boolean} enableDefaultStyles 17 | * @prop {String} scroll 18 | * @prop {object} style 19 | * @prop {string} className 20 | */ 21 | /** 22 | * @extends React.Component 23 | */ 24 | declare class AnvilEmbedFrame extends React.Component { 25 | constructor(props: any); 26 | iframeRef: React.RefObject; 27 | componentDidMount(): void; 28 | componentWillUnmount(): void; 29 | /** 30 | * @param {Object} options 31 | * @param {String} options.origin 32 | * @param {Object} options.data 33 | */ 34 | handleEvent: ({ origin, data }: { 35 | origin: string; 36 | data: object; 37 | }) => void; 38 | render() : JSX.Element; 39 | } 40 | declare namespace AnvilEmbedFrame { 41 | namespace defaultProps { 42 | function onEvent(): void; 43 | const anvilURL: string; 44 | const enableDefaultStyles: boolean; 45 | } 46 | namespace propTypes { 47 | export const iframeURL: PropTypes.Requireable; 48 | const onEvent_1: PropTypes.Validator<(...args: any[]) => any>; 49 | export { onEvent_1 as onEvent }; 50 | const anvilURL_1: PropTypes.Requireable; 51 | export { anvilURL_1 as anvilURL }; 52 | const enableDefaultStyles_1: PropTypes.Requireable; 53 | export { enableDefaultStyles_1 as enableDefaultStyles }; 54 | export const scroll: PropTypes.Requireable; 55 | export const style: PropTypes.Requireable; 56 | export const className: PropTypes.Requireable; 57 | } 58 | } 59 | import Reacat from "react"; 60 | import PropTypes from "prop-types"; 61 | //# sourceMappingURL=index.d.ts.map 62 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/test/src/index.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import AnvilEmbedFrame from '../../src/index' 3 | 4 | describe('AnvilEmbedFrame', function () { 5 | def('handleEvent', () => sinon.spy()) 6 | def('anvilURL', 'https://app.useanvil.com') 7 | 8 | def('render', () => shallow( 9 | , 14 | )) 15 | 16 | it('renders', async function () { 17 | const wrapper = $.render 18 | expect(wrapper).to.exist 19 | expect(wrapper.find('iframe')).to.exist 20 | }) 21 | 22 | describe('onEvent', function () { 23 | it('does not call onEvent when non-anvil url passed in', async function () { 24 | const origin = 'https://chess.com' 25 | const data = { action: 'forgeComplete' } 26 | const wrapper = $.render 27 | wrapper.instance().handleEvent({ origin, data }) 28 | expect($.handleEvent).to.not.have.been.called 29 | }) 30 | 31 | it('does not call onEvent when non-object data passed in', async function () { 32 | const origin = $.anvilURL 33 | const data = 'signerComplete' 34 | const wrapper = $.render 35 | wrapper.instance().handleEvent({ origin, data }) 36 | expect($.handleEvent).to.not.have.been.called 37 | }) 38 | 39 | it('calls onEvent successfully', async function () { 40 | const origin = $.anvilURL 41 | const data = { action: 'castEdit' } 42 | const wrapper = $.render 43 | wrapper.instance().handleEvent({ origin, data }) 44 | expect($.handleEvent).to.have.been.calledWith(data) 45 | }) 46 | }) 47 | 48 | it('calls postMessage successfully', () => { 49 | const wrapper = $.render 50 | const iframe = wrapper.find('iframe') 51 | const postMessage = sinon.spy() 52 | const iframeMock = { 53 | contentWindow: { 54 | postMessage, 55 | }, 56 | } 57 | 58 | iframe.getElement().ref.current = iframeMock 59 | 60 | wrapper.instance().postMessage({ action: 'test' }) 61 | expect(postMessage.called).to.be.equal(true) 62 | }) 63 | }) 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "https://github.com/anvilco/react-ui#readme", 3 | "private": true, 4 | "workspaces": [ 5 | "packages/*" 6 | ], 7 | "scripts": { 8 | "lint": "yarn eslint 'packages/*/src/**.js'", 9 | "prettify": "prettier 'packages/*/src/**.js'", 10 | "prettify:check": "yarn prettify --check", 11 | "prettify:write": "yarn prettify --write", 12 | "test": "yarn lerna run test", 13 | "prebuild": "git clean -fdx packages -e packages/*/node_modules", 14 | "build": "yarn && yarn lerna run build", 15 | "build:changelog": "yarn lerna run build:changelog", 16 | "release:local": "yarn build && yarn lerna run pack", 17 | "release:npm": "yarn build && yarn lerna publish" 18 | }, 19 | "devDependencies": { 20 | "@babel/core": "^7.22.20", 21 | "@babel/eslint-parser": "^7.22.15", 22 | "@babel/plugin-proposal-class-properties": "^7.18.6", 23 | "@babel/preset-env": "^7.22.20", 24 | "@babel/preset-react": "^7.22.15", 25 | "@babel/register": "^7.22.15", 26 | "@wojtekmaj/enzyme-adapter-react-17": "^0.8.0", 27 | "auto-changelog": "^2.4.0", 28 | "babel-eslint": "^10.1.0", 29 | "babel-loader": "^9.1.3", 30 | "bdd-lazy-var": "^2.6.1", 31 | "chai": "^4.3.8", 32 | "chai-as-promised": "^7.1.1", 33 | "chai-enzyme": "^1.0.0-beta.1", 34 | "css-loader": "^6.8.1", 35 | "enzyme": "^3.11.0", 36 | "eslint": "^8.49.0", 37 | "eslint-config-nicenice": "^4.1.1", 38 | "eslint-config-prettier": "^9.0.0", 39 | "eslint-config-standard": "^17.1.0", 40 | "eslint-config-standard-jsx": "^11.0.0", 41 | "eslint-plugin-import": "^2.28.1", 42 | "eslint-plugin-jsx-a11y": "^6.7.1", 43 | "eslint-plugin-mocha": "^10.1.0", 44 | "eslint-plugin-n": "^16.1.0", 45 | "eslint-plugin-no-only-tests": "^3.1.0", 46 | "eslint-plugin-prettier": "^5.0.0", 47 | "eslint-plugin-promise": "^6.1.1", 48 | "eslint-plugin-react": "^7.33.2", 49 | "eslint-plugin-react-hooks": "^4.6.0", 50 | "eslint-plugin-svg-jsx": "^1.2.2", 51 | "jsdom": "^22.1.0", 52 | "lerna": "^7.3.0", 53 | "mini-css-extract-plugin": "^2.7.6", 54 | "mocha": "^10.2.0", 55 | "prettier": "3.6.2", 56 | "sinon": "^16.0.0", 57 | "sinon-chai": "^3.7.0", 58 | "style-loader": "^3.3.3", 59 | "webpack": "^5.88.2", 60 | "webpack-cli": "^5.1.4" 61 | } 62 | } -------------------------------------------------------------------------------- /packages/anvil-embed-frame/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | /** 5 | * @typedef Props 6 | * @prop {String} iframeURL 7 | * @prop {Function} onEvent 8 | * @prop {String} anvilURL 9 | * @prop {String} scroll 10 | * @prop {object} style 11 | * @prop {string} className 12 | */ 13 | 14 | /** 15 | * @extends React.Component 16 | */ 17 | class AnvilEmbedFrame extends React.Component { 18 | constructor (props) { 19 | super(props) 20 | this.iframeRef = React.createRef() 21 | } 22 | 23 | componentDidMount () { 24 | const { scroll } = this.props 25 | if (scroll) this.iframeRef.current.scrollIntoView({ behavior: scroll }) 26 | window.addEventListener('message', this.handleEvent) 27 | } 28 | 29 | componentWillUnmount () { 30 | window.removeEventListener('message', this.handleEvent) 31 | } 32 | 33 | postMessage = (message) => { 34 | this.iframeRef.current.contentWindow.postMessage(message, '*') 35 | } 36 | 37 | /** 38 | * @param {Object} options 39 | * @param {String} options.origin 40 | * @param {Object} options.data 41 | */ 42 | handleEvent = ({ origin, data }) => { 43 | const { anvilURL, onEvent } = this.props 44 | if (anvilURL !== origin) return 45 | if (typeof data === 'object') { 46 | onEvent(data) 47 | } 48 | } 49 | 50 | render () { 51 | const { 52 | iframeURL, 53 | onEvent, 54 | anvilURL, 55 | scroll, 56 | style, 57 | className, 58 | ...others 59 | } = this.props 60 | return ( 61 | 72 | ) 73 | } 74 | } 75 | 76 | AnvilEmbedFrame.defaultProps = { 77 | onEvent: () => {}, 78 | anvilURL: 'https://app.useanvil.com', 79 | } 80 | 81 | AnvilEmbedFrame.propTypes = { 82 | iframeURL: PropTypes.string.isRequired, 83 | onLoad: PropTypes.func, 84 | onEvent: PropTypes.func, 85 | anvilURL: PropTypes.string, 86 | scroll: PropTypes.oneOf(['auto', 'smooth']), 87 | style: PropTypes.object, 88 | className: PropTypes.string, 89 | } 90 | 91 | export default AnvilEmbedFrame 92 | -------------------------------------------------------------------------------- /packages/react-signature-modal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@anvilco/react-signature-modal", 3 | "version": "2.1.4", 4 | "description": "The AnvilSignatureModal React component for embedded Etch signatures", 5 | "author": "Anvil Foundry Inc.", 6 | "license": "MIT", 7 | "main": "dist/index.js", 8 | "types": "dist/react-signature-modal/src/index.d.ts", 9 | "scripts": { 10 | "build": "tsc && webpack --mode production", 11 | "build:changelog": "yarn auto-changelog", 12 | "clean": "rimraf dist", 13 | "clean:build": "yarn clean && yarn build", 14 | "prepack": "yarn clean:build", 15 | "pack": "yarn pack", 16 | "version": "yarn build:changelog && git add CHANGELOG.md" 17 | }, 18 | "files": [ 19 | "dist/**" 20 | ], 21 | "engines": { 22 | "node": "*" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/anvilco/react-ui.git" 27 | }, 28 | "homepage": "https://github.com/anvilco/react-ui#readme", 29 | "bugs": { 30 | "url": "https://github.com/anvilco/react-ui/issues", 31 | "email": "support@useanvil.com" 32 | }, 33 | "publishConfig": { 34 | "registry": "https://registry.npmjs.org", 35 | "@anvilco:registry": "https://registry.npmjs.org", 36 | "access": "public" 37 | }, 38 | "keywords": [ 39 | "signature", 40 | "documents", 41 | "pdf", 42 | "modal" 43 | ], 44 | "devDependencies": { 45 | "@babel/core": "^7.22.20", 46 | "@babel/plugin-proposal-class-properties": "^7.16.7", 47 | "@babel/preset-env": "^7.22.20", 48 | "@babel/preset-react": "^7.22.15", 49 | "@babel/register": "^7.22.15", 50 | "@types/react": "^18.2.22", 51 | "@wojtekmaj/enzyme-adapter-react-17": "^0.8.0", 52 | "auto-changelog": "^2.4.0", 53 | "babel-loader": "^9.1.3", 54 | "chai": "^4.3.8", 55 | "eslint-plugin-import": "^2.28.1", 56 | "eslint-plugin-jsx-a11y": "^6.5.1", 57 | "eslint-plugin-react": "^7.33.2", 58 | "eslint-plugin-react-hooks": "^4.4.0", 59 | "jsdom": "^22.1.0", 60 | "mocha": "^10.2.0", 61 | "prop-types": "^15.8.1", 62 | "react": "^18.2.0", 63 | "react-dom": "^18.2.0", 64 | "react-modal": "^3.14.4", 65 | "rimraf": "6.0.1", 66 | "typescript": "^5.2.2", 67 | "webpack": "^5.70.0", 68 | "webpack-cli": "^5.1.4" 69 | }, 70 | "peerDependencies": { 71 | "prop-types": "^15.6.0", 72 | "react": ">=16", 73 | "react-dom": ">=16", 74 | "react-modal": "^3.11.2" 75 | }, 76 | "auto-changelog": { 77 | "output": "CHANGELOG.md", 78 | "template": "../../changelog-template.hbs", 79 | "unreleased": false, 80 | "commitLimit": true, 81 | "tagPrefix": "@anvilco/react-signature-modal@", 82 | "breakingPattern": "BREAKING CHANGE:" 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/react-signature-frame/types/index.d.ts: -------------------------------------------------------------------------------- 1 | export default AnvilSignatureFrame; 2 | export type Props = { 3 | signURL: string; 4 | scroll: string; 5 | anvilURL: string; 6 | enableDefaultStyles: boolean; 7 | iframeWarningProps: any; 8 | onLoad: React.ReactEventHandler; 9 | onError: Function; 10 | onFinishSigning: Function; 11 | /** 12 | * - Deprecated: Use onFinishSigning or onError instead. 13 | */ 14 | onFinish: Function; 15 | }; 16 | /** 17 | * @typedef Props 18 | * @prop {String} signURL 19 | * @prop {String} scroll 20 | * @prop {String} anvilURL 21 | * @prop {boolean} enableDefaultStyles 22 | * @prop {Object} iframeWarningProps 23 | * @prop {React.ReactEventHandler} onLoad 24 | * @prop {Function} onError 25 | * @prop {Function} onFinishSigning 26 | * @prop {Function} onFinish - Deprecated: Use onFinishSigning or onError instead. 27 | */ 28 | /** 29 | * @extends React.Component 30 | */ 31 | declare class AnvilSignatureFrame extends React.Component { 32 | constructor(props: any); 33 | iframeRef: React.RefObject; 34 | componentDidMount(): void; 35 | componentWillUnmount(): void; 36 | /** 37 | * @param {Object} options 38 | * @param {String} options.origin 39 | * @param {String} options.data 40 | */ 41 | handleSignFinish: ({ origin, data }: { 42 | origin: string; 43 | data: string; 44 | }) => void; 45 | render(): JSX.Element; 46 | } 47 | declare namespace AnvilSignatureFrame { 48 | namespace defaultProps { 49 | function onFinish(): void; 50 | function onFinishSigning(): void; 51 | function onError(): void; 52 | const anvilURL: string; 53 | const enableDefaultStyles: boolean; 54 | } 55 | namespace propTypes { 56 | export const signURL: PropTypes.Requireable; 57 | export const scroll: PropTypes.Requireable; 58 | export const onLoad: PropTypes.Requireable<(...args: any[]) => any>; 59 | const onError_1: PropTypes.Validator<(...args: any[]) => any>; 60 | export { onError_1 as onError }; 61 | const onFinishSigning_1: PropTypes.Validator<(...args: any[]) => any>; 62 | export { onFinishSigning_1 as onFinishSigning }; 63 | const anvilURL_1: PropTypes.Requireable; 64 | export { anvilURL_1 as anvilURL }; 65 | const enableDefaultStyles_1: PropTypes.Requireable; 66 | export { enableDefaultStyles_1 as enableDefaultStyles }; 67 | const onFinish_1: PropTypes.Requireable<(...args: any[]) => any>; 68 | export { onFinish_1 as onFinish }; 69 | } 70 | } 71 | import React from "react"; 72 | import PropTypes from "prop-types"; 73 | //# sourceMappingURL=index.d.ts.map -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-frame/src/index.d.ts: -------------------------------------------------------------------------------- 1 | export default AnvilSignatureFrame; 2 | export type Props = { 3 | signURL: string; 4 | scroll: string; 5 | anvilURL: string; 6 | enableDefaultStyles: boolean; 7 | iframeWarningProps: any; 8 | onLoad: React.ReactEventHandler; 9 | onError: Function; 10 | onFinishSigning: Function; 11 | /** 12 | * - Deprecated: Use onFinishSigning or onError instead. 13 | */ 14 | onFinish: Function; 15 | }; 16 | /** 17 | * @typedef Props 18 | * @prop {String} signURL 19 | * @prop {String} scroll 20 | * @prop {String} anvilURL 21 | * @prop {boolean} enableDefaultStyles 22 | * @prop {Object} iframeWarningProps 23 | * @prop {React.ReactEventHandler} onLoad 24 | * @prop {Function} onError 25 | * @prop {Function} onFinishSigning 26 | * @prop {Function} onFinish - Deprecated: Use onFinishSigning or onError instead. 27 | */ 28 | /** 29 | * @extends React.Component 30 | */ 31 | declare class AnvilSignatureFrame extends React.Component { 32 | constructor(props: any); 33 | iframeRef: React.RefObject; 34 | componentDidMount(): void; 35 | componentWillUnmount(): void; 36 | /** 37 | * @param {Object} options 38 | * @param {String} options.origin 39 | * @param {String} options.data 40 | */ 41 | handleSignFinish: ({ origin, data }: { 42 | origin: string; 43 | data: string; 44 | }) => void; 45 | render(): JSX.Element; 46 | } 47 | declare namespace AnvilSignatureFrame { 48 | namespace defaultProps { 49 | function onFinish(): void; 50 | function onFinishSigning(): void; 51 | function onError(): void; 52 | const anvilURL: string; 53 | const enableDefaultStyles: boolean; 54 | } 55 | namespace propTypes { 56 | export const signURL: PropTypes.Requireable; 57 | export const scroll: PropTypes.Requireable; 58 | export const onLoad: PropTypes.Requireable<(...args: any[]) => any>; 59 | const onError_1: PropTypes.Validator<(...args: any[]) => any>; 60 | export { onError_1 as onError }; 61 | const onFinishSigning_1: PropTypes.Validator<(...args: any[]) => any>; 62 | export { onFinishSigning_1 as onFinishSigning }; 63 | const anvilURL_1: PropTypes.Requireable; 64 | export { anvilURL_1 as anvilURL }; 65 | const enableDefaultStyles_1: PropTypes.Requireable; 66 | export { enableDefaultStyles_1 as enableDefaultStyles }; 67 | const onFinish_1: PropTypes.Requireable<(...args: any[]) => any>; 68 | export { onFinish_1 as onFinish }; 69 | } 70 | } 71 | import React from "react"; 72 | import PropTypes from "prop-types"; 73 | //# sourceMappingURL=index.d.ts.map -------------------------------------------------------------------------------- /packages/react-signature-modal/types/react-signature-modal/src/index.d.ts: -------------------------------------------------------------------------------- 1 | export default AnvilSignatureModal; 2 | export type Props = { 3 | signURL: string; 4 | isOpen: boolean; 5 | onClose: Function; 6 | onLoad: Function; 7 | onError: Function; 8 | onFinish: Function; 9 | onFinishSigning: Function; 10 | modalAppElement: string | Element; 11 | anvilURL: string; 12 | showIconClose: boolean; 13 | anvilFrameProps: any; 14 | iconCloseProps: any; 15 | }; 16 | /** 17 | * @typedef Props 18 | * @prop {String} signURL 19 | * @prop {boolean} isOpen 20 | * @prop {Function} onClose 21 | * @prop {Function} onLoad 22 | * @prop {Function} onError 23 | * @prop {Function} onFinish 24 | * @prop {Function} onFinishSigning 25 | * @prop {String|Element} modalAppElement 26 | * @prop {String} anvilURL 27 | * @prop {boolean} showIconClose 28 | * @prop {Object} anvilFrameProps 29 | * @prop {Object} iconCloseProps 30 | */ 31 | /** 32 | * @extends React.Component 33 | */ 34 | declare class AnvilSignatureModal extends React.Component { 35 | constructor(props: any); 36 | render(): JSX.Element; 37 | } 38 | declare namespace AnvilSignatureModal { 39 | namespace defaultProps { 40 | const isOpen: boolean; 41 | const modalAppElement: HTMLElement; 42 | const showIconClose: boolean; 43 | namespace anvilFrameProps { 44 | const id: string; 45 | } 46 | const iconCloseProps: {}; 47 | } 48 | namespace propTypes { 49 | export const signURL: PropTypes.Requireable; 50 | const isOpen_1: PropTypes.Requireable; 51 | export { isOpen_1 as isOpen }; 52 | export const onClose: PropTypes.Requireable<(...args: any[]) => any>; 53 | export const onLoad: PropTypes.Requireable<(...args: any[]) => any>; 54 | export const onError: PropTypes.Requireable<(...args: any[]) => any>; 55 | export const onFinish: PropTypes.Requireable<(...args: any[]) => any>; 56 | export const onFinishSigning: PropTypes.Requireable<(...args: any[]) => any>; 57 | const modalAppElement_1: PropTypes.Requireable; 58 | export { modalAppElement_1 as modalAppElement }; 59 | export const anvilURL: PropTypes.Requireable; 60 | const showIconClose_1: PropTypes.Requireable; 61 | export { showIconClose_1 as showIconClose }; 62 | const anvilFrameProps_1: PropTypes.Requireable; 63 | export { anvilFrameProps_1 as anvilFrameProps }; 64 | const iconCloseProps_1: PropTypes.Requireable; 65 | export { iconCloseProps_1 as iconCloseProps }; 66 | } 67 | } 68 | import React from "react"; 69 | import PropTypes from "prop-types"; 70 | //# sourceMappingURL=index.d.ts.map -------------------------------------------------------------------------------- /packages/react-signature-modal/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import ReactModal from 'react-modal' 4 | 5 | import AnvilEmbedFrame from '../../anvil-embed-frame/src/index.js' 6 | import IconClose from './components/IconClose.js' 7 | import './styles.css' 8 | 9 | /** 10 | * @typedef Props 11 | * @prop {String} id 12 | * @prop {String} iframeURL 13 | * @prop {boolean} isOpen 14 | * @prop {Function} onClose 15 | * @prop {Function} onLoad 16 | * @prop {Function} onEvent 17 | * @prop {String|Element} modalAppElement 18 | * @prop {String} anvilURL 19 | * @prop {boolean} showIconClose 20 | * @prop {Object} anvilFrameProps 21 | * @prop {Object} iconCloseProps 22 | */ 23 | 24 | /** 25 | * @extends React.Component 26 | */ 27 | class AnvilSignatureModal extends React.Component { 28 | componentDidMount () { 29 | // defaults this prop here to avoid SSR issues in defaultProps 30 | ReactModal.setAppElement(this.props.modalAppElement || document.body) 31 | } 32 | 33 | render () { 34 | const { 35 | id, 36 | iframeURL, 37 | isOpen, 38 | onClose, 39 | onLoad, 40 | onEvent, 41 | anvilURL, 42 | showIconClose, 43 | anvilFrameProps, 44 | iconCloseProps, 45 | ...otherProps 46 | } = this.props 47 | 48 | return ( 49 | 66 | 74 | {showIconClose && ( 75 | 80 | )} 81 | 82 | ) 83 | } 84 | } 85 | 86 | AnvilSignatureModal.defaultProps = { 87 | isOpen: false, 88 | showIconClose: true, 89 | anvilFrameProps: {}, 90 | iconCloseProps: {}, 91 | id: 'anvil-signature-modal', 92 | } 93 | 94 | AnvilSignatureModal.propTypes = { 95 | id: PropTypes.string, 96 | iframeURL: PropTypes.string, 97 | isOpen: PropTypes.bool, 98 | onClose: PropTypes.func, 99 | onLoad: PropTypes.func, 100 | onEvent: PropTypes.func, 101 | modalAppElement: PropTypes.oneOfType([ 102 | PropTypes.string, 103 | PropTypes.instanceOf(Element), 104 | ]), 105 | anvilURL: PropTypes.string, 106 | showIconClose: PropTypes.bool, 107 | anvilFrameProps: PropTypes.object, 108 | iconCloseProps: PropTypes.object, 109 | } 110 | 111 | export default AnvilSignatureModal 112 | -------------------------------------------------------------------------------- /packages/react-signature-frame/test/src/helpers.test.js: -------------------------------------------------------------------------------- 1 | import { omit, parseURLParams } from '../../src/helpers' 2 | 3 | describe('parseURLParams', function () { 4 | const params = [ 5 | 'noparam=', 6 | 'hello="hello"', 7 | 'num=3', 8 | 'stringPlus=test+me', 9 | 'stringEncode=test%20me', 10 | 'jsonThingsEncoded=json%3A%3D%7B%7D', 11 | 'jsonThingsDecoded=json}:{{', 12 | 'action=signerComplete', 13 | 'documentGroupEid=9fQnvfy51p7oKrEYajMh', 14 | 'documentGroupStatus=partial', 15 | 'etchPacketEid=J1phQTO6WQH6gZcMJAG5', 16 | 'nextSignerEid=HRLhx4khticpfxsUFSpj', 17 | 'signerEid=kJzR6mcIWKoZs6KOxV4w', 18 | 'signerStatus=completed', 19 | ] 20 | const paramString = params.join('&') 21 | const result = { 22 | hello: '"hello"', 23 | jsonThingsEncoded: 'json:={}', 24 | jsonThingsDecoded: 'json}:{{', 25 | noparam: '', 26 | num: '3', 27 | stringEncode: 'test me', 28 | stringPlus: 'test me', 29 | action: 'signerComplete', 30 | documentGroupEid: '9fQnvfy51p7oKrEYajMh', 31 | documentGroupStatus: 'partial', 32 | etchPacketEid: 'J1phQTO6WQH6gZcMJAG5', 33 | nextSignerEid: 'HRLhx4khticpfxsUFSpj', 34 | signerEid: 'kJzR6mcIWKoZs6KOxV4w', 35 | signerStatus: 'completed', 36 | } 37 | 38 | it('URLSearchParams is available', async function () { 39 | expect(typeof URLSearchParams).to.equal('function') 40 | }) 41 | 42 | describe('when URLSearchParams is used to parse', function () { 43 | it('returns the an empty object when bad data passed in', async function () { 44 | expect(parseURLParams(undefined)).to.eql({}) 45 | expect(parseURLParams(null)).to.eql({}) 46 | expect(parseURLParams([])).to.eql({}) 47 | expect(parseURLParams('')).to.eql({}) 48 | expect(parseURLParams(' ')).to.eql({}) 49 | expect(parseURLParams('nope')).to.eql({ nope: '' }) 50 | expect(parseURLParams(' this is nonsense')).to.eql({ 'this is nonsense': '' }) 51 | expect(parseURLParams(' notAnError== ')).to.eql({ notAnError: '=' }) 52 | }) 53 | 54 | it('returns the result', async function () { 55 | expect(parseURLParams(paramString)).to.eql(result) 56 | }) 57 | }) 58 | 59 | describe('when forceManualParse is true', function () { 60 | const options = { forceManualParse: true } 61 | it('returns the result', async function () { 62 | expect(parseURLParams(paramString, options)).to.eql(result) 63 | }) 64 | 65 | it('returns the an empty object when bad data passed in', async function () { 66 | expect(parseURLParams(undefined, options)).to.eql({}) 67 | expect(parseURLParams(null, options)).to.eql({}) 68 | expect(parseURLParams([], options)).to.eql({}) 69 | expect(parseURLParams('', options)).to.eql({}) 70 | expect(parseURLParams(' ', options)).to.eql({}) 71 | expect(parseURLParams('nope', options)).to.eql({ nope: '' }) 72 | expect(parseURLParams(' this is nonsense', options)).to.eql({ 'this is nonsense': '' }) 73 | }) 74 | 75 | it('gracefully handles parse error', async function () { 76 | expect(parseURLParams(' parseError== ', options)).to.eql({}) 77 | }) 78 | }) 79 | }) 80 | 81 | describe('omit', function () { 82 | it('returns an empty object with garbage data', async function () { 83 | expect(omit()).to.eql({}) 84 | expect(omit(undefined, [])).to.eql({}) 85 | expect(omit(null, [])).to.eql({}) 86 | expect(omit({}, [])).to.eql({}) 87 | }) 88 | 89 | it('returns an object minus the keys passed', async function () { 90 | const original = { a: 1, b: 2 } 91 | expect(omit(original)).to.eql(original) 92 | expect(omit(original)).not.to.equal(original) 93 | expect(omit(original, [])).to.eql(original) 94 | expect(omit(original, ['b'])).to.eql({ a: 1 }) 95 | }) 96 | }) 97 | -------------------------------------------------------------------------------- /packages/react-signature-frame/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | import { omit, parseURLParams } from './helpers' 5 | 6 | const IGNORED_KEYS = ['token'] 7 | 8 | /** 9 | * @typedef Props 10 | * @prop {String} signURL 11 | * @prop {String} scroll 12 | * @prop {String} anvilURL 13 | * @prop {boolean} enableDefaultStyles 14 | * @prop {Object} iframeWarningProps 15 | * @prop {React.ReactEventHandler} onLoad 16 | * @prop {Function} onError 17 | * @prop {Function} onFinishSigning 18 | * @prop {Function} onFinish - Deprecated: Use onFinishSigning or onError instead. 19 | */ 20 | 21 | /** 22 | * @extends React.Component 23 | */ 24 | class AnvilSignatureFrame extends React.Component { 25 | constructor (props) { 26 | super(props) 27 | this.iframeRef = React.createRef() 28 | } 29 | 30 | componentDidMount () { 31 | const { scroll } = this.props 32 | window.addEventListener('message', this.handleSignFinish) 33 | if (scroll) this.iframeRef.current.scrollIntoView({ behavior: scroll }) 34 | } 35 | 36 | componentWillUnmount () { 37 | window.removeEventListener('message', this.handleSignFinish) 38 | } 39 | 40 | /** 41 | * @param {Object} options 42 | * @param {String} options.origin 43 | * @param {String} options.data 44 | */ 45 | handleSignFinish = ({ origin, data }) => { 46 | const { anvilURL, onFinish, onFinishSigning, onError } = this.props 47 | if (anvilURL !== origin) return 48 | if (typeof data === 'string') { 49 | if (onFinish) { 50 | onFinish(data) 51 | } 52 | 53 | const searchStr = data.split('?')[1] 54 | const payload = omit(parseURLParams(searchStr), IGNORED_KEYS) 55 | const hasError = 56 | payload.action === 'signerError' || payload.error || payload.errorType 57 | if (!payload.action) { 58 | payload.action = hasError ? 'signerError' : 'signerComplete' 59 | } 60 | if (hasError) { 61 | onError(payload) 62 | } else { 63 | onFinishSigning(payload) 64 | } 65 | } 66 | } 67 | 68 | render () { 69 | const { 70 | signURL, 71 | onLoad, 72 | enableDefaultStyles, 73 | anvilURL, 74 | onError, 75 | onFinish, 76 | onFinishSigning, // ignore these props here. 77 | ...otherProps 78 | } = this.props 79 | const { iframeWarningProps, ...anvilFrameProps } = otherProps 80 | return ( 81 | 104 | ) 105 | } 106 | } 107 | 108 | AnvilSignatureFrame.defaultProps = { 109 | onFinish: () => {}, 110 | onFinishSigning: () => {}, 111 | onError: () => {}, 112 | anvilURL: 'https://app.useanvil.com', 113 | enableDefaultStyles: true, 114 | } 115 | 116 | AnvilSignatureFrame.propTypes = { 117 | signURL: PropTypes.string, 118 | scroll: PropTypes.string, 119 | onLoad: PropTypes.func, 120 | onError: PropTypes.func.isRequired, 121 | onFinishSigning: PropTypes.func.isRequired, 122 | anvilURL: PropTypes.string, 123 | enableDefaultStyles: PropTypes.bool, 124 | 125 | // DEPRECATED: use onFinishSigning or onError instead 126 | onFinish: PropTypes.func, 127 | } 128 | 129 | export default AnvilSignatureFrame 130 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [@anvilco/anvil-embed-frame@2.2.1](https://github.com/anvilco/react-ui/compare/@anvilco/anvil-embed-frame@2.2.0...@anvilco/anvil-embed-frame@2.2.1) - 2025-10-27 6 | 7 | ### Merged 8 | 9 | - iframeURL instead of signURL [`#25`](https://github.com/anvilco/react-ui/pull/25) 10 | 11 | ### Commits 12 | 13 | - fix up packaging [`74ce1cb`](https://github.com/anvilco/react-ui/commit/74ce1cb7a77295545ef89b6f43777e874ec5ce60) 14 | 15 | ## [@anvilco/anvil-embed-frame@2.2.0](https://github.com/anvilco/react-ui/compare/v2.1.4...@anvilco/anvil-embed-frame@2.2.0) - 2024-05-02 16 | 17 | ## [v2.1.4](https://github.com/anvilco/react-ui/compare/v2.1.3...v2.1.4) - 2025-10-28 18 | 19 | ### Commits 20 | 21 | - being extra cautious [`02beb3c`](https://github.com/anvilco/react-ui/commit/02beb3c650dc774a84cf96166e38eaee5f17b0ca) 22 | 23 | ## [v2.1.3](https://github.com/anvilco/react-ui/compare/v2.1.2...v2.1.3) - 2025-10-28 24 | 25 | ### Commits 26 | 27 | - set document inside component did mount [`5a055ed`](https://github.com/anvilco/react-ui/commit/5a055edfd2d5dcef9d3b6c4b8d6dd4a8fd1def77) 28 | 29 | ## [v2.1.2](https://github.com/anvilco/react-ui/compare/v2.1.1...v2.1.2) - 2025-10-27 30 | 31 | ### Merged 32 | 33 | - iframeURL instead of signURL [`#25`](https://github.com/anvilco/react-ui/pull/25) 34 | - Add className prop and type [`#22`](https://github.com/anvilco/react-ui/pull/22) 35 | - publish better [`#20`](https://github.com/anvilco/react-ui/pull/20) 36 | 37 | ### Commits 38 | 39 | - fix up packaging [`74ce1cb`](https://github.com/anvilco/react-ui/commit/74ce1cb7a77295545ef89b6f43777e874ec5ce60) 40 | 41 | ## [v2.1.1](https://github.com/anvilco/react-ui/compare/@anvilco/anvil-embed-frame@2.0.0...v2.1.1) - 2024-04-17 42 | 43 | ### Merged 44 | 45 | - Add style prop and add postMessage helper [`#19`](https://github.com/anvilco/react-ui/pull/19) 46 | 47 | ### Commits 48 | 49 | - Update changelogs [`73908a8`](https://github.com/anvilco/react-ui/commit/73908a846d6cf7da180303270a4d726335ff881f) 50 | 51 | ## [@anvilco/anvil-embed-frame@2.0.0](https://github.com/anvilco/react-ui/compare/@anvilco/anvil-embed-frame@2.0.0-alpha.0...@anvilco/anvil-embed-frame@2.0.0) - 2023-09-20 52 | 53 | ### Merged 54 | 55 | - [Breaking] Update dependencies [`#16`](https://github.com/anvilco/react-ui/pull/16) 56 | 57 | ### Commits 58 | 59 | - Update readmes [`c932e4c`](https://github.com/anvilco/react-ui/commit/c932e4c5716c0b113f1840baeb0aa9118facdc26) 60 | 61 | ## [@anvilco/anvil-embed-frame@2.0.0-alpha.0](https://github.com/anvilco/react-ui/compare/v1.9.2...@anvilco/anvil-embed-frame@2.0.0-alpha.0) - 2023-09-18 62 | 63 | ## [v1.9.2](https://github.com/anvilco/react-ui/compare/@anvilco/anvil-embed-frame@1.1.0...v1.9.2) - 2025-10-30 64 | 65 | ### Merged 66 | 67 | - iframeURL instead of signURL [`#25`](https://github.com/anvilco/react-ui/pull/25) 68 | - Add className prop and type [`#22`](https://github.com/anvilco/react-ui/pull/22) 69 | - publish better [`#20`](https://github.com/anvilco/react-ui/pull/20) 70 | - Add style prop and add postMessage helper [`#19`](https://github.com/anvilco/react-ui/pull/19) 71 | - [Breaking] Update dependencies [`#16`](https://github.com/anvilco/react-ui/pull/16) 72 | - Update readme to fix import error [`#15`](https://github.com/anvilco/react-ui/pull/15) 73 | 74 | ### Commits 75 | 76 | - Update deps [`52a73bd`](https://github.com/anvilco/react-ui/commit/52a73bd5f16d5435f80cd8ae76f20b2834807c40) 77 | 78 | ## @anvilco/anvil-embed-frame@1.1.0 - 2022-10-05 79 | 80 | ### Merged 81 | 82 | - Add Typescript support to `AnvilEmbedFrame` [`#13`](https://github.com/anvilco/react-ui/pull/13) 83 | - New `@anvilco/anvil-embed-frame` package [`#12`](https://github.com/anvilco/react-ui/pull/12) 84 | - Update Readme [`#11`](https://github.com/anvilco/react-ui/pull/11) 85 | - [1-min] Fix output path for type defs [`#10`](https://github.com/anvilco/react-ui/pull/10) 86 | - Add Typescript typings [`#9`](https://github.com/anvilco/react-ui/pull/9) 87 | - Update dependencies and peer dependencies [`#7`](https://github.com/anvilco/react-ui/pull/7) 88 | - Add onError handler [`#6`](https://github.com/anvilco/react-ui/pull/6) 89 | - Add onFinishSigning prop & upgrade all minor version deps [`#5`](https://github.com/anvilco/react-ui/pull/5) 90 | - Refactor the Docs [`#3`](https://github.com/anvilco/react-ui/pull/3) 91 | - Review Follow Ups and Refactoring [`#2`](https://github.com/anvilco/react-ui/pull/2) 92 | - Setup Linting [`#1`](https://github.com/anvilco/react-ui/pull/1) 93 | 94 | ### Commits 95 | 96 | - AnvilSignatureFrame and AnvilSignatureModal [`7ab8fc2`](https://github.com/anvilco/react-ui/commit/7ab8fc2026411cbcc0186d9650290ba3d1afcfa5) 97 | -------------------------------------------------------------------------------- /packages/anvil-embed-frame/README.md: -------------------------------------------------------------------------------- 1 | # AnvilEmbedFrame 2 | 3 | `AnvilEmbedFrame` is a very minimal React component that allows you to embed Anvil [Etch e-signatures](https://www.useanvil.com/docs/api/e-signatures#embedding-the-signing-ui-in-an-iframe), [Workflows](https://www.useanvil.com/docs/api/workflows#embedding-workflows-in-your-app), and [embedded builders](https://www.useanvil.com/blog/engineering/embedded-edit-pdf-experience/) into your app with an `iframe`. It will give you information via callback `onEvent`. 4 | 5 | See the Etch e-sign [live demo](https://esign-demo.useanvil.com/) and open-source [demo repository](https://github.com/anvilco/anvil-e-signature-api-node-example) for an embedded Etch e-sign usage example using this component. 6 | 7 | ## What is Anvil? 8 | 9 | [Anvil](https://www.useanvil.com/developers) provides easy APIs for all things paperwork. 10 | 11 | 1. [PDF filling API](https://www.useanvil.com/products/pdf-filling-api/) - fill out a PDF template with a web request and structured JSON data. 12 | 2. [PDF generation API](https://www.useanvil.com/products/pdf-generation-api/) - send markdown or HTML and Anvil will render it to a PDF. 13 | 3. [Etch E-sign with API](https://www.useanvil.com/products/etch/) - customizable, embeddable, e-signature platform with an API to control the signing process end-to-end. 14 | 4. [Anvil Workflows (w/ API)](https://www.useanvil.com/products/workflows/) - Webforms + PDF + E-sign with a powerful no-code builder. Easily collect structured data, generate PDFs, and request signatures. 15 | 16 | Learn more on our [Anvil developer page](https://www.useanvil.com/developers). 17 | 18 | ## Usage 19 | 20 | ```sh 21 | yarn add @anvilco/anvil-embed-frame 22 | ``` 23 | 24 | ```sh 25 | npm install @anvilco/anvil-embed-frame 26 | ``` 27 | 28 | ```js 29 | import AnvilEmbedFrame from '@anvilco/anvil-embed-frame' 30 | 31 | console.log('Event object:', eventObject)} 34 | className="anvil-embed-frame" 35 | style={{ border: 'none' }} 36 | /> 37 | ``` 38 | 39 | ## Upgrading from v1 to v2 40 | 41 | Beginning in v2.0, the `enableDefaultStyles` prop has been removed. There are now _no_ default styles embedded in the `AnvilEmbedFrame`, the frame will use default browser `iframe` styling. You can style the iframe with CSS and add `className` and `style` props to the component 42 | 43 | ## Props 44 | 45 | ### iframeURL 46 | 47 | *String (required)* - A URL to the Anvil page you'd like to embed. 48 | For Etch e-sign, [refer to these docs](https://www.useanvil.com/docs/api/e-signatures#embedding-the-signing-ui-in-an-iframe) for instructions on generating the signing URL. 49 | For Workflows, [refer to these docs](https://www.useanvil.com/docs/api/workflows#embedding-workflows-in-your-app) for instructions on retrieving the Workflow URL. 50 | 51 | Example 52 | ```js 53 | // Etch e-signatures 54 | 57 | 58 | // For Workflows 59 | 62 | ``` 63 | 64 | ### onEvent 65 | 66 | *Function* - This function is called when an event is triggered. 67 | Possible event types for [Etch e-sign include](https://www.useanvil.com/docs/api/e-signatures/#iframe-event-details): `signerComplete`, `signerError`. 68 | Possible event types for [Workflows include](https://www.useanvil.com/docs/api/workflows/#iframe-event-details): `forgeSubmitPage`, `forgeComplete`, `weldComplete`. 69 | 70 | Defaults to `(eventObject) => {}` 71 | 72 | ### scroll 73 | 74 | *String* - Set scroll to the iframe 75 | 76 | * `auto` - scrolls the window to the iframe when mounted 77 | * `smooth` smoothly scrolls the window to the iframe when mounted 78 | * `null` - disables scrolling 79 | 80 | ## Anvil Documentation 81 | 82 | * [Get started with Anvil API](https://www.useanvil.com/docs/api/getting-started) 83 | * [Etch E-sign API](https://www.useanvil.com/docs/api/e-signatures) 84 | * [Workflows API](https://www.useanvil.com/docs/api/workflows) 85 | 86 | ## Notes 87 | 88 | * To enable iframe embedding, go to your organization's settings in Anvil, and enable "Iframe Embedding" in the API section. 89 | * Please contact us at [support@useanvil.com](mailto:support@useanvil.com) to enable iframe embedding for our [embedded builders UIs](https://www.useanvil.com/blog/engineering/embedded-edit-pdf-experience/): the PDF template builder, e-sign packet builder, or Workflow builder. 90 | * React >= v16.0 required. 91 | 92 | ## Bugs 93 | 94 | Please file an issue for bugs, missing documentation, or unexpected behavior. 95 | 96 | ## Questions or Feedback 97 | 98 | Please email us at [support@useanvil.com](mailto:support@useanvil.com). 99 | 100 | ## License 101 | 102 | MIT 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Horizontal Lockupblack](https://user-images.githubusercontent.com/293079/169453889-ae211c6c-7634-4ccd-8ca9-8970c2621b6f.png#gh-light-mode-only) 2 | ![Horizontal Lockup copywhite](https://user-images.githubusercontent.com/293079/169453892-895f637b-4633-4a14-b997-960c9e17579b.png#gh-dark-mode-only) 3 | 4 | # Anvil React UI Components 5 | 6 | This repo contains multiple React components used to embed [Anvil E-signatures](https://www.useanvil.com/docs/api/e-signatures), [Workflows](https://www.useanvil.com/docs/api/workflows#embedding-workflows-in-your-app), and editors into your app or website. Pick and choose the component that best suits your use case, integrate it into your code, and the components will take care of the rest. 7 | 8 | The following components will embed the Anvil product in an `iframe` within your app or website. To enable, go to your organization's settings in Anvil, and enable "Iframe Embedding" in the API section. Test `EtchPackets` [created with `isTest: true`](https://www.useanvil.com/docs/api/e-signatures#testing-your-packet-configuration)and `Workflow submissions` are embeddable without contacting us. 9 | 10 | * [AnvilEmbedFrame](#AnvilEmbedFrame) - an `iframe` component with a simple `onEvent` callback for embedding Etch e-sign, Workflows, or editors. 11 | * [AnvilSignatureModal](#AnvilSignatureModal) - a modal popup window component with lifecycle callbacks for embedding Anvil e-signatures. 12 | 13 | See the [live demo](https://esign-demo.useanvil.com/) and open-source [demo repository](https://github.com/anvilco/anvil-e-signature-api-node-example) for a usage example of `AnvilEmbedFrame` and `AnvilSignatureModal`. 14 | 15 | ## What is Anvil? 16 | 17 | [Anvil](https://www.useanvil.com/developers) provides easy APIs for all things paperwork. 18 | 19 | 1. [PDF filling API](https://www.useanvil.com/products/pdf-filling-api/) - fill out a PDF template with a web request and structured JSON data. 20 | 2. [PDF generation API](https://www.useanvil.com/products/pdf-generation-api/) - send markdown or HTML and Anvil will render it to a PDF. 21 | 3. [Etch E-sign with API](https://www.useanvil.com/products/etch/) - customizable, embeddable, e-signature platform with an API to control the signing process end-to-end. 22 | 4. [Anvil Workflows (w/ API)](https://www.useanvil.com/products/workflows/) - Webforms + PDF + E-sign with a powerful no-code builder. Easily collect structured data, generate PDFs, and request signatures. 23 | 24 | Learn more on our [Anvil developer page](https://www.useanvil.com/developers). 25 | 26 | ## AnvilEmbedFrame 27 | 28 | A very minimal component that allows you to embed Anvil into your app with an `iframe`. It will give you information via the `onEvent` callback. 29 | 30 | ### Usage 31 | 32 | See the [AnvilEmbedFrame README](./packages/anvil-embed-frame/README.md) for full details. 33 | 34 | ```sh 35 | yarn add @anvilco/anvil-embed-frame 36 | ``` 37 | 38 | ```sh 39 | npm install @anvilco/anvil-embed-frame 40 | ``` 41 | 42 | ```js 43 | import AnvilEmbedFrame from '@anvilco/anvil-embed-frame' 44 | 45 | console.log('Event object:', event)} 48 | className="anvil-embed-frame" 49 | /> 50 | ``` 51 | 52 | 53 | ## AnvilSignatureModal 54 | 55 | A minimal modal component that allows you to embed Anvil e-signatures via a modal popup in your app. It will give you information via callbacks through the signing process lifecycle. Compatible with mobile viewports with minimal dependencies. 56 | 57 | ![image](https://user-images.githubusercontent.com/26425671/101393509-0f604680-387c-11eb-8e09-b889b0c21c7f.png) 58 | 59 | ### Usage 60 | 61 | See the [AnvilSignatureModal README](./packages/react-signature-modal/README.md) for full details. 62 | 63 | ```sh 64 | yarn add @anvilco/react-signature-modal 65 | ``` 66 | ```sh 67 | npm install @anvilco/react-signature-modal 68 | ``` 69 | 70 | ```js 71 | import AnvilSignatureModal from '@anvilco/react-signature-modal' 72 | import '@anvilco/react-signature-modal/dist/styles.css' 73 | 74 | setIsModalOpen(false)} 78 | onLoad={() => setLoading(false)} 79 | onEvent={(eventObject) => console.log(eventObject)} 80 | /> 81 | ``` 82 | 83 | ## Links 🔗 84 | 85 | * [@anvilco/anvil-embed-frame](https://www.npmjs.com/package/@anvilco/anvil-embed-frame) 86 | * [@anvilco/react-signature-modal](https://www.npmjs.com/package/@anvilco/react-signature-modal) 87 | * [Getting started with Anvil API](https://www.useanvil.com/docs/api/getting-started) 88 | * [Anvil e-signature API docs](https://www.useanvil.com/docs/api/e-signatures) 89 | 90 | 91 | ## Notes 92 | 93 | * Please contact us at [support@useanvil.com](mailto:support@useanvil.com) to enable iframe embedding for editors. 94 | * React >= v16.0 required. 95 | 96 | ## Bugs 97 | 98 | Please file an issue for bugs, missing documentation, or unexpected behavior. 99 | 100 | ## Questions or Feedback 101 | 102 | Please email us at [support@useanvil.com](mailto:support@useanvil.com). 103 | 104 | ## License 105 | 106 | MIT 107 | -------------------------------------------------------------------------------- /packages/react-signature-frame/test/src/index.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactSignatureFrame from '../../src/index' 3 | 4 | describe('ReactSignatureFrame', function () { 5 | def('anvilURL', 'https://app.useanvil.com') 6 | def('handleLoad', () => sinon.spy()) 7 | def('handleError', () => sinon.spy()) 8 | def('handleFinish', () => sinon.spy()) 9 | def('handleFinishSigning', () => sinon.spy()) 10 | 11 | def('render', () => shallow( 12 | , 20 | )) 21 | 22 | it('renders', async function () { 23 | const wrapper = $.render 24 | expect(wrapper).to.exist 25 | expect(wrapper.find('iframe')).to.exist 26 | }) 27 | 28 | describe('handleSignFinish', function () { 29 | it('does not call any callbacks when non-anvil url passed in', async function () { 30 | const origin = 'https://google.com' 31 | const data = {} 32 | const wrapper = $.render 33 | wrapper.instance().handleSignFinish({ origin, data }) 34 | expect($.handleLoad).not.to.have.been.called 35 | expect($.handleError).not.to.have.been.called 36 | expect($.handleFinish).not.to.have.been.called 37 | expect($.handleFinishSigning).not.to.have.been.called 38 | }) 39 | 40 | it('does not call any callbacks when non-string data is passed in', async function () { 41 | const origin = $.anvilURL 42 | const data = { action: 'signerComplete' } 43 | const wrapper = $.render 44 | wrapper.instance().handleSignFinish({ origin, data }) 45 | expect($.handleLoad).not.to.have.been.called 46 | expect($.handleError).not.to.have.been.called 47 | expect($.handleFinish).not.to.have.been.called 48 | expect($.handleFinishSigning).not.to.have.been.called 49 | }) 50 | 51 | it('calls onFinishSigning with an action when no action specified', async function () { 52 | const origin = $.anvilURL 53 | const data = `${$.anvilURL}/finish?token=a&signerEid=9fQnvfy51p7oKrEYajMh&signerStatus=completed&extra=ok` 54 | const wrapper = $.render 55 | wrapper.instance().handleSignFinish({ origin, data }) 56 | expect($.handleError).not.to.have.been.called 57 | expect($.handleFinish).to.have.been.calledWith(data) 58 | expect($.handleFinishSigning).to.have.been.calledWith({ 59 | action: 'signerComplete', 60 | signerEid: '9fQnvfy51p7oKrEYajMh', 61 | signerStatus: 'completed', 62 | extra: 'ok', 63 | }) 64 | }) 65 | 66 | it('calls onFinishSigning with the action specified', async function () { 67 | const origin = $.anvilURL 68 | const data = `${$.anvilURL}/finish?action=signerComplete&token=a&signerEid=9fQnvfy51p7oKrEYajMh` 69 | const wrapper = $.render 70 | wrapper.instance().handleSignFinish({ origin, data }) 71 | expect($.handleError).not.to.have.been.called 72 | expect($.handleFinish).to.have.been.calledWith(data) 73 | expect($.handleFinishSigning).to.have.been.calledWith({ 74 | action: 'signerComplete', 75 | signerEid: '9fQnvfy51p7oKrEYajMh', 76 | }) 77 | }) 78 | 79 | it('calls onFinishSigning with a custom action', async function () { 80 | const origin = $.anvilURL 81 | const data = `${$.anvilURL}/finish?action=signerCustom&token=a&signerEid=9fQnvfy51p7oKrEYajMh` 82 | const wrapper = $.render 83 | wrapper.instance().handleSignFinish({ origin, data }) 84 | expect($.handleError).not.to.have.been.called 85 | expect($.handleFinish).to.have.been.calledWith(data) 86 | expect($.handleFinishSigning).to.have.been.calledWith({ 87 | action: 'signerCustom', 88 | signerEid: '9fQnvfy51p7oKrEYajMh', 89 | }) 90 | }) 91 | 92 | it('calls onError when there are error params but no action', async function () { 93 | const origin = $.anvilURL 94 | const data = `${$.anvilURL}/finish?token=a&signerEid=9fQnvfy51p7oKrEYajMh&error=Token+Expired` 95 | const wrapper = $.render 96 | wrapper.instance().handleSignFinish({ origin, data }) 97 | expect($.handleFinishSigning).not.to.have.been.called 98 | expect($.handleFinish).to.have.been.calledWith(data) 99 | expect($.handleError).to.have.been.calledWith({ 100 | action: 'signerError', 101 | signerEid: '9fQnvfy51p7oKrEYajMh', 102 | error: 'Token Expired', 103 | }) 104 | }) 105 | 106 | it('calls onError when there is an error', async function () { 107 | const origin = $.anvilURL 108 | const data = `${$.anvilURL}/finish?action=signerError&token=a&signerEid=9fQnvfy51p7oKrEYajMh&errorType=tokenExpired` 109 | const wrapper = $.render 110 | wrapper.instance().handleSignFinish({ origin, data }) 111 | expect($.handleFinishSigning).not.to.have.been.called 112 | expect($.handleFinish).to.have.been.calledWith(data) 113 | expect($.handleError).to.have.been.calledWith({ 114 | action: 'signerError', 115 | signerEid: '9fQnvfy51p7oKrEYajMh', 116 | errorType: 'tokenExpired', 117 | }) 118 | }) 119 | }) 120 | }) 121 | -------------------------------------------------------------------------------- /packages/react-signature-frame/README.md: -------------------------------------------------------------------------------- 1 | # (Deprecated) AnvilSignatureFrame 2 | 3 | A very minimal component that allows you to embed [Anvil Etch e-signatures](https://www.useanvil.com/docs/api/e-signatures) in your app with an `iframe`. It will give you information via callbacks through the signing process lifecycle. 4 | 5 | See the [live demo](https://esign-demo.useanvil.com/) and open-source [demo repository](https://github.com/anvilco/anvil-e-signature-api-node-example) for a usage example. 6 | 7 | ![image](https://user-images.githubusercontent.com/26425671/101393358-d7590380-387b-11eb-827c-5041709a612a.png) 8 | 9 | ## What is Anvil? 10 | 11 | [Anvil](https://www.useanvil.com/developers) provides easy APIs for all things paperwork. 12 | 13 | 1. [PDF filling API](https://www.useanvil.com/products/pdf-filling-api/) - fill out a PDF template with a web request and structured JSON data. 14 | 2. [PDF generation API](https://www.useanvil.com/products/pdf-generation-api/) - send markdown or HTML and Anvil will render it to a PDF. 15 | 3. [Etch E-sign with API](https://www.useanvil.com/products/etch/) - customizable, embeddable, e-signature platform with an API to control the signing process end-to-end. 16 | 4. [Anvil Workflows (w/ API)](https://www.useanvil.com/products/workflows/) - Webforms + PDF + E-sign with a powerful no-code builder. Easily collect structured data, generate PDFs, and request signatures. 17 | 18 | Learn more on our [Anvil developer page](https://www.useanvil.com/developers). 19 | 20 | ## Usage 21 | 22 | ```sh 23 | yarn add @anvilco/react-signature-frame 24 | ``` 25 | 26 | ```sh 27 | npm install @anvilco/react-signature-frame 28 | ``` 29 | 30 | ```js 31 | import AnvilSignatureFrame from '@anvilco/react-signature-frame' 32 | 33 | setLoading(true)} 37 | onFinishSigning={(payload) => console.log(payload)} 38 | onError={(errorPayload) => console.log(errorPayload)} 39 | /> 40 | ``` 41 | 42 | ## Props 43 | 44 | ### signURL 45 | 46 | *string (required)* - A URL to the Anvil signature page generated from the [`generateEtchSignURL` GraphQL mutation](https://www.useanvil.com/docs/api/e-signatures#controlling-the-signature-process-with-embedded-signers). The signature frame will be displaying the signing page through this URL. 47 | 48 | Example: 49 | ```js 50 | signURL={`https://app.useanvil.com/etch/8iJDbq8dkEmjrsNw7Dnb/sign?token=dsa...`} 51 | ``` 52 | 53 | ### scroll 54 | 55 | *string | null* - Optionally scroll to the signing frame 56 | 57 | * `auto` - scrolls the window to the signing frame when mounted 58 | * `smooth` - smoothly scrolls the window to the signing frame when mounted 59 | * `null` - disables scrolling 60 | 61 | ### onLoad 62 | 63 | *function* - This function is called when the signing page has finished loading. 64 | 65 | Example: 66 | ```js 67 | onLoad={() => setLoading(false)} 68 | ``` 69 | 70 | ### onFinishSigning 71 | 72 | *function* - A callback function with `payload` as a parameter. It is called when a user has successfully finished signing. 73 | 74 | Example: 75 | ```js 76 | onFinishSigning={(payload) => console.log(payload)} 77 | 78 | /* 79 | { 80 | action: "signerComplete", 81 | signerEid: "kJzR6mcIWKoZs6KOxV4w", 82 | signerStatus: "completed", 83 | nextSignerEid: "HRLhx4khticpfxsUFSpj", 84 | documentGroupEid: "9fQnvfy51p7oKrEYajMh", 85 | documentGroupStatus: "partial", 86 | etchPacketEid: "J1phQTO6WQH6gZcMJAG5", // If from an EtchPacket 87 | weldDataEid: "J1phQTO6WQH6gZcMJAG5", // If from a workflow 88 | } 89 | */ 90 | ``` 91 | 92 | ### onError 93 | 94 | *function* - A callback function with an error-specific `payload` as a parameter. It is called when a user experienced an error while attempting to sign. See the docs for details on [how to recover from errors](https://www.useanvil.com/docs/api/e-signatures#handling-signing-errors). 95 | 96 | Example: 97 | ```js 98 | onError={(payload) => console.log(payload)} 99 | 100 | /* 101 | { 102 | action: "signerError", 103 | errorType: "tokenExpired", tokenExpired || tokenInvalid || notFound 104 | error: "Token Expired", 105 | message: "Error specific message", 106 | signerEid: "kJzR6mcIWKoZs6KOxV4w", 107 | 108 | // depending on the errorType, you may or may not receive the following 109 | signerStatus: "sent", 110 | nextSignerEid: "HRLhx4khticpfxsUFSpj", 111 | documentGroupEid: "9fQnvfy51p7oKrEYajMh", 112 | documentGroupStatus: "sent", 113 | etchPacketEid: "J1phQTO6WQH6gZcMJAG5", // If from an EtchPacket 114 | weldDataEid: "J1phQTO6WQH6gZcMJAG5", // If from a workflow 115 | } 116 | */ 117 | ``` 118 | 119 | ### onFinish (deprecated) 120 | 121 | *function* - This function will have `redirectURL` as a parameter; called when a user has finished signing or experienced and error. Please use `onFinishSigning` and `onError` above. 122 | 123 | Example: 124 | ```js 125 | onFinish={(redirectURL) => console.log(redirectURL)} 126 | ``` 127 | 128 | ### enableDefaultStyles 129 | 130 | *boolean (default: true)* - Set to false to disable the default inline styles of the component. 131 | 132 | 133 | ### iframeWarningProps 134 | 135 | *object* - Pass in custom props into the paragraph tag displayed if the user's browser does not support iframes. 136 | 137 | Example: 138 | ```js 139 | iframeWarningProps={{ className: 'warning-text' }} 140 | ``` 141 | 142 | 143 | ## Styling 144 | 145 | Customize the component by disabling `enableDefaultStyles` and importing CSS or passing in inline styles. Override IDs or classNames by passing them in as props. 146 | 147 | 148 | ## Anvil Etch E-Sign Docs 149 | 150 | [Read the Docs](https://www.useanvil.com/docs/api/e-signatures) 151 | 152 | 153 | ## Links 🔗 154 | * [@anvilco/react-signature-frame](https://www.npmjs.com/package/@anvilco/react-signature-frame) 155 | * [Getting started with Anvil API](https://www.useanvil.com/docs/api/getting-started) 156 | 157 | 158 | ## Notes 159 | 160 | * To enable Iframe embedding: go to your organization's settings in Anvil, and enable "Iframe Embedding" in the API section. 161 | * React >= v16.0 required. 162 | 163 | 164 | ## Bugs 165 | 166 | Please file an issue for bugs, missing documentation, or unexpected behavior. 167 | 168 | 169 | ## Questions or Feedback 170 | 171 | Please email us at [support@useanvil.com](mailto:support@useanvil.com). 172 | -------------------------------------------------------------------------------- /packages/react-signature-modal/README.md: -------------------------------------------------------------------------------- 1 | # AnvilSignatureModal 2 | 3 | A lightweight modal component that allows embedding [Anvil Etch e-signatures](https://www.useanvil.com/docs/api/e-signatures) via a modal popup in your app. It will give you information via callbacks through the signing process lifecycle. Compatible with mobile viewports with minimal dependencies. 4 | 5 | See the [live demo](https://esign-demo.useanvil.com/) and open-source [demo repository](https://github.com/anvilco/anvil-e-signature-api-node-example) for a usage example. 6 | 7 | ![image](https://user-images.githubusercontent.com/26425671/101393509-0f604680-387c-11eb-8e09-b889b0c21c7f.png) 8 | 9 | ## What is Anvil? 10 | 11 | [Anvil](https://www.useanvil.com/developers) provides easy APIs for all things paperwork. 12 | 13 | 1. [PDF filling API](https://www.useanvil.com/products/pdf-filling-api/) - fill out a PDF template with a web request and structured JSON data. 14 | 2. [PDF generation API](https://www.useanvil.com/products/pdf-generation-api/) - send markdown or HTML and Anvil will render it to a PDF. 15 | 3. [Etch E-sign with API](https://www.useanvil.com/products/etch/) - customizable, embeddable, e-signature platform with an API to control the signing process end-to-end. 16 | 4. [Anvil Workflows (w/ API)](https://www.useanvil.com/products/workflows/) - Webforms + PDF + E-sign with a powerful no-code builder. Easily collect structured data, generate PDFs, and request signatures. 17 | 18 | Learn more on our [Anvil developer page](https://www.useanvil.com/developers). 19 | 20 | ## Usage 21 | 22 | ```sh 23 | yarn add @anvilco/react-signature-modal 24 | ``` 25 | 26 | ```sh 27 | npm install @anvilco/react-signature-modal 28 | ``` 29 | 30 | ```js 31 | import AnvilSignatureModal from '@anvilco/react-signature-modal' 32 | import '@anvilco/react-signature-modal/dist/styles.css' 33 | 34 | setIsModalOpen(false)} 38 | onLoad={() => setLoading(false)} 39 | onEvent={(eventObject) => { 40 | console.log(eventObject) 41 | 42 | // See https://www.useanvil.com/docs/api/e-signatures/#iframe-event-details 43 | // for all event details. 44 | // 45 | // Example: 46 | // 47 | // { 48 | // action: 'signerComplete', 49 | // signerStatus: 'completed', 50 | // signerEid: 'Jc1ZJisPnpF5lHyfyqBW', 51 | // nextSignerEid: 'WBqyfyHl5FpnPsiJZ1cJ', 52 | // documentGroupStatus: 'partial', 53 | // documentGroupEid: 'nEKq2eGim0ijSqKd98nG', 54 | // etchPacketEid: 'XzfmVPfGUEyBc1XyylFo', 55 | // } 56 | }} 57 | /> 58 | ``` 59 | 60 | ## Upgrading from v1 to v2 61 | 62 | As of v2.0, the `AnvilSignatureModal` now uses `AnvilEmbedFrame` under the hood. The props have changed slightly: 63 | 64 | * `signURL` -> `iframeURL` 65 | * `onFinishSigning` -> `onEvent`. Check the `eventObject.action === 'signerComplete'` to detect a signer has finished signing 66 | * `onError` -> `onEvent`. Check the `eventObject.error` to determine if there is an error 67 | 68 | ```js 69 | // v1.x 70 | console.log(eventObject)} 74 | onError={(eventObject) => console.log(eventObject)} 75 | 76 | // Unchanged! 77 | isOpen={isModalOpen} 78 | onClose={() => setIsModalOpen(false)} 79 | onLoad={() => setLoading(false)} 80 | /> 81 | 82 | // v2.x 83 | { 87 | console.log(eventObject) 88 | if (eventObject.action === 'signerComplete') { 89 | // Signer has finished signing 90 | } else if (eventObject.error) { 91 | // There has been an error 92 | } 93 | }} 94 | 95 | // Unchanged! 96 | isOpen={isModalOpen} 97 | onClose={() => setIsModalOpen(false)} 98 | onLoad={() => setLoading(false)} 99 | /> 100 | ``` 101 | 102 | ## Props 103 | 104 | ### id 105 | *string* - html id attribute, overriding the `id` will also remove all default styling for the `react-siganture-modal`. If you just want to override specific styling elements use the `anvilFrameProps` below. 106 | 107 | ### iframeURL 108 | 109 | *string (required)* - A URL to the Anvil signature page generated from the [`generateEtchSignURL` GraphQL mutation](https://www.useanvil.com/docs/api/e-signatures#controlling-the-signature-process-with-embedded-signers). The signature frame will be displaying the signing page through this URL. 110 | 111 | Example: 112 | ```js 113 | iframeURL={`https://app.useanvil.com/etch/8iJDbq8dkEmjrsNw7Dnb/sign?token=dsa...`} 114 | ``` 115 | 116 | ### isOpen 117 | 118 | *boolean* - The modal is displayed if `isOpen` is true. 119 | 120 | ### onClose 121 | 122 | *function* - This function is called when the X button is clicked on the top right corner. 123 | 124 | Example: 125 | ```js 126 | onClose={() => setIsOpen(false))} 127 | ``` 128 | 129 | ### onEvent 130 | 131 | *function* - A callback function with `payload` as a parameter. It is called when a user has successfully finished signing. 132 | 133 | Example: 134 | 135 | ```js 136 | onEvent={(eventObject) => console.log(eventObject)} 137 | 138 | /* 139 | { 140 | action: "signerComplete", 141 | signerEid: "kJzR6mcIWKoZs6KOxV4w", 142 | signerStatus: "completed", 143 | nextSignerEid: "HRLhx4khticpfxsUFSpj", 144 | documentGroupEid: "9fQnvfy51p7oKrEYajMh", 145 | documentGroupStatus: "partial", 146 | etchPacketEid: "J1phQTO6WQH6gZcMJAG5", // If from an EtchPacket 147 | weldDataEid: "J1phQTO6WQH6gZcMJAG5", // If from a workflow 148 | } 149 | */ 150 | ``` 151 | 152 | See [our e-sign docs](https://www.useanvil.com/docs/api/e-signatures/#iframe-event-details) for full details on all iframe events. 153 | 154 | `onEvent` is also called when a user experiences an error while attempting to sign. See the docs for details on [how to recover from errors](https://www.useanvil.com/docs/api/e-signatures#handling-signing-errors). 155 | 156 | Example error payload: 157 | 158 | ```js 159 | { 160 | action: "signerError", 161 | errorType: "tokenExpired", tokenExpired || tokenInvalid || notFound 162 | error: "Token Expired", 163 | message: "Error specific message", 164 | signerEid: "kJzR6mcIWKoZs6KOxV4w", 165 | 166 | // depending on the errorType, you may or may not receive the following 167 | signerStatus: "sent", 168 | nextSignerEid: "HRLhx4khticpfxsUFSpj", 169 | documentGroupEid: "9fQnvfy51p7oKrEYajMh", 170 | documentGroupStatus: "sent", 171 | etchPacketEid: "J1phQTO6WQH6gZcMJAG5", // If from an EtchPacket 172 | weldDataEid: "J1phQTO6WQH6gZcMJAG5", // If from a workflow 173 | } 174 | ``` 175 | 176 | ### onLoad 177 | 178 | *function* - This function is called when the signing page has finished loading. 179 | 180 | Example: 181 | ```js 182 | onLoad={() => setLoading(false)} 183 | ``` 184 | 185 | ### modalAppElement 186 | 187 | *string* - Pass in a query selector identifying the root of your app. Used to hide other page content while the modal is open for 188 | screenreaders and other accessibility purposes. 189 | 190 | Default: `#root` 191 | 192 | 193 | ### showIconClose 194 | 195 | *boolean* -Show the close icon on the top right of the modal if true. 196 | 197 | 198 | ### iframeWarningProps 199 | 200 | *object* - Pass in custom props into the paragraph tag displayed if the user's browser does not support iframes. 201 | 202 | Example: 203 | ```js 204 | iframeWarningProps={{ className: 'warning-text' }} 205 | ``` 206 | 207 | 208 | ### anvilFrameProps 209 | 210 | *object* - Pass in custom props into the iframe tag displayed within the modal. 211 | 212 | Example: 213 | ```js 214 | anvilFrameProps={{ 215 | style: { background: 'white' }, 216 | }} 217 | ``` 218 | 219 | 220 | ### iconCloseProps 221 | 222 | *object* - Pass in custom props into the svg tag for the delete button displayed within the modal. 223 | 224 | Example: 225 | ```js 226 | iconCloseProps={{ className: 'red-delete-button' }} 227 | ``` 228 | 229 | 230 | ## Styling 231 | 232 | Customize the component by importing your own CSS stylesheet. Override IDs or classNames by passing them in as props. 233 | 234 | 235 | ## Anvil Etch E-Sign Docs 236 | 237 | [Read the Docs](https://www.useanvil.com/docs/api/e-signatures) 238 | 239 | 240 | ## Links 🔗 241 | 242 | * [@anvilco/react-signature-modal](https://www.npmjs.com/package/@anvilco/react-signature-modal) 243 | * [Getting started with Anvil API](https://www.useanvil.com/docs/api/getting-started) 244 | 245 | 246 | ## Notes 247 | 248 | * To enable Iframe embedding: go to your organization's settings in Anvil, and enable "Iframe Embedding" in the API section. 249 | * React >= v16.0 required. 250 | 251 | 252 | ## Bugs 253 | 254 | Please file an issue for bugs, missing documentation, or unexpected behavior. 255 | 256 | 257 | ## Questions or Feedback 258 | 259 | Please email us at [support@useanvil.com](mailto:support@useanvil.com). 260 | -------------------------------------------------------------------------------- /packages/react-signature-frame/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [v2.1.4](https://github.com/anvilco/react-ui/compare/v2.1.3...v2.1.4) - 2025-10-28 6 | 7 | ### Commits 8 | 9 | - being extra cautious [`02beb3c`](https://github.com/anvilco/react-ui/commit/02beb3c650dc774a84cf96166e38eaee5f17b0ca) 10 | 11 | ## [v2.1.3](https://github.com/anvilco/react-ui/compare/v2.1.2...v2.1.3) - 2025-10-28 12 | 13 | ### Commits 14 | 15 | - set document inside component did mount [`5a055ed`](https://github.com/anvilco/react-ui/commit/5a055edfd2d5dcef9d3b6c4b8d6dd4a8fd1def77) 16 | 17 | ## [v2.1.2](https://github.com/anvilco/react-ui/compare/v2.1.1...v2.1.2) - 2025-10-27 18 | 19 | ### Merged 20 | 21 | - iframeURL instead of signURL [`#25`](https://github.com/anvilco/react-ui/pull/25) 22 | - Add className prop and type [`#22`](https://github.com/anvilco/react-ui/pull/22) 23 | - publish better [`#20`](https://github.com/anvilco/react-ui/pull/20) 24 | 25 | ### Commits 26 | 27 | - fix up packaging [`74ce1cb`](https://github.com/anvilco/react-ui/commit/74ce1cb7a77295545ef89b6f43777e874ec5ce60) 28 | 29 | ## [v2.1.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.9.1...v2.1.1) - 2024-04-17 30 | 31 | ## [@anvilco/react-signature-frame@1.9.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.9.0...@anvilco/react-signature-frame@1.9.1) - 2025-10-27 32 | 33 | ### Merged 34 | 35 | - iframeURL instead of signURL [`#25`](https://github.com/anvilco/react-ui/pull/25) 36 | 37 | ### Commits 38 | 39 | - fix up packaging [`74ce1cb`](https://github.com/anvilco/react-ui/commit/74ce1cb7a77295545ef89b6f43777e874ec5ce60) 40 | 41 | ## [@anvilco/react-signature-frame@1.9.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.8.3...@anvilco/react-signature-frame@1.9.0) - 2024-05-02 42 | 43 | ### Merged 44 | 45 | - Add className prop and type [`#22`](https://github.com/anvilco/react-ui/pull/22) 46 | - publish better [`#20`](https://github.com/anvilco/react-ui/pull/20) 47 | - Add style prop and add postMessage helper [`#19`](https://github.com/anvilco/react-ui/pull/19) 48 | - [Breaking] Update dependencies [`#16`](https://github.com/anvilco/react-ui/pull/16) 49 | - Update readme to fix import error [`#15`](https://github.com/anvilco/react-ui/pull/15) 50 | 51 | ### Commits 52 | 53 | - Update deps [`52a73bd`](https://github.com/anvilco/react-ui/commit/52a73bd5f16d5435f80cd8ae76f20b2834807c40) 54 | 55 | ## [@anvilco/react-signature-frame@1.8.3](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.8.2...@anvilco/react-signature-frame@1.8.3) - 2022-10-05 56 | 57 | ### Merged 58 | 59 | - Add Typescript support to `AnvilEmbedFrame` [`#13`](https://github.com/anvilco/react-ui/pull/13) 60 | - New `@anvilco/anvil-embed-frame` package [`#12`](https://github.com/anvilco/react-ui/pull/12) 61 | 62 | ### Commits 63 | 64 | - add package files [`da0e18b`](https://github.com/anvilco/react-ui/commit/da0e18ba795d467d7b62b66069932bb84e9bd05e) 65 | 66 | ## [@anvilco/react-signature-frame@1.8.2](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.8.1...@anvilco/react-signature-frame@1.8.2) - 2022-05-25 67 | 68 | ### Merged 69 | 70 | - Update Readme [`#11`](https://github.com/anvilco/react-ui/pull/11) 71 | 72 | ### Commits 73 | 74 | - Add blurb to package readmes [`7e670e0`](https://github.com/anvilco/react-ui/commit/7e670e04d3eb8fb00b19927220dde0083d2f07ae) 75 | 76 | ## [@anvilco/react-signature-frame@1.8.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.8.0...@anvilco/react-signature-frame@1.8.1) - 2022-04-18 77 | 78 | ### Merged 79 | 80 | - [1-min] Fix output path for type defs [`#10`](https://github.com/anvilco/react-ui/pull/10) 81 | 82 | ### Commits 83 | 84 | - Update CHANGELOG [`a4e0dec`](https://github.com/anvilco/react-ui/commit/a4e0dece2bd52702da8d0c60db06c070c1d7d4ff) 85 | 86 | ## [@anvilco/react-signature-frame@1.8.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.7.1...@anvilco/react-signature-frame@1.8.0) - 2022-04-18 87 | 88 | ### Merged 89 | 90 | - Add Typescript typings [`#9`](https://github.com/anvilco/react-ui/pull/9) 91 | 92 | ### Commits 93 | 94 | - Add initial TS support for packages [`0154812`](https://github.com/anvilco/react-ui/commit/0154812070cd23eb7f409efec7dd34dd7aef4f77) 95 | 96 | ## [@anvilco/react-signature-frame@1.7.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.7.0...@anvilco/react-signature-frame@1.7.1) - 2022-03-31 97 | 98 | ### Merged 99 | 100 | - Update dependencies and peer dependencies [`#7`](https://github.com/anvilco/react-ui/pull/7) 101 | 102 | ### Commits 103 | 104 | - Update CHANGELOG [`a48550b`](https://github.com/anvilco/react-ui/commit/a48550b1889bd411531e6eb3808e7b6ce63be61b) 105 | 106 | ## [@anvilco/react-signature-frame@1.7.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.6.0...@anvilco/react-signature-frame@1.7.0) - 2022-03-31 107 | 108 | ### Commits 109 | 110 | - Update dependencies [`d5ee61b`](https://github.com/anvilco/react-ui/commit/d5ee61b147655d4ca1de4b968b54f09a3d162de4) 111 | - Update peer dependencies [`6c19399`](https://github.com/anvilco/react-ui/commit/6c19399e15d8922aeee87dee14da14c10a0405f3) 112 | - Update changelogs [`16affa7`](https://github.com/anvilco/react-ui/commit/16affa7746d135f3e09d0cb4104f0ef24e4547cc) 113 | 114 | ## [@anvilco/react-signature-frame@1.6.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.5.0...@anvilco/react-signature-frame@1.6.0) - 2021-10-26 115 | 116 | ### Merged 117 | 118 | - Add onError handler [`#6`](https://github.com/anvilco/react-ui/pull/6) 119 | 120 | ### Commits 121 | 122 | - Add mocha / enzyme tests [`697d7a2`](https://github.com/anvilco/react-ui/commit/697d7a2e0b67c182b7c213847c45879fe5309d45) 123 | 124 | ## [@anvilco/react-signature-frame@1.5.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.4.6...@anvilco/react-signature-frame@1.5.0) - 2021-10-20 125 | 126 | ### Merged 127 | 128 | - Add onFinishSigning prop & upgrade all minor version deps [`#5`](https://github.com/anvilco/react-ui/pull/5) 129 | - Refactor the Docs [`#3`](https://github.com/anvilco/react-ui/pull/3) 130 | - Review Follow Ups and Refactoring [`#2`](https://github.com/anvilco/react-ui/pull/2) 131 | 132 | ### Commits 133 | 134 | - all minor upgrades [`ce50a7b`](https://github.com/anvilco/react-ui/commit/ce50a7b1c106a868d45e00f7616d4e7b024bd29a) 135 | 136 | ## [@anvilco/react-signature-frame@1.4.6](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.4.5...@anvilco/react-signature-frame@1.4.6) - 2020-12-03 137 | 138 | ### Commits 139 | 140 | - remove enableDefaultStyles from modal component [`7a8bdbb`](https://github.com/anvilco/react-ui/commit/7a8bdbb108599ee86aae0e05386c223ac1de2d9f) 141 | - add css media queries to modal [`3f12aed`](https://github.com/anvilco/react-ui/commit/3f12aed362444872ea920fd3c14e703813811a2f) 142 | - update docs for styling [`4c88290`](https://github.com/anvilco/react-ui/commit/4c88290dbac227d8f8e01f96e270ed8fcfa2021a) 143 | 144 | ## [@anvilco/react-signature-frame@1.4.5](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.4.4...@anvilco/react-signature-frame@1.4.5) - 2020-12-02 145 | 146 | ### Commits 147 | 148 | - Publish [`e6dcf2a`](https://github.com/anvilco/react-ui/commit/e6dcf2a5d113e26f4777932a488db115d2ab1ce3) 149 | - signatureFrame should have 'withinIframe' query param in signURL [`d6268cf`](https://github.com/anvilco/react-ui/commit/d6268cfa2cc5b1f6304ab6aed7aef8f7892cac1d) 150 | - Update index.js [`050ffcc`](https://github.com/anvilco/react-ui/commit/050ffcc1760df814ec0d2eb919d9b8ae8f21c949) 151 | 152 | ## [@anvilco/react-signature-frame@1.4.4](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.4.3...@anvilco/react-signature-frame@1.4.4) - 2020-11-24 153 | 154 | ### Commits 155 | 156 | - component updates from review [`309d070`](https://github.com/anvilco/react-ui/commit/309d070d451cb6ef7fa2d0fb8626f224b24b1665) 157 | - Publish [`764437b`](https://github.com/anvilco/react-ui/commit/764437b3963b12b0ca7f7f53a26d2c83e334fa7c) 158 | 159 | ## [@anvilco/react-signature-frame@1.4.3](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.4.2...@anvilco/react-signature-frame@1.4.3) - 2020-11-18 160 | 161 | ### Merged 162 | 163 | - Setup Linting [`#1`](https://github.com/anvilco/react-ui/pull/1) 164 | 165 | ### Commits 166 | 167 | - convert to class components [`7801184`](https://github.com/anvilco/react-ui/commit/7801184ad8f819f206348fc8807ce6da4f661b8a) 168 | 169 | ## [@anvilco/react-signature-frame@1.4.2](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.4.1...@anvilco/react-signature-frame@1.4.2) - 2020-11-16 170 | 171 | ### Commits 172 | 173 | - let css control width/height [`eb3ed23`](https://github.com/anvilco/react-ui/commit/eb3ed2357a1489839a08c7dac8a6cc47163c0c93) 174 | - Publish [`99fed5b`](https://github.com/anvilco/react-ui/commit/99fed5b7a7f19c0ab1df63b7e7ccdcfbdc76af04) 175 | 176 | ## [@anvilco/react-signature-frame@1.4.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.4.0...@anvilco/react-signature-frame@1.4.1) - 2020-11-16 177 | 178 | ### Commits 179 | 180 | - lotta docs [`1abd6c3`](https://github.com/anvilco/react-ui/commit/1abd6c32eb4e0ba859805c7153f20977e81ec6e8) 181 | - use react-modal [`015048c`](https://github.com/anvilco/react-ui/commit/015048cf2e22ba6b99360358fbd1cc4d66a09cb8) 182 | - update webpack output to /dist [`49145ef`](https://github.com/anvilco/react-ui/commit/49145ef75764f517737a317caf9a8ffce8a79e78) 183 | 184 | ## [@anvilco/react-signature-frame@1.4.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.3.0...@anvilco/react-signature-frame@1.4.0) - 2020-11-13 185 | 186 | ### Commits 187 | 188 | - more package.json scripts, let components work with staging [`354cee0`](https://github.com/anvilco/react-ui/commit/354cee088db9316d7a87587a84fef4babfa03c51) 189 | - update classnames and id's to start with anvil [`cc5d7d9`](https://github.com/anvilco/react-ui/commit/cc5d7d9253edf63b466abd422b02a555d5d8a6db) 190 | - add miniCssExtractPlugin [`fde50f0`](https://github.com/anvilco/react-ui/commit/fde50f01733c56df7a8e431c1406ba0f444d5a93) 191 | 192 | ## [@anvilco/react-signature-frame@1.3.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.2.0...@anvilco/react-signature-frame@1.3.0) - 2020-11-12 193 | 194 | ### Commits 195 | 196 | - packages v0.0.0 [`295fbc8`](https://github.com/anvilco/react-ui/commit/295fbc8b64030437a3eb73d35abe453312cc1b08) 197 | - remove private: true in root package.json [`bac98a2`](https://github.com/anvilco/react-ui/commit/bac98a2b47870d1128aab58859e26085a0d086c7) 198 | - Publish [`ec2671e`](https://github.com/anvilco/react-ui/commit/ec2671ed64922bc7c7e151657680b28e17b39606) 199 | 200 | ## [@anvilco/react-signature-frame@1.2.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.1.0...@anvilco/react-signature-frame@1.2.0) - 2020-11-12 201 | 202 | ### Commits 203 | 204 | - packages v1.0.0 [`42168e8`](https://github.com/anvilco/react-ui/commit/42168e8c1f9245a64471eaea1752a708de432b36) 205 | - Publish [`d78f954`](https://github.com/anvilco/react-ui/commit/d78f954e8fa1ddd9121fb27442fb4657fdd7b902) 206 | - Publish [`a7e5cd9`](https://github.com/anvilco/react-ui/commit/a7e5cd922b184af47087c83e7370269d38cf7c93) 207 | 208 | ## [@anvilco/react-signature-frame@1.1.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.0.2-alpha.0...@anvilco/react-signature-frame@1.1.0) - 2020-11-12 209 | 210 | ### Commits 211 | 212 | - move react, react-dom, prop-types to each package.json [`ed6c725`](https://github.com/anvilco/react-ui/commit/ed6c725fa03d120b227645be83fa797e77f10ee8) 213 | - add webpack externals [`ca3152c`](https://github.com/anvilco/react-ui/commit/ca3152c48e81182af82383bcec4f65c8cadf9c4b) 214 | - add webpack sourcemap [`78b3189`](https://github.com/anvilco/react-ui/commit/78b318931f0fd7fdc893d039fc2c52c173a223e2) 215 | 216 | ## [@anvilco/react-signature-frame@1.0.2-alpha.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-frame@1.0.0...@anvilco/react-signature-frame@1.0.2-alpha.0) - 2020-11-11 217 | 218 | ## @anvilco/react-signature-frame@1.0.0 - 2020-11-12 219 | 220 | ### Commits 221 | 222 | - AnvilSignatureFrame and AnvilSignatureModal [`7ab8fc2`](https://github.com/anvilco/react-ui/commit/7ab8fc2026411cbcc0186d9650290ba3d1afcfa5) 223 | - publish config [`c3683cc`](https://github.com/anvilco/react-ui/commit/c3683ccb2dd12523ae85118d26307fc5ab2cd495) 224 | - add babel devDependencies [`51ce830`](https://github.com/anvilco/react-ui/commit/51ce830e44defc0615261f94a42e9b7bc156c4f4) 225 | -------------------------------------------------------------------------------- /packages/react-signature-modal/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [v2.1.3](https://github.com/anvilco/react-ui/compare/v2.1.2...v2.1.3) - 2025-10-28 6 | 7 | ### Commits 8 | 9 | - set document inside component did mount [`5a055ed`](https://github.com/anvilco/react-ui/commit/5a055edfd2d5dcef9d3b6c4b8d6dd4a8fd1def77) 10 | 11 | ## [v2.1.2](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@2.1.1...v2.1.2) - 2025-10-27 12 | 13 | ## [@anvilco/react-signature-modal@2.1.1](https://github.com/anvilco/react-ui/compare/v2.1.1...@anvilco/react-signature-modal@2.1.1) - 2025-10-27 14 | 15 | ### Merged 16 | 17 | - iframeURL instead of signURL [`#25`](https://github.com/anvilco/react-ui/pull/25) 18 | - Add className prop and type [`#22`](https://github.com/anvilco/react-ui/pull/22) 19 | - publish better [`#20`](https://github.com/anvilco/react-ui/pull/20) 20 | 21 | ### Commits 22 | 23 | - fix up packaging [`74ce1cb`](https://github.com/anvilco/react-ui/commit/74ce1cb7a77295545ef89b6f43777e874ec5ce60) 24 | 25 | ## [v2.1.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@2.1.0...v2.1.1) - 2024-04-17 26 | 27 | ## [@anvilco/react-signature-modal@2.1.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@2.0.1...@anvilco/react-signature-modal@2.1.0) - 2024-05-02 28 | 29 | ### Merged 30 | 31 | - Add className prop and type [`#22`](https://github.com/anvilco/react-ui/pull/22) 32 | - publish better [`#20`](https://github.com/anvilco/react-ui/pull/20) 33 | - Add style prop and add postMessage helper [`#19`](https://github.com/anvilco/react-ui/pull/19) 34 | 35 | ### Commits 36 | 37 | - yarn lock updates [`57401aa`](https://github.com/anvilco/react-ui/commit/57401aa56d7a70f352382768c0be8fd536b5d5e2) 38 | 39 | ## [@anvilco/react-signature-modal@2.0.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@2.0.1-alpha.0...@anvilco/react-signature-modal@2.0.1) - 2023-09-20 40 | 41 | ### Merged 42 | 43 | - [Breaking] Update dependencies [`#16`](https://github.com/anvilco/react-ui/pull/16) 44 | 45 | ### Commits 46 | 47 | - Update readmes [`c932e4c`](https://github.com/anvilco/react-ui/commit/c932e4c5716c0b113f1840baeb0aa9118facdc26) 48 | 49 | ## [@anvilco/react-signature-modal@2.0.1-alpha.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@2.0.0-alpha.0...@anvilco/react-signature-modal@2.0.1-alpha.0) - 2023-09-19 50 | 51 | ### Commits 52 | 53 | - Publish [`d758493`](https://github.com/anvilco/react-ui/commit/d7584938d5a472eb1f86af81128a96316e0739af) 54 | - Update signURL -> iframeURL [`9569521`](https://github.com/anvilco/react-ui/commit/956952117657671ec841e3c042219537a74ffd6e) 55 | 56 | ## [@anvilco/react-signature-modal@2.0.0-alpha.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.8.4...@anvilco/react-signature-modal@2.0.0-alpha.0) - 2023-09-18 57 | 58 | ### Commits 59 | 60 | - Update deps [`52a73bd`](https://github.com/anvilco/react-ui/commit/52a73bd5f16d5435f80cd8ae76f20b2834807c40) 61 | - Upgrade all deps [`2a89f80`](https://github.com/anvilco/react-ui/commit/2a89f80996fdf9bac6b4dfc2cd343641955dc20c) 62 | - Publish [`4024144`](https://github.com/anvilco/react-ui/commit/4024144e3122e2e2feae8b0a119a413348e47651) 63 | 64 | ## [@anvilco/react-signature-modal@1.8.4](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.8.3...@anvilco/react-signature-modal@1.8.4) - 2023-08-04 65 | 66 | ### Merged 67 | 68 | - Update readme to fix import error [`#15`](https://github.com/anvilco/react-ui/pull/15) 69 | 70 | ### Commits 71 | 72 | - Remove AnvilSignatureFrame from main readme + fix import [`f93ef25`](https://github.com/anvilco/react-ui/commit/f93ef251be022bae5521fa57cd3fac818e896954) 73 | 74 | ## [@anvilco/react-signature-modal@1.8.3](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.8.2...@anvilco/react-signature-modal@1.8.3) - 2022-10-05 75 | 76 | ### Merged 77 | 78 | - Add Typescript support to `AnvilEmbedFrame` [`#13`](https://github.com/anvilco/react-ui/pull/13) 79 | - New `@anvilco/anvil-embed-frame` package [`#12`](https://github.com/anvilco/react-ui/pull/12) 80 | 81 | ### Commits 82 | 83 | - add package files [`da0e18b`](https://github.com/anvilco/react-ui/commit/da0e18ba795d467d7b62b66069932bb84e9bd05e) 84 | 85 | ## [@anvilco/react-signature-modal@1.8.2](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.8.1...@anvilco/react-signature-modal@1.8.2) - 2022-05-25 86 | 87 | ### Merged 88 | 89 | - Update Readme [`#11`](https://github.com/anvilco/react-ui/pull/11) 90 | 91 | ### Commits 92 | 93 | - Add blurb to package readmes [`7e670e0`](https://github.com/anvilco/react-ui/commit/7e670e04d3eb8fb00b19927220dde0083d2f07ae) 94 | 95 | ## [@anvilco/react-signature-modal@1.8.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.8.0...@anvilco/react-signature-modal@1.8.1) - 2022-04-18 96 | 97 | ### Merged 98 | 99 | - [1-min] Fix output path for type defs [`#10`](https://github.com/anvilco/react-ui/pull/10) 100 | 101 | ### Commits 102 | 103 | - Update CHANGELOG [`a4e0dec`](https://github.com/anvilco/react-ui/commit/a4e0dece2bd52702da8d0c60db06c070c1d7d4ff) 104 | 105 | ## [@anvilco/react-signature-modal@1.8.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.7.1...@anvilco/react-signature-modal@1.8.0) - 2022-04-18 106 | 107 | ### Merged 108 | 109 | - Add Typescript typings [`#9`](https://github.com/anvilco/react-ui/pull/9) 110 | 111 | ### Commits 112 | 113 | - Add initial TS support for packages [`0154812`](https://github.com/anvilco/react-ui/commit/0154812070cd23eb7f409efec7dd34dd7aef4f77) 114 | 115 | ## [@anvilco/react-signature-modal@1.7.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.7.0...@anvilco/react-signature-modal@1.7.1) - 2022-03-31 116 | 117 | ### Merged 118 | 119 | - Update dependencies and peer dependencies [`#7`](https://github.com/anvilco/react-ui/pull/7) 120 | 121 | ### Commits 122 | 123 | - Update CHANGELOG [`a48550b`](https://github.com/anvilco/react-ui/commit/a48550b1889bd411531e6eb3808e7b6ce63be61b) 124 | 125 | ## [@anvilco/react-signature-modal@1.7.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.6.0...@anvilco/react-signature-modal@1.7.0) - 2022-03-31 126 | 127 | ### Commits 128 | 129 | - Update dependencies [`d5ee61b`](https://github.com/anvilco/react-ui/commit/d5ee61b147655d4ca1de4b968b54f09a3d162de4) 130 | - Update peer dependencies [`6c19399`](https://github.com/anvilco/react-ui/commit/6c19399e15d8922aeee87dee14da14c10a0405f3) 131 | - Update changelogs [`16affa7`](https://github.com/anvilco/react-ui/commit/16affa7746d135f3e09d0cb4104f0ef24e4547cc) 132 | 133 | ## [@anvilco/react-signature-modal@1.6.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.5.0...@anvilco/react-signature-modal@1.6.0) - 2021-10-26 134 | 135 | ### Merged 136 | 137 | - Add onError handler [`#6`](https://github.com/anvilco/react-ui/pull/6) 138 | 139 | ### Commits 140 | 141 | - Add mocha / enzyme tests [`697d7a2`](https://github.com/anvilco/react-ui/commit/697d7a2e0b67c182b7c213847c45879fe5309d45) 142 | 143 | ## [@anvilco/react-signature-modal@1.5.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.4.6...@anvilco/react-signature-modal@1.5.0) - 2021-10-20 144 | 145 | ### Merged 146 | 147 | - Add onFinishSigning prop & upgrade all minor version deps [`#5`](https://github.com/anvilco/react-ui/pull/5) 148 | - Refactor the Docs [`#3`](https://github.com/anvilco/react-ui/pull/3) 149 | - Review Follow Ups and Refactoring [`#2`](https://github.com/anvilco/react-ui/pull/2) 150 | 151 | ### Commits 152 | 153 | - all minor upgrades [`ce50a7b`](https://github.com/anvilco/react-ui/commit/ce50a7b1c106a868d45e00f7616d4e7b024bd29a) 154 | 155 | ## [@anvilco/react-signature-modal@1.4.6](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.4.5...@anvilco/react-signature-modal@1.4.6) - 2020-12-03 156 | 157 | ### Commits 158 | 159 | - remove enableDefaultStyles from modal component [`7a8bdbb`](https://github.com/anvilco/react-ui/commit/7a8bdbb108599ee86aae0e05386c223ac1de2d9f) 160 | - add css media queries to modal [`3f12aed`](https://github.com/anvilco/react-ui/commit/3f12aed362444872ea920fd3c14e703813811a2f) 161 | - update docs for styling [`4c88290`](https://github.com/anvilco/react-ui/commit/4c88290dbac227d8f8e01f96e270ed8fcfa2021a) 162 | 163 | ## [@anvilco/react-signature-modal@1.4.5](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.4.4...@anvilco/react-signature-modal@1.4.5) - 2020-12-02 164 | 165 | ### Commits 166 | 167 | - Publish [`e6dcf2a`](https://github.com/anvilco/react-ui/commit/e6dcf2a5d113e26f4777932a488db115d2ab1ce3) 168 | - signatureFrame should have 'withinIframe' query param in signURL [`d6268cf`](https://github.com/anvilco/react-ui/commit/d6268cfa2cc5b1f6304ab6aed7aef8f7892cac1d) 169 | - Update index.js [`050ffcc`](https://github.com/anvilco/react-ui/commit/050ffcc1760df814ec0d2eb919d9b8ae8f21c949) 170 | 171 | ## [@anvilco/react-signature-modal@1.4.4](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.4.3...@anvilco/react-signature-modal@1.4.4) - 2020-11-24 172 | 173 | ### Commits 174 | 175 | - component updates from review [`309d070`](https://github.com/anvilco/react-ui/commit/309d070d451cb6ef7fa2d0fb8626f224b24b1665) 176 | - Publish [`764437b`](https://github.com/anvilco/react-ui/commit/764437b3963b12b0ca7f7f53a26d2c83e334fa7c) 177 | 178 | ## [@anvilco/react-signature-modal@1.4.3](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.4.2...@anvilco/react-signature-modal@1.4.3) - 2020-11-18 179 | 180 | ### Merged 181 | 182 | - Setup Linting [`#1`](https://github.com/anvilco/react-ui/pull/1) 183 | 184 | ### Commits 185 | 186 | - convert to class components [`7801184`](https://github.com/anvilco/react-ui/commit/7801184ad8f819f206348fc8807ce6da4f661b8a) 187 | 188 | ## [@anvilco/react-signature-modal@1.4.2](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.4.1...@anvilco/react-signature-modal@1.4.2) - 2020-11-16 189 | 190 | ### Commits 191 | 192 | - let css control width/height [`eb3ed23`](https://github.com/anvilco/react-ui/commit/eb3ed2357a1489839a08c7dac8a6cc47163c0c93) 193 | - Publish [`99fed5b`](https://github.com/anvilco/react-ui/commit/99fed5b7a7f19c0ab1df63b7e7ccdcfbdc76af04) 194 | 195 | ## [@anvilco/react-signature-modal@1.4.1](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.4.0...@anvilco/react-signature-modal@1.4.1) - 2020-11-16 196 | 197 | ### Commits 198 | 199 | - lotta docs [`1abd6c3`](https://github.com/anvilco/react-ui/commit/1abd6c32eb4e0ba859805c7153f20977e81ec6e8) 200 | - use react-modal [`015048c`](https://github.com/anvilco/react-ui/commit/015048cf2e22ba6b99360358fbd1cc4d66a09cb8) 201 | - update webpack output to /dist [`49145ef`](https://github.com/anvilco/react-ui/commit/49145ef75764f517737a317caf9a8ffce8a79e78) 202 | 203 | ## [@anvilco/react-signature-modal@1.4.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.3.0...@anvilco/react-signature-modal@1.4.0) - 2020-11-13 204 | 205 | ### Commits 206 | 207 | - more package.json scripts, let components work with staging [`354cee0`](https://github.com/anvilco/react-ui/commit/354cee088db9316d7a87587a84fef4babfa03c51) 208 | - update classnames and id's to start with anvil [`cc5d7d9`](https://github.com/anvilco/react-ui/commit/cc5d7d9253edf63b466abd422b02a555d5d8a6db) 209 | - add miniCssExtractPlugin [`fde50f0`](https://github.com/anvilco/react-ui/commit/fde50f01733c56df7a8e431c1406ba0f444d5a93) 210 | 211 | ## [@anvilco/react-signature-modal@1.3.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.2.0...@anvilco/react-signature-modal@1.3.0) - 2020-11-12 212 | 213 | ### Commits 214 | 215 | - packages v0.0.0 [`295fbc8`](https://github.com/anvilco/react-ui/commit/295fbc8b64030437a3eb73d35abe453312cc1b08) 216 | - remove private: true in root package.json [`bac98a2`](https://github.com/anvilco/react-ui/commit/bac98a2b47870d1128aab58859e26085a0d086c7) 217 | - Publish [`ec2671e`](https://github.com/anvilco/react-ui/commit/ec2671ed64922bc7c7e151657680b28e17b39606) 218 | 219 | ## [@anvilco/react-signature-modal@1.2.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.1.0...@anvilco/react-signature-modal@1.2.0) - 2020-11-12 220 | 221 | ### Commits 222 | 223 | - packages v1.0.0 [`42168e8`](https://github.com/anvilco/react-ui/commit/42168e8c1f9245a64471eaea1752a708de432b36) 224 | - Publish [`d78f954`](https://github.com/anvilco/react-ui/commit/d78f954e8fa1ddd9121fb27442fb4657fdd7b902) 225 | - Publish [`a7e5cd9`](https://github.com/anvilco/react-ui/commit/a7e5cd922b184af47087c83e7370269d38cf7c93) 226 | 227 | ## [@anvilco/react-signature-modal@1.1.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.0.2-alpha.0...@anvilco/react-signature-modal@1.1.0) - 2020-11-12 228 | 229 | ### Commits 230 | 231 | - move react, react-dom, prop-types to each package.json [`ed6c725`](https://github.com/anvilco/react-ui/commit/ed6c725fa03d120b227645be83fa797e77f10ee8) 232 | - add webpack externals [`ca3152c`](https://github.com/anvilco/react-ui/commit/ca3152c48e81182af82383bcec4f65c8cadf9c4b) 233 | - add webpack sourcemap [`78b3189`](https://github.com/anvilco/react-ui/commit/78b318931f0fd7fdc893d039fc2c52c173a223e2) 234 | 235 | ## [@anvilco/react-signature-modal@1.0.2-alpha.0](https://github.com/anvilco/react-ui/compare/@anvilco/react-signature-modal@1.0.0...@anvilco/react-signature-modal@1.0.2-alpha.0) - 2020-11-11 236 | 237 | ## @anvilco/react-signature-modal@1.0.0 - 2020-11-12 238 | 239 | ### Commits 240 | 241 | - AnvilSignatureFrame and AnvilSignatureModal [`7ab8fc2`](https://github.com/anvilco/react-ui/commit/7ab8fc2026411cbcc0186d9650290ba3d1afcfa5) 242 | - publish config [`c3683cc`](https://github.com/anvilco/react-ui/commit/c3683ccb2dd12523ae85118d26307fc5ab2cd495) 243 | - add babel devDependencies [`51ce830`](https://github.com/anvilco/react-ui/commit/51ce830e44defc0615261f94a42e9b7bc156c4f4) 244 | --------------------------------------------------------------------------------