From fa583e8c4d5a68b840352658241ace99218d1831 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Wed, 18 Feb 2026 11:32:20 +0000 Subject: [PATCH 1/6] refactor: migrate What's New to control-strip and extract viewport SCSS Rewrite picker-release-notes.ts to use a PCUI Button inside a control-strip Container instead of a custom popup. Use a real span dismiss icon inside the button DOM since pseudo-elements cannot receive click events. Extract .viewport, .control-strip, .whoisonline, and .chat-widget styles from _editor-main.scss into a new _editor-viewport.scss partial. Delete _editor-release-notes.scss (absorbed into _editor-viewport.scss). Co-authored-by: Cursor --- sass/editor.scss | 2 +- sass/editor/_editor-main.scss | 540 ------------------- sass/editor/_editor-release-notes.scss | 41 -- sass/editor/_editor-viewport.scss | 574 +++++++++++++++++++++ src/editor/pickers/picker-release-notes.ts | 42 +- 5 files changed, 598 insertions(+), 601 deletions(-) delete mode 100644 sass/editor/_editor-release-notes.scss create mode 100644 sass/editor/_editor-viewport.scss diff --git a/sass/editor.scss b/sass/editor.scss index e90711ce5..546585a8e 100644 --- a/sass/editor.scss +++ b/sass/editor.scss @@ -48,7 +48,7 @@ @import 'editor/editor-settings-scripts-panel'; @import 'editor/editor-sprite-editor'; @import 'editor/editor-tooltip'; -@import 'editor/editor-release-notes'; +@import 'editor/editor-viewport'; @import 'editor/editor-fix-templates'; @import 'editor/editor-store-cms'; @import 'editor/editor-storeitem-panel'; diff --git a/sass/editor/_editor-main.scss b/sass/editor/_editor-main.scss index b70f8f2e1..378b389e4 100644 --- a/sass/editor/_editor-main.scss +++ b/sass/editor/_editor-main.scss @@ -418,62 +418,6 @@ strong { } } } - -.viewport { - @extend .noSelect; - - > .camera-preview { - display: none; - position: absolute; - top: 41px; - left: 4px; - width: 256px; - height: 196px; - border: 2px solid $text-primary; - - &.active { - display: block; - } - - &.clickable { - cursor: pointer; - - &:hover { - border-color: $text-active; - } - } - - > .lock { - position: absolute; - top: 0; - right: 0; - width: 24px; - height: 24px; - line-height: 26px; - padding: 0; - margin: 0; - border: none; - border-radius: 0; - color: rgba($text-primary, 0.75); - background-color: rgba($bcg-darker, 0.5); - - &.active { - color: $text-active; - box-shadow: none; - - &::before { - content: '\E341'; - } - } - - &:hover { - color: $text-primary; - background-color: rgba($bcg-darker, 0.75); - } - } - } -} - .ui-panel.files { > .content { background-color: $bcg-darker; @@ -511,490 +455,6 @@ strong { } } -.control-strip { - position: absolute; - display: flex; - gap: 2px; - - > .pcui-button, - > .render > .pcui-button, - > .camera > .pcui-button, - > .launch > .pcui-button { - height: 33px; - margin: 0; - border: none; - border-radius: 0; - color: rgba($text-primary, 0.75); - background-color: rgba($bcg-darker, 0.5); - - &:hover, - &.active { - color: $text-primary; - background-color: rgba($bcg-darker, 0.75); - box-shadow: none; - } - - &::before { - font-size: 14px; - } - - &:empty { - width: 33px; - padding: 0; - } - - &:not(:empty) { - padding: 0 10px; - } - } - - &.top-left { - top: 4px; - left: 4px; - } - - &.top-right { - top: 4px; - right: 4px; - - > .pcui-button.expand { - &::before { - font-size: 16px; - } - - &.active { - background-color: $text-active; - } - } - - > .pcui-container.render, - > .pcui-container.camera { - position: relative; - - &:hover > .pcui-button { - color: $text-primary; - background-color: rgba($bcg-darker, 0.75); - } - - > .render-options, - > .camera-options { - position: absolute; - padding: 10px; - top: 33px; - right: 0; - text-align: start; - min-width: 150px; - max-height: 300px; - overflow: hidden auto; - background-color: rgba($bcg-darker, .75); - - .pcui-container { - flex-direction: row; - line-height: 22px; - width: 100%; - background: transparent; - - .pcui-boolean-input { - margin: 7px 3px 3px; - vertical-align: text-bottom; - } - - .pcui-radio-button { - align-self: center; - height: 16px; - margin: 0 3px 0 2px; - width: 16px; - flex-shrink: 0; - } - - .pcui-label { - margin: 3px; - max-width: 200px; - min-height: 20px; - font-size: 12px; - word-wrap: break-word; - white-space: pre-wrap; - vertical-align: bottom; - } - } - - .divider { - height: 3px; - background-color: rgba($bcg-darker, .75); - margin: 5px 0; - } - } - } - - > .launch { - position: relative; - - &:not(.disabled):hover { - > .pcui-button { - background-color: $text-active; - } - } - - > .pcui-button { - &::before { - font-size: 20px; - } - } - - .pcui-container.options { - position: absolute; - top: 33px; - right: 0; - margin: 0; - padding: 5px; - list-style: none; - background-color: rgba($bcg-darker, 0.75); - - .pcui-boolean-input:not(.pcui-boolean-input-ticked) { - background-color: #20292b; - } - - .pcui-label { - vertical-align: top; - font-size: 12px; - } - - .pcui-container { - @extend .noSelect; - - background: transparent; - width: 200px; - cursor: pointer; - margin: 2px 0; - - &:has(.pcui-button):hover { - .pcui-button { - color: $text-active; - } - } - } - - .pcui-button { - width: 100%; - border: 0; - padding: 0; - margin: 0; - margin-left: 5px; - background-color: transparent; - font-size: 12px; - text-align: left; - - &::before { - font-size: 20px; - vertical-align: middle; - } - - &:hover { - box-shadow: none; - } - } - } - } - } -} - -.pcui-container.whoisonline { - position: absolute; - bottom: 34px; - left: 246px; - background-color: transparent; - padding: 2px; - transition: left 100ms; - - &.chat-minified { - left: 106px; - } - - &.no-chat { - left: 2px; - } - - &.expanded { - bottom: 2px; - left: 2px; - transition: none; - } - - > a { - position: relative; - display: block; - margin-right: 4px; - float: left; - background-color: $bcg-darkest; - - > img { - display: block; - width: 28px; - height: 28px; - margin: 2px; - } - - &::after { - content: '\00a0'; - position: absolute; - right: 2px; - bottom: 2px; - width: 6px; - height: 6px; - background: inherit; - } - } -} - -.pcui-panel.chat-widget { - position: absolute; - bottom: 36px; - left: 4px; - width: 240px; - height: 192px; - - &.pcui-collapsed { - width: 100px; - - > .pcui-panel-header { - color: $text-secondary; - - &::before { - content: '\E233'; - color: $text-secondary; - } - - > .typers { - display: none; - } - - > .pcui-button { - display: none; - } - } - } - - &.notify { - > .pcui-panel-header { - &::after { - color: $text-active; - } - - > .title { - color: $text-primary; - } - } - } - - > .pcui-panel-header { - // header collapsible hover state - &:hover { - color: $text-primary; - - &::before { - color: $text-primary; - } - } - - &::before { - content: '\E233'; - } - - > .typers { - float: right; - max-width: 132px; - padding-right: 4px; - font-size: 10px; - text-overflow: ellipsis; - order: 0; - overflow: hidden; - color: $text-secondary; - - > .single, - > .double, - > .multiple { - display: none; - - &.active { - display: block; - } - - > .user { - font-weight: bold; - } - } - } - - > .notifications { - border-radius: 0; - color: $text-darkest; - float: right; - font-size: 18px; - order: 1; - overflow: initial; - width: 32px; - height: 32px; - - &.active { - color: $text-secondary; - } - - &:hover { - color: $text-primary; - background-color: $bcg-darkest; - box-shadow: none; - } - } - - > .number { - display: none; - float: right; - margin-right: 4px; - padding: 0 6px; - height: 18px; - line-height: 18px; - border-radius: 9px; - pointer-events: none; - - &.notify { - display: block; - color: $text-primary; - background-color: $text-active; - } - - &.typing { - display: block; - color: $text-primary; - } - } - } - - > .pcui-panel-content { - height: 160px; - - > .messages { - height: 124px; - overflow-x: hidden; - padding-bottom: 4px; - user-select: text; - width: 240px; - word-break: break-word; - - > .divider { - background-color: $bcg-darker; - margin: 4px 8px; - height: 1px; - } - - > .message + .message.multi { - margin-top: -4px; - } - - > .message.multi + .message.multi { - margin-top: 0; - } - - > .message { - margin: 4px; - padding-left: 18px; - line-height: 14px; - font-size: 12px; - - &.multi { - margin: 0 4px; - } - - > img { - vertical-align: text-bottom; - margin-right: 4px; - margin-left: -18px; - - @extend .noSelect; - } - - > span { - vertical-align: text-top; - - &.username { - font-weight: bold; - color: $text-primary; - } - } - } - - > .system { - margin: 4px; - line-height: 12px; - font-size: 12px; - font-weight: bold; - color: $text-active; - } - } - - > .pcui-input-element { - border: none; - height: 32px; - margin: 0; - width: 240px; - - &.pcui-focus, - &:hover { - box-shadow: none; - } - - &::after { - right: auto; - left: 0; - line-height: 32px; - width: 32px; - text-align: center; - padding: 0; - } - - &.not-empty { - padding: 0; - content: ''; - background-color: $bcg-darkest; - - &::after { - content: ''; - } - - > .clear { - display: block; - } - - > input { - color: $text-primary; - width: calc(100% - 40px); - } - } - - > input { - padding: 0 8px; - } - - > .clear { - display: none; - position: absolute; - top: 0; - right: 0; - width: 32px; - height: 32px; - line-height: 32px; - color: #d34141; - - @extend .font-icon; - - font-size: 18px; - font-weight: bold; - text-align: center; - cursor: pointer; - } - } - } -} - .ui-overlay.script-priorities { > .content { width: 400px; diff --git a/sass/editor/_editor-release-notes.scss b/sass/editor/_editor-release-notes.scss deleted file mode 100644 index aace10f93..000000000 --- a/sass/editor/_editor-release-notes.scss +++ /dev/null @@ -1,41 +0,0 @@ -@use 'sass:color'; - -.popup-release-notes { - position: absolute; - bottom: 5px; - right: 5px; - z-index: 1; - background: color.adjust($text-active, $lightness: -5%); - height: 32px; - align-items: center; - padding-left: 3px; - - > .pcui-label { - color: $text-primary; - font-size: 12px; - - &::before { - @extend .font-icon; - - content: '\E191'; - margin-right: $element-margin; - } - } - - &:hover { - cursor: pointer; - background: $text-active; - } - - .pcui-button { - float: right; - background: transparent; - border: 0; - margin: 0; - transition: none; - - &:hover { - background: transparent !important; - } - } -} diff --git a/sass/editor/_editor-viewport.scss b/sass/editor/_editor-viewport.scss new file mode 100644 index 000000000..de0cfd131 --- /dev/null +++ b/sass/editor/_editor-viewport.scss @@ -0,0 +1,574 @@ +@use 'sass:color'; + +.viewport { + @extend .noSelect; + + > .camera-preview { + display: none; + position: absolute; + top: 41px; + left: 4px; + width: 256px; + height: 196px; + border: 2px solid $text-primary; + + &.active { + display: block; + } + + &.clickable { + cursor: pointer; + + &:hover { + border-color: $text-active; + } + } + + > .lock { + position: absolute; + top: 0; + right: 0; + width: 24px; + height: 24px; + line-height: 26px; + padding: 0; + margin: 0; + border: none; + border-radius: 0; + color: rgba($text-primary, 0.75); + background-color: rgba($bcg-darker, 0.5); + + &.active { + color: $text-active; + box-shadow: none; + + &::before { + content: '\E341'; + } + } + + &:hover { + color: $text-primary; + background-color: rgba($bcg-darker, 0.75); + } + } + } +} + +.control-strip { + position: absolute; + display: flex; + gap: 2px; + + > .pcui-button, + > .render > .pcui-button, + > .camera > .pcui-button, + > .launch > .pcui-button { + height: 33px; + margin: 0; + border: none; + border-radius: 0; + color: rgba($text-primary, 0.75); + background-color: rgba($bcg-darker, 0.5); + + &:hover, + &.active { + color: $text-primary; + background-color: rgba($bcg-darker, 0.75); + box-shadow: none; + } + + &::before { + font-size: 14px; + } + + &:empty { + width: 33px; + padding: 0; + } + + &:not(:empty) { + padding: 0 10px; + } + } + + &.top-left { + top: 4px; + left: 4px; + } + + &.bottom-right { + bottom: 4px; + right: 4px; + } + + &.top-right { + top: 4px; + right: 4px; + + > .pcui-button.expand { + &::before { + font-size: 16px; + } + + &.active { + background-color: $text-active; + } + } + + > .pcui-container.render, + > .pcui-container.camera { + position: relative; + + &:hover > .pcui-button { + color: $text-primary; + background-color: rgba($bcg-darker, 0.75); + } + + > .render-options, + > .camera-options { + position: absolute; + padding: 10px; + top: 33px; + right: 0; + text-align: start; + min-width: 150px; + max-height: 300px; + overflow: hidden auto; + background-color: rgba($bcg-darker, .75); + + .pcui-container { + flex-direction: row; + line-height: 22px; + width: 100%; + background: transparent; + + .pcui-boolean-input { + margin: 7px 3px 3px; + vertical-align: text-bottom; + } + + .pcui-radio-button { + align-self: center; + height: 16px; + margin: 0 3px 0 2px; + width: 16px; + flex-shrink: 0; + } + + .pcui-label { + margin: 3px; + max-width: 200px; + min-height: 20px; + font-size: 12px; + word-wrap: break-word; + white-space: pre-wrap; + vertical-align: bottom; + } + } + + .divider { + height: 3px; + background-color: rgba($bcg-darker, .75); + margin: 5px 0; + } + } + } + + > .launch { + position: relative; + + &:not(.disabled):hover { + > .pcui-button { + background-color: $text-active; + } + } + + > .pcui-button { + &::before { + font-size: 20px; + } + } + + .pcui-container.options { + position: absolute; + top: 33px; + right: 0; + margin: 0; + padding: 5px; + list-style: none; + background-color: rgba($bcg-darker, 0.75); + + .pcui-boolean-input:not(.pcui-boolean-input-ticked) { + background-color: #20292b; + } + + .pcui-label { + vertical-align: top; + font-size: 12px; + } + + .pcui-container { + @extend .noSelect; + + background: transparent; + width: 200px; + cursor: pointer; + margin: 2px 0; + + &:has(.pcui-button):hover { + .pcui-button { + color: $text-active; + } + } + } + + .pcui-button { + width: 100%; + border: 0; + padding: 0; + margin: 0; + margin-left: 5px; + background-color: transparent; + font-size: 12px; + text-align: left; + + &::before { + font-size: 20px; + vertical-align: middle; + } + + &:hover { + box-shadow: none; + } + } + } + } + } +} + +.control-strip > .pcui-button.whats-new { + color: $text-primary; + background-color: color.adjust($text-active, $lightness: -5%); + padding-right: 0; + text-transform: uppercase; + + &:hover { + background-color: $text-active; + } + + .dismiss-icon { + display: inline-block; + padding: 0 10px; + cursor: pointer; + color: rgba($text-primary, 0.5); + transition: none; + + &::before { + @extend .font-icon; + content: '\E132'; + font-size: 10px; + } + + &:hover { + color: $text-primary; + } + } +} + +.pcui-container.whoisonline { + position: absolute; + bottom: 34px; + left: 246px; + background-color: transparent; + padding: 2px; + transition: left 100ms; + + &.chat-minified { + left: 106px; + } + + &.no-chat { + left: 2px; + } + + &.expanded { + bottom: 2px; + left: 2px; + transition: none; + } + + > a { + position: relative; + display: block; + margin-right: 4px; + float: left; + background-color: $bcg-darkest; + + > img { + display: block; + width: 28px; + height: 28px; + margin: 2px; + } + + &::after { + content: '\00a0'; + position: absolute; + right: 2px; + bottom: 2px; + width: 6px; + height: 6px; + background: inherit; + } + } +} + +.pcui-panel.chat-widget { + position: absolute; + bottom: 36px; + left: 4px; + width: 240px; + height: 192px; + + &.pcui-collapsed { + width: 100px; + + > .pcui-panel-header { + color: $text-secondary; + + &::before { + content: '\E233'; + color: $text-secondary; + } + + > .typers { + display: none; + } + + > .pcui-button { + display: none; + } + } + } + + &.notify { + > .pcui-panel-header { + &::after { + color: $text-active; + } + + > .title { + color: $text-primary; + } + } + } + + > .pcui-panel-header { + // header collapsible hover state + &:hover { + color: $text-primary; + + &::before { + color: $text-primary; + } + } + + &::before { + content: '\E233'; + } + + > .typers { + float: right; + max-width: 132px; + padding-right: 4px; + font-size: 10px; + text-overflow: ellipsis; + order: 0; + overflow: hidden; + color: $text-secondary; + + > .single, + > .double, + > .multiple { + display: none; + + &.active { + display: block; + } + + > .user { + font-weight: bold; + } + } + } + + > .notifications { + border-radius: 0; + color: $text-darkest; + float: right; + font-size: 18px; + order: 1; + overflow: initial; + width: 32px; + height: 32px; + + &.active { + color: $text-secondary; + } + + &:hover { + color: $text-primary; + background-color: $bcg-darkest; + box-shadow: none; + } + } + + > .number { + display: none; + float: right; + margin-right: 4px; + padding: 0 6px; + height: 18px; + line-height: 18px; + border-radius: 9px; + pointer-events: none; + + &.notify { + display: block; + color: $text-primary; + background-color: $text-active; + } + + &.typing { + display: block; + color: $text-primary; + } + } + } + + > .pcui-panel-content { + height: 160px; + + > .messages { + height: 124px; + overflow-x: hidden; + padding-bottom: 4px; + user-select: text; + width: 240px; + word-break: break-word; + + > .divider { + background-color: $bcg-darker; + margin: 4px 8px; + height: 1px; + } + + > .message + .message.multi { + margin-top: -4px; + } + + > .message.multi + .message.multi { + margin-top: 0; + } + + > .message { + margin: 4px; + padding-left: 18px; + line-height: 14px; + font-size: 12px; + + &.multi { + margin: 0 4px; + } + + > img { + vertical-align: text-bottom; + margin-right: 4px; + margin-left: -18px; + + @extend .noSelect; + } + + > span { + vertical-align: text-top; + + &.username { + font-weight: bold; + color: $text-primary; + } + } + } + + > .system { + margin: 4px; + line-height: 12px; + font-size: 12px; + font-weight: bold; + color: $text-active; + } + } + + > .pcui-input-element { + border: none; + height: 32px; + margin: 0; + width: 240px; + + &.pcui-focus, + &:hover { + box-shadow: none; + } + + &::after { + right: auto; + left: 0; + line-height: 32px; + width: 32px; + text-align: center; + padding: 0; + } + + &.not-empty { + padding: 0; + content: ''; + background-color: $bcg-darkest; + + &::after { + content: ''; + } + + > .clear { + display: block; + } + + > input { + color: $text-primary; + width: calc(100% - 40px); + } + } + + > input { + padding: 0 8px; + } + + > .clear { + display: none; + position: absolute; + top: 0; + right: 0; + width: 32px; + height: 32px; + line-height: 32px; + color: #d34141; + + @extend .font-icon; + + font-size: 18px; + font-weight: bold; + text-align: center; + cursor: pointer; + } + } + } +} diff --git a/src/editor/pickers/picker-release-notes.ts b/src/editor/pickers/picker-release-notes.ts index b1cf2bc88..4e536df72 100644 --- a/src/editor/pickers/picker-release-notes.ts +++ b/src/editor/pickers/picker-release-notes.ts @@ -1,42 +1,46 @@ -import { Container, Label, Button } from '@playcanvas/pcui'; +import { Button, Container } from '@playcanvas/pcui'; import { config } from '@/editor/config'; editor.once('load', () => { const LOCALSTORAGE_KEY = 'playcanvas-editor-latest-release-notes'; const latestVersionSeen = localStorage.getItem(LOCALSTORAGE_KEY); + if (latestVersionSeen === config.version) { return; } - const popup = new Container({ - class: 'popup-release-notes', - flex: true, - flexDirection: 'row' + const viewport = editor.call('layout.viewport'); + + const container = new Container({ + class: ['control-strip', 'bottom-right'] }); - const label = new Label({ - text: 'WHAT\'S NEW' + viewport.append(container); + + const btn = new Button({ + class: 'whats-new', + icon: 'E259', + text: "What's New" }); - popup.append(label); + container.append(btn); - function dismiss() { + const dismiss = () => { localStorage.setItem(LOCALSTORAGE_KEY, config.version); - popup.destroy(); - } + container.destroy(); + }; - popup.on('click', () => { + btn.on('click', () => { dismiss(); window.open(`https://github.com/playcanvas/editor/releases/tag/v${config.version}`); }); - const btnDismiss = new Button({ - icon: 'E132' - }); - popup.append(btnDismiss); - btnDismiss.on('click', (evt) => { + // Dismiss icon: a real inside the button DOM + // (pseudo-elements cannot receive their own click events) + const dismissIcon = document.createElement('span'); + dismissIcon.classList.add('dismiss-icon'); + btn.dom.appendChild(dismissIcon); + dismissIcon.addEventListener('click', (evt) => { evt.stopPropagation(); dismiss(); }); - - editor.call('layout.viewport').append(popup); }); From 8f95ece8dfa82fa867e374bb32a25e5778d62062 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Wed, 18 Feb 2026 11:36:31 +0000 Subject: [PATCH 2/6] refactor: move whats-new from pickers/ to toolbar/ Co-authored-by: Cursor --- src/editor/index.ts | 2 +- .../picker-release-notes.ts => toolbar/toolbar-whats-new.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/editor/{pickers/picker-release-notes.ts => toolbar/toolbar-whats-new.ts} (100%) diff --git a/src/editor/index.ts b/src/editor/index.ts index d96c81cc0..c80847d45 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -294,6 +294,7 @@ import './toolbar/toolbar-publish'; import './toolbar/toolbar-code-editor'; import './toolbar/toolbar-scene'; import './toolbar/toolbar-launch'; +import './toolbar/toolbar-whats-new'; import './toolbar/toolbar-cameras'; import './toolbar/toolbar-whois'; import './toolbar/toolbar-connection'; @@ -363,7 +364,6 @@ import './pickers/picker-gradient'; import './pickers/picker-text-input'; import './pickers/picker-legacy-scripts'; import './pickers/picker-recompress-textures'; -import './pickers/picker-release-notes'; import './pickers/picker-fix-corrupted-templates'; // team management picker diff --git a/src/editor/pickers/picker-release-notes.ts b/src/editor/toolbar/toolbar-whats-new.ts similarity index 100% rename from src/editor/pickers/picker-release-notes.ts rename to src/editor/toolbar/toolbar-whats-new.ts From c8bbedb912cc095656f7ad6aa78c996fa95506cd Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Wed, 18 Feb 2026 11:45:52 +0000 Subject: [PATCH 3/6] fix: stylelint errors in extracted viewport SCSS Co-authored-by: Cursor --- sass/editor/_editor-main.scss | 1 + sass/editor/_editor-viewport.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/sass/editor/_editor-main.scss b/sass/editor/_editor-main.scss index 378b389e4..af43d878b 100644 --- a/sass/editor/_editor-main.scss +++ b/sass/editor/_editor-main.scss @@ -418,6 +418,7 @@ strong { } } } + .ui-panel.files { > .content { background-color: $bcg-darker; diff --git a/sass/editor/_editor-viewport.scss b/sass/editor/_editor-viewport.scss index de0cfd131..b85b9d1f7 100644 --- a/sass/editor/_editor-viewport.scss +++ b/sass/editor/_editor-viewport.scss @@ -266,6 +266,7 @@ &::before { @extend .font-icon; + content: '\E132'; font-size: 10px; } From c4dd9903f5aaa9e3c9ae7b70347356910989369d Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Wed, 18 Feb 2026 11:49:16 +0000 Subject: [PATCH 4/6] fix: use single quotes for ESLint compliance Co-authored-by: Cursor --- src/editor/toolbar/toolbar-whats-new.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/editor/toolbar/toolbar-whats-new.ts b/src/editor/toolbar/toolbar-whats-new.ts index 4e536df72..e9c81cbbd 100644 --- a/src/editor/toolbar/toolbar-whats-new.ts +++ b/src/editor/toolbar/toolbar-whats-new.ts @@ -20,7 +20,7 @@ editor.once('load', () => { const btn = new Button({ class: 'whats-new', icon: 'E259', - text: "What's New" + text: 'What\'s New' }); container.append(btn); From 1771872445cc8200427e83779bc9b980fbbce3d4 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Wed, 18 Feb 2026 11:54:56 +0000 Subject: [PATCH 5/6] fix: scope compact-mode selectors to top strips and type evt param Co-authored-by: Cursor --- src/editor/toolbar/toolbar-launch.ts | 9 +++++---- src/editor/toolbar/toolbar-whats-new.ts | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/editor/toolbar/toolbar-launch.ts b/src/editor/toolbar/toolbar-launch.ts index ef18a1d70..f80502869 100644 --- a/src/editor/toolbar/toolbar-launch.ts +++ b/src/editor/toolbar/toolbar-launch.ts @@ -408,11 +408,12 @@ editor.once('load', () => { const topLeft = document.querySelector('.control-strip.top-left'); const minGap = 20; + const topStripPrefix = '.control-strip.top-left, .control-strip.top-right'; const buttonSelector = [ - '.control-strip > .pcui-button', - '.control-strip > .render > .pcui-button', - '.control-strip > .camera > .pcui-button', - '.control-strip > .launch > .pcui-button' + ':is(' + topStripPrefix + ') > .pcui-button', + ':is(' + topStripPrefix + ') > .render > .pcui-button', + ':is(' + topStripPrefix + ') > .camera > .pcui-button', + ':is(' + topStripPrefix + ') > .launch > .pcui-button' ].join(', '); const restoreButtonText = () => { diff --git a/src/editor/toolbar/toolbar-whats-new.ts b/src/editor/toolbar/toolbar-whats-new.ts index e9c81cbbd..5871a2b8b 100644 --- a/src/editor/toolbar/toolbar-whats-new.ts +++ b/src/editor/toolbar/toolbar-whats-new.ts @@ -39,7 +39,7 @@ editor.once('load', () => { const dismissIcon = document.createElement('span'); dismissIcon.classList.add('dismiss-icon'); btn.dom.appendChild(dismissIcon); - dismissIcon.addEventListener('click', (evt) => { + dismissIcon.addEventListener('click', (evt: MouseEvent) => { evt.stopPropagation(); dismiss(); }); From 8c88fd2697b8d0ac4697df75f9013c7b44e9bda9 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Wed, 18 Feb 2026 11:58:21 +0000 Subject: [PATCH 6/6] fix: use template literals for prefer-template ESLint rule Co-authored-by: Cursor --- src/editor/toolbar/toolbar-launch.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/editor/toolbar/toolbar-launch.ts b/src/editor/toolbar/toolbar-launch.ts index f80502869..491096409 100644 --- a/src/editor/toolbar/toolbar-launch.ts +++ b/src/editor/toolbar/toolbar-launch.ts @@ -408,12 +408,12 @@ editor.once('load', () => { const topLeft = document.querySelector('.control-strip.top-left'); const minGap = 20; - const topStripPrefix = '.control-strip.top-left, .control-strip.top-right'; + const topStrips = ':is(.control-strip.top-left, .control-strip.top-right)'; const buttonSelector = [ - ':is(' + topStripPrefix + ') > .pcui-button', - ':is(' + topStripPrefix + ') > .render > .pcui-button', - ':is(' + topStripPrefix + ') > .camera > .pcui-button', - ':is(' + topStripPrefix + ') > .launch > .pcui-button' + `${topStrips} > .pcui-button`, + `${topStrips} > .render > .pcui-button`, + `${topStrips} > .camera > .pcui-button`, + `${topStrips} > .launch > .pcui-button` ].join(', '); const restoreButtonText = () => {