UI Integration
The full useNiyase() bridge surface, how audience relates to role, @niyase/plugin-sdk/ui, and rendering across three apps.
You write a plugin's UI in React and access data, notifications, and navigation through the useNiyase() bridge.
One plugin = one menu entry in the sidebar (cloud/desktop) or shelf (mobile) — what it shows changes by role.
The full useNiyase() surface
| Namespace | Use |
|---|---|
niyase.data | CRUD on your own plugin's plg_* tables (Data Model) |
niyase.core | Read core data (employees, departments, spaces — Core API) |
niyase.connections | PROVIDER-CLIENT plugins only. List/invite/request/accept/suspend/terminate connections, plus data(connectionId) for connection-scoped CRUD on shared tables |
niyase.context | { spaceId, workspaceType, role, audience, locale, theme, plugin } (reactive — subscribers are notified when values change) |
niyase.i18n | t(key, vars?) / locale. Resolves your plugin's own ja/en messages using context.locale |
niyase.navigate | Tab / route navigation within your own plugin |
niyase.toast | success / error / info notifications |
niyase.palette | Register / trigger intents in the unified palette (tied to paletteMetadata) |
const niyase = useNiyase();
// Subscribe to reactive context (follows theme / language switches)
useEffect(() => niyase.context.subscribe((ctx) => setTheme(ctx.theme)), []);
// Resolve a message from the plugin's own ja/en bundle
const title = niyase.i18n.t("task.title", { count: 3 });
niyase.toast.success("保存しました");
niyase.navigate.toTab("settings");
niyase.connectionsis cloud-space only. Calling it from a purely local space (desktop PGlite / mobile SQLite with no cloud account) returns theCLOUD_REQUIREDerror code. Design PROVIDER-CLIENT plugins together withrequiresCloud: truein the manifest (see Manifest).
audience (the display role) and resolveAudience()
Declare per-role display in manifest.audiences[]. A role that isn't in the array gets no side-menu entry and no tabs at all.
| audience | Intended user | Display |
|---|---|---|
executive | Executives, managers | All management + execution tabs |
employee | Employees | Execution tabs only |
customer | Business partners (the CLIENT side of a PROVIDER-CLIENT pair) | Customer-facing tabs only |
The value that lands in niyase.context.audience isn't the manifest's defaultRole itself. It's derived by resolveAudience(role, isAdmin) from the plugin_activation.role (PROVIDER / CLIENT / LOCAL) chosen at activation time and whether the current user is an admin:
role === "CLIENT" → audience = "customer"
isAdmin === true → audience = "executive"
otherwise → audience = "employee"
In other words, defaultRole only decides which role a fresh activation starts in — the audience actually shown is resolved per user, every time. Executives see the full "management + execution" tab set by default; if someone wants to see execution tabs only, that's handled by the host's own TabSettings (display settings), not something your plugin needs to build.
UI components
Import niyase's UI components from @niyase/plugin-sdk/ui (the host supplies the real ones).
import {
Button,
Input,
Tabs,
TabsList,
TabsTrigger,
TabsContent,
} from "@niyase/plugin-sdk/ui";
You can also write with plain HTML + Tailwind-like classes. To follow niyase.context.theme (light/dark),
it is safer to handle colors with semantic tokens.
The same bundle on three apps
The single bundle you build runs on cloud (Web), desktop (Electron), and mobile (Expo). On all three, your plugin runs in an execution context isolated from the host's own rendering (cloud = a sandboxed iframe, desktop = a <webview>, mobile = a React Native WebView), and every useNiyase() call travels to the host over postMessage. That isolation is a security boundary; the SDK absorbs the transport differences, so your plugin code stays identical across all three.
Your plugin's nav entry (audiences[].nav) shows up, based on the category you declared, inside the section-nav column on cloud/desktop or inside the mobile shelf (the left-hand, two-tier overlay drawer). There's no dedicated app bar or hamburger menu — all three apps have retired those. The page body itself renders inside the host's standard tab layout.
Check the look locally
niyase-plugin dev
It renders for real inside the generic shell, and you can check it while switching role, space type, theme, and language in the DevBar (see Setup).