Extension Component Library
Reference the sandboxed extension UI components, layout patterns, and style rules for GlobalStacks extensions.
Extension component library
Extension UI is declarative. Extension code sends a serializable component tree, and the console displays it through a sandboxed iframe running the GlobalStacks extension renderer. Use these components instead of custom HTML so extension UI stays consistent, accessible, and safe inside host viewports.
Each component is a versioned contract. The library records the component name, stability, introduced version, properties, supported examples, and compatibility notes so extension authors can build against a stable UI surface.
Render model
GlobalStacks extensions use the same basic shape as sandboxed app views: the console owns the viewport, embeds a sandboxed iframe for extension UI, and passes context to the extension runtime. The extension returns a serializable GlobalStacks component tree that the iframe renderer displays with approved components.
The extension does not mount arbitrary React into the parent console, inject parent-page HTML, or access the console DOM. It runs inside the extension iframe, receives host-provided context, renders supported component contracts, and sends user actions back through brokered async events.
Console viewport -> sandboxed iframe -> extension context -> extension runtime
Iframe renderer <- component tree <- extension view function
Iframe events -> parent bridge -> broker operation -> extension handlerThis keeps extension UI isolated from the parent console while still letting GlobalStacks own the component renderer, theme bridge, viewport sizing, provider permissions, and operation broker.
Principles
- Start every view with
ContextView,SettingsView,FocusView,SignInView, orFullPageView. - Prefer compact, scannable layouts over marketing-style panels.
- Use
DataGridfor operational tables andTablefor simple static rows. - Keep text short; extension panes are often embedded in dense console pages.
- Use status, badge, and progress cells instead of inventing custom color systems.
- Put side effects behind explicit actions and bridge events.
Component registry
Components are published as registry entries instead of untracked renderer internals. A registry entry includes:
| Field | Purpose |
|---|---|
name | Stable component identifier used in extension render trees. |
version | Component contract version, starting at 1.0.0. |
status | stable, beta, deprecated, or removed. |
introduced | Extension UI protocol version that first exposed the component. |
deprecated | Optional version where replacement guidance begins. |
props | Serializable property schema for validation and generated SDK types. |
examples | Named examples rendered in docs and used as compatibility fixtures. |
notes | Accessibility, viewport, behavior, and migration guidance. |
Component versions follow semantic versioning:
- Patch releases clarify docs, examples, or renderer bugs without changing the accepted contract.
- Minor releases add optional properties, examples, or supported enum values.
- Major releases remove properties, change default behavior, or make previously optional properties required.
- Deprecated components and properties remain documented with replacement guidance until the next major extension UI protocol.
Example registry entry:
{
"name": "Badge",
"version": "1.0.0",
"status": "stable",
"introduced": "[email protected]",
"props": {
"tone": {
"type": "enum",
"values": ["default", "muted", "info", "success", "warning", "danger"],
"default": "default"
},
"children": {
"type": "text",
"required": true
}
},
"examples": ["default", "status-tones", "metadata"]
}Reference format
Every component reference should include:
| Section | Required content |
|---|---|
| Overview | What the component is for and when not to use it. |
| Version | Current version, stability, and introduced protocol version. |
| Properties | Name, type, required state, default, and behavior. |
| Examples | At least one minimal example and one realistic usage example. |
| Events | Bridge events, operations, or callbacks the component can emit. |
| Accessibility | Labeling, keyboard, focus, and screen-reader expectations. |
| Compatibility | Deprecated props, migrations, and viewport constraints. |
Root views
RushFS
Storage status and connection details for this extension.
Connection settings
<ContextView title="RushFS">
<Stack gap="md">
<Text tone="muted">Storage status and connection details.</Text>
<Badge tone="success">ready</Badge>
</Stack>
</ContextView>ContextView
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
title | string | yes | - | Short view title rendered by the iframe renderer. |
description | string | no | - | Optional muted summary below the title. |
actions | Action[] | no | [] | Renderer-owned view actions. Prefer one primary action. |
children | Component[] | yes | - | Serializable child components. |
Examples: extension-summary, status-panel, resource-details.
SettingsView
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
title | string | yes | - | Settings page title. |
description | string | no | - | Optional summary for the settings surface. |
actions | Action[] | no | [] | Header-level actions. Keep these secondary to form submit actions. |
children | Component[] | yes | - | Forms, fields, alerts, and supporting text. |
<SettingsView title="Connection settings" description="Configure the RushFS endpoint.">
<Form operation="rushfs.storage.configure">
<Stack gap="sm">
<TextInput name="endpoint" label="Endpoint" defaultValue={endpoint} />
<Button type="submit">Save settings</Button>
</Stack>
</Form>
</SettingsView>Examples: connection-settings, install-follow-up.
FocusView
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
title | string | yes | - | Focused flow title. |
description | string | no | - | Optional context for the task. |
primaryAction | Action | no | - | Main task action. |
secondaryAction | Action | no | - | Secondary or cancel action. |
children | Component[] | yes | - | Focused task content. |
<FocusView title="Import storage backend" primaryAction={{ id: "start-import", label: "Start import" }}>
<Alert tone="warning">Existing bucket policy will be verified before import.</Alert>
</FocusView>Examples: guided-import, review-before-submit.
SignInView
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
title | string | yes | - | External account connection title. |
description | string | no | - | Short reason for connecting the account. |
provider | string | no | - | Provider name shown in the view. |
action | Action | yes | - | Brokered sign-in or OAuth start action. |
children | Component[] | no | [] | Optional details, legal links, or permission notes. |
<SignInView
title="Connect RushFS"
provider="RushFS"
action={{ id: "connect", label: "Connect account" }}
>
<Text tone="muted">GlobalStacks will request storage metadata access.</Text>
</SignInView>Examples: connect-provider, reauthorize-provider.
FullPageView
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
title | string | yes | - | Full-page extension title. |
description | string | no | - | Optional page summary. |
actions | Action[] | no | [] | Page-level commands. |
children | Component[] | yes | - | Dense tables, filters, or operational panels. |
<FullPageView title="RushFS volumes" actions={[{ id: "refresh", label: "Refresh" }]}>
<DataGrid columns={columns} rows={rows} pagination={pagination} />
</FullPageView>Examples: resource-index, operational-dashboard.
Layout and text
Use Stack for vertical rhythm and Text for host-owned typography. Available text variants are body, heading, caption, and mono; tones are default, muted, info, success, warning, and danger.
Volume import
Import state is synchronized through a brokered operation.
rushfs.storage.configure
<Stack gap="sm">
<Text variant="heading">Volume import</Text>
<Text tone="muted">Import state is synchronized through a brokered operation.</Text>
<Text variant="mono">rushfs.storage.configure</Text>
</Stack>Stack
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
gap | "xs" | "sm" | "md" | "lg" | no | "md" | Vertical spacing token. |
children | Component[] | yes | - | Stack items rendered in order. |
Examples: basic-stack, settings-group, status-summary.
Text
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
variant | "body" | "heading" | "caption" | "mono" | no | "body" | Host typography variant. |
tone | "default" | "muted" | "info" | "success" | "warning" | "danger" | no | "default" | Semantic text tone. |
children | string | yes | - | Plain text only. |
Examples: heading-with-caption, mono-operation, muted-help-text.
Status and feedback
Use Badge, Alert, and Progress for status. The renderer owns the color mapping so success, warning, danger, and muted states stay consistent with the console.
<Alert tone="info">Settings are applied through a brokered extension operation.</Alert>
<Badge tone="success">healthy</Badge>
<Progress value={68} />Badge
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
tone | "default" | "muted" | "info" | "success" | "warning" | "danger" | no | "default" | Semantic status tone. |
children | string | yes | - | Short label, usually one or two words. |
Examples: status-tones, metadata-badge, provider-state.
Alert
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
tone | "info" | "success" | "warning" | "danger" | no | "info" | Semantic alert tone. |
title | string | no | - | Optional short alert title. |
children | string | Component[] | yes | - | Alert body content. |
Examples: info-alert, recoverable-warning, permission-error.
Progress
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
value | number | yes | - | Progress value from 0 to 100. |
label | string | no | - | Accessible progress label. |
Examples: bounded-progress, sync-progress.
Forms and actions
Use Form, TextInput, Select, Checkbox, and Button. Form submits should dispatch an operation or bridge event; extensions should not mutate host state directly.
<Form operation="rushfs.storage.configure">
<Stack gap="sm">
<TextInput name="endpoint" label="Endpoint" value={endpoint} />
<Checkbox name="health" label="Enable health checks" checked />
<Button type="submit">Save settings</Button>
</Stack>
</Form>Form
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
operation | string | yes | - | Broker operation dispatched on submit. |
defaultValues | Record<string, unknown> | no | {} | Initial field values. |
children | Component[] | yes | - | Form controls and actions. |
Events: emits a broker operation submit event.
Examples: settings-submit, connection-test.
TextInput
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
name | string | yes | - | Form field name submitted to the operation. |
label | string | yes | - | Visible field label. |
defaultValue | string | no | "" | Initial uncontrolled value. |
value | string | no | - | Controlled value. Prefer defaultValue for typing-heavy fields. |
placeholder | string | no | - | Hint text, not a replacement for label. |
helpText | string | no | - | Supporting text below the input. |
error | string | no | - | Validation error text. |
disabled | boolean | no | false | Prevents editing and submission updates. |
required | boolean | no | false | Marks the field as required. |
<TextInput
name="endpoint"
label="Endpoint"
defaultValue="https://rushfs.example.com"
helpText="Use the provider API endpoint for this tenant."
required
/>Examples: endpoint-field, secret-name-field.
Select
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
name | string | yes | - | Form field name submitted to the operation. |
label | string | yes | - | Visible field label. |
options | SelectOption[] | yes | - | Serializable options with label and value. |
defaultValue | string | no | - | Initial selected value. |
value | string | no | - | Controlled selected value. |
placeholder | string | no | - | Empty selection label. |
helpText | string | no | - | Supporting text below the select. |
error | string | no | - | Validation error text. |
disabled | boolean | no | false | Prevents selection changes. |
<Select
name="region"
label="Region"
defaultValue="auto"
options={[
{ label: "Automatic", value: "auto" },
{ label: "Europe", value: "eu" },
]}
/>Examples: region-select, provider-account-select.
Checkbox
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
name | string | yes | - | Form field name submitted to the operation. |
label | string | yes | - | Visible checkbox label. |
checked | boolean | no | - | Controlled checked state. |
defaultChecked | boolean | no | false | Initial uncontrolled checked state. |
helpText | string | no | - | Supporting text below the checkbox. |
disabled | boolean | no | false | Prevents changes. |
<Checkbox
name="healthChecks"
label="Enable health checks"
defaultChecked
helpText="Run a brokered provider check after settings are saved."
/>Examples: health-check-toggle, confirm-destructive-action.
Button
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
type | "button" | "submit" | no | "button" | Submit buttons must live inside Form. |
variant | "primary" | "secondary" | "ghost" | "danger" | no | "primary" | Host action style. |
action | Action | no | - | Bridge action for non-submit buttons. |
children | string | yes | - | Short command label. |
Examples: primary-submit, secondary-test, danger-disconnect.
DataGrid
Use DataGrid for operational resources. It accepts serializable columns, rows, pagination, selection, sorting, row actions, loading, and empty states. The iframe renderer owns the internal table engine.
| Name | Provider | Status | Used | Actions |
|---|---|---|---|---|
| rushfs-primary | RushFS | ready | 68% | |
| rushfs-archive | RushFS | syncing | 41% |
<DataGrid
columns={[
{ id: "name", header: "Name", sortable: true, minWidth: 180 },
{ id: "provider", header: "Provider" },
{ id: "status", header: "Status", type: "status", pinned: "right" },
{ id: "used", header: "Used", type: "number", align: "right" },
]}
rows={[
{ id: "primary", name: "rushfs-primary", provider: "RushFS", status: "ready", used: 68 },
{ id: "archive", name: "rushfs-archive", provider: "RushFS", status: "syncing", used: 41 },
]}
pagination={{ page: 1, pageSize: 25, totalRows: 2 }}
selection={{ mode: "multiple", selectedRowIds: [] }}
rowActions={[{ id: "open", label: "Open", variant: "secondary" }]}
onAction={() => undefined}
onSortChange={() => undefined}
onPageChange={() => undefined}
onSelectionChange={() => undefined}
/>DataGrid
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
columns | DataGridColumn[] | yes | - | Serializable column definitions. |
rows | Record<string, unknown>[] | yes | - | Rows must include a stable id. |
pagination | Pagination | no | - | Renderer-owned pagination controls. |
selection | Selection | no | - | Single or multiple row selection. |
rowActions | Action[] | no | [] | Per-row renderer-owned commands. |
loading | boolean | no | false | Shows host loading state. |
emptyState | EmptyStateProps | no | - | Rendered when rows is empty. |
Events: emits sort, page, selection, and row-action bridge events.
Examples: resource-list, paginated-volumes, selectable-buckets, empty-results.
Table
Use Table when the rows are static and do not need selection, row actions, or pagination.
<Table
columns={[
{ id: "key", header: "Property" },
{ id: "value", header: "Value" },
]}
rows={[
{ key: "Runtime", value: "sandbox" },
{ key: "Distribution", value: "private" },
]}
/>Table
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
columns | TableColumn[] | yes | - | Static column definitions. |
rows | Record<string, unknown>[] | yes | - | Static display rows. |
Examples: key-value-table, static-provider-summary.
Empty and navigation states
Use EmptyState when a supported surface has no records yet. Use Link for host-approved navigation or external documentation.
EmptyState
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
title | string | yes | - | Short empty-state title. |
description | string | no | - | Explanation or next step. |
action | Action | no | - | Optional primary action. |
children | Component[] | no | [] | Optional secondary content. |
<EmptyState
title="No buckets found"
description="Create a bucket in RushFS or refresh provider metadata."
action={{ id: "refresh", label: "Refresh" }}
/>Examples: empty-resource-list, unsupported-provider-state.
Link
- Version:
1.0.0 - Status: stable
- Introduced:
[email protected]
| Property | Type | Required | Default | Notes |
|---|---|---|---|---|
href | string | yes | - | Host-approved URL or route. |
children | string | yes | - | Link text. |
external | boolean | no | false | Opens through the host external-navigation path. |
tone | "default" | "muted" | no | "default" | Visual emphasis. |
<Link href="https://rushfs.example.com/docs" external>
RushFS provider documentation
</Link>Examples: external-docs-link, internal-resource-link.
Current component surface
| Component | Version | Status | Use for |
|---|---|---|---|
ContextView | 1.0.0 | stable | Contextual extension panels and detail surfaces. |
SettingsView | 1.0.0 | stable | Extension configuration and install follow-up flows. |
FocusView | 1.0.0 | stable | Focused tasks that need a framed flow. |
SignInView | 1.0.0 | stable | External account connection or onboarding state. |
FullPageView | 1.0.0 | stable | Dense extension pages with more screen real estate. |
Stack | 1.0.0 | stable | Vertical spacing and layout. |
Text | 1.0.0 | stable | Body, heading, caption, and mono text. |
Badge | 1.0.0 | stable | Compact status and metadata labels. |
Alert | 1.0.0 | stable | Inline feedback or callouts. |
Form | 1.0.0 | stable | Operation-backed form submission. |
TextInput | 1.0.0 | stable | Text entry with label. |
Select | 1.0.0 | stable | Small option sets. |
Checkbox | 1.0.0 | stable | Boolean settings. |
Button | 1.0.0 | stable | Primary, secondary, ghost, and icon actions. |
Progress | 1.0.0 | stable | Bounded numeric progress. |
Table | 1.0.0 | stable | Simple static tabular data. |
DataGrid | 1.0.0 | stable | Sortable, selectable, paginated operational data. |
EmptyState | 1.0.0 | stable | Empty or unsupported states. |
Link | 1.0.0 | stable | Host-approved navigation or external references. |
Style rules
- Keep root views narrow unless the viewport is
globalstacks.console.full_page. - Prefer one primary action per view.
- Use action buttons for commands and links for navigation.
- Use
DataGridrow actions instead of embedding multiple buttons in plain text. - Avoid custom color names, gradients, and decorative elements.
- Keep column headers short and make status columns use
type: "status". - Use the style extension UI page for supported style tokens, layout props, spacing, sizing, and preset component style controls.