Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Mui Panel

ASecurity

How to use @owlmeans/mui-panel — the LEGACY MUI v7 browser layer: makeContext, the render() entry point with the MUI ThemeProvider, the Block/Text/Link/Status/Form components and the auth-only subpaths. Superseded by @owlmeans/web-panel for new work. Auto-invoked when maintaining an app that already imports mui-panel or deciding how to migrate one off it.

3 stars
0 votes
0 copies
0 views
Added 9/22/2026
developmenttypescriptgoshellreactapifrontend

Works with

cliapi

Security Analysis

A100/100

Scanned 9/22/2026

Install to Claude Code

$npx -y skills add owlmeans/common --skill mui-panel --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mui Panel?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Mui Panel
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/owlmeans-mui-panel/badge)](https://www.skillsdirectory.com/skills/owlmeans-mui-panel)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: mui-panel
description: "How to use @owlmeans/mui-panel — the LEGACY MUI v7 browser layer: makeContext, the render() entry point with the MUI ThemeProvider, the Block/Text/Link/Status/Form components and the auth-only subpaths. Superseded by @owlmeans/web-panel for new work. Auto-invoked when maintaining an app that already imports mui-panel or deciding how to migrate one off it."
user-invocable: false
---

# @owlmeans/mui-panel

**Layer:** Web (React)
**Install:** `"@owlmeans/mui-panel": "^0.1.18-rc.44"` in `dependencies`

## This is the legacy UI layer

**`@owlmeans/web-panel` is the current browser panel family — shadcn/Radix over Tailwind — and
every new application uses it.** This package is the MUI v7 predecessor, kept for the applications
that already run on it. Do not start a new app here, do not add a screen family here, and do not
port a shadcn component back into it.

What that means in practice:

| Concern | Legacy (this package) | Current |
|---|---|---|
| Context factory | `makeContext` here | `makeContext` in `@owlmeans/web-panel` |
| Rendering | `render(context, theme?, opts?)` — MUI `ThemeProvider` + `CssBaseline` | `render(context, opts?)` in `@owlmeans/web-panel` — mounts `PanelApp`, which carries the i18n context |
| Layout / navigation | `Layout` — a bare `Box`; navigation is the app's own | `NavLayout` / `TopNav` / `SideNav` / `Footer` |
| Theme | an MUI `Theme` object passed to `render` | CSS tokens and the `.dark` class |
| OIDC sign-in | `@owlmeans/mui-oidc-rp` | `@owlmeans/web-oidc-rp`, or `@owlmeans/client-iam` for one-call wiring |
| Styling props | `styles?: SxProps` on `Block`, `Text`, `Link` and `Form` only | `className` / `style` merged through `cn` |

Both families sit on the same `@owlmeans/client-panel` primitives and the same entrypoint model, so
a migration is component-by-component rather than a rewrite: the context factory, the entrypoint
declarations and the form model all survive it.

## Key Exports

| Export | Description |
|--------|-------------|
| `makeContext<C, T>(cfg)` | The browser context: registers `apiConfigMiddleware`, appends the flow service, and adds the `context.flow()` accessor |
| `useContext<C, T>()` | The current context, from React |
| `render(context, theme?, opts?)` | Mounts the tree inside `PanelApp` — MUI `ThemeProvider`, `CssBaseline` and the i18n context, with the browser language detector installed |
| `PanelApp` | That wrapper on its own, for a host that mounts the tree itself |
| `entrypoints` | The base declaration list — `@owlmeans/web-client`'s plus `@owlmeans/api-config-client`'s |
| `Block` | A `Card` panel with optional `Actions`, carrying a `PanelContext` for i18n |
| `Text` / `Link` | `Typography` and an anchor whose `href` is the entrypoint's own `url()` answer |
| `Status` | An `Alert` that resolves a `ResilientError` to a translated message |
| `Form` | `react-hook-form` + AJV (`ajvResolver`, `coerceTypes`, `ajv-formats`) over a `Grid`; `decorate` adds the `Card`, the root-error `Status` and the submit action — see the gotcha below |
| `TextInput` | The `TextField` field control. `label` / `placeholder` / `hint` are resolved from the form namespace **only when passed boolean `true`** — see the gotcha below |
| `Button` / `SubmitButton` | Buttons with the loader spinner and the three-tier label lookup |
| `ButtonSelector` | A `ButtonGroup` acting as a single-choice control |
| `ImageUploader` | `@owlmeans/web-client`'s uploader in a `Paper` drop target with a preview |
| `Layout` | A bare `Box` — this family ships no navigation shell |
| `scalingToStyles(h, v, theme)` | `BlockScaling` → `SxProps`, the sizing every panel here shares |
| `useBreakPoint()` | The current MUI breakpoint name — `xs`/`sm`/`md`/`lg`/`xl`, or `unknown` when none matches |
| `useMapBreakpoint(map, def?, breakpoint?)` | The `map` entry for the current breakpoint (or for the `breakpoint` passed), falling back to `def`. It **throws a `SyntaxError`** when neither yields a value, so give it a `def` or cover every breakpoint |
| Re-exports | Protocol binding helpers (`bind`, `bindAll`, `bindScreen`), `handler`, route and frontend helpers, navigation/state/config APIs, authentication exports and theme integration. Use shared protocol references for typed entrypoint calls. |
| Re-export of `@owlmeans/client-panel` | The whole cross-platform panel surface — `ClientForm`, `PanelContext`, `usePanelI18n`, `useFormRef`, `BlockScaling`, … |

## Subpath Exports

- `./auth` — a **separate, smaller** context factory for an auth-only surface: it builds a client
  context directly (`extractPrimaryHost`, `appendWebDbService`, `appendWebRouter`,
  `apiConfigMiddleware`, `appendFlowService`) instead of the full web-client one, plus its own
  re-export set and the authentication UI plugins.
- `./auth/entrypoints` — the auth-manager declarations plus the API-config ones.

Importing `./auth` registers the authentication renderers by side effect:
`AuthenticationType.BasicEd25519`, `ReCaptcha` and `WalletConsumer` get their MUI renderers pushed
into the shared plugin registry of `@owlmeans/client-auth/manager`. That registry is a module
singleton, so **importing both this package's plugins and another family's replaces the renderers
rather than combining them** — one UI family per bundle.

## Wiring

```typescript
import { makeContext as makeBasicContext } from '@owlmeans/mui-panel'
import { appendOidcGuard } from '@owlmeans/mui-oidc-rp'

export const makeContext = <C extends Config, T extends Context<C>>(cfg: C): T => {
  const context = makeBasicContext<C, T>(cfg) as T
  appendOidcGuard<C, T>(context)
  return context
}
```

**A context is created once per process, by one factory.** An app factory calls the factory of the
layer below it, applies idempotent `append*(context)` mixins, and returns that same context.
Nothing is stored for re-creation, and every service, resource and entrypoint binds to exactly the
one context it was appended to.

Compose the entrypoints over the base set, then render with the app's theme:

```typescript
import { entrypoints as baseEntrypoints, render } from '@owlmeans/mui-panel'

export const clientBindings = [...baseEntrypoints, ...appBindings]

render(context, theme)
```

`render` builds a default MUI theme when none is passed, so an app with no branding still gets a
consistent surface. `PanelApp` memoises the theme on identity — hand it a stable object, not a
`createTheme(...)` call inside the render body, or every render rebuilds the whole theme.

## Gotchas

- **MUI is a peer, not a dependency.** `@mui/material`, `@mui/icons-material`, `@emotion/react`,
  `@emotion/styled`, `react`, `react-dom`, `react-hook-form` and `ajv` are all supplied by the app,
  at v7 for the MUI packages. A second copy of `@mui/material` in the tree gives two theme contexts
  and components that read the wrong one.
- **`Link` takes the screen on a prop named `module`, not `entrypoint`.** `LinkProps` declares
  `module?: string | RegisteredEntrypoint` — the context-bound protocol registration used by the
  tree say entrypoint. There is no `entrypoint` prop, and a `Link` given none renders an anchor with
  no `href`. Its default label key is `modules.<alias>`, from the same legacy family.
- **`Link` resolves its `href` asynchronously.** It asks the entrypoint for its own URL, so the
  anchor has no `href` for the first paint and settles once the URL is known — never key a test or
  a layout on the attribute being present synchronously. Address a screen by alias; `src` is the
  escape hatch for a literal URL, and `open` opens a new tab.
- **`TextInput` resolves copy from a boolean, and DISCARDS a string.** `label`, `placeholder` and
  `hint` are typed `string | boolean`, but only `true` does anything: it looks up `<name>.label` /
  `<name>.placeholder` / `<name>.hint` in the form namespace. Any other value — a literal string
  included — is replaced with `undefined`. So `<TextInput label="Email" />` compiles and renders no
  label at all. Put the wording in the form's translation bundle and pass `label`.
  (`@owlmeans/web-panel`'s `TextInput` honours a string; do not carry the habit either way.)
- **`Form` renders a bare `Grid` unless `decorate` is set.** With `decorate={true}` it wraps the
  fields in a `Card`, surfaces the root error through `Status`, and renders a `SubmitButton` in
  `CardActions` when `onSubmit` is given. Without it there is no card, no root-error surface and no
  submit button — the caller renders its own action. `styles` is applied only on the decorated
  `Card`; the scaling from `horizontal`/`vertical` lands on the `Grid` otherwise.
- **`Form` validates through AJV, and the schema is the source of the defaults.** Given
  `validation` and no `defaults`, the initial values come from `schemaToFormDefault`. Its AJV
  instance coerces types, so a numeric field arrives as a number rather than the input's string.
- **Label lookup in `Button` is three-tier** — panel namespace, then the app namespace's `buttons`
  section, then `client-panel`'s. Pass `i18n: { suppress: true }` to render a literal label instead.
- **`Status` rewrites `:` to `.` in an error message** before looking it up, so a marshalled
  `ResilientError` resolves as `<type>.<message>` in the translation tree. A key written with a
  colon never matches.
- This family has **no navigation shell**. `Layout` is a `Box`; a menu, header and footer are the
  app's own MUI code. That is the largest single gap against `@owlmeans/web-panel`, and the reason
  a migration usually starts by adopting `NavLayout`.

## Depends On

- `@owlmeans/web-client`, `@owlmeans/client-panel`, `@owlmeans/client-i18n`, `@owlmeans/web-router`,
  `@owlmeans/web-flow`, `@owlmeans/web-db`, `@owlmeans/client-auth`, `@owlmeans/api-config-client`
- Peers (app-provided): `@mui/material` v7, `@mui/icons-material` v7, `@emotion/react`,
  `@emotion/styled`, `react`, `react-dom`, `react-hook-form`, `ajv`
- `ajv-formats` is imported at module scope by `Form` but is declared in no dependency section of
  the manifest, which lists `ajv` alone. An install that does not otherwise pull it in fails at
  import time, so declare `ajv-formats` next to `ajv` in the consuming application.

## Related

- `web-panel` — **the current panel family**; read it for anything new
- `mui-oidc-rp` — the OIDC relying party of this same legacy family
- `client-panel` — the cross-platform primitives both families are written against
- `shadcn-web` — how the current family is built, and the MUI→shadcn component mapping

Attribution

owlmeansowlmeans
View sourceMore from owlmeans →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284072 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2192 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →