-
Couldn't load subscription status.
- Fork 5
Add Custom Overlay Signing Demo for Document Workflows #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Did some QA, below are my findings:
CleanShot.2025-10-28.at.21.49.15.mp4
CleanShot.2025-10-28.at.21.57.33.mp4
CleanShot.2025-10-28.at.22.03.20.mp4 |
@InosRahul thanks a lot.
3. will add
4. will add
5. I'll check it out
|
| ## Support | ||
|
|
||
| For issues related to: | ||
| - **Nutrient Viewer**: Check the [Nutrient documentation](https://docs.nutrient.io/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This URL is incorrect. Should be https://www.nutrient.io/guides/web/
| The demo now supports all available NutrientViewer FormField types: | ||
| - **SignatureFormField**: Signature and Initials | ||
| - **TextFormField**: Text, Name, Email, Date (with format validation) | ||
| - **CheckBoxFormField**: Checkbox controls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I'm wrong but the UI didn't show this,
| ### Developer-Friendly Features | ||
| - **TypeScript-Ready**: Structured for easy TypeScript integration | ||
| - **Modular Architecture**: Separated concerns with dedicated utility modules | ||
| - **Comprehensive Error Handling**: Graceful degradation when SDK features are unavailable | ||
| - **Performance Monitoring**: Built-in performance tracking utilities |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These lines can be removed.
| "widget", | ||
| "overlay" | ||
| ], | ||
| "author": "Your Name", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be Nutrient or Eli
| "license": "MIT", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/yourusername/nutrient-signing-demo.git" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL should be corrected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should commit this file. Can be kept in .gitignore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Completely disagree. Always keep the package-lock.json. That's the only thing that actually freezes the versions of the dependencies.
https://docs.npmjs.com/cli/v11/configuring-npm/package-lock-json#description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh yes, I forgot about this. My comment can be ignored in this case, thank you for correcting.
| }; | ||
|
|
||
| // Widget Overlay Manager Class | ||
| class WidgetOverlayManager { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there a class inside a hook file? 😲 You can probably extract this into a different file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, definitely to be extracted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, This could be a nightmare to debug. This should be simplified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All in all it looks solid. Few comments, but mostly me being annoying and/or a smartass. All in all good job! Happy to approve once @InosRahul is happy.
One thing to consider - you have a lot of CSS text just baked in the code. Might be worth to "unbloat" the code by extracting it to classes and applying those to elements, but that's just a personal taste kind of thing.
| }; | ||
|
|
||
| // Widget Overlay Manager Class | ||
| class WidgetOverlayManager { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, definitely to be extracted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Completely disagree. Always keep the package-lock.json. That's the only thing that actually freezes the versions of the dependencies.
https://docs.npmjs.com/cli/v11/configuring-npm/package-lock-json#description
| function hexToRgb(hex) { | ||
| const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); | ||
| return result ? | ||
| `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}` : | ||
| "0, 123, 255"; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Sorry, I have natural allergy to regex -- if you're happy with this, ignore this comment.
This helper's not really required, since you're only using it with element.style.backgroundColor. CSS can take color in a lot of formats, including hex. That also includes opacity, so if you have a color #aaffee and want to change it to 10% opacity, you can just write it as #aaffee1a (where 1a is 0.1 * 255 ≈ 26). So lines like fieldElement.style.backgroundColor = 'rgba(${hexToRgb(fieldType.color)}, 0.1)'; can be simplified to fieldElement.style.backgroundColor = fieldType.color + "1a";. It's also a little more performant for the browser to render, but that's a totally marginal gain.
Also this helper function kinda doesn't really belong here, but I'm just being annoying, it doesn't matter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the idea and I understand ui customization guides use dynamic element creation, but I feel like this is taking it to extreme, resulting in very hard to maintain code. Since you're using React, I'd consider hacking it around a bit, creating a proper React component and just returning it as HTMLElement. I did not test this approach and can't guarantee it'll work, but think it's worth exploring. Here's a short snippet that might help, by the courtesy of GPT 5-mini:
import { createRoot } from 'react-dom/client';
function createInteractiveElement(props) {
const container = document.createElement('div'); // not in DOM unless you append it
const root = createRoot(container);
root.render(<MyComplexComponent {...props} />);
// Return the element the library expects.
// If the library will insert this into the document, you may want to return container.firstElementChild
// or append `container` itself where needed.
return {
element: container.firstElementChild,
cleanup: () => root.unmount(), // caller can call when done
};
}Please feel free to reach out if you need help with that.



Overview
This PR introduces a new signing demo implementation that leverages Custom Overlays instead of the traditional CustomRenderer callback approach, providing a more robust and developer-friendly solution for signing workflows.
Key Features
Why Custom Overlays Beat CustomRenderer?
The Problem with CustomRenderer:
The Custom Overlay Solution:
Key Technical Improvements
Demo Capabilities
This approach provides a more maintainable and scalable foundation for document signing workflows while significantly reducing implementation complexity.