Skip to content

feat: view as surface - #4469

Open
Julusian wants to merge 15 commits into
mainfrom
feat/grid-view-as-v2
Open

Julusian wants to merge 15 commits into
mainfrom
feat/grid-view-as-v2

Conversation

@Julusian

@Julusian Julusian commented Sep 17, 2026 •

Copy link
Copy Markdown
Member

Related: #1352
Closes: #2189
closes #3205

Replaces #2945

This is intended to solve 2 workflow problems:

  1. When programming buttons for some surfaces, it is non obvious which grid cells align with the physical controls. The SD+XL is a good example of this with its x-xx-xx-x pattern of encoder/lcd alignment.
  2. When programming for a surface which does not have square buttons, the only way to preview the correct aspect ratio is the button style editor. It is impossible to get an overview of a whole page.

For now this is gated behind a flag in the advanced settings page, so that this can be merged before being complete (to avoid large merge conflicts)

To achieve this, there is a new button+dropdown in the button grid, which allows for choosing a surface to see the grid as. This has 2 modes, you can pick a surface that your companion currently or has previously had connected (once it has been connected recently enough for us to grab and persist the layout info), or any model reported as compatible by an enabled surface module.

image image

The grid below then gets reconfigured to match the selected surface. For modules which aren't providing a new 'surfaceAppearance' definition, we make our best attempt based upon the technical layout of the controls it requests. These are usually messy, but at least filter down the controls and provide the correct resolutions to the controls: (Some CSS polish still needed)

image image image

Surfaces can now also provide a full appearance description to drive this drawing properly. For example:

image image image

Note that these are not 100% faithful to the original, but they should be accurate enough for any view and alignment a user may want to do. Primarily as they are svgs measured from either photos or manufacturer pngs. Intentionally using svgs here to avoid the bloat of high res pngs which will need to come in over satellite.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Added “View as surface” to preview the button grid using a connected device’s layout or a declared surface model, including control shapes, colors, and LED indicators.
    • Added fit-to-panel zoom, remembered view and zoom settings, surface selection and positioning controls, and guidance when surface controls extend beyond the configured grid.
    • Surface views now display appearance and model information, and declared models are available for preview.
  • Documentation
    • Updated the Buttons guide with instructions for viewing the grid as a surface.

@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

This change adds plugin-declared surface models and appearance metadata, resolves surface layouts into control geometry, and integrates surface selection and rendering into the Buttons view. It also adds color and LED feedback, per-surface zoom, and related tests and documentation.

Changes: Surface-aware Button Grid

Layer / File(s) Summary
Surface model metadata and updates
shared-lib/lib/Model/Surfaces.ts, companion/lib/Instance/Surface/*, companion/lib/Surface/*, companion/test/Surface/*, shared-lib/lib/ModuleApiVersionCheck.ts, package.json
Plugin-declared models pass through IPC, validation, controller aggregation, and model update subscriptions. Surface appearance and model identifiers are included in surface metadata and configuration.
Surface view geometry
shared-lib/lib/SurfaceLayout.ts, shared-lib/lib/SurfaceLayoutEstimate.ts, shared-lib/lib/__tests__/SurfaceLayout*.test.ts
The resolver produces face-relative control bounds, shapes, feedback, and grid placement. Face geometry is estimated when appearance data cannot provide it.
Surface and model selection
webui/src/Buttons/GridViewAs*, webui/src/Buttons/useGridViewAs.ts, webui/src/Components/Dropdown*, webui/src/Components/__tests__/DropdownInputField.test.tsx, webui/src/Buttons/__tests__/GridViewAs.test.ts, docs/user-guide/3_config/buttons/index.md
The UI stores and resolves a selected surface or model, supports model offsets, and shows status banners. Dropdown choices carry disabled state. The guide describes the surface view.
Surface canvas and grid interaction
webui/src/Buttons/SurfaceView/SurfaceCanvas*, webui/src/Buttons/SurfaceView/surfaceGeometry.ts, webui/src/Buttons/index.tsx, webui/src/Buttons/ButtonGridPanel*, webui/src/Buttons/GridViewGrowPanel.tsx, webui/src/Buttons/__tests__/ButtonGridPanel.test.tsx, webui/src/Buttons/__tests__/ButtonsPage.test.tsx
The Buttons page can render a surface canvas, navigate between its controls, and show a grid-growth action for controls outside the configured grid. The canvas supports hit testing and marquee selection.
Button feedback and surface zoom
shared-lib/lib/Model/Common.ts, companion/lib/Preview/Graphics.ts, webui/src/Buttons/GridButtonCell.tsx, webui/src/Buttons/GridButtonPreview.tsx, webui/src/Buttons/SurfaceView/SurfaceLeds*, webui/src/Hooks/useButtonImageForLocation.ts, webui/src/Buttons/GridZoom.tsx, webui/src/Buttons/ButtonGridZoomControl*, webui/src/Buttons/__tests__/*, webui/src/Hooks/__tests__/useButtonImageForLocation.test.tsx, companion/test/Preview/Graphics.test.ts, webui/src/ImportExport/Import/Page.tsx
Preview data includes color and LED gauge fields. Button cells render color feedback and LED overlays. Surface views support fit-to-panel zoom and stored per-surface zoom levels.

Priority: ➖ Normal

Merge Risk: 🟡 Moderate · up to dbfc7

Resolve the nightly surface dependency and compatibility versions before merging. The guide also needs a small clarification so users know a selected surface may require growing the grid.

Security architecture risk: 🔵 Low · up to a775b

Plugin-provided display metadata now reaches saved configurations and browser rendering. Validation, host-owned lifecycle management, and existing grid-location controls limit the observed exposure. No introduced vulnerability was established, but image-source restrictions and operational rollback remain incompletely verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The traced exposure begins with an initialized surface plugin and extends to host model aggregation, saved surface display metadata, and browsers displaying the selected surface. The source inspected does not establish anonymous remote access, new tenant privileges, or infrastructure authority.

Trust Boundaries and Controls

  • observed — Plugin model data crosses an IPC boundary through host validation and host-supplied instance and module identity. Module qualification and host-owned registration prevent the plugin from directly choosing an unqualified aggregate identity.
  • observed — Surface interactions map resolved controls to existing grid-location actions. Off-grid controls take the separate grow-grid path rather than rendering the normal actionable grid cell.
  • observed — The geometry resolver copies appearance.bodyImage into the resolved body image, which the renderer assigns to CSS backgroundImage. Appearance validation is delegated to the external surface base package; its image-source restrictions were not available for verification. This establishes a display sink, not a verified network-fetch or script-execution vulnerability.

Resilience and Maintainability Implications

  • observed — Instance cleanup removes transient model declarations, while disconnected physical surfaces intentionally retain saved layout metadata. The UI distinguishes missing producers and unavailable layouts, limiting silent rebinding after removal or reconnect.

Hardening Proposals

  • proposed — Confirm and document the enforced image-source policy at the shared appearance-validation boundary. If network URLs are accepted, consider restricting surface artwork to embedded or explicitly approved sources so selecting a model cannot unexpectedly initiate requests from a viewing browser. This is a proposal addressing an evidence gap, not an observed defect.
Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Linked Issues check Warning Issue #2189 requires the Buttons view to reflect an attached Stream Deck +, enable rotary encoder options by default, and allow manual selection when no device is attached. The PR implements manual su… Please add or document automatic selection for an attached Stream Deck + and enable its rotary encoder options by default, with automated tests. For #3205, add the requested preset customization and factory-default reset, or confirm that th…
Passed Passed checks: 3 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main change: adding the ability to view the button grid as a surface.
Out of Scope Changes check Passed The surface model IPC, layout resolution, appearance rendering, grid controls, zoom behavior, dropdown disabled-state support, documentation, and related tests support the view-as-surface feature and …
Full details: Linked Issues check

Explanation

Issue #2189 requires the Buttons view to reflect an attached Stream Deck +, enable rotary encoder options by default, and allow manual selection when no device is attached. The PR implements manual surface selection through GridViewAsControl and useGridViewAs. The stored state defaults to disabled with no selection, so automatic attached-device selection is not established. The change summary shows no rotary encoder default change or test. Issue #3205 requires quick layout switching with non-destructive hiding. The PR provides a surface selector, preserves off-view controls, and supports grid growth. It does not provide the requested configurable name/row/column presets or a factory-default reset.

Resolution

Please add or document automatic selection for an attached Stream Deck + and enable its rotary encoder options by default, with automated tests. For #3205, add the requested preset customization and factory-default reset, or confirm that those requirements are intentionally superseded by the surface-model selector.

  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A surface finds its place in view
Each control takes its shape anew
Colors glow and LEDs gleam
Zoom fits the panel to the scene
Models arrive through updates shared
A grid grows where controls are paired
Buttons take a surface’s view

Comment @coderabbitai help to get the list of available commands.

@github-project-automation github-project-automation Bot moved this to In Progress in Companion Plan Sep 17, 2026
@Julusian Julusian added this to the v5.1 milestone Sep 17, 2026
@socket-security

socket-security Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​companion-surface/​host@​1.4.2 ⏵ 1.5.0-nightly-main-20261014-213723-0afe92981 +310076 +197 +1100
Updated@​companion-surface/​base@​1.4.1 ⏵ 1.5.0-nightly-main-20261014-213444-0afe92982 +310087 +297 +2100

View full report

@Julusian Julusian mentioned this pull request Sep 17, 2026
@peternewman

Copy link
Copy Markdown
Contributor

For modules which aren't providing a new 'surfaceAppearance' definition,
image
Surfaces can now also provide a full appearance description to drive this drawing properly. For example:

So is it just that required to do the "col span" type behaviour on the Neo to get the "long" button at the bottom to align with the four normal buttons above it, or is there some additional work/future enhancement required first?

I assume the pain of stuff like the Shuttle with a row of four buttons, then a row of five below will always be a pain/you won't necessarily support different column spacing (I guess like the SD + XL), although in theory with some clever col spans, it ought to be possible to represent.

@Julusian

Copy link
Copy Markdown
Member Author

The current screenshots show the basic 'auto' mode of displaying a surface. Our best guess at how to arrange things with the limited information provided.

The part I am still working on is detailed drawing, relying on the surface module providing more details. This is currently achieving the below but it needs some more work (Largely background images, and figuring out some edge cases):
image
image

@peternewman

Copy link
Copy Markdown
Contributor

The part I am still working on is detailed drawing, relying on the surface module providing more details. This is currently achieving the below but it needs some more work

That already looks pretty awesome for those ones.

(Largely background images, and figuring out some edge cases):

Are those edge cases likely to go as far as the complexities of Shuttle which is effectively a doughnut and then the whole as separate controls in terms of the jog shuttle?

@Julusian
Julusian force-pushed the feat/grid-view-as-v2 branch 4 times, most recently from d8a91b5 to abf4777 Compare October 3, 2026 17:54
@Julusian
Julusian force-pushed the feat/grid-view-as-v2 branch 2 times, most recently from e2e8c4a to fba3ccd Compare October 3, 2026 21:06
@Julusian
Julusian marked this pull request as ready for review October 3, 2026 21:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: dd7612af-9b83-4b27-afc6-14d7cb665afb
📥 Commits

Reviewing files that changed from the base of the PR and between 5eaea25 and fba3ccd.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (66)
  • companion/lib/Instance/Surface/ChildHandler.ts
  • companion/lib/Instance/Surface/IpcTypes.ts
  • companion/lib/Instance/Surface/Thread/Entrypoint.ts
  • companion/lib/Preview/Graphics.ts
  • companion/lib/Surface/Config.ts
  • companion/lib/Surface/Controller.ts
  • companion/lib/Surface/Handler.ts
  • companion/lib/Surface/IP/ElgatoEmulator.ts
  • companion/lib/Surface/IP/Satellite.ts
  • companion/lib/Surface/LayoutSummary.ts
  • companion/lib/Surface/PluginPanel.ts
  • companion/lib/Surface/PluginSurfaceModels.ts
  • companion/lib/Surface/Types.ts
  • companion/test/Preview/Graphics.test.ts
  • companion/test/Surface/ControllerLayouts.test.ts
  • companion/test/Surface/ControllerModels.test.ts
  • companion/test/Surface/LayoutSummary.test.ts
  • companion/test/Surface/PluginSurfaceModels.test.ts
  • docs/user-guide/3_config/buttons/index.md
  • package.json
  • shared-lib/lib/Model/Common.ts
  • shared-lib/lib/Model/Surfaces.ts
  • shared-lib/lib/ModuleApiVersionCheck.ts
  • shared-lib/lib/SurfaceLayout.ts
  • shared-lib/lib/SurfaceLayoutEstimate.ts
  • shared-lib/lib/__tests__/SurfaceLayout.test.ts
  • shared-lib/lib/__tests__/SurfaceLayoutEstimate.test.ts
  • webui/src/Buttons/ButtonGridPanel.css
  • webui/src/Buttons/ButtonGridPanel.tsx
  • webui/src/Buttons/ButtonGridZoomControl.stories.tsx
  • webui/src/Buttons/ButtonGridZoomControl.tsx
  • webui/src/Buttons/ButtonInfiniteGrid.tsx
  • webui/src/Buttons/GridButtonCell.tsx
  • webui/src/Buttons/GridButtonPreview.tsx
  • webui/src/Buttons/GridViewAs.css
  • webui/src/Buttons/GridViewAs.ts
  • webui/src/Buttons/GridViewAsBanner.stories.tsx
  • webui/src/Buttons/GridViewAsBanner.tsx
  • webui/src/Buttons/GridViewAsControl.tsx
  • webui/src/Buttons/GridViewGrowPanel.tsx
  • webui/src/Buttons/GridZoom.tsx
  • webui/src/Buttons/SurfaceView/SurfaceCanvas.css
  • webui/src/Buttons/SurfaceView/SurfaceCanvas.tsx
  • webui/src/Buttons/SurfaceView/SurfaceLeds.css
  • webui/src/Buttons/SurfaceView/SurfaceLeds.tsx
  • webui/src/Buttons/SurfaceView/__tests__/ledLayout.test.ts
  • webui/src/Buttons/SurfaceView/__tests__/surfaceGeometry.test.ts
  • webui/src/Buttons/SurfaceView/ledLayout.ts
  • webui/src/Buttons/SurfaceView/surfaceGeometry.ts
  • webui/src/Buttons/__tests__/ButtonGridPanel.test.tsx
  • webui/src/Buttons/__tests__/ButtonsPage.test.tsx
  • webui/src/Buttons/__tests__/GridButtonDragOverlay.test.tsx
  • webui/src/Buttons/__tests__/GridButtonIcons.test.tsx
  • webui/src/Buttons/__tests__/GridButtonPreview.test.tsx
  • webui/src/Buttons/__tests__/GridViewAs.test.ts
  • webui/src/Buttons/__tests__/GridZoom.test.tsx
  • webui/src/Buttons/index.tsx
  • webui/src/Buttons/useGridViewAs.ts
  • webui/src/Components/DropdownChoices.tsx
  • webui/src/Components/DropdownInputField/Popup.tsx
  • webui/src/Components/DropdownInputField/useFuzzyChoices.ts
  • webui/src/Components/DropdownInputFieldSimple.tsx
  • webui/src/Components/__tests__/DropdownInputField.test.tsx
  • webui/src/Hooks/__tests__/useButtonImageForLocation.test.tsx
  • webui/src/Hooks/useButtonImageForLocation.ts
  • webui/src/ImportExport/Import/Page.tsx

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread companion/lib/Surface/PluginSurfaceModels.ts
Comment thread docs/user-guide/3_config/buttons/index.md Outdated
Comment thread package.json Outdated
@Julusian

Julusian commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

I am happy with this now, and think it is ready to merge and update other modules to properly support.

@peternewman check out the last 3 screenshots in the description. Thats what I've been aiming for, and will hopefully translate to other surface modules just fine.
The earlier screenshots still apply for when these detailed layouts havent been supplied

@Julusian
Julusian force-pushed the feat/grid-view-as-v2 branch from fba3ccd to a775b9b Compare October 3, 2026 22:01
@krocheck

krocheck commented Oct 3, 2026

Copy link
Copy Markdown
Member

This looks great; nice work!

@Julusian
Julusian added this pull request to stack #4497 October 3, 2026 22:28
@Julusian Julusian modified the milestones: v5.1, v5.2 Oct 6, 2026
@Julusian
Julusian force-pushed the feat/grid-view-as-v2 branch from a775b9b to 79ee3b9 Compare October 8, 2026 21:07
@Julusian
Julusian removed this pull request from stack #4497 October 8, 2026 21:12
@Julusian
Julusian added this pull request to stack #4505 October 8, 2026 21:12
@Julusian
Julusian force-pushed the feat/grid-view-as-v2 branch from 79ee3b9 to 13352bf Compare October 9, 2026 17:50
Julusian and others added 14 commits October 14, 2026 22:40
A choice can say it is disabled, and both the simple and the searchable
dropdown then show it without letting it be chosen.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The surface api for declaring the models a plugin supports, describing the
appearance of a surface, and saying which declared model a surface is, is not
yet in a release.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The grid is larger than any one surface, and a surface is not always a plain
rectangle of square buttons. Viewing the grid as a surface - one which has
been connected, or a model of one a surface module declares - draws the grid
as the face of that surface: each control where it sits and at the shape it
is drawn, with the cell coordinates still the grid's own. Controls beyond the
configured grid are drawn but cannot be configured, and offer to grow the
grid to fit.

The choice is made per browser, as a way of looking at the grid rather than
part of the config.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A surface can describe its face: where each control sits and its shape, the
colour of its body, and artwork for it. That is kept with the surface's config
alongside its layout, so it is known while the surface is unplugged, and the
view draws it exactly rather than estimating positions from the layout's rows
and columns. Artwork is drawn without the body colour under it, so the shape
of the device shows, and a control is only rounded when given a radius.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…in ones

A fixed few pixels taken off every side of a control was nothing on a key but
squashed a thin one, like the Neo's info bar, out of the shape its image is
drawn at. Controls are now drawn exactly where the surface has them, as the
face already leaves gaps between them.

A control thinner than a fingertip is given a hit area grown around it, cut
back to the middle of the gap wherever it would meet another's, so even a
dense face never has two overlap. One too small to hold its location leaves it
out.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A style with colours and no bitmap, like the Neo's touch buttons, is lit
rather than drawn on. Such a control is drawn as a swatch of the button's
background, which the preview stream now carries, rather than its image
squeezed into a sliver it was never going to be shown in.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A control's style can declare leds, as a ring around an encoder or a strip.
The preview stream now carries the gauge a button drives them with, and the
view draws them around or along the control, each segment lit with the same
sampling the surface is driven with.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The dark ground the grid uses fights with a face of any colour but its own, so
a face the surface describes is drawn on the page instead, with a hairline and
soft shadow tracing its outline, and scrollbars to match. Press mode keeps the
armed ground, as marking out what is live matters more there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The panel's min-height was only ever set by the grid, so a surface face kept
whatever the grid had last asked for, and zooming out left the panel far
taller than the face. The face now asks for its own: the whole face when it is
short, or two rows of keys when it is tall, so it scrolls within the panel
rather than stretching the page.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…by default

A Neo and a Studio want very different zoom levels, so one shared between them
is always wrong for one. Viewing as a surface has a zoom of its own, remembered
for its model so a plugged in surface shares it with its model. One not zoomed
by hand fits to the panel's width, following it as it changes, within 60-100%
so a very wide surface stays readable and a small one is not blown up. The zoom
control offers going back to fitting.

Steps work from the previous setting, so a burst of them - a fast ctrl+wheel -
all count, and the controller only changes with the kind of surface, so the
wheel listener holding it is not redone at every step.

The grid's own zoom now starts at 100% when storage cannot be read, rather
than failing the buttons page where storage is blocked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A surface can say which of its module's declared models it is. That is kept
with its config, like its appearance, so it is still known while the surface
is unplugged, and the layout summary qualifies it with the module, as the
declared models are.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Matching by the model id a surface reports, before falling back to its name,
which a module is free to word differently from the model's.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A display bigger than the others in its row or column, like an info bar under
a row of keys, now spills into the empty cells beside it rather than widening
its own track, so the keys around it stay evenly spaced. A cell two would both
spill into is left to neither.

A control with no display fills the cell the displays around it leave, rather
than being drawn a fixed square, while one with a ring of leds stays round.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Julusian
Julusian force-pushed the feat/grid-view-as-v2 branch from 13352bf to dbfc79b Compare October 14, 2026 22:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: dea920ca-11db-4422-99bd-cd2ee2ff0ed8
📥 Commits

Reviewing files that changed from the base of the PR and between 13352bf and dbfc79b.

⛔ Files ignored due to path filters: 1
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing: 19
  • companion/lib/Instance/Surface/ChildHandler.ts
  • companion/lib/Surface/IP/Satellite.ts
  • docs/user-guide/3_config/buttons/index.md
  • package.json
  • shared-lib/lib/ModuleApiVersionCheck.ts
  • shared-lib/lib/SurfaceLayout.ts
  • shared-lib/lib/__tests__/SurfaceLayout.test.ts
  • webui/src/Buttons/ButtonGridPanel.css
  • webui/src/Buttons/ButtonGridPanel.tsx
  • webui/src/Buttons/ButtonInfiniteGrid.tsx
  • webui/src/Buttons/GridViewAsBanner.tsx
  • webui/src/Buttons/GridViewAsControl.tsx
  • webui/src/Buttons/SurfaceView/SurfaceCanvas.tsx
  • webui/src/Buttons/__tests__/ButtonGridPanel.test.tsx
  • webui/src/Buttons/__tests__/ButtonsPage.test.tsx
  • webui/src/Buttons/index.tsx
  • webui/src/Components/DropdownInputFieldSimple.tsx
  • webui/src/Components/__tests__/DropdownInputField.test.tsx
  • webui/src/ImportExport/Import/Page.tsx
🚧 Files skipped from review as they are similar to previous changes: 1
  • webui/src/Buttons/ButtonGridPanel.css

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.


## Viewing the grid as a surface

The grid is larger than any one surface, and a surface is not always a plain rectangle of square

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clarify that a surface can extend beyond the grid.

Line 111 says the grid is larger than every surface, but Lines 122-124 say a surface can reach beyond the grid. Please describe the grid and surface as having different sizes so users do not expect every surface to fit without growing the grid.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

request: ButtonGrid view quick change on GUI button click Button view for Stream Deck +

3 participants