wso2/oxygen-ui/oxygen-component

Claude Code and agent skill by wso2/oxygen-ui

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Generate Oxygen UI React components following best practices. Use when creating new components, data tables, cards, or UI elements with the Oxygen UI library.

Install

npx vskill@latest install wso2/oxygen-ui/oxygen-component

SKILL.md

Generate Oxygen UI Component

Instructions

  1. Read .claude/oxygen-ui/CLAUDE.md for critical rules
  2. Read .claude/oxygen-ui/components.md for API reference
  3. Generate component using Oxygen UI patterns

Critical Rules

  • Import ALL components from @wso2/oxygen-ui (never from @mui/material)
  • Import icons from @wso2/oxygen-ui-icons-react
  • Use theme tokens via sx prop (e.g., p: 2, bgcolor: 'background.paper')
  • Never hardcode colors or spacing values
  • For data tables, prefer ListingTable over MUI's Table
  • For layouts, use AppShell, Header, Sidebar
  • Write all UI text in sentence case (see below)

UI Text

Write all titles, action text, and content in sentence case. Capitalize only the first word, proper nouns, product names, and acronyms.

text
✓ Create project ✓ API keys ✓ Last modified
✗ Create Project ✗ API Keys ✗ LAST MODIFIED
  • Applies to titles, headings, buttons, links, menu items, tabs, labels, placeholders, table columns, tooltips, and messages
  • Write the text in sentence case in the source; never change case with textTransform: 'uppercase' or 'capitalize'

Choosing a Table

Pick the table type by what users do with the data:

TypeUse whenSetup
Listing table (default)Scanning and comparing records across columns; tables inside a page section, panel, or dialog<ListingTable variant="table">
Card tableTop level listing of entities users click to open (projects, components); rich rows with few columns<ListingTable variant="card">, disablePaper on Container, variant="card" hover clickable on each Row
Data tableLarge or server-paginated data; column filtering, resizing, hiding, reordering; bulk selection<ListingTable.DataGrid> inside ListingTable.Provider (variant="data-grid-card" on the Provider only for entity listings)
  • Default to the listing table when unsure
  • Do not nest a card table inside a card, dialog, or drawer
  • Do not use striped or bordered with the card variant
  • Use one table type for the same kind of data across the product

Table Toolbar

Every data table toolbar uses the same element order. Leave out elements a table doesn't need; never reorder the rest, except search and filters:

text
[Scope] [Search] [Filters] ······ [View toggles] [Utility icons] [Secondary]
[Applied filter chips] [Clear all]

Search and filters swap by page context. Put whichever users rely on more first, right after scope:

  • Search first when users look up a specific item by name (users, resources)
  • Filters first when users narrow by an attribute (logs by level, events by type)
  • Scope always stays first; use the same order for the same kind of page across the product
  • If the page's purpose doesn't make the choice clear, default to search first
  • Scope control (time range, workspace, region) comes first; its label shows the value (Time: Last 24 hours); at most one per table; never shown as a chip
  • Search is always visible; placeholder names what is searched (Search by name, Search events)
  • Prefer column header filters; use toolbar filters only when no column matches; a filter lives in one place only; max 3 toolbar filters, the rest under More filters
  • Right side order: view toggles (segmented control), utility icon buttons (export, column settings, refresh; refresh last), then secondary actions (outlined or text, more than 2 go to an overflow menu)
  • The primary action (Add user) is not in the toolbar; put it in PageTitle.Actions at the top right of the page header, vertically centered with the title block (header and subheader)
  • Applied filters show as Label: value chips in a row below the toolbar; show Clear all at 2+ chips (clears filters only, not scope or search); hide the row when empty
  • Put the result count in the footer next to pagination (1–25 of 120, or 25 events loaded without pagination), never in the toolbar
  • When rows are selected, a bulk actions bar replaces the toolbar: count and Select all on the left, actions on the right with destructive ones last and confirmed
  • On narrow screens collapse in order: secondary actions, toolbar filters (into Filters · 2), view toggles and utility icons (refresh stays); scope and search never collapse
  • Icon buttons always have a Tooltip and an aria-label
  • Use one date format across tables (28 Oct 2026, 04:29 UTC) and always show the time zone
tsx
import { Button, IconButton, ListingTable, TextField, Tooltip, useListingTableRequired } from '@wso2/oxygen-ui';
import { ChevronDown, RefreshCw } from '@wso2/oxygen-ui-icons-react';
// Render inside ListingTable.Provider so search reaches the table
function UsersToolbar() {
const { searchValue, onSearchChange } = useListingTableRequired();
return (
<ListingTable.Toolbar
actions={
<>
<Tooltip title="Refresh">
<IconButton size="small" aria-label="Refresh"><RefreshCw size={18} /></IconButton>
</Tooltip>
</>
}
>
<Button variant="outlined" endIcon={<ChevronDown size={16} />}>Region: All regions</Button>
<TextField
size="small"
placeholder="Search by name"
value={searchValue ?? ''}
onChange={(event) => onSearchChange?.(event.target.value)}
slotProps={{ htmlInput: { 'aria-label': 'Search by name' } }}
/>
</ListingTable.Toolbar>
);
}

ListingTable.Toolbar renders showSearch before children, so when a table has a scope control or puts filters first, render search as a child in the right position instead of using showSearch.

Choosing a Container

Use the lightest container that fits the task: modal → right drawer → page form → full page wizard. Ask in order and stop at the first "yes":

  1. Quick decision or 1 to 3 fields, with no scrolling content and no need to reference other pages? Use a modal
  2. Must the page behind stay visible, and is the task a single step? Use a right drawer
  3. Do later steps depend on earlier choices? Use a full page wizard
  4. Otherwise, use a page form with a back button
PatternUse whenAvoid whenTypical size
ModalConfirm, delete, rename, 1 to 3 fieldsScrolling content, referencing other pages, nested dialogsSmall to medium
Right drawerViewing or editing an item while keeping context visibleLong or multi-step forms, complex validation400 to 600px wide
Page formCreating or editing one entity with many fieldsQuick editsFull content area
WizardSequential setup with dependent stepsUnder 3 steps, non-linear editingFull page, 3 to 7 steps
  • Modal: one task, one decision; if it needs scrolling, it is not a modal. Title states the action (Delete item?), body explains the consequence. Buttons use specific verbs, never OK or Yes. Destructive actions use danger styling; high-impact deletes require typing the resource name. Trap focus, close on Esc, return focus to the trigger. Never nest modals or use them for unprompted interruptions
  • Right drawer: content relates to the page behind it (details, filters, settings, short edit forms). One standard width; wider variant only when content requires it. Sticky header (title, close) and sticky footer (primary and secondary actions). Warn about unsaved changes on close, Esc, or outside click. Don't stack drawers; open a modal from a drawer only for confirmations. Move focus in on open; return it to the trigger on close
  • Page form: back returns to the originating page and restores its state (filters, scroll, pagination). Clear page title (Create …, Edit …); breadcrumbs when navigation is deep. Group fields into titled sections; progressive disclosure for advanced settings. Keep the primary action reachable on long forms (sticky footer or top right). Prompt on unsaved changes for back button, browser back, and in-app links. Inline validation on blur; on submit, summarize errors at the top with links to fields
  • Wizard: stepper with step names and current position; 3 to 7 steps. Back never loses data; validate each step before Next. Order steps by dependency; optional steps last or skippable. Review step before final submit, with edit links per step. Cancel always available, confirms if progress will be lost; save drafts for long flows. Success state with clear next actions
  • Editing a resource with 5 to 6 fields defaults to a right drawer. Switch to a page form for long content (rich text, code or JSON editor, spec files), fields that depend on each other, an edit likely to grow or that sits alongside other settings, or when users must reference other pages while editing
  • Use the same pattern for the same task type across the product
  • Every editable container guards against unsaved changes the same way
  • Support keyboard use, visible focus, and labelled controls; meet WCAG 2.2 AA

Component Template

tsx
import { Box, Typography, Button } from '@wso2/oxygen-ui';
import { IconName } from '@wso2/oxygen-ui-icons-react';
interface MyComponentProps {
// Define props
}
function MyComponent({ ...props }: MyComponentProps) {
return (
<Box sx={{ p: 2, bgcolor: 'background.paper' }}>
{/* Component content */}
</Box>
);
}
export default MyComponent;

Common Patterns

Data Table Component
tsx
import { ListingTable, Chip, IconButton } from '@wso2/oxygen-ui';
import { EditIcon, TrashIcon } from '@wso2/oxygen-ui-icons-react';
<ListingTable.Container>
<ListingTable.Toolbar showSearch actions={<Button>Add item</Button>} />
<ListingTable variant="card">
<ListingTable.Head>
<ListingTable.Row>
<ListingTable.Cell>Name</ListingTable.Cell>
<ListingTable.Cell>Status</ListingTable.Cell>
<ListingTable.Cell align="right">Actions</ListingTable.Cell>
</ListingTable.Row>
</ListingTable.Head>
<ListingTable.Body>
{data.map((item) => (
<ListingTable.Row key={item.id}>
<ListingTable.Cell>{item.name}</ListingTable.Cell>
<ListingTable.Cell>
<Chip label={item.status} color="success" size="small" />
</ListingTable.Cell>
<ListingTable.Cell align="right">
<IconButton size="small"><EditIcon size={18} /></IconButton>
<IconButton size="small" color="error"><TrashIcon size={18} /></IconButton>
</ListingTable.Cell>
</ListingTable.Row>
))}
</ListingTable.Body>
</ListingTable>
</ListingTable.Container>
Card Component
tsx
import { Paper, Typography, Box, Button } from '@wso2/oxygen-ui';
<Paper sx={{ p: 3 }}>
<Typography variant="h6" gutterBottom>Card title</Typography>
<Typography color="text.secondary" sx={{ mb: 2 }}>
Card description text
</Typography>
<Box sx={{ display: 'flex', gap: 1 }}>
<Button variant="contained">Primary</Button>
<Button variant="outlined">Secondary</Button>
</Box>
</Paper>
Dialog Component
tsx
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
Button,
} from '@wso2/oxygen-ui';
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
<DialogTitle>Dialog title</DialogTitle>
<DialogContent>
<DialogContentText>Dialog content goes here.</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={onClose}>Cancel</Button>
<Button variant="contained" onClick={onConfirm}>Confirm</Button>
</DialogActions>
</Dialog>

MUI X Components (Use Namespaces)

tsx
import { DataGrid, DatePickers, TreeView } from '@wso2/oxygen-ui';
// DataGrid
<DataGrid.DataGrid rows={rows} columns={columns} />
// DatePickers
<DatePickers.DatePicker value={date} onChange={setDate} />
// TreeView
<TreeView.SimpleTreeView>
<TreeView.TreeItem itemId="1" label="Item 1" />
</TreeView.SimpleTreeView>

Charts (Separate Package)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
62
Repository forks
55
7-day trend score
21

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 23 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/wso2/oxygen-ui/oxygen-component/badge)](https://verified-skill.com/skills/wso2/oxygen-ui/oxygen-component)

Something wrong with this skill or its page? Tell us.