From 020f30541aeb3224ecfa8a85212639f0d6a8610c Mon Sep 17 00:00:00 2001 From: LukeGus Date: Fri, 6 Nov 2026 13:36:36 -0600 Subject: [PATCH] feat: shared toolbar, footer and host dot pieces for plugin UI --- CHANGELOG.md | 5 + packages/plugin-sdk/CHANGELOG.md | 23 +++++ packages/plugin-sdk/PLUGIN-GUIDE.md | 26 ++++- packages/plugin-sdk/cli/commands/validate.mjs | 89 +++++++++++++++++ packages/plugin-sdk/package.json | 2 +- packages/plugin-sdk/src/frontend.ts | 27 ++++- packages/plugin-sdk/ui.api.txt | 8 +- scripts/check-sdk-ui-exports.cjs | 4 + src/ui/components/form-fields.tsx | 6 +- src/ui/components/list-kit.tsx | 6 +- src/ui/components/loading-state.tsx | 2 + src/ui/components/manager-card.tsx | 2 +- src/ui/components/panel-layout.tsx | 98 +++++++++++++++++-- src/ui/components/tile-grid/TileGrid.tsx | 2 +- src/ui/components/tile-grid/TileStack.tsx | 2 +- src/ui/components/tile-grid/edge.tsx | 24 ++++- src/ui/look/RepairView.tsx | 2 +- src/ui/plugin-host/PluginViewPlaceholder.tsx | 12 +-- src/ui/plugin-host/app.ts | 8 +- src/ui/plugin-host/sdk-ui.ts | 4 + src/ui/shell/stage/TabStage.tsx | 1 + src/ui/sidebar/HostDotGroup.tsx | 90 +++++++++++++++++ src/ui/sidebar/host-contributions.ts | 35 ++++++- src/ui/tests/components/panel-layout.test.tsx | 61 ++++++++++++ src/ui/tests/sidebar/HostDotGroup.test.tsx | 39 ++++++++ 25 files changed, 539 insertions(+), 39 deletions(-) create mode 100644 src/ui/sidebar/HostDotGroup.tsx create mode 100644 src/ui/tests/sidebar/HostDotGroup.test.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ce04a48e..cc8d3dbf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Plugins can build pages of tiles you drag and resize, and add many copies of one dashboard card, each with its own settings - A plugin a newer release ships is downloaded on its own when your image does not have it, and tried again on the next start when offline - Plugins can decide who may connect to a host, so a host can need approved access before an SSH or remote desktop session opens +- When more than one plugin flags a host, its row shows one status dot with every reason in its tooltip ### Changed @@ -25,6 +26,7 @@ - The Linux Flatpak now installs from flatpak.termix.site on x86_64 and arm64, and `flatpak update` keeps it current - Dropdowns and text areas are the same size as the text fields next to them - A page's own tabs sit above its search bar +- A plugin view that is still starting shows the same loading spinner as the rest of Termix ### Fixed @@ -43,6 +45,9 @@ - The hint at the bottom of Browse and the stored data footer on plugin pages have the same padding as the rest of the page - Sign in methods on the Security page have a line between them - Chart axis labels with long units, like KiB/s, are no longer cut off +- Filters, view toggles and small buttons in a toolbar are the same height as the search box next to them +- Save and Cancel at the bottom of a form are the same height as other buttons +- State badges in tables no longer stretch across the whole column ## 26.11.0 diff --git a/packages/plugin-sdk/CHANGELOG.md b/packages/plugin-sdk/CHANGELOG.md index 391d3b1c6..af9a7c6b1 100644 --- a/packages/plugin-sdk/CHANGELOG.md +++ b/packages/plugin-sdk/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## 1.1.2 + +Plugin API 1.15.0. + +### Added + +- `/ui` exports `ToolbarBand` (a toolbar row outside the PanelShell toolbar), `ToolbarSelect` (a small select for those rows) and `TOOLBAR_FIT` (the classes that make every control in a row 32px) +- `PANEL.section`, the one inner layout for a SectionCard body +- `TextAreaField` takes `fill`, so a config or log editor uses the rest of the height +- `registerHostBadge` takes `useDot`. Every plugin's dots merge into one dot on the host row, with the worst tone and each reason in its tooltip. `/ui` exports `HostDotGroup` for layouts that draw host rows + +### Changed + +- Controls in the PanelShell toolbar, tab band and footer are all 32px, so small buttons line up with search boxes and selects +- `Segmented` and `ViewToggle` match the height of inputs and buttons, and `Segmented` keeps its natural width +- `FormFooter` buttons are full height +- `PANEL.body` is `p-3`, the same padding `InlineView` gives a form +- A body with a pinned footer no longer draws a closing line just above the footer's own line +- The placeholder for a plugin view that is still starting uses `LoadingState` +- `termix-plugin validate` warns about UI drift: raw loading spinners, small back buttons, native selects, stretched filters, filled headers, capped log views and footers that scroll away +- A `ToolbarBand` right inside a `TileStack` leaves the line under it to the stack +- `ListBadge` and `StatusBadge` keep their own width in a table cell instead of filling it + ## 1.1.1 Plugin API 1.15.0. diff --git a/packages/plugin-sdk/PLUGIN-GUIDE.md b/packages/plugin-sdk/PLUGIN-GUIDE.md index 707a9979d..ca1c2186c 100644 --- a/packages/plugin-sdk/PLUGIN-GUIDE.md +++ b/packages/plugin-sdk/PLUGIN-GUIDE.md @@ -1,6 +1,6 @@ # Termix plugin guide -SDK 1.1.1 | Plugin API 1.15.0 +SDK 1.1.2 | Plugin API 1.15.0 This guide is for anyone, person or AI coding tool, building a Termix plugin. It ships inside `@termix-ssh/plugin-sdk`, so the copy in your `node_modules` always matches the SDK you have installed. @@ -782,9 +782,27 @@ exports with props is `ui.api.txt` in the Termix repo `StatTile` or `MetricCard`, and use `TileFrame` for a titled section. Cards drop their own box inside these. Forms keep `PANEL.body` padding inside their section. An `InlineView` form made of `SectionCard`s takes `stacked`. -- Page views go in `PanelShell`'s `tabs` band as a `TabStrip`. `Segmented` is for filters and view modes. - A page with many sections uses `SideNav` on the left. Put the refresh button in the header with - `RefreshButton`, and the docs link with the `docs` prop. +- Page views go in `PanelShell`'s `tabs` band as a `TabStrip`. `Segmented` is for filters and view modes and + keeps its natural width, never stretched across the pane. A page with many sections uses `SideNav` on the + left. Put the refresh button in the header with `RefreshButton`, and the docs link with the `docs` prop. +- Toolbars: search, filters and buttons go in `PanelShell`'s `toolbar` slot, or in a `ToolbarBand` for a second + row. Both make every control in the row 32px, so a `size="sm"` button lines up with a search box. Use + `ToolbarSelect` for a small select there, never a native `