Version: su.onno:onno-ui-starter:1.4.5
Problem
The widget SDK (@onno/widget-sdk) exposes the host's React, hooks, api, and html on window.onno — but not the host's UI component library (components/ui/*: Select, Segmented, Button, Popover, Badge, Checkbox, Switch, …).
So a custom widget that needs a dropdown, a view switcher, or a button has to re-implement those as lookalikes. Two problems with that:
- Inconsistency / drift. A hand-rolled
<select> or a div-based menu won't match the real Radix-backed Select (facet drawer on mobile via vaul, keyboard nav, theming, animations). It diverges the moment the design system changes.
- The Tailwind-emission gotcha compounds it. Widget
.tsx is compiled outside the host Tailwind build, so utility classes the host doesn't itself emit (opacity variants, size-*, arbitrary values) silently produce no CSS. To style a lookalike I had to inject a fallback <style> for exactly those utilities. Reusing the real components would sidestep this entirely.
Repro / context
Building a full-screen resource-scheduler widget (rooms × time grid, drag-to-move, filters, day/week/month switcher) on 1.4.5. To make the filter dropdowns and the view switcher match the rest of the app I copied onno's own class strings out of segmented.tsx / button.tsx / select.tsx and rebuilt the components by hand — because the real ones aren't importable from a widget.
Request
Expose the host UI primitives to widgets, e.g. one of:
- add them to the
window.onno host object and re-export from the SDK:
import { ui } from "@onno/widget-sdk";
const { Select, SelectTrigger, SelectContent, SelectItem, Segmented, Button, Popover, Badge } = ui;
- or a dedicated entry
@onno/widget-sdk/ui that the Gradle plugin aliases to the host bundle (same mechanism React is aliased today).
Since the plugin already aliases react/react/jsx-runtime to the host singletons, aliasing @/components/ui/* (or a curated subset) to the host should be a small extension of the existing esbuild alias config. A curated, documented subset (Select, Segmented, Button, Popover, Badge, Checkbox, Switch, Input) would cover the vast majority of widget needs.
Why it matters
Custom widgets are the sanctioned way to build surfaces the framework has no built-in for (calendars, schedulers, kanban, dashboards). Right now every one of them reinvents the control layer and risks visual drift from the product. Exposing the primitives makes widgets first-class citizens of the design system.
Version: su.onno:onno-ui-starter:1.4.5
Problem
The widget SDK (
@onno/widget-sdk) exposes the host'sReact, hooks,api, andhtmlonwindow.onno— but not the host's UI component library (components/ui/*:Select,Segmented,Button,Popover,Badge,Checkbox,Switch, …).So a custom widget that needs a dropdown, a view switcher, or a button has to re-implement those as lookalikes. Two problems with that:
<select>or a div-based menu won't match the real Radix-backedSelect(facet drawer on mobile viavaul, keyboard nav, theming, animations). It diverges the moment the design system changes..tsxis compiled outside the host Tailwind build, so utility classes the host doesn't itself emit (opacity variants,size-*, arbitrary values) silently produce no CSS. To style a lookalike I had to inject a fallback<style>for exactly those utilities. Reusing the real components would sidestep this entirely.Repro / context
Building a full-screen resource-scheduler widget (rooms × time grid, drag-to-move, filters, day/week/month switcher) on 1.4.5. To make the filter dropdowns and the view switcher match the rest of the app I copied onno's own class strings out of
segmented.tsx/button.tsx/select.tsxand rebuilt the components by hand — because the real ones aren't importable from a widget.Request
Expose the host UI primitives to widgets, e.g. one of:
window.onnohost object and re-export from the SDK:@onno/widget-sdk/uithat the Gradle plugin aliases to the host bundle (same mechanism React is aliased today).Since the plugin already aliases
react/react/jsx-runtimeto the host singletons, aliasing@/components/ui/*(or a curated subset) to the host should be a small extension of the existing esbuild alias config. A curated, documented subset (Select, Segmented, Button, Popover, Badge, Checkbox, Switch, Input) would cover the vast majority of widget needs.Why it matters
Custom widgets are the sanctioned way to build surfaces the framework has no built-in for (calendars, schedulers, kanban, dashboards). Right now every one of them reinvents the control layer and risks visual drift from the product. Exposing the primitives makes widgets first-class citizens of the design system.