diff --git a/services/premiere-plugin-uxp/index.html b/services/premiere-plugin-uxp/index.html index fa93213..ee19824 100644 --- a/services/premiere-plugin-uxp/index.html +++ b/services/premiere-plugin-uxp/index.html @@ -35,9 +35,9 @@ - + - + Disconnect @@ -47,22 +47,22 @@ - + - - + + 0 - + - + - - + + - + @@ -112,30 +112,30 @@ diff --git a/services/premiere-plugin-uxp/src/main.js b/services/premiere-plugin-uxp/src/main.js index c3a0ad9..46d980d 100644 --- a/services/premiere-plugin-uxp/src/main.js +++ b/services/premiere-plugin-uxp/src/main.js @@ -6,6 +6,28 @@ const $ = id => document.getElementById(id); + // UXP renders native chrome that ignores CSS `background` and does + // not draw -only button content, so the rail/dock icon controls are + // (divs render custom backgrounds + SVG children fine). + // Divs have no native `disabled`, so reflect the `.disabled` property the + // rest of the code sets onto a [disabled] attribute the stylesheet keys off. + const ICON_CONTROLS = [ + 'menu-btn', 'tab-library', 'tab-growing', 'export-timeline-btn', 'refresh-btn', + 'import-proxy-btn', 'import-hires-btn', 'mount-live-btn', 'relink-btn', + 'import-all-btn', 'export-conform-btn', 'fetch-relink-btn' + ]; + function enableDivDisabled() { + ICON_CONTROLS.forEach(id => { + const el = document.getElementById(id); + if (!el || Object.getOwnPropertyDescriptor(el, 'disabled')) return; + Object.defineProperty(el, 'disabled', { + configurable: true, + get() { return this.hasAttribute('disabled'); }, + set(v) { if (v) this.setAttribute('disabled', ''); else this.removeAttribute('disabled'); } + }); + }); + } + function syncConnectBtn() { $('connect-btn').disabled = !$('server-url').value.trim() || !$('api-token').value.trim(); } @@ -465,6 +487,7 @@ } function init() { + enableDivDisabled(); wireConnectPane(); wireLibraryPane(); wireExportPanel(); wireConformPanel(); wireRelinkPanel(); showVersion(); diff --git a/services/premiere-plugin-uxp/styles.css b/services/premiere-plugin-uxp/styles.css index 8221c40..ce4ecf1 100644 --- a/services/premiere-plugin-uxp/styles.css +++ b/services/premiere-plugin-uxp/styles.css @@ -255,43 +255,28 @@ input[type="search"]::-webkit-search-cancel-button { display: none; } padding: 8px 0; gap: 2px; } +/* Rail/dock controls are (not ): UXP renders + native button chrome that ignores `background` and won't draw SVG-only + content. Divs honor backgrounds and render SVG children correctly. */ .rail-btn { position: relative; width: 34px; height: 34px; - border: none; - /* Leave background transparent — UXP native chrome cannot be overridden via - `background` on icon-only buttons. Cover it with a ::before pseudo-element - instead; authored content renders above native chrome. */ background: transparent; - appearance: none; - -webkit-appearance: none; border-radius: 8px; color: var(--text-3); display: flex; align-items: center; justify-content: center; cursor: pointer; - transition: color var(--t-fast) var(--ease); + transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease); } -/* Full-face cover painted above native chrome */ -.rail-btn::before { - content: ''; - position: absolute; - inset: 0; - border-radius: 8px; - background: var(--bg-base); - transition: background var(--t-fast) var(--ease); - pointer-events: none; -} -.rail-btn:hover { color: var(--text-1); } -.rail-btn:hover::before { background: var(--bg-hover); } -.rail-btn.active { color: var(--accent-bright); } -.rail-btn.active::before { background: var(--accent-subtle); } -/* SVG and badge sit above the ::before cover */ -.rail-btn svg { position: relative; z-index: 1; width: 18px; height: 18px; } +.rail-btn:hover { background: var(--bg-hover); color: var(--text-1); } +.rail-btn.active { background: var(--accent-subtle); color: var(--accent-bright); } +.rail-btn svg { width: 18px; height: 18px; } +.rail-btn[disabled] { opacity: 0.32; cursor: default; pointer-events: none; } .rail-btn--accent { color: var(--accent-bright); } -.rail-btn--accent:hover::before { background: var(--accent-subtle); } +.rail-btn--accent:hover { background: var(--accent-subtle); } .rail-spacer { flex: 1; } .rail-count { @@ -493,40 +478,22 @@ input[type="search"]::-webkit-search-cancel-button { display: none; } width: 30px; height: 30px; flex-shrink: 0; - border: none; - /* Same ::before strategy as .rail-btn — authored pseudo-element covers - UXP's native button chrome which ignores explicit background rules. */ background: transparent; - appearance: none; - -webkit-appearance: none; border-radius: 7px; color: var(--text-2); display: flex; align-items: center; justify-content: center; cursor: pointer; - transition: color var(--t-fast) var(--ease); + transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease); } -.iconbtn::before { - content: ''; - position: absolute; - inset: 0; - border-radius: 7px; - background: var(--bg-base); - transition: background var(--t-fast) var(--ease); - pointer-events: none; -} -.iconbtn:hover { color: var(--text-1); } -.iconbtn:hover::before { background: var(--bg-hover); } -/* SVG sits above the ::before cover */ -.iconbtn svg { position: relative; z-index: 1; width: 16px; height: 16px; } -.iconbtn:disabled { opacity: 0.32; cursor: default; pointer-events: none; } +.iconbtn:hover { background: var(--bg-hover); color: var(--text-1); } +.iconbtn svg { width: 16px; height: 16px; } +.iconbtn[disabled] { opacity: 0.32; cursor: default; pointer-events: none; } .iconbtn--sm { width: 24px; height: 24px; border-radius: 6px; color: var(--text-3); } -.iconbtn--sm::before { border-radius: 6px; } .iconbtn--sm svg { width: 15px; height: 15px; } -.iconbtn--primary::before { background: var(--accent); } -.iconbtn--primary { color: #fff; } -.iconbtn--primary:not(:disabled):hover::before { background: var(--accent-hover); } +.iconbtn--primary { background: var(--accent); color: #fff; } +.iconbtn--primary:not([disabled]):hover { background: var(--accent-hover); } /* ── progress ───────────────────────────────────────────────────── */ .progress-row { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px 0; flex-shrink: 0; }