reactionview 0.1.6 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9ee1ff2149791b83d72bae4971072283d8842089ad0a693cafa82f91468ec68
4
- data.tar.gz: e9ff25dcd09cc2ed81754721b8a8087ed7026a999a8aa5e6b73435ab1165cd4f
3
+ metadata.gz: eabbdb501059b1a02b70690b7508869e27138db2ef4724f253f0f93629776289
4
+ data.tar.gz: 2ef8970ff9203865f90c1a21ae9b68814cbbbb68f6537df49201f056748de101
5
5
  SHA512:
6
- metadata.gz: 0ce297c60ee88c3e386fede727cc2eb11f2e9fcf8c7c85ed7dd887c05fe640e23648040346a3c54c46c0825d4032837bc37444b7d033f55154d4910d2924137e
7
- data.tar.gz: 2f45e3e9da625e7c0ad3d3dec260f74976f83040db423a00f12a943a50816c21574466ebf7a2f92bdedaafca35e68b728de8890990854759088153a0de63c6c5
6
+ metadata.gz: ac7332ce2bd8ca7090ab3481b0f2ff29f08d7ed94786d37c656d7cb7dae32d0e028d2cf12ad7d86a9a72aeef2297767352873ab932bd7013d6c567979e365daf
7
+ data.tar.gz: 66904734f10b5ee2a6af5df4bdc3c68155010f74526119883b11aed8418a6ad5f2cc0068dc3e05253f8480d79d3d6cc8038fdae0306e01702db304858f3745df
@@ -25,7 +25,7 @@ function styleInject(css, ref) {
25
25
  }
26
26
  }
27
27
 
28
- var css_248z = ".herb-overlay-label{background:rgba(0,0,0,.8);border-radius:3px;color:#fff;cursor:pointer;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,monospace;font-size:11px;font-weight:500;left:4px;line-height:1.2;padding:2px 6px;position:absolute;top:-18px;transition:all .2s ease;white-space:nowrap;z-index:1000}.herb-overlay-label:hover{background:rgba(0,0,0,.9);color:#374151;transform:scale(1.02);z-index:1001}[data-herb-debug-outline-type*=view]>.herb-overlay-label{background:#dbeafe;border-color:#93c5fd;color:#1e40af}[data-herb-debug-outline-type*=partial]>.herb-overlay-label{background:#d1fae5;border-color:#6ee7b7;color:#065f46}[data-herb-debug-outline-type*=component]>.herb-overlay-label{background:#fef3c7;border-color:#fcd34d;color:#92400e}[data-herb-debug-outline-type*=erb-output]{transition:all .3s ease}.herb-tooltip{background:#fff;border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.08);display:flex;flex-direction:column;font-family:SF Mono,Monaco,Inconsolata,Fira Code,monospace;font-size:14px;gap:12px;max-width:calc(100vw - 16px);opacity:0;overflow:visible;padding:16px 20px;pointer-events:none;position:fixed;transition:opacity .2s ease,visibility .2s ease;visibility:hidden;white-space:nowrap;z-index:10001}.herb-tooltip.visible{opacity:1;pointer-events:auto;visibility:visible}.herb-tooltip .herb-location{align-items:center;background:#f8f9fa;border-radius:12px 12px 0 0;color:#6b7280;cursor:pointer;display:flex;font-size:13px;font-weight:500;gap:12px;justify-content:space-between;margin:-16px -20px 0;padding:12px 20px;transition:all .2s ease}.herb-tooltip .herb-location:hover{background:#f1f3f4;color:#374151}.herb-copy-path-btn{background:transparent;border:none;border-radius:4px;color:#6b7280;cursor:pointer;flex-shrink:0;font-size:14px;padding:4px;position:relative;transition:all .2s ease}.herb-copy-path-btn:hover{background:hsla(220,9%,46%,.1);color:#374151}.herb-copy-path-btn:active{transform:scale(.95)}.herb-location:after{background:#1f2937;border-radius:6px;bottom:calc(100% + 8px);color:#fff;content:attr(data-tooltip);font-size:12px;padding:6px 10px;pointer-events:none;white-space:nowrap}.herb-location:after,.herb-location:before{left:50%;opacity:0;position:absolute;transform:translateX(-50%);transition:all .2s ease;visibility:hidden;z-index:10002}.herb-location:before{border:4px solid transparent;border-top-color:#1f2937;bottom:calc(100% + 2px);content:\"\"}.herb-location:hover:after,.herb-location:hover:before{opacity:1;visibility:visible}.herb-location:has(.herb-copy-path-btn:hover):after,.herb-location:has(.herb-copy-path-btn:hover):before{opacity:0!important;visibility:hidden!important}.herb-copy-path-btn:after{background:#1f2937;border-radius:6px;color:#fff;content:attr(data-tooltip);font-size:12px;padding:6px 10px;pointer-events:none;top:-36px;white-space:nowrap}.herb-copy-path-btn:after,.herb-copy-path-btn:before{left:50%;opacity:0;position:absolute;transform:translateX(-50%);transition:all .2s ease;visibility:hidden;z-index:10003}.herb-copy-path-btn:before{border:4px solid transparent;border-bottom-color:#1f2937;content:\"\";top:-6px}.herb-copy-path-btn:hover:after,.herb-copy-path-btn:hover:before{opacity:1;visibility:visible}.herb-tooltip .herb-erb-code{color:#111827;cursor:text;font-size:16px;font-weight:600;letter-spacing:-.025em;user-select:text}.herb-tooltip:before{bottom:-8px;content:\"\";height:8px;left:0;pointer-events:auto;position:absolute;right:0}.herb-tooltip:after{border:6px solid transparent;border-top-color:#e5e7eb;bottom:-6px;content:\"\";left:50%;pointer-events:none;position:absolute;transform:translateX(-50%);z-index:10000}.herb-floating-menu{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;position:fixed;right:0;top:0;z-index:2147483643}.herb-menu-trigger{align-items:center;background:#fff;border:1px solid silver;border-radius:0 0 0 10px;border-right:none;border-top:none;box-shadow:0 1px 3px rgba(0,0,0,.1);cursor:pointer;display:flex;font-size:12px;gap:4px;justify-content:center;padding:4px 7px;position:relative;transition:all .2s ease;z-index:2147483640}.herb-menu-trigger:hover{background:#f9fafb;border-color:#9ca3af;box-shadow:0 4px 12px rgba(0,0,0,.15)}.herb-menu-trigger:active{transform:scale(.98)}.herb-menu-trigger.has-active-options{background:#dbeafe;border-color:#3b82f6}.herb-menu-trigger.has-active-options:hover{background:#bfdbfe;border-color:#2563eb}.herb-menu-trigger.has-active-options .herb-text{color:#1d4ed8}.herb-icon{display:block;font-size:14px;line-height:1}.herb-text{color:#555;font-size:11px;font-weight:600;letter-spacing:.2px}.herb-menu-panel{background:#fff;border:1px solid silver;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.1);min-width:280px;opacity:0;padding:0;position:absolute;right:10px;top:28px;transform:translateY(-10px) scale(.95);transform-origin:top right;transition:all .3s cubic-bezier(.4,0,.2,1);visibility:hidden}.herb-menu-panel.open{opacity:1;transform:translateY(0) scale(1);visibility:visible}.herb-menu-header{background:#f9fafb;border-bottom:1px solid #e5e7eb;border-radius:8px 8px 0 0;color:#374151;font-size:14px;font-weight:600;padding:16px 20px}.herb-toggle-item{border-bottom:1px solid #f3f4f6;padding:12px 20px}.herb-toggle-item:last-child{border-bottom:none;border-radius:0 0 8px 8px}.herb-nested-toggle{border-left:2px solid #f3f4f6;margin-top:8px;padding-left:24px;transition:all .3s ease}.herb-nested-label{opacity:.8}.herb-nested-label .herb-toggle-text{color:#6b7280;font-size:13px}.herb-nested-switch{background:#e5e7eb;height:20px;width:36px}.herb-nested-switch:after{height:14px;left:3px;top:3px;width:14px}.herb-toggle-input:checked+.herb-nested-switch:after{transform:translateX(16px)}.herb-toggle-label{align-items:center;cursor:pointer;display:flex;gap:12px;user-select:none}.herb-toggle-input{display:none}.herb-toggle-switch{background:#cbd5e1;border-radius:12px;flex-shrink:0;height:24px;position:relative;transition:background .3s ease;width:44px}.herb-toggle-switch:after{background:#fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2);content:\"\";height:18px;left:3px;position:absolute;top:3px;transition:transform .3s ease;width:18px}.herb-toggle-input:checked+.herb-toggle-switch{background:#8b5cf6}.herb-toggle-input:checked+.herb-toggle-switch:after{transform:translateX(20px)}.herb-toggle-text{color:#374151;flex:1;font-size:14px}.herb-toggle-label:hover .herb-toggle-switch{background:#94a3b8}.herb-toggle-label:hover .herb-toggle-input:checked+.herb-toggle-switch{background:#7c3aed}.herb-disable-all-section{background:#f9fafb;border-radius:0 0 8px 8px;border-top:1px solid #f3f4f6;padding:16px 20px}.herb-disable-all-btn{background:#ef4444;border:none;border-radius:6px;color:#fff;cursor:pointer;font-size:13px;font-weight:500;padding:8px 16px;transition:background .2s ease;width:100%}.herb-disable-all-btn:hover{background:#dc2626}.herb-disable-all-btn:active{background:#b91c1c}.herb-validation-overlay{align-items:center;backdrop-filter:blur(4px);background:rgba(0,0,0,.8);bottom:0;color:#e5e5e5;display:flex;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;justify-content:center;left:0;line-height:1.6;overflow-y:auto;padding:20px;position:fixed;right:0;top:0;z-index:2147483640}.herb-validation-panel{background:#000;border:1px solid #374151;border-radius:12px;box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);display:flex;flex-direction:column;max-height:80vh;max-width:1200px;overflow:hidden;width:100%}.herb-validation-header{align-items:flex-start;background:linear-gradient(135deg,#dc2626,#b91c1c);border-bottom:1px solid #374151;border-radius:12px 12px 0 0;color:#fff;display:flex;flex-shrink:0;gap:16px;justify-content:space-between;padding:20px 24px}.herb-validation-title{font-size:18px;font-weight:600;margin:0}.herb-validation-close{align-items:center;background:hsla(0,0%,100%,.1);border:1px solid hsla(0,0%,100%,.2);border-radius:6px;color:#fff;cursor:pointer;display:flex;flex-shrink:0;font-size:16px;height:32px;justify-content:center;padding:0;transition:all .2s;width:32px}.herb-validation-close:hover{background:hsla(0,0%,100%,.2);border-color:hsla(0,0%,100%,.3)}.herb-file-tabs{background:#262626;border-bottom:1px solid #374151;display:flex;flex-shrink:0;overflow-x:auto}.herb-file-tab{background:none;border:none;border-bottom:3px solid transparent;color:#9ca3af;cursor:pointer;font-size:14px;font-weight:500;padding:12px 16px;transition:all .2s ease;white-space:nowrap}.herb-file-tab:hover{background:#2d2d2d;color:#e5e5e5}.herb-file-tab.active{background:#374151;border-bottom-color:#3b82f6;color:#fff}.herb-validation-content{flex:1;overflow-y:auto;padding:24px}.herb-validator-section{margin-bottom:32px}.herb-validator-section:last-child{margin-bottom:0}.herb-validator-section.hidden{display:none}.herb-validator-header{align-items:center;background:#262626;border-bottom:1px solid #374151;border-radius:8px 8px 0 0;color:#e5e5e5;display:flex;font-size:16px;font-weight:600;justify-content:space-between;padding:12px 16px}.herb-validator-count{background:hsla(0,0%,100%,.2);border-radius:12px;font-size:14px;font-weight:500;padding:2px 8px}.herb-validator-items{background:#111;border:1px solid #374151;border-radius:0 0 8px 8px;border-top:none}.herb-validation-item{background:#111;border-bottom:1px solid #374151;padding:20px}.herb-validation-item:last-child{border-bottom:none;border-radius:0 0 8px 8px}.herb-validation-item.hidden{display:none}.herb-validation-item .herb-validation-header{align-items:center;background:#1a1a1a;border:none;border-bottom:1px solid #374151;color:#9ca3af;display:flex;font-size:13px;gap:12px;margin:-20px -20px 16px;padding:12px 16px}.herb-validation-badge{border-radius:4px;color:#fff;font-size:12px;font-weight:600;letter-spacing:.025em;padding:4px 8px;text-transform:uppercase}.herb-validation-location{color:#9ca3af;font-family:SF Mono,Monaco,Inconsolata,Fira Code,monospace;font-size:13px}.herb-validation-message{background:#1a1a1a;border-bottom:1px solid #374151;color:#fbbf24;font-size:13px;font-weight:500;line-height:1.4;margin:-16px -16px 16px;padding:12px 16px}.herb-code-snippet{background:#1f2937;border-radius:6px;font-family:SF Mono,Monaco,Inconsolata,Fira Code,monospace;margin-bottom:16px;overflow:hidden}.herb-code-line{align-items:stretch;display:flex}.herb-code-line.herb-error-line{background:rgba(239,68,68,.1)}.herb-validation-overlay .herb-line-number{background:#374151;border-right:1px solid #4b5563;color:#9ca3af;flex-shrink:0;font-size:13px;padding:8px 12px;text-align:right;user-select:none;width:40px}.herb-validation-overlay .herb-error-line .herb-line-number{background:#dc2626;color:#fff}.herb-validation-overlay .herb-line-content{color:#e5e7eb;flex:1;font-size:13px;padding:8px 16px;white-space:pre-wrap}.herb-validation-overlay .herb-error-pointer{background:#1f2937;color:#dc2626;font-size:13px;font-weight:700;padding:4px 16px 8px 57px}.herb-validation-suggestion{align-items:flex-start;background:#111;border:1px solid #374151;border-radius:6px;color:#d1d5db;display:flex;font-size:14px;gap:8px;margin-top:16px;padding:12px 16px}.herb-suggestion-icon{color:#10b981;flex-shrink:0;font-size:16px;margin-top:1px}.herb-erb{color:#fbbf24;font-weight:600}.herb-erb-content{color:#34d399}.herb-tag{color:#60a5fa;font-weight:500}.herb-attr{color:#f472b6}.herb-value{color:#a78bfa}.herb-comment{color:#6b7280;font-style:italic}";
28
+ var css_248z = ".herb-overlay-label{background:rgba(0,0,0,.8);border-radius:3px;color:#fff;cursor:pointer;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,monospace;font-size:11px;font-weight:500;left:4px;line-height:1.2;padding:2px 6px;position:absolute;top:-18px;transition:all .2s ease;white-space:nowrap;z-index:1000}.herb-overlay-label:hover{background:rgba(0,0,0,.9);color:#374151;transform:scale(1.02);z-index:1001}[data-herb-debug-outline-type*=view]>.herb-overlay-label{background:#dbeafe;border-color:#93c5fd;color:#1e40af}[data-herb-debug-outline-type*=partial]>.herb-overlay-label{background:#d1fae5;border-color:#6ee7b7;color:#065f46}[data-herb-debug-outline-type*=component]>.herb-overlay-label{background:#fef3c7;border-color:#fcd34d;color:#92400e}[data-herb-debug-outline-type*=erb-output]{transition:all .3s ease}.herb-tooltip{background:#fff;border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.08);display:flex;flex-direction:column;font-family:SF Mono,Monaco,Inconsolata,Fira Code,monospace;font-size:14px;gap:12px;max-width:calc(100vw - 16px);opacity:0;overflow:visible;padding:16px 20px;pointer-events:none;position:fixed;transition:opacity .2s ease,visibility .2s ease;visibility:hidden;white-space:nowrap;z-index:10001}.herb-tooltip.visible{opacity:1;pointer-events:auto;visibility:visible}.herb-tooltip .herb-location{align-items:center;background:#f8f9fa;border-radius:12px 12px 0 0;color:#6b7280;cursor:pointer;display:flex;font-size:13px;font-weight:500;gap:12px;justify-content:space-between;margin:-16px -20px 0;padding:12px 20px;transition:all .2s ease}.herb-tooltip .herb-location:hover{background:#f1f3f4;color:#374151}.herb-copy-path-btn{background:transparent;border:none;border-radius:4px;color:#6b7280;cursor:pointer;flex-shrink:0;font-size:14px;padding:4px;position:relative;transition:all .2s ease}.herb-copy-path-btn:hover{background:hsla(220,9%,46%,.1);color:#374151}.herb-copy-path-btn:active{transform:scale(.95)}.herb-location:after{background:#1f2937;border-radius:6px;bottom:calc(100% + 8px);color:#fff;content:attr(data-tooltip);font-size:12px;padding:6px 10px;pointer-events:none;white-space:nowrap}.herb-location:after,.herb-location:before{left:50%;opacity:0;position:absolute;transform:translateX(-50%);transition:all .2s ease;visibility:hidden;z-index:10002}.herb-location:before{border:4px solid transparent;border-top-color:#1f2937;bottom:calc(100% + 2px);content:\"\"}.herb-location:hover:after,.herb-location:hover:before{opacity:1;visibility:visible}.herb-location:has(.herb-copy-path-btn:hover):after,.herb-location:has(.herb-copy-path-btn:hover):before{opacity:0!important;visibility:hidden!important}.herb-copy-path-btn:after{background:#1f2937;border-radius:6px;color:#fff;content:attr(data-tooltip);font-size:12px;padding:6px 10px;pointer-events:none;top:-36px;white-space:nowrap}.herb-copy-path-btn:after,.herb-copy-path-btn:before{left:50%;opacity:0;position:absolute;transform:translateX(-50%);transition:all .2s ease;visibility:hidden;z-index:10003}.herb-copy-path-btn:before{border:4px solid transparent;border-bottom-color:#1f2937;content:\"\";top:-6px}.herb-copy-path-btn:hover:after,.herb-copy-path-btn:hover:before{opacity:1;visibility:visible}.herb-tooltip .herb-erb-code{color:#111827;cursor:text;font-size:16px;font-weight:600;letter-spacing:-.025em;user-select:text}.herb-tooltip:before{bottom:-8px;content:\"\";height:8px;left:0;pointer-events:auto;position:absolute;right:0}.herb-tooltip:after{border:6px solid transparent;border-top-color:#e5e7eb;bottom:-6px;content:\"\";left:50%;pointer-events:none;position:absolute;transform:translateX(-50%);z-index:10000}.herb-floating-menu{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;position:fixed;right:0;top:0;z-index:2147483643}.herb-menu-trigger{align-items:center;background:#fff;border:1px solid silver;border-radius:0 0 0 10px;border-right:none;border-top:none;box-shadow:0 1px 3px rgba(0,0,0,.1);cursor:pointer;display:flex;font-size:12px;gap:4px;justify-content:center;padding:4px 7px;position:relative;transition:all .2s ease;z-index:2147483640}.herb-menu-trigger:hover{background:#f9fafb;border-color:#9ca3af;box-shadow:0 4px 12px rgba(0,0,0,.15)}.herb-menu-trigger:active{transform:scale(.98)}.herb-menu-trigger.has-active-options{background:#dbeafe;border-color:#3b82f6}.herb-menu-trigger.has-active-options:hover{background:#bfdbfe;border-color:#2563eb}.herb-menu-trigger.has-active-options .herb-text{color:#1d4ed8}.herb-icon{display:block;font-size:14px;line-height:1}.herb-text{color:#555;font-size:11px;font-weight:600;letter-spacing:.2px}.herb-menu-panel{background:#fff;border:1px solid silver;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.1);min-width:280px;opacity:0;padding:0;position:absolute;right:10px;top:28px;transform:translateY(-10px) scale(.95);transform-origin:top right;transition:all .3s cubic-bezier(.4,0,.2,1);visibility:hidden}.herb-menu-panel.open{opacity:1;transform:translateY(0) scale(1);visibility:visible}.herb-menu-header{background:#f9fafb;border-bottom:1px solid #e5e7eb;border-radius:8px 8px 0 0;color:#374151;font-size:14px;font-weight:600;padding:16px 20px}.herb-toggle-item{border-bottom:1px solid #f3f4f6;padding:12px 20px}.herb-toggle-item:last-child{border-bottom:none;border-radius:0 0 8px 8px}.herb-nested-toggle{border-left:2px solid #f3f4f6;margin-top:8px;padding-left:24px;transition:all .3s ease}.herb-nested-label{opacity:.8}.herb-nested-label .herb-toggle-text{color:#6b7280;font-size:13px}.herb-nested-switch{background:#e5e7eb;height:20px;width:36px}.herb-nested-switch:after{height:14px;left:3px;top:3px;width:14px}.herb-toggle-input:checked+.herb-nested-switch:after{transform:translateX(16px)}.herb-toggle-label{align-items:center;cursor:pointer;display:flex;gap:12px;user-select:none}.herb-toggle-input{display:none}.herb-toggle-switch{background:#cbd5e1;border-radius:12px;flex-shrink:0;height:24px;position:relative;transition:background .3s ease;width:44px}.herb-toggle-switch:after{background:#fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2);content:\"\";height:18px;left:3px;position:absolute;top:3px;transition:transform .3s ease;width:18px}.herb-toggle-input:checked+.herb-toggle-switch{background:#8b5cf6}.herb-toggle-input:checked+.herb-toggle-switch:after{transform:translateX(20px)}.herb-toggle-text{color:#374151;flex:1;font-size:14px}.herb-outline-preview{border:2px dotted transparent;border-radius:4px;padding:2px 8px}.herb-outline-view{background-color:#eff6ff;border-color:#3b82f6}.herb-outline-partial{background-color:#ecfdf5;border-color:#10b981}.herb-outline-component{background-color:#fffbeb;border-color:#f59e0b}.herb-outline-erb{background-color:#f5f3ff;border-color:#a78bfa}.herb-toggle-label:hover .herb-toggle-switch{background:#94a3b8}.herb-toggle-label:hover .herb-toggle-input:checked+.herb-toggle-switch{background:#7c3aed}.herb-editor-section{background:linear-gradient(135deg,#fafbfc,#f8f9fa);border-bottom:1px solid #f3f4f6;overflow:hidden;padding:16px 20px;position:relative}.herb-editor-section:before{background:linear-gradient(90deg,transparent,rgba(139,92,246,.2),transparent);content:\"\";height:2px;left:0;position:absolute;right:0;top:0}.herb-editor-label{cursor:default;display:flex;flex-direction:column;gap:10px}.herb-editor-text{align-items:center;color:#6b7280;display:flex;font-size:12px;font-weight:600;gap:6px;letter-spacing:.5px;text-transform:uppercase}.herb-editor-select{appearance:none;background:#fff;border:1.5px solid #e5e7eb;border-radius:8px;box-shadow:0 1px 2px rgba(0,0,0,.05);color:#1f2937;cursor:pointer;font-size:13.5px;font-weight:500;padding:10px 36px 10px 12px;transition:all .2s cubic-bezier(.4,0,.2,1);width:100%}.herb-editor-select,.herb-editor-select option{font-family:Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.herb-editor-select option{font-size:14px;font-weight:400;padding:8px 12px}.herb-editor-select:hover{background-color:#fafafa;border-color:#8b5cf6;box-shadow:0 2px 4px rgba(0,0,0,.08),0 0 0 1px rgba(139,92,246,.1);transform:translateY(-1px)}.herb-editor-select:focus{background-color:#fff;border-color:#8b5cf6;box-shadow:0 0 0 3px rgba(139,92,246,.15),0 2px 8px rgba(139,92,246,.1);outline:none;transform:translateY(-1px)}.herb-editor-select:active{box-shadow:0 1px 2px rgba(0,0,0,.05);transform:translateY(0)}.herb-disable-all-section{background:#f9fafb;border-radius:0 0 8px 8px;border-top:1px solid #f3f4f6;padding:16px 20px}.herb-disable-all-btn{background:#ef4444;border:none;border-radius:6px;color:#fff;cursor:pointer;font-size:13px;font-weight:500;padding:8px 16px;transition:background .2s ease;width:100%}.herb-disable-all-btn:hover{background:#dc2626}.herb-disable-all-btn:active{background:#b91c1c}.herb-validation-overlay{align-items:center;backdrop-filter:blur(4px);background:rgba(0,0,0,.8);bottom:0;color:#e5e5e5;display:flex;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;justify-content:center;left:0;line-height:1.6;overflow-y:auto;padding:20px;position:fixed;right:0;top:0;z-index:2147483640}.herb-validation-panel{background:#000;border:1px solid #374151;border-radius:12px;box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);display:flex;flex-direction:column;max-height:80vh;max-width:1200px;overflow:hidden;width:100%}.herb-validation-header{align-items:flex-start;background:linear-gradient(135deg,#dc2626,#b91c1c);border-bottom:1px solid #374151;border-radius:12px 12px 0 0;color:#fff;display:flex;flex-shrink:0;gap:16px;justify-content:space-between;padding:20px 24px}.herb-validation-title{font-size:18px;font-weight:600;margin:0}.herb-validation-close{align-items:center;background:hsla(0,0%,100%,.1);border:1px solid hsla(0,0%,100%,.2);border-radius:6px;color:#fff;cursor:pointer;display:flex;flex-shrink:0;font-size:16px;height:32px;justify-content:center;padding:0;transition:all .2s;width:32px}.herb-validation-close:hover{background:hsla(0,0%,100%,.2);border-color:hsla(0,0%,100%,.3)}.herb-file-tabs{background:#262626;border-bottom:1px solid #374151;display:flex;flex-shrink:0;overflow-x:auto}.herb-file-tab{background:none;border:none;border-bottom:3px solid transparent;color:#9ca3af;cursor:pointer;font-size:14px;font-weight:500;padding:12px 16px;transition:all .2s ease;white-space:nowrap}.herb-file-tab:hover{background:#2d2d2d;color:#e5e5e5}.herb-file-tab.active{background:#374151;border-bottom-color:#3b82f6;color:#fff}.herb-validation-content{flex:1;overflow-y:auto;padding:24px}.herb-validator-section{margin-bottom:32px}.herb-validator-section:last-child{margin-bottom:0}.herb-validator-section.hidden{display:none}.herb-validator-header{align-items:center;background:#262626;border-bottom:1px solid #374151;border-radius:8px 8px 0 0;color:#e5e5e5;display:flex;font-size:16px;font-weight:600;justify-content:space-between;padding:12px 16px}.herb-validator-count{background:hsla(0,0%,100%,.2);border-radius:12px;font-size:14px;font-weight:500;padding:2px 8px}.herb-validator-items{background:#111;border:1px solid #374151;border-radius:0 0 8px 8px;border-top:none}.herb-validation-item{background:#111;border-bottom:1px solid #374151;padding:20px}.herb-validation-item:last-child{border-bottom:none;border-radius:0 0 8px 8px}.herb-validation-item.hidden{display:none}.herb-validation-item .herb-validation-header{align-items:center;background:#1a1a1a;border:none;border-bottom:1px solid #374151;color:#9ca3af;display:flex;font-size:13px;gap:12px;margin:-20px -20px 16px;padding:12px 16px}.herb-validation-badge{border-radius:4px;color:#fff;font-size:12px;font-weight:600;letter-spacing:.025em;padding:4px 8px;text-transform:uppercase}.herb-validation-location{color:#9ca3af;font-family:SF Mono,Monaco,Inconsolata,Fira Code,monospace;font-size:13px}.herb-validation-message{background:#1a1a1a;border-bottom:1px solid #374151;color:#fbbf24;font-size:13px;font-weight:500;line-height:1.4;margin:-16px -16px 16px;padding:12px 16px}.herb-code-snippet{background:#1f2937;border-radius:6px;font-family:SF Mono,Monaco,Inconsolata,Fira Code,monospace;margin-bottom:16px;overflow:hidden}.herb-code-line{align-items:stretch;display:flex}.herb-code-line.herb-error-line{background:rgba(239,68,68,.1)}.herb-validation-overlay .herb-line-number{background:#374151;border-right:1px solid #4b5563;color:#9ca3af;flex-shrink:0;font-size:13px;padding:8px 12px;text-align:right;user-select:none;width:40px}.herb-validation-overlay .herb-error-line .herb-line-number{background:#dc2626;color:#fff}.herb-validation-overlay .herb-line-content{color:#e5e7eb;flex:1;font-size:13px;padding:8px 16px;white-space:pre-wrap}.herb-validation-overlay .herb-error-pointer{background:#1f2937;color:#dc2626;font-size:13px;font-weight:700;padding:4px 16px 8px 57px}.herb-validation-suggestion{align-items:flex-start;background:#111;border:1px solid #374151;border-radius:6px;color:#d1d5db;display:flex;font-size:14px;gap:8px;margin-top:16px;padding:12px 16px}.herb-suggestion-icon{color:#10b981;flex-shrink:0;font-size:16px;margin-top:1px}.herb-erb{color:#fbbf24;font-weight:600}.herb-erb-content{color:#34d399}.herb-tag{color:#60a5fa;font-weight:500}.herb-attr{color:#f472b6}.herb-value{color:#a78bfa}.herb-comment{color:#6b7280;font-style:italic}";
29
29
  styleInject(css_248z);
30
30
 
31
31
  class ErrorOverlay {
@@ -856,6 +856,8 @@ class HerbOverlay {
856
856
  this.showingComponentOutlines = false;
857
857
  this.menuOpen = false;
858
858
  this.projectPath = '';
859
+ this.preferredEditor = 'auto';
860
+ this.defaultEditorFromServer = 'vscode';
859
861
  this.currentlyHoveredERBElement = null;
860
862
  this.errorOverlay = null;
861
863
  this.handleRevealedERBClick = (event) => {
@@ -877,10 +879,12 @@ class HerbOverlay {
877
879
  }
878
880
  init() {
879
881
  this.loadProjectPath();
882
+ this.loadDefaultEditor();
880
883
  this.loadSettings();
881
884
  this.injectMenu();
882
885
  this.setupMenuToggle();
883
886
  this.setupToggleSwitches();
887
+ this.setupEditorDropdown();
884
888
  this.initializeErrorOverlay();
885
889
  this.setupTurboListeners();
886
890
  this.applySettings();
@@ -895,6 +899,16 @@ class HerbOverlay {
895
899
  this.projectPath = metaTag.content;
896
900
  }
897
901
  }
902
+ loadDefaultEditor() {
903
+ const metaTag = document.querySelector('meta[name="herb-default-editor"]');
904
+ if (metaTag?.content) {
905
+ const defaultEditor = metaTag.content.toLowerCase();
906
+ const isValidEditor = HerbOverlay.EDITOR_OPTIONS.some(option => option.value === defaultEditor);
907
+ if (isValidEditor) {
908
+ this.defaultEditorFromServer = defaultEditor;
909
+ }
910
+ }
911
+ }
898
912
  loadSettings() {
899
913
  const savedSettings = localStorage.getItem(HerbOverlay.SETTINGS_KEY);
900
914
  if (savedSettings) {
@@ -908,6 +922,9 @@ class HerbOverlay {
908
922
  this.showingPartialOutlines = settings.showingPartialOutlines || false;
909
923
  this.showingComponentOutlines = settings.showingComponentOutlines || false;
910
924
  this.menuOpen = settings.menuOpen || false;
925
+ if (settings.preferredEditor) {
926
+ this.preferredEditor = settings.preferredEditor;
927
+ }
911
928
  }
912
929
  catch (e) {
913
930
  console.warn('Failed to load Herb dev tools settings:', e);
@@ -923,7 +940,8 @@ class HerbOverlay {
923
940
  showingViewOutlines: this.showingViewOutlines,
924
941
  showingPartialOutlines: this.showingPartialOutlines,
925
942
  showingComponentOutlines: this.showingComponentOutlines,
926
- menuOpen: this.menuOpen
943
+ menuOpen: this.menuOpen,
944
+ preferredEditor: this.preferredEditor
927
945
  };
928
946
  localStorage.setItem(HerbOverlay.SETTINGS_KEY, JSON.stringify(settings));
929
947
  this.updateMenuButtonState();
@@ -959,7 +977,7 @@ class HerbOverlay {
959
977
  <label class="herb-toggle-label">
960
978
  <input type="checkbox" id="herbToggleViewOutlines" class="herb-toggle-input">
961
979
  <span class="herb-toggle-switch"></span>
962
- <span class="herb-toggle-text">Show View Outlines</span>
980
+ <span class="herb-toggle-text herb-outline-preview herb-outline-view">View Outlines</span>
963
981
  </label>
964
982
  </div>
965
983
 
@@ -967,7 +985,7 @@ class HerbOverlay {
967
985
  <label class="herb-toggle-label">
968
986
  <input type="checkbox" id="herbTogglePartialOutlines" class="herb-toggle-input">
969
987
  <span class="herb-toggle-switch"></span>
970
- <span class="herb-toggle-text">Show Partial Outlines</span>
988
+ <span class="herb-toggle-text herb-outline-preview herb-outline-partial">Partial Outlines</span>
971
989
  </label>
972
990
  </div>
973
991
 
@@ -975,7 +993,7 @@ class HerbOverlay {
975
993
  <label class="herb-toggle-label">
976
994
  <input type="checkbox" id="herbToggleComponentOutlines" class="herb-toggle-input">
977
995
  <span class="herb-toggle-switch"></span>
978
- <span class="herb-toggle-text">Show Component Outlines</span>
996
+ <span class="herb-toggle-text herb-outline-preview herb-outline-component">Component Outlines</span>
979
997
  </label>
980
998
  </div>
981
999
 
@@ -983,7 +1001,7 @@ class HerbOverlay {
983
1001
  <label class="herb-toggle-label">
984
1002
  <input type="checkbox" id="herbToggleERBOutlines" class="herb-toggle-input">
985
1003
  <span class="herb-toggle-switch"></span>
986
- <span class="herb-toggle-text">Show ERB Output Outlines</span>
1004
+ <span class="herb-toggle-text herb-outline-preview herb-outline-erb">ERB Output Outlines</span>
987
1005
  </label>
988
1006
 
989
1007
  <div class="herb-nested-toggle" id="herbERBHoverRevealNested" style="display: none;">
@@ -1011,6 +1029,15 @@ class HerbOverlay {
1011
1029
  </label>
1012
1030
  </div>
1013
1031
 
1032
+ <div class="herb-editor-section">
1033
+ <label class="herb-editor-label">
1034
+ <span class="herb-editor-text">Editor</span>
1035
+ <select id="herbEditorSelect" class="herb-editor-select">
1036
+ ${HerbOverlay.EDITOR_OPTIONS.map(editor => `<option value="${editor.value}">${editor.label}</option>`).join('')}
1037
+ </select>
1038
+ </label>
1039
+ </div>
1040
+
1014
1041
  <div class="herb-disable-all-section">
1015
1042
  <button id="herbDisableAll" class="herb-disable-all-btn">Disable All</button>
1016
1043
  </div>
@@ -1075,6 +1102,7 @@ class HerbOverlay {
1075
1102
  this.injectMenu();
1076
1103
  this.setupMenuToggle();
1077
1104
  this.setupToggleSwitches();
1105
+ this.setupEditorDropdown();
1078
1106
  this.applySettings();
1079
1107
  this.updateMenuButtonState();
1080
1108
  }
@@ -1148,6 +1176,27 @@ class HerbOverlay {
1148
1176
  });
1149
1177
  }
1150
1178
  }
1179
+ setupEditorDropdown() {
1180
+ const editorSelect = document.getElementById('herbEditorSelect');
1181
+ if (editorSelect) {
1182
+ const autoOption = editorSelect.querySelector('option[value="auto"]');
1183
+ if (autoOption) {
1184
+ const editorLabel = HerbOverlay.EDITOR_OPTIONS.find(opt => opt.value === this.defaultEditorFromServer)?.label || this.defaultEditorFromServer;
1185
+ const metaTag = document.querySelector('meta[name="herb-default-editor"]');
1186
+ if (metaTag?.content) {
1187
+ autoOption.textContent = `Auto (from server): ${editorLabel}`;
1188
+ }
1189
+ else {
1190
+ autoOption.textContent = `Auto (default): ${editorLabel}`;
1191
+ }
1192
+ }
1193
+ editorSelect.value = this.preferredEditor;
1194
+ editorSelect.addEventListener('change', () => {
1195
+ this.preferredEditor = editorSelect.value;
1196
+ this.saveSettings();
1197
+ });
1198
+ }
1199
+ }
1151
1200
  toggleViewOutlines(show) {
1152
1201
  this.showingViewOutlines = show !== undefined ? show : !this.showingViewOutlines;
1153
1202
  const viewOutlines = document.querySelectorAll('[data-herb-debug-outline-type="view"], [data-herb-debug-outline-type*="view"]');
@@ -1244,14 +1293,21 @@ class HerbOverlay {
1244
1293
  parent.style.outlineOffset = parent.tagName.toLowerCase() === 'html' ? '-2px' : '2px';
1245
1294
  parent.classList.add('show-outline');
1246
1295
  parent.setAttribute('data-herb-debug-attached-outline-type', type);
1247
- parent.style.position = 'relative';
1296
+ if (window.getComputedStyle(parent).position === 'static') {
1297
+ parent.style.position = 'relative';
1298
+ }
1248
1299
  label.style.position = 'absolute';
1249
1300
  label.style.top = '0';
1250
1301
  label.style.left = '0';
1251
1302
  parent.appendChild(label);
1252
1303
  return;
1253
1304
  }
1254
- element.style.position = 'relative';
1305
+ if (element.localName === 'html' || window.getComputedStyle(element).overflowY !== 'visible') {
1306
+ label.style.top = '0';
1307
+ }
1308
+ if (window.getComputedStyle(element).position === 'static') {
1309
+ element.style.position = 'relative';
1310
+ }
1255
1311
  element.appendChild(label);
1256
1312
  }
1257
1313
  removeOverlayLabel(element) {
@@ -1589,21 +1645,55 @@ class HerbOverlay {
1589
1645
  delete element._lazyTooltipHandler;
1590
1646
  }
1591
1647
  }
1648
+ getEditorUrl(editor, absolutePath, line, column) {
1649
+ switch (editor) {
1650
+ case 'cursor':
1651
+ return `cursor://file/${absolutePath}:${line}:${column}`;
1652
+ case 'vscode':
1653
+ return `vscode://file/${absolutePath}:${line}:${column}`;
1654
+ case 'vscodium':
1655
+ return `vscodium://file/${absolutePath}:${line}:${column}`;
1656
+ case 'zed':
1657
+ return `zed://file/${absolutePath}:${line}:${column}`;
1658
+ case 'windsurf':
1659
+ return `windsurf://file/${absolutePath}:${line}:${column}`;
1660
+ case 'sublime':
1661
+ return `subl://open?url=file://${absolutePath}&line=${line}&column=${column}`;
1662
+ case 'atom':
1663
+ return `atom://core/open/file?filename=${absolutePath}&line=${line}&column=${column}`;
1664
+ case 'textmate':
1665
+ return `txmt://open?url=file://${absolutePath}&line=${line}&column=${column}`;
1666
+ case 'emacs':
1667
+ return `emacs://open?url=file://${absolutePath}&line=${line}&column=${column}`;
1668
+ case 'idea':
1669
+ return `idea://open?file=${absolutePath}&line=${line}&column=${column}`;
1670
+ case 'rubymine':
1671
+ return `x-mine://open?file=${absolutePath}&line=${line}&column=${column}`;
1672
+ case 'nova':
1673
+ return `nova://open?path=${absolutePath}&line=${line}&column=${column}`;
1674
+ case 'macvim':
1675
+ return `mvim://open?url=file://${absolutePath}&line=${line}&column=${column}`;
1676
+ case 'vim':
1677
+ return `vim://open?url=file://${absolutePath}&line=${line}&column=${column}`;
1678
+ case 'nvim':
1679
+ return `nvim://open?url=file://${absolutePath}&line=${line}&column=${column}`;
1680
+ default:
1681
+ return '';
1682
+ }
1683
+ }
1592
1684
  openFileInEditor(file, line, column) {
1593
1685
  const absolutePath = file.startsWith('/') ? file : (this.projectPath ? `${this.projectPath}/${file}` : file);
1594
- const editors = [
1595
- `cursor://file/${absolutePath}:${line}:${column}`,
1596
- `vscode://file/${absolutePath}:${line}:${column}`,
1597
- `zed://file/${absolutePath}:${line}:${column}`,
1598
- `subl://open?url=file://${absolutePath}&line=${line}&column=${column}`,
1599
- `atom://core/open/file?filename=${absolutePath}&line=${line}&column=${column}`,
1600
- `txmt://open?url=file://${absolutePath}&line=${line}&column=${column}`,
1601
- `x-mine://open?file=//${absolutePath}&line=${line}&column=${column}`,
1602
- ];
1603
- try {
1604
- window.open(editors[0], '_self');
1686
+ const editorToUse = this.preferredEditor === 'auto' ? this.defaultEditorFromServer : this.preferredEditor;
1687
+ const url = this.getEditorUrl(editorToUse, absolutePath, line, column);
1688
+ if (url) {
1689
+ try {
1690
+ window.open(url, '_self');
1691
+ }
1692
+ catch (error) {
1693
+ console.log(`Open in editor: ${absolutePath}:${line}:${column}`);
1694
+ }
1605
1695
  }
1606
- catch (error) {
1696
+ else {
1607
1697
  console.log(`Open in editor: ${absolutePath}:${line}:${column}`);
1608
1698
  }
1609
1699
  }
@@ -1664,6 +1754,24 @@ class HerbOverlay {
1664
1754
  }
1665
1755
  }
1666
1756
  HerbOverlay.SETTINGS_KEY = 'herb-dev-tools-settings';
1757
+ HerbOverlay.EDITOR_OPTIONS = [
1758
+ { value: 'auto', label: 'Auto (from server via RAILS_EDITOR or EDITOR)' },
1759
+ { value: 'atom', label: 'Atom' },
1760
+ { value: 'cursor', label: 'Cursor' },
1761
+ { value: 'emacs', label: 'Emacs' },
1762
+ { value: 'idea', label: 'IntelliJ IDEA' },
1763
+ { value: 'macvim', label: 'MacVim' },
1764
+ { value: 'nova', label: 'Nova' },
1765
+ { value: 'nvim', label: 'Neovim' },
1766
+ { value: 'rubymine', label: 'RubyMine' },
1767
+ { value: 'sublime', label: 'Sublime Text' },
1768
+ { value: 'textmate', label: 'TextMate' },
1769
+ { value: 'vim', label: 'Vim' },
1770
+ { value: 'vscode', label: 'Visual Studio Code' },
1771
+ { value: 'vscodium', label: 'VSCodium' },
1772
+ { value: 'windsurf', label: 'Windsurf' },
1773
+ { value: 'zed', label: 'Zed' },
1774
+ ];
1667
1775
 
1668
1776
  function initHerbDevTools(options = {}) {
1669
1777
  return new HerbOverlay(options);