pushfeedback 0.1.69 → 0.1.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/cjs/{feedback-button_2.cjs.entry.js → canvas-editor_3.cjs.entry.js} +883 -718
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/pushfeedback.cjs.js +1 -1
  4. package/dist/collection/collection-manifest.json +1 -0
  5. package/dist/collection/components/canvas-editor/canvas-editor.css +404 -0
  6. package/dist/collection/components/canvas-editor/canvas-editor.js +1282 -0
  7. package/dist/collection/components/feedback-button/feedback-button.js +220 -0
  8. package/dist/collection/components/feedback-modal/feedback-modal.css +2 -458
  9. package/dist/collection/components/feedback-modal/feedback-modal.js +247 -782
  10. package/dist/components/canvas-editor.d.ts +11 -0
  11. package/dist/components/canvas-editor.js +6 -0
  12. package/dist/components/canvas-editor2.js +917 -0
  13. package/dist/components/feedback-button.js +40 -1
  14. package/dist/components/feedback-modal2.js +68 -784
  15. package/dist/components/index.d.ts +1 -0
  16. package/dist/components/index.js +1 -0
  17. package/dist/esm/{feedback-button_2.entry.js → canvas-editor_3.entry.js} +883 -719
  18. package/dist/esm/loader.js +1 -1
  19. package/dist/esm/pushfeedback.js +1 -1
  20. package/dist/pushfeedback/p-2c39091c.entry.js +1 -0
  21. package/dist/pushfeedback/pushfeedback.esm.js +1 -1
  22. package/dist/types/components/canvas-editor/canvas-editor.d.ts +108 -0
  23. package/dist/types/components/feedback-button/feedback-button.d.ts +11 -0
  24. package/dist/types/components/feedback-modal/feedback-modal.d.ts +22 -79
  25. package/dist/types/components.d.ts +102 -0
  26. package/package.json +3 -4
  27. package/dist/pushfeedback/p-e7f48090.entry.js +0 -1
@@ -1,6 +1,7 @@
1
1
  import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
2
+ import { d as defineCustomElement$1 } from './canvas-editor2.js';
2
3
 
3
- const feedbackModalCss = ".text-center{flex-grow:1;text-align:center}.feedback-modal-wrapper *{font-family:var(--feedback-font-family)}.feedback-modal-wrapper--custom-font *{font-family:inherit}.feedback-modal-wrapper{position:absolute;z-index:var(--feedback-modal-modal-wrapper-z-index)}.feedback-overlay{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;opacity:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index);transition:opacity 0.2s ease-out}.feedback-overlay--visible{opacity:1}.feedback-modal{display:inline-block;position:relative}.feedback-modal-content{background-color:var(--feedback-modal-content-bg-color);border-color:1px solid var(--feedback-modal-header-text-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-content-text-color);display:flex;flex-direction:column;left:50%;max-width:90%;padding:20px;position:fixed;top:50%;transform:translate(-50%, -50%) scale(0.95);opacity:0;width:100%;z-index:var(--feedback-modal-content-z-index);transition:transform 0.2s ease-out, opacity 0.2s ease-out}.feedback-modal-content--open{transform:translate(-50%, -50%) scale(1);opacity:1}.feedback-modal-header{align-items:center;color:var(--feedback-modal-header-text-color);display:flex;font-size:var(--feedback-header-font-size);font-weight:var(--feedback-modal-header-font-weight);justify-content:space-between;margin-bottom:20px}.feedback-modal-rating-buttons{width:100%;margin-bottom:20px}.feedback-modal-rating-button{padding:0;background-color:transparent;border:transparent;margin-right:5px;cursor:pointer}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button{border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);font-size:var(--feedback-modal-button-font-size);font-weight:500;margin-right:10px;justify-content:center;padding:5px 10px}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover svg,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected svg{stroke:var(--feedback-modal-rating-button-selected-color)}.feedback-modal-rating-buttons svg{stroke:var(--feedback-modal-rating-button-color);cursor:pointer}.feedback-modal-rating-buttons--stars .feedback-modal-rating-button--selected svg{fill:var(--feedback-modal-rating-button-stars-selected-color);stroke:var(--feedback-modal-rating-button-stars-selected-color)}.feedback-modal-text textarea{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:100px;min-height:100px;padding:10px;resize:vertical;width:100%}.feedback-modal-email input{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:40px;padding:10px;width:100%;margin-bottom:20px}.feedback-modal-privacy{font-size:var(--feedback-modal-input-font-size);margin-bottom:20px}.feedback-modal-text textarea:focus,.feedback-modal-email input:focus{border:1px solid var(--feedback-modal-input-border-color-focused);outline:none}.feedback-modal-buttons{display:flex;flex-direction:column}.feedback-modal-buttons .feedback-modal-button{margin-bottom:20px}.feedback-modal-button{align-items:center;background-color:transparent;border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);cursor:pointer;display:flex;font-size:var(--feedback-modal-button-font-size);font-weight:500;justify-content:center;min-height:40px;padding:5px 10px}.feedback-modal-button svg{margin-right:6px}.feedback-modal-button path{fill:var(--feedback-modal-button-icon-color)}.feedback-modal-button:hover path,.feedback-modal-button--active path{fill:var(--feedback-modal-button-icon-color-active)}.feedback-modal-button--submit{background-color:var(--feedback-modal-button-submit-bg-color);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-submit-text-color)}.feedback-modal-button:hover,.feedback-modal-button--active{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-button--submit:hover{background-color:var(--feedback-modal-button-submit-bg-color-hover);border:1px solid var(--feedback-modal-button-submit-border-color-hover);color:var(--feedback-modal-button-submit-text-color-hover)}.feedback-modal-input-heading{display:block;font-size:14px;font-weight:300;padding-bottom:10px}.feedback-modal-footer{font-size:12px;text-align:center}.feedback-modal-footer a{color:var(--feedback-modal-footer-link);font-weight:500;text-decoration:none}.feedback-logo,.feedback-footer-text{display:block;text-align:center;margin-top:5px}.feedback-footer-text{margin-top:10px;line-height:1.5}.feedback-modal-close{background-color:var(--feedback-modal-close-bg-color);border:0;border-radius:50%;cursor:pointer;height:22px;margin-left:auto;padding:0;width:22px}.feedback-modal-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-screenshot{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index)}.feedback-modal-screenshot-header{align-items:center;background-color:var(--feedback-modal-screenshot-header-bg-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-screenshot-header-text-color);cursor:pointer;display:flex;left:50%;top:20px;transform:translateX(-50%);padding:10px;position:fixed;width:max-content;z-index:var(--feedback-modal-screenshot-header-z-index)}.feedback-modal-screenshot-close{height:24px;padding-left:10px;width:24px}.feedback-modal-screenshot-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-message{font-size:var(--feedback-modal-message-font-size);margin-top:0}.feedback-modal-element-hover{background-color:transparent;cursor:pointer;border:1px solid var(--feedback-modal-element-hover-border-color)}.feedback-modal-element-selected{background-color:transparent;border:3px solid var(--feedback-modal-element-selected-border-color) !important;box-shadow:0 0 0 2px rgba(0, 123, 255, 0.3) !important}.screenshot-preview{display:inline-block;width:30px;height:30px;overflow:hidden;border-radius:4px;margin-right:10px;box-shadow:0 2px 4px rgba(0, 0, 0, 0.1);cursor:pointer;transition:transform 0.2s ease}.screenshot-preview:hover{transform:scale(1.1)}.screenshot-preview img{width:100%;height:100%;object-fit:cover}.screenshot-loading{display:inline-flex;align-items:center;margin-right:8px}.canvas-editor-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:var(--feedback-modal-screenshot-bg-color);z-index:10001;display:flex;align-items:center;justify-content:center}.canvas-editor-modal{width:95vw;height:98vh;background:var(--feedback-canvas-editor-bg-color);border-radius:var(--feedback-modal-content-border-radius);display:flex;flex-direction:column;overflow:hidden;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15)}.canvas-editor-header{background:var(--feedback-canvas-editor-header-bg-color);border-bottom:1px solid var(--feedback-canvas-editor-border-color);padding:12px 16px;display:flex;flex-direction:column;gap:12px;flex-shrink:0}.canvas-editor-title h3{margin:0;font-size:var(--feedback-modal-header-font-size);font-weight:var(--feedback-modal-header-font-weight);color:var(--feedback-modal-header-text-color);font-family:var(--feedback-modal-header-font-family)}.canvas-editor-toolbar{display:flex;align-items:center;gap:20px;flex-wrap:wrap}.toolbar-section{display:flex;align-items:center}.toolbar-section:last-child{margin-left:auto;gap:10px}.tool-group{display:flex;align-items:center;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:4px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .10)}.tool-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;background:none;border-radius:var(--feedback-modal-button-border-radius);cursor:pointer;color:var(--feedback-canvas-editor-tool-text-color);transition:all 0.2s ease;position:relative}.tool-btn:hover{background:var(--feedback-canvas-editor-tool-bg-hover);color:var(--feedback-modal-button-text-color-active)}.tool-btn.active{background:var(--feedback-canvas-editor-tool-bg-active);color:var(--feedback-canvas-editor-tool-text-active)}.tool-btn:disabled{opacity:0.4;cursor:not-allowed}.tool-btn:disabled:hover{background:none;color:var(--feedback-canvas-editor-tool-text-color)}.toolbar-divider{width:1px;height:20px;background:var(--feedback-canvas-editor-divider-color);margin:0 6px}.undo-btn{background:var(--feedback-canvas-editor-tool-bg-color) !important;border:1px solid var(--feedback-canvas-editor-border-color) !important}.undo-btn:hover:not(:disabled){background:var(--feedback-canvas-editor-tool-bg-hover) !important}.color-palette{display:flex;align-items:center;gap:6px;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:6px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .10)}.color-slot-wrapper{position:relative}.color-btn{width:28px;height:28px;border-radius:var(--feedback-modal-button-border-radius);border:2px solid transparent;cursor:pointer;transition:all 0.2s ease;position:relative;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .15);display:flex;align-items:center;justify-content:center}.color-btn:hover{transform:scale(1.05);box-shadow:0px 2px 4px 0px rgba(60, 64, 67, .25)}.color-btn.active{border-color:var(--feedback-primary-color);transform:scale(1.1);box-shadow:0 0 0 2px rgba(0, 112, 244, 0.2)}.color-btn.editing{border-color:var(--feedback-highlight-color);box-shadow:0 0 0 2px rgba(255, 180, 34, 0.3)}.color-btn.editing:hover{border-color:var(--feedback-highlight-color);box-shadow:0 0 0 2px rgba(255, 180, 34, 0.4)}.color-picker-dropdown{position:absolute;top:100%;left:50%;transform:translateX(-50%);margin-top:6px;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:6px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);z-index:1000}.color-picker-dropdown input[type=\"color\"]{width:50px;height:32px;border:none;border-radius:var(--feedback-modal-button-border-radius);cursor:pointer}.size-control{display:flex;align-items:center;gap:10px;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:6px 12px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .10)}.size-slider{width:70px;height:4px;border-radius:2px;background:var(--feedback-canvas-editor-slider-track);outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;border:none}.size-slider::-webkit-slider-track{width:100%;height:4px;cursor:pointer;background:var(--feedback-canvas-editor-slider-track);border-radius:2px;border:none;box-shadow:none}.size-slider::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;border-radius:50%;background:var(--feedback-primary-color);cursor:pointer;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .20);border:none;margin-top:-5px;}.size-slider::-moz-range-track{width:100%;height:4px;cursor:pointer;background:var(--feedback-canvas-editor-slider-track);border-radius:2px;border:none;box-shadow:none}.size-slider::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--feedback-primary-color);cursor:pointer;border:none;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .20)}.size-slider::-moz-range-progress{background:var(--feedback-canvas-editor-slider-track);height:4px;border-radius:2px}.size-slider::-ms-track{width:100%;height:4px;cursor:pointer;background:transparent;border-color:transparent;color:transparent}.size-slider::-ms-fill-lower{background:var(--feedback-canvas-editor-slider-track);border-radius:2px}.size-slider::-ms-fill-upper{background:var(--feedback-canvas-editor-slider-track);border-radius:2px}.size-slider::-ms-thumb{width:14px;height:14px;border-radius:50%;background:var(--feedback-primary-color);cursor:pointer;border:none}.size-value{font-weight:500;color:var(--feedback-canvas-editor-tool-text-color);font-size:var(--feedback-text-font-size);min-width:30px}.action-btn{display:flex;align-items:center;gap:6px;padding:5px 12px;border:1px solid var(--feedback-canvas-editor-action-secondary-border);border-radius:var(--feedback-modal-button-border-radius);cursor:pointer;font-size:var(--feedback-modal-button-font-size);font-weight:500;transition:all 0.2s ease;min-width:65px;justify-content:center;height:36px;font-family:var(--feedback-font-family)}.action-btn.secondary{background:var(--feedback-canvas-editor-action-secondary-bg);color:var(--feedback-canvas-editor-action-secondary-text);border-color:var(--feedback-canvas-editor-action-secondary-border)}.action-btn.secondary:hover{background:var(--feedback-canvas-editor-tool-bg-hover);color:var(--feedback-modal-button-text-color-active);border-color:var(--feedback-modal-button-border-color-active)}.action-btn.primary{background:var(--feedback-canvas-editor-action-primary-bg);color:var(--feedback-canvas-editor-action-primary-text);border-color:var(--feedback-modal-button-border-color-active)}.action-btn.primary:hover{background:var(--feedback-modal-button-submit-bg-color-hover);border-color:var(--feedback-modal-button-submit-border-color-hover)}.canvas-editor-content{flex:1;display:flex;align-items:center;justify-content:center;padding:16px;background:var(--feedback-canvas-editor-content-bg);overflow:hidden;min-height:0;min-width:0}.annotation-canvas{max-width:100%;max-height:100%;width:auto;height:auto;cursor:crosshair;border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);background:var(--feedback-white-color);transition:box-shadow 0.3s ease;object-fit:contain;display:block}.annotation-canvas:hover{box-shadow:0px 2px 4px 0px rgba(60, 64, 67, .35), 0px 4px 12px 4px rgba(60, 64, 67, .20)}@media screen and (min-width: 768px){.feedback-modal-content{max-width:var(--feedback-modal-content-max-width)}.feedback-modal-content.feedback-modal-content--bottom-right{bottom:var(--feedback-modal-content-position-bottom);left:initial;right:var(--feedback-modal-content-position-right);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--bottom-left{bottom:var(--feedback-modal-content-position-bottom);left:var(--feedback-modal-content-position-left);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--top-right{right:var(--feedback-modal-content-position-right);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--top-left{left:var(--feedback-modal-content-position-left);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--center-left{left:5px;right:auto;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--center-right{left:auto;right:5px;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--sidebar-left.feedback-modal-content--open,.feedback-modal-content.feedback-modal-content--sidebar-right.feedback-modal-content--open{transform:translateX(0)}.feedback-modal-content.feedback-modal-content--sidebar-left{max-width:var(--feedback-modal-content-sidebar-max-width);left:0;right:auto;height:100vh;top:0;transform:translateX(-100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-content.feedback-modal-content--sidebar-right{max-width:var(--feedback-modal-content-sidebar-max-width);left:auto;right:0;height:100vh;top:0;transform:translateX(100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-text textarea{height:150px;min-height:150px}.feedback-modal-content.feedback-modal-content--bottom-right{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--bottom-left{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-left.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-right{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-left{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-left.feedback-modal-content--open{transform:translateY(0)}}@media (max-width: 768px){.canvas-editor-modal{width:100vw;height:100vh;border-radius:0}.canvas-editor-header{padding:8px 12px;gap:8px}.canvas-editor-toolbar{flex-direction:column;align-items:stretch;gap:12px}.toolbar-section{justify-content:center}.toolbar-section:last-child{margin-left:0;justify-content:stretch;gap:8px}.action-btn{flex:1;min-width:auto}.canvas-editor-content{padding:8px}.tool-group{flex-wrap:wrap;justify-content:center}.color-palette{flex-wrap:wrap;justify-content:center}.size-control{flex-direction:column;gap:6px;text-align:center}.size-slider{width:100px}}@keyframes feather-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.feather-loader{animation:feather-spin 1s linear infinite;display:block}.screenshot-error-notification{position:fixed;top:20px;left:50%;transform:translateX(-50%);z-index:10001;max-width:500px;width:90%;animation:slideDown 0.3s ease-out}@keyframes slideDown{from{opacity:0;transform:translateX(-50%) translateY(-20px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}.screenshot-error-content{background:#fee;border:1px solid #fcc;border-radius:8px;padding:12px 16px;display:flex;align-items:center;gap:12px;box-shadow:0 4px 12px rgba(0, 0, 0, 0.15);color:#c53030}.screenshot-error-content svg:first-child{color:#e53e3e;flex-shrink:0}.screenshot-error-content span{flex:1;font-size:14px;line-height:1.4;font-weight:500}.error-close-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:4px;color:#c53030;flex-shrink:0;transition:background-color 0.2s ease}.error-close-btn:hover{background:rgba(197, 48, 48, 0.1)}@media (max-width: 768px){.canvas-editor-toolbar .tool-group,.canvas-editor-toolbar .color-palette,.canvas-editor-toolbar .size-control,.canvas-editor-toolbar .toolbar-divider{display:none !important}.canvas-editor-toolbar{justify-content:center}.canvas-editor-toolbar .toolbar-section:first-child{display:none}.canvas-editor-toolbar .toolbar-section:nth-child(2){display:none}.canvas-editor-toolbar .toolbar-section:nth-child(3){display:none}.canvas-editor-title{display:none}}";
4
+ const feedbackModalCss = ".text-center{flex-grow:1;text-align:center}.feedback-modal-wrapper *{font-family:var(--feedback-font-family)}.feedback-modal-wrapper--custom-font *{font-family:inherit}.feedback-modal-wrapper{position:absolute;z-index:var(--feedback-modal-modal-wrapper-z-index)}.feedback-overlay{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;opacity:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index);transition:opacity 0.2s ease-out}.feedback-overlay--visible{opacity:1}.feedback-modal{display:inline-block;position:relative}.feedback-modal-content{background-color:var(--feedback-modal-content-bg-color);border-color:1px solid var(--feedback-modal-header-text-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-content-text-color);display:flex;flex-direction:column;left:50%;max-width:90%;padding:20px;position:fixed;top:50%;transform:translate(-50%, -50%) scale(0.95);opacity:0;width:100%;z-index:var(--feedback-modal-content-z-index);transition:transform 0.2s ease-out, opacity 0.2s ease-out}.feedback-modal-content--open{transform:translate(-50%, -50%) scale(1);opacity:1}.feedback-modal-header{align-items:center;color:var(--feedback-modal-header-text-color);display:flex;font-size:var(--feedback-header-font-size);font-weight:var(--feedback-modal-header-font-weight);justify-content:space-between;margin-bottom:20px}.feedback-modal-rating-buttons{width:100%;margin-bottom:20px}.feedback-modal-rating-button{padding:0;background-color:transparent;border:transparent;margin-right:5px;cursor:pointer}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button{border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);font-size:var(--feedback-modal-button-font-size);font-weight:500;margin-right:10px;justify-content:center;padding:5px 10px}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover svg,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected svg{stroke:var(--feedback-modal-rating-button-selected-color)}.feedback-modal-rating-buttons svg{stroke:var(--feedback-modal-rating-button-color);cursor:pointer}.feedback-modal-rating-buttons--stars .feedback-modal-rating-button--selected svg{fill:var(--feedback-modal-rating-button-stars-selected-color);stroke:var(--feedback-modal-rating-button-stars-selected-color)}.feedback-modal-text textarea{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:100px;min-height:100px;padding:10px;resize:vertical;width:100%}.feedback-modal-email input{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:40px;padding:10px;width:100%;margin-bottom:20px}.feedback-modal-privacy{font-size:var(--feedback-modal-input-font-size);margin-bottom:20px}.feedback-modal-text textarea:focus,.feedback-modal-email input:focus{border:1px solid var(--feedback-modal-input-border-color-focused);outline:none}.feedback-modal-buttons{display:flex;flex-direction:column}.feedback-modal-buttons .feedback-modal-button{margin-bottom:20px}.feedback-modal-button{align-items:center;background-color:transparent;border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);cursor:pointer;display:flex;font-size:var(--feedback-modal-button-font-size);font-weight:500;justify-content:center;min-height:40px;padding:5px 10px}.feedback-modal-button svg{margin-right:6px}.feedback-modal-button path{fill:var(--feedback-modal-button-icon-color)}.feedback-modal-button:hover path,.feedback-modal-button--active path{fill:var(--feedback-modal-button-icon-color-active)}.feedback-modal-button--submit{background-color:var(--feedback-modal-button-submit-bg-color);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-submit-text-color)}.feedback-modal-button:hover,.feedback-modal-button--active{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-button--submit:hover{background-color:var(--feedback-modal-button-submit-bg-color-hover);border:1px solid var(--feedback-modal-button-submit-border-color-hover);color:var(--feedback-modal-button-submit-text-color-hover)}.feedback-modal-input-heading{display:block;font-size:14px;font-weight:300;padding-bottom:10px}.feedback-modal-footer{font-size:12px;text-align:center}.feedback-modal-footer a{color:var(--feedback-modal-footer-link);font-weight:500;text-decoration:none}.feedback-logo,.feedback-footer-text{display:block;text-align:center;margin-top:5px}.feedback-footer-text{margin-top:10px;line-height:1.5}.feedback-modal-close{background-color:var(--feedback-modal-close-bg-color);border:0;border-radius:50%;cursor:pointer;height:22px;margin-left:auto;padding:0;width:22px}.feedback-modal-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-screenshot{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index)}.feedback-modal-screenshot-header{align-items:center;background-color:var(--feedback-modal-screenshot-header-bg-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-screenshot-header-text-color);cursor:pointer;display:flex;left:50%;top:20px;transform:translateX(-50%);padding:10px;position:fixed;width:max-content;z-index:var(--feedback-modal-screenshot-header-z-index)}.feedback-modal-screenshot-close{height:24px;padding-left:10px;width:24px}.feedback-modal-screenshot-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-message{font-size:var(--feedback-modal-message-font-size);margin-top:0}.feedback-modal-element-hover{background-color:transparent;cursor:pointer;border:1px solid var(--feedback-modal-element-hover-border-color)}.feedback-modal-element-selected{background-color:transparent;border:3px solid var(--feedback-modal-element-selected-border-color) !important;box-shadow:0 0 0 2px rgba(0, 123, 255, 0.3) !important}.screenshot-preview{display:inline-block;width:30px;height:30px;overflow:hidden;border-radius:4px;margin-right:10px;box-shadow:0 2px 4px rgba(0, 0, 0, 0.1);cursor:pointer;transition:transform 0.2s ease}.screenshot-preview:hover{transform:scale(1.1)}.screenshot-preview img{width:100%;height:100%;object-fit:cover}.screenshot-loading{display:inline-flex;align-items:center;margin-right:8px}@media screen and (min-width: 768px){.feedback-modal-content{max-width:var(--feedback-modal-content-max-width)}.feedback-modal-content.feedback-modal-content--bottom-right{bottom:var(--feedback-modal-content-position-bottom);left:initial;right:var(--feedback-modal-content-position-right);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--bottom-left{bottom:var(--feedback-modal-content-position-bottom);left:var(--feedback-modal-content-position-left);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--top-right{right:var(--feedback-modal-content-position-right);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--top-left{left:var(--feedback-modal-content-position-left);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--center-left{left:5px;right:auto;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--center-right{left:auto;right:5px;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--sidebar-left.feedback-modal-content--open,.feedback-modal-content.feedback-modal-content--sidebar-right.feedback-modal-content--open{transform:translateX(0)}.feedback-modal-content.feedback-modal-content--sidebar-left{max-width:var(--feedback-modal-content-sidebar-max-width);left:0;right:auto;height:100vh;top:0;transform:translateX(-100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-content.feedback-modal-content--sidebar-right{max-width:var(--feedback-modal-content-sidebar-max-width);left:auto;right:0;height:100vh;top:0;transform:translateX(100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-text textarea{height:150px;min-height:150px}.feedback-modal-content.feedback-modal-content--bottom-right{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--bottom-left{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-left.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-right{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-left{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-left.feedback-modal-content--open{transform:translateY(0)}}@keyframes feather-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.feather-loader{animation:feather-spin 1s linear infinite;display:block}.screenshot-error-notification{position:fixed;top:20px;left:50%;transform:translateX(-50%);z-index:10001;max-width:500px;width:90%;animation:slideDown 0.3s ease-out}@keyframes slideDown{from{opacity:0;transform:translateX(-50%) translateY(-20px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}.screenshot-error-content{background:#fee;border:1px solid #fcc;border-radius:8px;padding:12px 16px;display:flex;align-items:center;gap:12px;box-shadow:0 4px 12px rgba(0, 0, 0, 0.15);color:#c53030}.screenshot-error-content svg:first-child{color:#e53e3e;flex-shrink:0}.screenshot-error-content span{flex:1;font-size:14px;line-height:1.4;font-weight:500}.error-close-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:4px;color:#c53030;flex-shrink:0;transition:background-color 0.2s ease}.error-close-btn:hover{background:rgba(197, 48, 48, 0.1)}";
4
5
 
5
6
  const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
6
7
  constructor() {
@@ -93,26 +94,6 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
93
94
  document.querySelectorAll('.feedback-modal-element-selected').forEach(el => {
94
95
  el.classList.remove('feedback-modal-element-selected');
95
96
  });
96
- // Reset canvas editor states
97
- this.takingScreenshot = false;
98
- this.showPreviewModal = false;
99
- this.showCanvasEditor = false;
100
- this.annotations = [];
101
- this.currentAnnotation = null;
102
- this.isDrawing = false;
103
- this.canvasRef = null;
104
- this.canvasContext = null;
105
- this.originalImageData = null;
106
- // Reset error states
107
- this.showScreenshotError = false;
108
- this.screenshotError = '';
109
- // Reset resizing states
110
- this.isResizing = false;
111
- this.resizingAnnotation = null;
112
- this.resizeStartSize = 16;
113
- this.resizeStartDimensions = null;
114
- this.hoveredAnnotation = null;
115
- this.resizeHandle = false;
116
97
  // Reset form states
117
98
  this.formSuccess = false;
118
99
  this.formError = false;
@@ -122,681 +103,50 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
122
103
  this.resetOverflow();
123
104
  }, 200);
124
105
  };
125
- this.openScreenShot = async () => {
126
- // Show loading state immediately
127
- this.takingScreenshot = true;
128
- this.showScreenshotError = false;
129
- // Clear any previous annotations when taking a new screenshot
130
- this.annotations = [];
131
- this.currentAnnotation = null;
132
- this.isDrawing = false;
133
- this.hoveredAnnotation = null;
134
- // Hide the feedback modal temporarily to exclude it from screenshot
135
- const wasModalVisible = this.showModal;
136
- this.showModal = false;
137
- // Also hide any feedback buttons on the page
138
- this.hideAllFeedbackElements();
139
- try {
140
- // Wait a moment for UI to update before capturing
141
- await new Promise(resolve => setTimeout(resolve, 100));
142
- // Capture viewport screenshot using browser API
143
- const dataUrl = await this.captureViewportScreenshot();
144
- this.encodedScreenshot = dataUrl;
145
- this.originalImageData = dataUrl;
146
- // Reset loading state
147
- this.takingScreenshot = false;
148
- // Go directly to canvas editor (don't restore modal)
149
- this.showCanvasEditor = true;
150
- // Restore feedback elements visibility
151
- this.showAllFeedbackElements();
152
- // Initialize canvas after a short delay to ensure DOM is ready
153
- setTimeout(() => {
154
- this.initializeCanvas();
155
- }, 100);
156
- }
157
- catch (error) {
158
- console.error('Failed to capture screenshot:', error);
159
- // Reset loading state on error
160
- this.takingScreenshot = false;
161
- // Restore modal and feedback elements on error
162
- this.showModal = wasModalVisible;
163
- this.showAllFeedbackElements();
164
- // Show error message to user
165
- this.handleScreenshotError(error);
166
- }
167
- };
168
- this.hideAllFeedbackElements = () => {
169
- // Hide all feedback buttons and modals on the page
170
- const feedbackElements = document.querySelectorAll('feedback-button, feedback-modal');
171
- feedbackElements.forEach(element => {
172
- element.style.visibility = 'hidden';
173
- });
106
+ // Handle screenshot events from canvas editor
107
+ this.handleScreenshotReady = (event) => {
108
+ this.encodedScreenshot = event.detail.screenshot;
109
+ this.showModal = true;
110
+ this.takingScreenshot = false;
111
+ this.showCanvasEditor = false;
112
+ this.autoStartCapture = false;
174
113
  };
175
- this.showAllFeedbackElements = () => {
176
- // Show all feedback buttons and modals on the page
177
- const feedbackElements = document.querySelectorAll('feedback-button, feedback-modal');
178
- feedbackElements.forEach(element => {
179
- element.style.visibility = 'visible';
180
- });
114
+ this.handleScreenshotCancelled = () => {
115
+ this.showModal = true;
116
+ this.takingScreenshot = false;
117
+ this.showCanvasEditor = false;
118
+ this.autoStartCapture = false;
181
119
  };
182
- this.handleScreenshotError = (error) => {
183
- let errorMessage = 'Failed to capture screenshot. ';
184
- if (error.name === 'NotAllowedError') {
185
- errorMessage += 'Permission denied. Please allow screen sharing to take screenshots.';
186
- }
187
- else if (error.name === 'NotSupportedError') {
188
- errorMessage += 'Screen capture is not supported in this browser.';
189
- }
190
- else if (error.name === 'NotFoundError') {
191
- errorMessage += 'No screen sources available for capture.';
192
- }
193
- else if (error.name === 'AbortError') {
194
- errorMessage += 'Screenshot capture was cancelled.';
195
- }
196
- else if (error.message && error.message.includes('not supported')) {
197
- errorMessage += 'Your browser does not support screen capture. Please use a browser like Chrome, Firefox, or Safari.';
198
- }
199
- else {
200
- errorMessage += 'An unexpected error occurred. Please try again.';
201
- }
202
- this.screenshotError = errorMessage;
120
+ this.handleScreenshotError = (event) => {
121
+ console.error('Screenshot error:', event.detail.error);
122
+ // Store error message to display in feedback modal
123
+ this.screenshotError = event.detail.error;
203
124
  this.showScreenshotError = true;
204
- // Auto-hide error after 5 seconds
125
+ // Close canvas editor and return to feedback modal
126
+ this.showModal = true;
127
+ this.takingScreenshot = false;
128
+ this.showCanvasEditor = false;
129
+ this.autoStartCapture = false;
130
+ // Auto-hide error after 8 seconds
205
131
  setTimeout(() => {
206
132
  this.showScreenshotError = false;
207
- }, 5000);
133
+ }, 8000);
208
134
  };
135
+ // Trigger screenshot capture
136
+ this.openScreenShot = () => {
137
+ this.showModal = false;
138
+ this.takingScreenshot = true;
139
+ this.autoStartCapture = true; // Auto-start new screenshot
140
+ this.showCanvasEditor = true;
141
+ };
142
+ // Open canvas editor for existing screenshot
209
143
  this.openCanvasEditor = (event) => {
210
144
  if (event) {
211
145
  event.stopPropagation();
212
146
  }
213
147
  this.showModal = false;
148
+ this.autoStartCapture = false; // Don't auto-start, just edit existing
214
149
  this.showCanvasEditor = true;
215
- // Initialize canvas after a short delay to ensure DOM is ready
216
- setTimeout(() => {
217
- this.initializeCanvas();
218
- }, 100);
219
- };
220
- this.closeCanvasEditor = () => {
221
- this.showCanvasEditor = false;
222
- this.showModal = true;
223
- };
224
- this.saveAnnotations = () => {
225
- if (this.canvasRef) {
226
- // Create final image with annotations
227
- const finalDataUrl = this.canvasRef.toDataURL('image/png');
228
- this.encodedScreenshot = finalDataUrl;
229
- }
230
- this.showCanvasEditor = false;
231
- this.showModal = true;
232
- };
233
- this.initializeCanvas = () => {
234
- if (!this.canvasRef || !this.originalImageData)
235
- return;
236
- this.canvasContext = this.canvasRef.getContext('2d');
237
- const img = new Image();
238
- img.onload = () => {
239
- // Set canvas to original image dimensions
240
- this.canvasRef.width = img.width;
241
- this.canvasRef.height = img.height;
242
- // Get available container dimensions
243
- const containerWidth = this.canvasRef.parentElement.clientWidth - 32; // Account for reduced padding (16px * 2)
244
- const containerHeight = this.canvasRef.parentElement.clientHeight - 32;
245
- // Calculate scale factors for both dimensions
246
- const scaleX = containerWidth / img.width;
247
- const scaleY = containerHeight / img.height;
248
- // Use the smaller scale to ensure complete image fits
249
- const scale = Math.min(scaleX, scaleY, 1); // Never scale up, only down
250
- // Calculate final display dimensions
251
- const displayWidth = img.width * scale;
252
- const displayHeight = img.height * scale;
253
- // Set CSS size for display (this scales the canvas visually)
254
- this.canvasRef.style.width = `${displayWidth}px`;
255
- this.canvasRef.style.height = `${displayHeight}px`;
256
- console.log('Canvas initialized with complete image fit:', {
257
- originalWidth: img.width,
258
- originalHeight: img.height,
259
- displayWidth,
260
- displayHeight,
261
- scale,
262
- scaleX,
263
- scaleY,
264
- containerWidth,
265
- containerHeight,
266
- usingScale: scale === scaleX ? 'width-limited' : 'height-limited'
267
- });
268
- // Draw the original image at full resolution
269
- this.canvasContext.drawImage(img, 0, 0);
270
- // Redraw existing annotations
271
- this.redrawAnnotations();
272
- };
273
- img.src = this.originalImageData;
274
- };
275
- this.redrawAnnotations = () => {
276
- if (!this.canvasContext)
277
- return;
278
- // Clear and redraw background image
279
- const img = new Image();
280
- img.onload = () => {
281
- this.canvasContext.clearRect(0, 0, this.canvasRef.width, this.canvasRef.height);
282
- this.canvasContext.drawImage(img, 0, 0);
283
- // Draw all annotations
284
- this.annotations.forEach(annotation => {
285
- this.drawAnnotation(annotation);
286
- });
287
- };
288
- img.src = this.originalImageData;
289
- };
290
- this.drawAnnotation = (annotation) => {
291
- if (!this.canvasContext)
292
- return;
293
- this.canvasContext.strokeStyle = annotation.color;
294
- this.canvasContext.lineWidth = annotation.lineWidth;
295
- this.canvasContext.lineCap = 'round';
296
- this.canvasContext.lineJoin = 'round';
297
- switch (annotation.type) {
298
- case 'rectangle':
299
- this.canvasContext.strokeRect(annotation.startX, annotation.startY, annotation.width, annotation.height);
300
- // Draw resize handle if this annotation is hovered
301
- if (this.hoveredAnnotation === annotation) {
302
- this.drawRectangleResizeHandles(annotation);
303
- }
304
- break;
305
- case 'line':
306
- this.canvasContext.beginPath();
307
- this.canvasContext.moveTo(annotation.startX, annotation.startY);
308
- this.canvasContext.lineTo(annotation.endX, annotation.endY);
309
- this.canvasContext.stroke();
310
- // Draw resize handles if this annotation is hovered
311
- if (this.hoveredAnnotation === annotation) {
312
- this.drawLineResizeHandles(annotation);
313
- }
314
- break;
315
- case 'arrow':
316
- this.drawArrow(annotation.startX, annotation.startY, annotation.endX, annotation.endY);
317
- // Draw resize handles if this annotation is hovered
318
- if (this.hoveredAnnotation === annotation) {
319
- this.drawLineResizeHandles(annotation); // Same as line
320
- }
321
- break;
322
- case 'text':
323
- const fontSize = annotation.fontSize || 16;
324
- this.canvasContext.fillStyle = annotation.color;
325
- this.canvasContext.font = `${fontSize}px Arial`;
326
- this.canvasContext.fillText(annotation.text, annotation.x, annotation.y);
327
- // Draw resize handle if this annotation is hovered
328
- if (this.hoveredAnnotation === annotation) {
329
- this.drawTextResizeHandle(annotation);
330
- }
331
- break;
332
- }
333
- };
334
- // Draw resize handle for text annotation
335
- this.drawTextResizeHandle = (annotation) => {
336
- if (!this.canvasContext || annotation.type !== 'text')
337
- return;
338
- const fontSize = annotation.fontSize || 16;
339
- const textWidth = this.getTextWidth(annotation.text, fontSize);
340
- const handleSize = 8;
341
- const handleX = annotation.x + textWidth;
342
- const handleY = annotation.y;
343
- // Draw resize handle (small square) - using widget primary color
344
- this.canvasContext.fillStyle = '#0070F4'; // var(--feedback-primary-color)
345
- this.canvasContext.strokeStyle = '#ffffff';
346
- this.canvasContext.lineWidth = 2;
347
- this.canvasContext.fillRect(handleX - handleSize / 2, handleY - handleSize / 2, handleSize, handleSize);
348
- this.canvasContext.strokeRect(handleX - handleSize / 2, handleY - handleSize / 2, handleSize, handleSize);
349
- };
350
- this.drawArrow = (fromX, fromY, toX, toY) => {
351
- const headlen = 15; // Arrow head length
352
- const angle = Math.atan2(toY - fromY, toX - fromX);
353
- // Draw line
354
- this.canvasContext.beginPath();
355
- this.canvasContext.moveTo(fromX, fromY);
356
- this.canvasContext.lineTo(toX, toY);
357
- this.canvasContext.stroke();
358
- // Draw arrow head
359
- this.canvasContext.beginPath();
360
- this.canvasContext.moveTo(toX, toY);
361
- this.canvasContext.lineTo(toX - headlen * Math.cos(angle - Math.PI / 6), toY - headlen * Math.sin(angle - Math.PI / 6));
362
- this.canvasContext.moveTo(toX, toY);
363
- this.canvasContext.lineTo(toX - headlen * Math.cos(angle + Math.PI / 6), toY - headlen * Math.sin(angle + Math.PI / 6));
364
- this.canvasContext.stroke();
365
- };
366
- this.undoLastAnnotation = () => {
367
- this.annotations = this.annotations.slice(0, -1);
368
- this.redrawAnnotations();
369
- };
370
- // Handle color slot editing
371
- this.handleColorSlotClick = (colorIndex) => {
372
- if (this.editingColorIndex === colorIndex) {
373
- // If already editing this slot, just select the color
374
- this.canvasDrawingColor = this.defaultColors[colorIndex];
375
- this.showColorPicker = false;
376
- this.editingColorIndex = -1;
377
- }
378
- else {
379
- // Start editing this color slot
380
- this.editingColorIndex = colorIndex;
381
- this.showColorPicker = true;
382
- this.canvasDrawingColor = this.defaultColors[colorIndex];
383
- }
384
- };
385
- // Update color in slot
386
- this.updateColorSlot = (newColor) => {
387
- if (this.editingColorIndex >= 0 && this.editingColorIndex < this.defaultColors.length) {
388
- this.defaultColors[this.editingColorIndex] = newColor;
389
- this.canvasDrawingColor = newColor;
390
- this.showColorPicker = false;
391
- this.editingColorIndex = -1;
392
- // Force reactivity
393
- this.defaultColors = [...this.defaultColors];
394
- }
395
- };
396
- // Handle color picker input without closing
397
- this.handleColorPickerInput = (event) => {
398
- event.stopPropagation();
399
- const newColor = event.target.value;
400
- if (this.editingColorIndex >= 0 && this.editingColorIndex < this.defaultColors.length) {
401
- this.defaultColors[this.editingColorIndex] = newColor;
402
- this.canvasDrawingColor = newColor;
403
- // Force reactivity
404
- this.defaultColors = [...this.defaultColors];
405
- }
406
- };
407
- // Handle color picker click to prevent closing
408
- this.handleColorPickerClick = (event) => {
409
- event.stopPropagation();
410
- };
411
- // Close color picker
412
- this.closeColorPicker = () => {
413
- this.showColorPicker = false;
414
- this.editingColorIndex = -1;
415
- };
416
- // Check if point is in resize handle for any annotation type
417
- this.isPointInResizeHandle = (x, y, annotation) => {
418
- const handleSize = 8;
419
- switch (annotation.type) {
420
- case 'text':
421
- const textWidth = this.getTextWidth(annotation.text, annotation.fontSize || 16);
422
- const handleX = annotation.x + textWidth;
423
- const handleY = annotation.y;
424
- return x >= handleX - handleSize / 2 && x <= handleX + handleSize / 2 &&
425
- y >= handleY - handleSize / 2 && y <= handleY + handleSize / 2;
426
- case 'rectangle':
427
- const right = annotation.startX + annotation.width;
428
- const bottom = annotation.startY + annotation.height;
429
- // Only check bottom-right corner handle
430
- return x >= right - handleSize / 2 && x <= right + handleSize / 2 &&
431
- y >= bottom - handleSize / 2 && y <= bottom + handleSize / 2;
432
- case 'line':
433
- case 'arrow':
434
- // Check both endpoint handles
435
- const lineHandles = [
436
- { x: annotation.startX, y: annotation.startY, point: 'start' },
437
- { x: annotation.endX, y: annotation.endY, point: 'end' }
438
- ];
439
- for (const handle of lineHandles) {
440
- if (x >= handle.x - handleSize / 2 && x <= handle.x + handleSize / 2 &&
441
- y >= handle.y - handleSize / 2 && y <= handle.y + handleSize / 2) {
442
- return handle.point; // Return which endpoint was clicked
443
- }
444
- }
445
- return false;
446
- default:
447
- return false;
448
- }
449
- };
450
- // Get text width for resize handle positioning
451
- this.getTextWidth = (text, fontSize) => {
452
- // Approximate text width calculation
453
- return text.length * fontSize * 0.6;
454
- };
455
- // Start text resize
456
- this.startTextResize = (annotation, startPos) => {
457
- this.isResizing = true;
458
- this.resizingAnnotation = annotation;
459
- this.resizeStartSize = annotation.fontSize || 16;
460
- this.dragStartPos = startPos;
461
- };
462
- // Handle text resize
463
- this.handleTextResize = (currentPos) => {
464
- if (!this.resizingAnnotation || !this.dragStartPos)
465
- return;
466
- const deltaX = currentPos.x - this.dragStartPos.x;
467
- const deltaY = currentPos.y - this.dragStartPos.y;
468
- const avgDelta = (deltaX + deltaY) / 2;
469
- // Calculate new font size (minimum 8px, maximum 72px)
470
- const newSize = Math.max(8, Math.min(72, this.resizeStartSize + avgDelta * 0.5));
471
- // Update annotation font size
472
- const index = this.annotations.findIndex(a => a === this.resizingAnnotation);
473
- if (index !== -1) {
474
- this.annotations[index] = Object.assign(Object.assign({}, this.resizingAnnotation), { fontSize: Math.round(newSize) });
475
- this.resizingAnnotation = this.annotations[index];
476
- }
477
- this.redrawAnnotations();
478
- };
479
- // Start resize for any annotation type
480
- this.startResize = (annotation, handle, startPos) => {
481
- this.isResizing = true;
482
- this.resizingAnnotation = annotation;
483
- this.resizeHandle = handle;
484
- this.dragStartPos = startPos;
485
- // Store original values for different annotation types
486
- if (annotation.type === 'text') {
487
- this.resizeStartSize = annotation.fontSize || 16;
488
- }
489
- else if (annotation.type === 'rectangle') {
490
- this.resizeStartDimensions = { width: annotation.width, height: annotation.height };
491
- }
492
- };
493
- // Enhanced mouse down handler with resize detection for all annotation types
494
- this.handleCanvasMouseDown = (event) => {
495
- if (!this.canvasRef)
496
- return;
497
- // Disable drawing on mobile devices
498
- if (window.innerWidth <= 768)
499
- return;
500
- // Close color picker if open
501
- if (this.showColorPicker) {
502
- this.closeColorPicker();
503
- }
504
- const coords = this.getCanvasCoordinates(event);
505
- // Check if clicking on existing annotation first
506
- const found = this.findAnnotationAt(coords.x, coords.y);
507
- if (found) {
508
- // Check if clicking on resize handle for any annotation type
509
- const handle = this.isPointInResizeHandle(coords.x, coords.y, found.annotation);
510
- if (handle) {
511
- this.startResize(found.annotation, handle, coords);
512
- this.canvasRef.style.cursor = 'nw-resize';
513
- return;
514
- }
515
- // Start dragging existing annotation
516
- if (!this.isDrawing) {
517
- this.isDragging = true;
518
- this.draggedAnnotation = found.annotation;
519
- this.dragStartPos = coords;
520
- this.canvasRef.style.cursor = 'grabbing';
521
- return;
522
- }
523
- }
524
- // Original drawing logic
525
- this.isDrawing = true;
526
- if (this.canvasDrawingTool === 'text') {
527
- const text = prompt('Enter text:');
528
- if (text) {
529
- const annotation = {
530
- type: 'text',
531
- x: coords.x,
532
- y: coords.y,
533
- text,
534
- color: this.canvasDrawingColor,
535
- fontSize: 16
536
- };
537
- this.annotations = [...this.annotations, annotation];
538
- this.redrawAnnotations();
539
- }
540
- this.isDrawing = false;
541
- }
542
- else {
543
- this.currentAnnotation = {
544
- type: this.canvasDrawingTool,
545
- startX: coords.x,
546
- startY: coords.y,
547
- color: this.canvasDrawingColor,
548
- lineWidth: this.canvasLineWidth
549
- };
550
- }
551
- };
552
- this.handleCanvasMouseMove = (event) => {
553
- if (!this.canvasRef)
554
- return;
555
- // Disable drawing on mobile devices
556
- if (window.innerWidth <= 768)
557
- return;
558
- const coords = this.getCanvasCoordinates(event);
559
- // Handle resizing for any annotation type
560
- if (this.isResizing && this.resizingAnnotation) {
561
- this.handleResize(coords);
562
- return;
563
- }
564
- // Handle dragging existing annotation
565
- if (this.isDragging && this.draggedAnnotation && this.dragStartPos) {
566
- const deltaX = coords.x - this.dragStartPos.x;
567
- const deltaY = coords.y - this.dragStartPos.y;
568
- // Update annotation position
569
- const updatedAnnotation = Object.assign({}, this.draggedAnnotation);
570
- switch (updatedAnnotation.type) {
571
- case 'rectangle':
572
- updatedAnnotation.startX += deltaX;
573
- updatedAnnotation.startY += deltaY;
574
- break;
575
- case 'line':
576
- case 'arrow':
577
- updatedAnnotation.startX += deltaX;
578
- updatedAnnotation.startY += deltaY;
579
- updatedAnnotation.endX += deltaX;
580
- updatedAnnotation.endY += deltaY;
581
- break;
582
- case 'text':
583
- updatedAnnotation.x += deltaX;
584
- updatedAnnotation.y += deltaY;
585
- break;
586
- }
587
- // Update annotation in array
588
- const index = this.annotations.findIndex(a => a === this.draggedAnnotation);
589
- if (index !== -1) {
590
- this.annotations[index] = updatedAnnotation;
591
- this.draggedAnnotation = updatedAnnotation;
592
- }
593
- this.dragStartPos = coords;
594
- this.redrawAnnotations();
595
- return;
596
- }
597
- // Handle drawing new annotation
598
- if (this.isDrawing && this.currentAnnotation) {
599
- if (this.canvasDrawingTool === 'rectangle') {
600
- this.currentAnnotation.width = coords.x - this.currentAnnotation.startX;
601
- this.currentAnnotation.height = coords.y - this.currentAnnotation.startY;
602
- }
603
- else {
604
- this.currentAnnotation.endX = coords.x;
605
- this.currentAnnotation.endY = coords.y;
606
- }
607
- this.redrawAnnotations();
608
- this.drawAnnotation(this.currentAnnotation);
609
- return;
610
- }
611
- // Handle hover states and cursor changes
612
- const found = this.findAnnotationAt(coords.x, coords.y);
613
- if (found) {
614
- // Check if hovering over resize handle for any annotation type
615
- const handle = this.isPointInResizeHandle(coords.x, coords.y, found.annotation);
616
- if (handle) {
617
- this.canvasRef.style.cursor = 'nw-resize';
618
- this.hoveredAnnotation = found.annotation;
619
- this.redrawAnnotations();
620
- return;
621
- }
622
- // Regular hover over annotation
623
- this.canvasRef.style.cursor = 'grab';
624
- if (this.hoveredAnnotation !== found.annotation) {
625
- this.hoveredAnnotation = found.annotation;
626
- this.redrawAnnotations();
627
- }
628
- }
629
- else {
630
- // No annotation under cursor
631
- this.canvasRef.style.cursor = 'crosshair';
632
- if (this.hoveredAnnotation) {
633
- this.hoveredAnnotation = null;
634
- this.redrawAnnotations();
635
- }
636
- }
637
- };
638
- this.handleCanvasMouseUp = () => {
639
- // Disable drawing on mobile devices
640
- if (window.innerWidth <= 768)
641
- return;
642
- // Handle end of resizing
643
- if (this.isResizing) {
644
- this.isResizing = false;
645
- this.resizingAnnotation = null;
646
- this.dragStartPos = null;
647
- this.resizeHandle = false;
648
- this.resizeStartDimensions = null;
649
- if (this.canvasRef) {
650
- this.canvasRef.style.cursor = 'crosshair';
651
- }
652
- return;
653
- }
654
- // Handle end of dragging
655
- if (this.isDragging) {
656
- this.isDragging = false;
657
- this.draggedAnnotation = null;
658
- this.dragStartPos = null;
659
- if (this.canvasRef) {
660
- this.canvasRef.style.cursor = 'crosshair';
661
- }
662
- return;
663
- }
664
- // Handle end of drawing
665
- if (!this.isDrawing || !this.currentAnnotation)
666
- return;
667
- this.isDrawing = false;
668
- this.annotations = [...this.annotations, this.currentAnnotation];
669
- this.currentAnnotation = null;
670
- this.redrawAnnotations();
671
- };
672
- // Draw resize handles for rectangle annotation (only bottom-right corner)
673
- this.drawRectangleResizeHandles = (annotation) => {
674
- if (!this.canvasContext || annotation.type !== 'rectangle')
675
- return;
676
- const handleSize = 8;
677
- const right = annotation.startX + annotation.width;
678
- const bottom = annotation.startY + annotation.height;
679
- // Only draw bottom-right corner handle
680
- const handle = { x: right, y: bottom };
681
- // Draw the handle
682
- this.canvasContext.fillStyle = '#0070F4'; // Primary color
683
- this.canvasContext.strokeStyle = '#ffffff';
684
- this.canvasContext.lineWidth = 2;
685
- this.canvasContext.fillRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
686
- this.canvasContext.strokeRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
687
- };
688
- // Draw resize handles for line/arrow annotation
689
- this.drawLineResizeHandles = (annotation) => {
690
- if (!this.canvasContext || (annotation.type !== 'line' && annotation.type !== 'arrow'))
691
- return;
692
- const handleSize = 8;
693
- // Define handle positions (2 endpoints)
694
- const handles = [
695
- { x: annotation.startX, y: annotation.startY },
696
- { x: annotation.endX, y: annotation.endY } // End point
697
- ];
698
- // Draw each handle
699
- this.canvasContext.fillStyle = '#0070F4'; // Primary color
700
- this.canvasContext.strokeStyle = '#ffffff';
701
- this.canvasContext.lineWidth = 2;
702
- handles.forEach(handle => {
703
- this.canvasContext.fillRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
704
- this.canvasContext.strokeRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
705
- });
706
- };
707
- // Convert screen coordinates to canvas coordinates
708
- this.getCanvasCoordinates = (event) => {
709
- if (!this.canvasRef)
710
- return { x: 0, y: 0 };
711
- const rect = this.canvasRef.getBoundingClientRect();
712
- // Calculate the scale factor between display size and actual canvas size
713
- const scaleX = this.canvasRef.width / rect.width;
714
- const scaleY = this.canvasRef.height / rect.height;
715
- const x = (event.clientX - rect.left) * scaleX;
716
- const y = (event.clientY - rect.top) * scaleY;
717
- return { x, y };
718
- };
719
- // Find annotation under mouse cursor
720
- this.findAnnotationAt = (x, y) => {
721
- // Check in reverse order (top to bottom)
722
- for (let i = this.annotations.length - 1; i >= 0; i--) {
723
- const annotation = this.annotations[i];
724
- if (this.isPointInAnnotation(x, y, annotation)) {
725
- return { annotation, index: i };
726
- }
727
- }
728
- return null;
729
- };
730
- // Check if point is within annotation bounds
731
- this.isPointInAnnotation = (x, y, annotation) => {
732
- const tolerance = 10; // Click tolerance
733
- switch (annotation.type) {
734
- case 'rectangle':
735
- const left = Math.min(annotation.startX, annotation.startX + annotation.width);
736
- const right = Math.max(annotation.startX, annotation.startX + annotation.width);
737
- const top = Math.min(annotation.startY, annotation.startY + annotation.height);
738
- const bottom = Math.max(annotation.startY, annotation.startY + annotation.height);
739
- return x >= left - tolerance && x <= right + tolerance &&
740
- y >= top - tolerance && y <= bottom + tolerance;
741
- case 'line':
742
- case 'arrow':
743
- // Distance from point to line
744
- const A = annotation.endY - annotation.startY;
745
- const B = annotation.startX - annotation.endX;
746
- const C = annotation.endX * annotation.startY - annotation.startX * annotation.endY;
747
- const distance = Math.abs(A * x + B * y + C) / Math.sqrt(A * A + B * B);
748
- return distance <= tolerance;
749
- case 'text':
750
- // Simple bounding box for text
751
- return x >= annotation.x - tolerance && x <= annotation.x + 100 &&
752
- y >= annotation.y - 20 && y <= annotation.y + tolerance;
753
- default:
754
- return false;
755
- }
756
- };
757
- // Handle resize for different annotation types
758
- this.handleResize = (currentPos) => {
759
- if (!this.resizingAnnotation || !this.dragStartPos)
760
- return;
761
- const annotation = this.resizingAnnotation;
762
- const index = this.annotations.findIndex(a => a === annotation);
763
- if (index === -1)
764
- return;
765
- let updatedAnnotation = Object.assign({}, annotation);
766
- switch (annotation.type) {
767
- case 'text':
768
- // Text resize logic (existing)
769
- const deltaX = currentPos.x - this.dragStartPos.x;
770
- const deltaY = currentPos.y - this.dragStartPos.y;
771
- const avgDelta = (deltaX + deltaY) / 2;
772
- const newSize = Math.max(8, Math.min(72, this.resizeStartSize + avgDelta * 0.5));
773
- updatedAnnotation.fontSize = Math.round(newSize);
774
- break;
775
- case 'rectangle':
776
- // Rectangle resize logic - only bottom-right corner
777
- const rectDeltaX = currentPos.x - this.dragStartPos.x;
778
- const rectDeltaY = currentPos.y - this.dragStartPos.y;
779
- // Update width and height based on original dimensions plus delta
780
- updatedAnnotation.width = Math.max(10, this.resizeStartDimensions.width + rectDeltaX); // Minimum width of 10px
781
- updatedAnnotation.height = Math.max(10, this.resizeStartDimensions.height + rectDeltaY); // Minimum height of 10px
782
- break;
783
- case 'line':
784
- case 'arrow':
785
- // Line/arrow resize logic - move endpoints
786
- if (this.resizeHandle === 'start') {
787
- updatedAnnotation.startX = currentPos.x;
788
- updatedAnnotation.startY = currentPos.y;
789
- }
790
- else if (this.resizeHandle === 'end') {
791
- updatedAnnotation.endX = currentPos.x;
792
- updatedAnnotation.endY = currentPos.y;
793
- }
794
- break;
795
- }
796
- // Update annotation in array
797
- this.annotations[index] = updatedAnnotation;
798
- this.resizingAnnotation = updatedAnnotation;
799
- this.redrawAnnotations();
800
150
  };
801
151
  this.sending = false;
802
152
  this.formMessage = '';
@@ -812,28 +162,10 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
812
162
  this.overlayVisible = false;
813
163
  this.isAnimating = false;
814
164
  this.takingScreenshot = false;
815
- this.showPreviewModal = false;
816
- this.screenshotError = '';
817
165
  this.showScreenshotError = false;
166
+ this.screenshotError = '';
818
167
  this.showCanvasEditor = false;
819
- this.canvasDrawingTool = 'rectangle';
820
- this.canvasDrawingColor = '#ff0000';
821
- this.canvasLineWidth = 3;
822
- this.isDrawing = false;
823
- this.annotations = [];
824
- this.currentAnnotation = null;
825
- this.isDragging = false;
826
- this.draggedAnnotation = null;
827
- this.dragStartPos = null;
828
- this.showColorPicker = false;
829
- this.editingColorIndex = -1;
830
- this.isResizing = false;
831
- this.resizingAnnotation = null;
832
- this.resizeStartSize = 16;
833
- this.resizeStartDimensions = null;
834
- this.hoveredAnnotation = null;
835
- this.resizeHandle = false;
836
- this.defaultColors = ['#ff0000', '#00ff00', '#0000ff', '#000000'];
168
+ this.autoStartCapture = false;
837
169
  this.customFont = false;
838
170
  this.emailAddress = '';
839
171
  this.hideEmail = false;
@@ -872,6 +204,17 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
872
204
  this.canvasEditorTitle = 'Edit screenshot';
873
205
  this.canvasEditorCancelText = 'Cancel';
874
206
  this.canvasEditorSaveText = 'Save';
207
+ this.editTextButtonText = 'Edit Text';
208
+ this.sizeLabelText = 'Size:';
209
+ this.borderLabelText = 'Border:';
210
+ this.editTextPromptText = 'Edit text:';
211
+ this.screenshotErrorGeneral = 'Failed to capture screenshot.';
212
+ this.screenshotErrorPermission = 'Permission denied. Please allow screen sharing to take screenshots.';
213
+ this.screenshotErrorNotSupported = 'Screen capture is not supported in this browser.';
214
+ this.screenshotErrorNotFound = 'No screen sources available for capture.';
215
+ this.screenshotErrorCancelled = 'Screenshot capture was cancelled.';
216
+ this.screenshotErrorBrowserNotSupported = 'Your browser does not support screen capture. Please use a browser like Chrome, Firefox, or Safari.';
217
+ this.screenshotErrorUnexpected = 'An unexpected error occurred. Please try again.';
875
218
  }
876
219
  componentWillLoad() {
877
220
  if (this.fetchData)
@@ -906,63 +249,6 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
906
249
  handleEmailInput(event) {
907
250
  this.formEmail = event.target.value;
908
251
  }
909
- async captureViewportScreenshot() {
910
- try {
911
- // Check if Screen Capture API is supported
912
- if (!navigator.mediaDevices || !navigator.mediaDevices.getDisplayMedia) {
913
- throw new Error('Screen Capture API is not supported in this browser');
914
- }
915
- // Request screen capture with preference for current tab
916
- const stream = await navigator.mediaDevices.getDisplayMedia({
917
- video: {
918
- mediaSource: 'screen',
919
- width: { ideal: window.innerWidth },
920
- height: { ideal: window.innerHeight }
921
- },
922
- audio: false,
923
- preferCurrentTab: true
924
- });
925
- // Create video element to capture frame
926
- const video = document.createElement('video');
927
- video.srcObject = stream;
928
- video.autoplay = true;
929
- video.muted = true;
930
- return new Promise((resolve, reject) => {
931
- video.onloadedmetadata = () => {
932
- video.play();
933
- // Wait a moment for video to stabilize
934
- setTimeout(() => {
935
- try {
936
- // Create canvas to capture frame
937
- const canvas = document.createElement('canvas');
938
- canvas.width = video.videoWidth;
939
- canvas.height = video.videoHeight;
940
- const ctx = canvas.getContext('2d');
941
- ctx.drawImage(video, 0, 0);
942
- // Stop the stream
943
- stream.getTracks().forEach(track => track.stop());
944
- // Convert to data URL
945
- const dataUrl = canvas.toDataURL('image/png');
946
- console.log('Screenshot captured successfully using Screen Capture API');
947
- resolve(dataUrl);
948
- }
949
- catch (error) {
950
- stream.getTracks().forEach(track => track.stop());
951
- reject(error);
952
- }
953
- }, 100);
954
- };
955
- video.onerror = (_) => {
956
- stream.getTracks().forEach(track => track.stop());
957
- reject(new Error('Failed to load video for screenshot capture'));
958
- };
959
- });
960
- }
961
- catch (error) {
962
- console.error('Screen capture failed:', error);
963
- throw error;
964
- }
965
- }
966
252
  handleCheckboxChange(event) {
967
253
  this.isPrivacyChecked = event.target.checked;
968
254
  }
@@ -973,7 +259,7 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
973
259
  this.selectedRating = newRating;
974
260
  }
975
261
  render() {
976
- return (h("div", { class: `feedback-modal-wrapper ${this.customFont ? 'feedback-modal-wrapper--custom-font' : ''}` }, this.showScreenshotError && (h("div", { class: "screenshot-error-notification" }, h("div", { class: "screenshot-error-content" }, h("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("circle", { cx: "12", cy: "12", r: "10" }), h("line", { x1: "15", y1: "9", x2: "9", y2: "15" }), h("line", { x1: "9", y1: "9", x2: "15", y2: "15" })), h("span", null, this.screenshotError), h("button", { class: "error-close-btn", onClick: () => this.showScreenshotError = false, title: "Close" }, h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), h("line", { x1: "6", y1: "6", x2: "18", y2: "18" })))))), this.showModal && (h("div", { class: `feedback-overlay ${this.isAnimating ? 'feedback-overlay--visible' : ''}` })), this.showModal && (h("div", { class: `feedback-modal-content feedback-modal-content--${this.modalPosition} ${this.isAnimating ? 'feedback-modal-content--open' : ''}`, ref: (el) => (this.modalContent = el) }, h("div", { class: "feedback-modal-header" }, !this.formSuccess && !this.formError ? (h("span", null, this.modalTitle)) : this.formSuccess ? (h("span", null, this.modalTitleSuccess)) : (h("span", null, this.modalTitleError)), h("button", { class: "feedback-modal-close", onClick: this.close }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "#191919", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", class: "feather feather-x" }, h("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), h("line", { x1: "6", y1: "6", x2: "18", y2: "18" })))), h("div", { class: "feedback-modal-body" }, !this.formSuccess && !this.formError ? (h("form", { onSubmit: this.handleSubmit }, !this.hideRating && (h("div", { class: "feedback-modal-rating" }, this.ratingMode === 'thumbs' ? (h("div", { class: "feedback-modal-rating-content" }, h("span", { class: "feedback-modal-input-heading" }, this.ratingPlaceholder), h("div", { class: "feedback-modal-rating-buttons feedback-modal-rating-buttons--thumbs" }, h("button", { title: "Yes", class: `feedback-modal-rating-button ${this.selectedRating === 1
262
+ return (h("div", { class: `feedback-modal-wrapper ${this.customFont ? 'feedback-modal-wrapper--custom-font' : ''}` }, this.showCanvasEditor && (h("canvas-editor", { ref: (el) => this.canvasEditorRef = el, "canvas-editor-title": this.canvasEditorTitle, "canvas-editor-cancel-text": this.canvasEditorCancelText, "canvas-editor-save-text": this.canvasEditorSaveText, "screenshot-taking-text": this.screenshotTakingText, "screenshot-attached-text": this.screenshotAttachedText, "screenshot-button-text": this.screenshotButtonText, "auto-start-screenshot": this.autoStartCapture, "existing-screenshot": this.encodedScreenshot || '', "edit-text-button-text": this.editTextButtonText, "size-label-text": this.sizeLabelText, "border-label-text": this.borderLabelText, "edit-text-prompt-text": this.editTextPromptText, "screenshot-error-general": this.screenshotErrorGeneral, "screenshot-error-permission": this.screenshotErrorPermission, "screenshot-error-not-supported": this.screenshotErrorNotSupported, "screenshot-error-not-found": this.screenshotErrorNotFound, "screenshot-error-cancelled": this.screenshotErrorCancelled, "screenshot-error-browser-not-supported": this.screenshotErrorBrowserNotSupported, "screenshot-error-unexpected": this.screenshotErrorUnexpected, onScreenshotReady: this.handleScreenshotReady, onScreenshotCancelled: this.handleScreenshotCancelled, onScreenshotFailed: this.handleScreenshotError })), this.showScreenshotError && (h("div", { class: "screenshot-error-notification" }, h("div", { class: "screenshot-error-content" }, h("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("circle", { cx: "12", cy: "12", r: "10" }), h("line", { x1: "15", y1: "9", x2: "9", y2: "15" }), h("line", { x1: "9", y1: "9", x2: "15", y2: "15" })), h("span", null, this.screenshotError), h("button", { class: "error-close-btn", onClick: () => this.showScreenshotError = false, title: "Close" }, h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), h("line", { x1: "6", y1: "6", x2: "18", y2: "18" })))))), this.showModal && (h("div", { class: `feedback-overlay ${this.isAnimating ? 'feedback-overlay--visible' : ''}` })), this.showModal && (h("div", { class: `feedback-modal-content feedback-modal-content--${this.modalPosition} ${this.isAnimating ? 'feedback-modal-content--open' : ''}`, ref: (el) => (this.modalContent = el) }, h("div", { class: "feedback-modal-header" }, !this.formSuccess && !this.formError ? (h("span", null, this.modalTitle)) : this.formSuccess ? (h("span", null, this.modalTitleSuccess)) : (h("span", null, this.modalTitleError)), h("button", { class: "feedback-modal-close", onClick: this.close }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "#191919", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", class: "feather feather-x" }, h("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), h("line", { x1: "6", y1: "6", x2: "18", y2: "18" })))), h("div", { class: "feedback-modal-body" }, !this.formSuccess && !this.formError ? (h("form", { onSubmit: this.handleSubmit }, !this.hideRating && (h("div", { class: "feedback-modal-rating" }, this.ratingMode === 'thumbs' ? (h("div", { class: "feedback-modal-rating-content" }, h("span", { class: "feedback-modal-input-heading" }, this.ratingPlaceholder), h("div", { class: "feedback-modal-rating-buttons feedback-modal-rating-buttons--thumbs" }, h("button", { title: "Yes", class: `feedback-modal-rating-button ${this.selectedRating === 1
977
263
  ? 'feedback-modal-rating-button--selected'
978
264
  : ''}`, onClick: (event) => {
979
265
  event.preventDefault();
@@ -989,7 +275,7 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
989
275
  event.preventDefault();
990
276
  this.handleRatingChange(rating);
991
277
  } }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "#5F6368", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" })))))))))), h("div", { class: "feedback-modal-text" }, h("textarea", { placeholder: this.messagePlaceholder, value: this.formMessage, onInput: (event) => this.handleMessageInput(event) })), !this.hideEmail && (h("div", { class: "feedback-modal-email" }, h("input", { placeholder: this.emailPlaceholder, type: "email", onInput: (event) => this.handleEmailInput(event), value: this.formEmail, required: this.isEmailRequired }))), h("div", { class: "feedback-verification" }, h("input", { type: "text", name: "verification", style: { display: 'none' }, onInput: (event) => this.handleVerification(event), value: this.formVerification })), !this.hidePrivacyPolicy && (h("div", { class: "feedback-modal-privacy" }, h("input", { type: "checkbox", id: "privacyPolicy", onChange: (ev) => this.handleCheckboxChange(ev), required: true }), h("span", { innerHTML: this.privacyPolicyText }))), h("div", { class: `feedback-modal-buttons ${this.hideScreenshotButton ? 'single' : ''}` }, !this.hideScreenshotButton && (h("button", { type: "button", class: `feedback-modal-button feedback-modal-button--screenshot ${this.encodedScreenshot ? 'feedback-modal-button--active' : ''}`, onClick: this.openScreenShot, disabled: this.sending || this.takingScreenshot }, this.encodedScreenshot && (h("div", { class: "screenshot-preview", onClick: this.openCanvasEditor }, h("img", { src: this.encodedScreenshot, alt: "Screenshot Preview" }))), !this.encodedScreenshot && !this.takingScreenshot && (h("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24", viewBox: "0 -960 960 960", width: "24" }, h("path", { d: "M680-80v-120H560v-80h120v-120h80v120h120v80H760v120h-80ZM200-200v-200h80v120h120v80H200Zm0-360v-200h200v80H280v120h-80Zm480 0v-120H560v-80h200v200h-80Z" }))), this.takingScreenshot && (h("div", { class: "screenshot-loading" }, h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#666", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", class: "feather-loader" }, h("line", { x1: "12", y1: "2", x2: "12", y2: "6" }), h("line", { x1: "12", y1: "18", x2: "12", y2: "22" }), h("line", { x1: "4.93", y1: "4.93", x2: "7.76", y2: "7.76" }), h("line", { x1: "16.24", y1: "16.24", x2: "19.07", y2: "19.07" }), h("line", { x1: "2", y1: "12", x2: "6", y2: "12" }), h("line", { x1: "18", y1: "12", x2: "22", y2: "12" }), h("line", { x1: "4.93", y1: "19.07", x2: "7.76", y2: "16.24" }), h("line", { x1: "16.24", y1: "7.76", x2: "19.07", y2: "4.93" })))), this.takingScreenshot ? this.screenshotTakingText :
992
- this.encodedScreenshot ? this.screenshotAttachedText : this.screenshotButtonText)), h("button", { class: "feedback-modal-button feedback-modal-button--submit", type: "submit", disabled: this.sending }, this.sendButtonText)))) : this.formSuccess && !this.formError ? (h("div", { class: "feedback-modal-success" }, h("p", { class: "feedback-modal-message" }, this.successMessage))) : this.formError && this.formErrorStatus == 404 ? (h("p", { class: "feedback-modal-message" }, this.errorMessage404)) : this.formError && this.formErrorStatus == 403 ? (h("p", { class: "feedback-modal-message" }, this.errorMessage403)) : this.formError ? (h("p", { class: "feedback-modal-message" }, this.errorMessage)) : (h("span", null))), h("div", { class: "feedback-modal-footer" }, h("div", { class: "feedback-logo", style: { display: this.whitelabel ? 'none' : 'block' } }, "Powered by", ' ', h("a", { target: "_blank", href: "https://pushfeedback.com" }, "PushFeedback.com")), this.footerText && (h("div", { class: "feedback-footer-text" }, h("span", { innerHTML: this.footerText })))))), this.showCanvasEditor && (h("div", { class: "canvas-editor-overlay" }, h("div", { class: "canvas-editor-modal" }, h("div", { class: "canvas-editor-header" }, h("div", { class: "canvas-editor-title" }, h("h3", null, this.canvasEditorTitle)), h("div", { class: "canvas-editor-toolbar" }, h("div", { class: "toolbar-section" }, h("div", { class: "tool-group" }, h("button", { class: `tool-btn ${this.canvasDrawingTool === 'rectangle' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'rectangle', title: "Rectangle" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }))), h("button", { class: `tool-btn ${this.canvasDrawingTool === 'line' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'line', title: "Line" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { x1: "5", y1: "12", x2: "19", y2: "12" }))), h("button", { class: `tool-btn ${this.canvasDrawingTool === 'arrow' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'arrow', title: "Arrow" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { x1: "7", y1: "17", x2: "17", y2: "7" }), h("polyline", { points: "7,7 17,7 17,17" }))), h("button", { class: `tool-btn ${this.canvasDrawingTool === 'text' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'text', title: "Text" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { points: "4,7 4,4 20,4 20,7" }), h("line", { x1: "9", y1: "20", x2: "15", y2: "20" }), h("line", { x1: "12", y1: "4", x2: "12", y2: "20" }))), h("div", { class: "toolbar-divider" }), h("button", { class: "tool-btn undo-btn", onClick: this.undoLastAnnotation, disabled: this.annotations.length === 0, title: "Undo" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { points: "1,4 1,10 7,10" }), h("path", { d: "M3.51,15a9,9,0,0,0,14.85-3.36,9,9,0,0,0-9.19-10.15L1.83,10" }))))), h("div", { class: "toolbar-section" }, h("div", { class: "color-palette" }, this.defaultColors.map((color, index) => (h("div", { class: "color-slot-wrapper" }, h("button", { class: `color-btn ${this.canvasDrawingColor === color ? 'active' : ''} ${this.editingColorIndex === index ? 'editing' : ''}`, style: { backgroundColor: color }, onClick: () => this.handleColorSlotClick(index), title: `Color ${index + 1} - Click to customize` }, this.editingColorIndex === index && (h("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "white", "stroke-width": "2" }, h("path", { d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" })))), this.editingColorIndex === index && this.showColorPicker && (h("div", { class: "color-picker-dropdown" }, h("input", { type: "color", value: color, onInput: (e) => this.handleColorPickerInput(e), onClick: (e) => this.handleColorPickerClick(e) })))))))), h("div", { class: "toolbar-section" }, h("div", { class: "size-control" }, h("input", { type: "range", min: "1", max: "10", value: this.canvasLineWidth, onInput: (e) => this.canvasLineWidth = parseInt(e.target.value), class: "size-slider" }), h("span", { class: "size-value" }, this.canvasLineWidth, "px"))), h("div", { class: "toolbar-section" }, h("button", { class: "action-btn secondary", onClick: this.closeCanvasEditor }, this.canvasEditorCancelText), h("button", { class: "action-btn primary", onClick: this.saveAnnotations }, this.canvasEditorSaveText))), h("div", { class: "canvas-editor-content" }, h("canvas", { ref: (el) => this.canvasRef = el, class: "annotation-canvas", onMouseDown: this.handleCanvasMouseDown, onMouseMove: this.handleCanvasMouseMove, onMouseUp: this.handleCanvasMouseUp, onMouseLeave: this.handleCanvasMouseUp }))))))));
278
+ this.encodedScreenshot ? this.screenshotAttachedText : this.screenshotButtonText)), h("button", { class: "feedback-modal-button feedback-modal-button--submit", type: "submit", disabled: this.sending }, this.sendButtonText)))) : this.formSuccess && !this.formError ? (h("div", { class: "feedback-modal-success" }, h("p", { class: "feedback-modal-message" }, this.successMessage))) : this.formError && this.formErrorStatus == 404 ? (h("p", { class: "feedback-modal-message" }, this.errorMessage404)) : this.formError && this.formErrorStatus == 403 ? (h("p", { class: "feedback-modal-message" }, this.errorMessage403)) : this.formError ? (h("p", { class: "feedback-modal-message" }, this.errorMessage)) : (h("span", null))), h("div", { class: "feedback-modal-footer" }, h("div", { class: "feedback-logo", style: { display: this.whitelabel ? 'none' : 'block' } }, "Powered by", ' ', h("a", { target: "_blank", href: "https://pushfeedback.com" }, "PushFeedback.com")), this.footerText && (h("div", { class: "feedback-footer-text" }, h("span", { innerHTML: this.footerText }))))))));
993
279
  }
994
280
  componentDidRender() {
995
281
  if (this.showModal) {
@@ -1046,6 +332,17 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
1046
332
  "canvasEditorTitle": [1, "canvas-editor-title"],
1047
333
  "canvasEditorCancelText": [1, "canvas-editor-cancel-text"],
1048
334
  "canvasEditorSaveText": [1, "canvas-editor-save-text"],
335
+ "editTextButtonText": [1, "edit-text-button-text"],
336
+ "sizeLabelText": [1, "size-label-text"],
337
+ "borderLabelText": [1, "border-label-text"],
338
+ "editTextPromptText": [1, "edit-text-prompt-text"],
339
+ "screenshotErrorGeneral": [1, "screenshot-error-general"],
340
+ "screenshotErrorPermission": [1, "screenshot-error-permission"],
341
+ "screenshotErrorNotSupported": [1, "screenshot-error-not-supported"],
342
+ "screenshotErrorNotFound": [1, "screenshot-error-not-found"],
343
+ "screenshotErrorCancelled": [1, "screenshot-error-cancelled"],
344
+ "screenshotErrorBrowserNotSupported": [1, "screenshot-error-browser-not-supported"],
345
+ "screenshotErrorUnexpected": [1, "screenshot-error-unexpected"],
1049
346
  "sending": [32],
1050
347
  "formMessage": [32],
1051
348
  "formEmail": [32],
@@ -1060,41 +357,28 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
1060
357
  "overlayVisible": [32],
1061
358
  "isAnimating": [32],
1062
359
  "takingScreenshot": [32],
1063
- "showPreviewModal": [32],
1064
- "screenshotError": [32],
1065
360
  "showScreenshotError": [32],
361
+ "screenshotError": [32],
1066
362
  "showCanvasEditor": [32],
1067
- "canvasDrawingTool": [32],
1068
- "canvasDrawingColor": [32],
1069
- "canvasLineWidth": [32],
1070
- "isDrawing": [32],
1071
- "annotations": [32],
1072
- "currentAnnotation": [32],
1073
- "isDragging": [32],
1074
- "draggedAnnotation": [32],
1075
- "dragStartPos": [32],
1076
- "showColorPicker": [32],
1077
- "editingColorIndex": [32],
1078
- "isResizing": [32],
1079
- "resizingAnnotation": [32],
1080
- "resizeStartSize": [32],
1081
- "resizeStartDimensions": [32],
1082
- "hoveredAnnotation": [32],
1083
- "resizeHandle": [32],
1084
- "defaultColors": [32],
363
+ "autoStartCapture": [32],
1085
364
  "openModal": [64]
1086
365
  }]);
1087
366
  function defineCustomElement() {
1088
367
  if (typeof customElements === "undefined") {
1089
368
  return;
1090
369
  }
1091
- const components = ["feedback-modal"];
370
+ const components = ["feedback-modal", "canvas-editor"];
1092
371
  components.forEach(tagName => { switch (tagName) {
1093
372
  case "feedback-modal":
1094
373
  if (!customElements.get(tagName)) {
1095
374
  customElements.define(tagName, FeedbackModal);
1096
375
  }
1097
376
  break;
377
+ case "canvas-editor":
378
+ if (!customElements.get(tagName)) {
379
+ defineCustomElement$1();
380
+ }
381
+ break;
1098
382
  } });
1099
383
  }
1100
384