GlobalStacks logo GlobalStacks Extensions
Open app
Extensions

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.

Terminal
Console viewport -> sandboxed iframe -> extension context -> extension runtime
Iframe renderer <- component tree <- extension view function
Iframe events -> parent bridge -> broker operation -> extension handler

This 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, or FullPageView.
  • Prefer compact, scannable layouts over marketing-style panels.
  • Use DataGrid for operational tables and Table for 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:

FieldPurpose
nameStable component identifier used in extension render trees.
versionComponent contract version, starting at 1.0.0.
statusstable, beta, deprecated, or removed.
introducedExtension UI protocol version that first exposed the component.
deprecatedOptional version where replacement guidance begins.
propsSerializable property schema for validation and generated SDK types.
examplesNamed examples rendered in docs and used as compatibility fixtures.
notesAccessibility, 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:

Terminal
{
  "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:

SectionRequired content
OverviewWhat the component is for and when not to use it.
VersionCurrent version, stability, and introduced protocol version.
PropertiesName, type, required state, default, and behavior.
ExamplesAt least one minimal example and one realistic usage example.
EventsBridge events, operations, or callbacks the component can emit.
AccessibilityLabeling, keyboard, focus, and screen-reader expectations.
CompatibilityDeprecated props, migrations, and viewport constraints.

Root views

ContextView

RushFS

Storage status and connection details for this extension.

ready private
SettingsView

Connection settings

Terminal
<ContextView title="RushFS">
  <Stack gap="md">
    <Text tone="muted">Storage status and connection details.</Text>
    <Badge tone="success">ready</Badge>
  </Stack>
</ContextView>

ContextView

PropertyTypeRequiredDefaultNotes
titlestringyes-Short view title rendered by the iframe renderer.
descriptionstringno-Optional muted summary below the title.
actionsAction[]no[]Renderer-owned view actions. Prefer one primary action.
childrenComponent[]yes-Serializable child components.

Examples: extension-summary, status-panel, resource-details.

SettingsView

PropertyTypeRequiredDefaultNotes
titlestringyes-Settings page title.
descriptionstringno-Optional summary for the settings surface.
actionsAction[]no[]Header-level actions. Keep these secondary to form submit actions.
childrenComponent[]yes-Forms, fields, alerts, and supporting text.
Terminal
<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

PropertyTypeRequiredDefaultNotes
titlestringyes-Focused flow title.
descriptionstringno-Optional context for the task.
primaryActionActionno-Main task action.
secondaryActionActionno-Secondary or cancel action.
childrenComponent[]yes-Focused task content.
Terminal
<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

PropertyTypeRequiredDefaultNotes
titlestringyes-External account connection title.
descriptionstringno-Short reason for connecting the account.
providerstringno-Provider name shown in the view.
actionActionyes-Brokered sign-in or OAuth start action.
childrenComponent[]no[]Optional details, legal links, or permission notes.
Terminal
<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

PropertyTypeRequiredDefaultNotes
titlestringyes-Full-page extension title.
descriptionstringno-Optional page summary.
actionsAction[]no[]Page-level commands.
childrenComponent[]yes-Dense tables, filters, or operational panels.
Terminal
<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.

Stack and Text

Volume import

Import state is synchronized through a brokered operation.

rushfs.storage.configure
Terminal
<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

PropertyTypeRequiredDefaultNotes
gap"xs" | "sm" | "md" | "lg"no"md"Vertical spacing token.
childrenComponent[]yes-Stack items rendered in order.

Examples: basic-stack, settings-group, status-summary.

Text

PropertyTypeRequiredDefaultNotes
variant"body" | "heading" | "caption" | "mono"no"body"Host typography variant.
tone"default" | "muted" | "info" | "success" | "warning" | "danger"no"default"Semantic text tone.
childrenstringyes-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.

Status primitives
healthy syncing failed
Settings are applied through a brokered extension operation.
Terminal
<Alert tone="info">Settings are applied through a brokered extension operation.</Alert>
<Badge tone="success">healthy</Badge>
<Progress value={68} />

Badge

PropertyTypeRequiredDefaultNotes
tone"default" | "muted" | "info" | "success" | "warning" | "danger"no"default"Semantic status tone.
childrenstringyes-Short label, usually one or two words.

Examples: status-tones, metadata-badge, provider-state.

Alert

PropertyTypeRequiredDefaultNotes
tone"info" | "success" | "warning" | "danger"no"info"Semantic alert tone.
titlestringno-Optional short alert title.
childrenstring | Component[]yes-Alert body content.

Examples: info-alert, recoverable-warning, permission-error.

Progress

PropertyTypeRequiredDefaultNotes
valuenumberyes-Progress value from 0 to 100.
labelstringno-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.

Settings form
Terminal
<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

PropertyTypeRequiredDefaultNotes
operationstringyes-Broker operation dispatched on submit.
defaultValuesRecord<string, unknown>no{}Initial field values.
childrenComponent[]yes-Form controls and actions.

Events: emits a broker operation submit event.

Examples: settings-submit, connection-test.

TextInput

PropertyTypeRequiredDefaultNotes
namestringyes-Form field name submitted to the operation.
labelstringyes-Visible field label.
defaultValuestringno""Initial uncontrolled value.
valuestringno-Controlled value. Prefer defaultValue for typing-heavy fields.
placeholderstringno-Hint text, not a replacement for label.
helpTextstringno-Supporting text below the input.
errorstringno-Validation error text.
disabledbooleannofalsePrevents editing and submission updates.
requiredbooleannofalseMarks the field as required.
Terminal
<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

PropertyTypeRequiredDefaultNotes
namestringyes-Form field name submitted to the operation.
labelstringyes-Visible field label.
optionsSelectOption[]yes-Serializable options with label and value.
defaultValuestringno-Initial selected value.
valuestringno-Controlled selected value.
placeholderstringno-Empty selection label.
helpTextstringno-Supporting text below the select.
errorstringno-Validation error text.
disabledbooleannofalsePrevents selection changes.
Terminal
<Select
  name="region"
  label="Region"
  defaultValue="auto"
  options={[
    { label: "Automatic", value: "auto" },
    { label: "Europe", value: "eu" },
  ]}
/>

Examples: region-select, provider-account-select.

Checkbox

PropertyTypeRequiredDefaultNotes
namestringyes-Form field name submitted to the operation.
labelstringyes-Visible checkbox label.
checkedbooleanno-Controlled checked state.
defaultCheckedbooleannofalseInitial uncontrolled checked state.
helpTextstringno-Supporting text below the checkbox.
disabledbooleannofalsePrevents changes.
Terminal
<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

PropertyTypeRequiredDefaultNotes
type"button" | "submit"no"button"Submit buttons must live inside Form.
variant"primary" | "secondary" | "ghost" | "danger"no"primary"Host action style.
actionActionno-Bridge action for non-submit buttons.
childrenstringyes-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.

DataGrid
Name Provider Status Used Actions
rushfs-primary RushFS ready 68%
rushfs-archive RushFS syncing 41%
Terminal
<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

PropertyTypeRequiredDefaultNotes
columnsDataGridColumn[]yes-Serializable column definitions.
rowsRecord<string, unknown>[]yes-Rows must include a stable id.
paginationPaginationno-Renderer-owned pagination controls.
selectionSelectionno-Single or multiple row selection.
rowActionsAction[]no[]Per-row renderer-owned commands.
loadingbooleannofalseShows host loading state.
emptyStateEmptyStatePropsno-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.

Terminal
<Table
  columns={[
    { id: "key", header: "Property" },
    { id: "value", header: "Value" },
  ]}
  rows={[
    { key: "Runtime", value: "sandbox" },
    { key: "Distribution", value: "private" },
  ]}
/>

Table

PropertyTypeRequiredDefaultNotes
columnsTableColumn[]yes-Static column definitions.
rowsRecord<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

PropertyTypeRequiredDefaultNotes
titlestringyes-Short empty-state title.
descriptionstringno-Explanation or next step.
actionActionno-Optional primary action.
childrenComponent[]no[]Optional secondary content.
Terminal
<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.

PropertyTypeRequiredDefaultNotes
hrefstringyes-Host-approved URL or route.
childrenstringyes-Link text.
externalbooleannofalseOpens through the host external-navigation path.
tone"default" | "muted"no"default"Visual emphasis.
Terminal
<Link href="https://rushfs.example.com/docs" external>
  RushFS provider documentation
</Link>

Examples: external-docs-link, internal-resource-link.

Current component surface

ComponentVersionStatusUse for
ContextView1.0.0stableContextual extension panels and detail surfaces.
SettingsView1.0.0stableExtension configuration and install follow-up flows.
FocusView1.0.0stableFocused tasks that need a framed flow.
SignInView1.0.0stableExternal account connection or onboarding state.
FullPageView1.0.0stableDense extension pages with more screen real estate.
Stack1.0.0stableVertical spacing and layout.
Text1.0.0stableBody, heading, caption, and mono text.
Badge1.0.0stableCompact status and metadata labels.
Alert1.0.0stableInline feedback or callouts.
Form1.0.0stableOperation-backed form submission.
TextInput1.0.0stableText entry with label.
Select1.0.0stableSmall option sets.
Checkbox1.0.0stableBoolean settings.
Button1.0.0stablePrimary, secondary, ghost, and icon actions.
Progress1.0.0stableBounded numeric progress.
Table1.0.0stableSimple static tabular data.
DataGrid1.0.0stableSortable, selectable, paginated operational data.
EmptyState1.0.0stableEmpty or unsupported states.
Link1.0.0stableHost-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 DataGrid row 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.