@owlmeans/mui-panel 0.1.18-rc.64 → 0.1.18-rc.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,222 @@
1
1
  # @owlmeans/mui-panel
2
2
 
3
- Legacy MUI browser shell and panel components. New browser work uses `@owlmeans/web-panel`; existing
4
- MUI applications bind shared protocol declarations locally with `bindAll()` and `bindScreen()`.
3
+ The legacy MUI browser layer of OwlMeans: a web context factory, a `render()` entry that mounts the
4
+ app inside an MUI `ThemeProvider`, a small set of MUI panel components (`Block`, `Text`, `Link`,
5
+ `Status`, `Form`, `TextInput`, buttons, an image uploader) and a re-export surface for binding shared
6
+ protocol declarations, routes, i18n and flows from one import. It exists for applications that
7
+ already run on MUI; they bind shared protocol declarations locally with `bindAll()` and
8
+ `bindScreen()`. **New browser work uses `@owlmeans/web-panel`** (shadcn/Radix over Tailwind) — do
9
+ not start an app, add a screen family, or port a shadcn component here. Both families sit on the
10
+ same `@owlmeans/client-panel` primitives and entrypoint model, so an app migrates component by
11
+ component. The `mui-panel` skill covers this package.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ bun add @owlmeans/mui-panel@^0.1.18-rc.66
17
+ ```
18
+
19
+ Peer dependencies the app provides: `@mui/material`, `@mui/icons-material`, `@emotion/react`,
20
+ `@emotion/styled`, `react`, `react-dom`, `react-hook-form`, `ajv`. `Form` also imports `ajv-formats`,
21
+ which the manifest does not declare — add it to the app next to `ajv`.
22
+
23
+ ## Concepts
24
+
25
+ - **Context factory** — `makeContext(cfg)` builds on `@owlmeans/web-client`'s context, registers
26
+ `apiConfigMiddleware` and the flow service, and adds the `context.flow()` accessor. One context per
27
+ process; app factories call it and then apply their own `append*` mixins.
28
+ - **Entrypoints** — `entrypoints` is the base declaration list (`@owlmeans/web-client`'s plus
29
+ `@owlmeans/api-config-client`'s). An app appends its own, built from shared protocol declarations
30
+ with `bindAll` (API protocols) and `bindScreen` (frontend protocols bound to a component).
31
+ - **Theme** — an MUI `Theme` passed to `render` / `PanelApp`; a default `createTheme()` is used when
32
+ none is given.
33
+ - **Panel i18n** — components resolve copy through `@owlmeans/client-panel`'s panel and form
34
+ namespaces rather than taking literal strings.
35
+ - **Auth surface** — the `./auth` subpath is a smaller context for an authentication-only app, and
36
+ its import registers MUI renderers for the built-in authentication methods.
37
+
38
+ ## Usage
39
+
40
+ ### 1. Context factory
41
+
42
+ ```typescript
43
+ import { makeContext as makeMuiContext } from '@owlmeans/mui-panel'
44
+ import type { AppConfig, AppContext } from '@owlmeans/mui-panel'
45
+
46
+ export const makeContext = <C extends AppConfig, T extends AppContext<C>>(cfg: C): T => {
47
+ const context = makeMuiContext<C, T>(cfg)
48
+ // app-level append* mixins go here
49
+
50
+ return context
51
+ }
52
+ ```
53
+
54
+ ### 2. Entrypoints and rendering
55
+
56
+ ```tsx
57
+ import { bindAll, bindScreen, entrypoints as baseEntrypoints, handler, render } from '@owlmeans/mui-panel'
58
+ import { createTheme } from '@mui/material/styles'
59
+ import { apiProtocols, webProtocols } from 'my-app-common'
60
+ import { HomeScreen } from './screens/home.js'
61
+
62
+ export const appEntrypoints = [
63
+ ...baseEntrypoints,
64
+ ...bindAll(apiProtocols),
65
+ bindScreen(webProtocols.home, handler(HomeScreen)),
66
+ ]
67
+
68
+ const theme = createTheme({ palette: { mode: 'dark' } }) // module scope: a stable object
69
+
70
+ const context = makeContext(config)
71
+ context.registerEntrypoints(appEntrypoints)
72
+ render(context, theme)
73
+ ```
74
+
75
+ `render(context, theme?, opts?)` installs the browser language detector and mounts `PanelApp`
76
+ (`ThemeProvider`, `I18nContext`, `<App>`, `CssBaseline`). A host that mounts the tree itself uses
77
+ `PanelApp` directly.
78
+
79
+ ### 3. Panels, text, links and status
80
+
81
+ ```tsx
82
+ import { Block, BlockScaling, Link, Status, Text } from '@owlmeans/mui-panel'
83
+
84
+ export const HomeScreen = () =>
85
+ <Block horizontal={BlockScaling.Half} i18n={{ prefix: 'home' }}>
86
+ <Text name="title" variant="h4" />
87
+ <Link module="projects" /> {/* href resolved from the entrypoint's url() */}
88
+ <Link src="https://owlmeans.com" open>OwlMeans</Link>
89
+ <Status ok={false} error={lastError} />
90
+ </Block>
91
+ ```
92
+
93
+ ### 4. Forms
94
+
95
+ ```tsx
96
+ import { Form, SubmitButton, TextInput, useFormRef } from '@owlmeans/mui-panel'
97
+
98
+ export const ProfileForm = () => {
99
+ const formRef = useFormRef<ProfileInput>()
100
+
101
+ return <Form name="profile" formRef={formRef} validation={ProfileSchema} decorate
102
+ onSubmit={async data => { await saveProfile(data) }}>
103
+ <TextInput name="email" label placeholder hint />
104
+ <TextInput name="displayName" label />
105
+ </Form>
106
+ }
107
+ ```
108
+
109
+ With `decorate` the form renders a `Card`, the root error through `Status`, and a `SubmitButton`
110
+ when `onSubmit` is set. Without it the form is a bare `Grid` and the caller renders its own
111
+ `<SubmitButton onSubmit={...} />`. `label`, `placeholder` and `hint` take `true` to look up
112
+ `<name>.label` / `.placeholder` / `.hint` in the form namespace.
113
+
114
+ ### 5. Auth-only surface
115
+
116
+ ```typescript
117
+ import { makeContext, render } from '@owlmeans/mui-panel/auth'
118
+ import { entrypoints } from '@owlmeans/mui-panel/auth/entrypoints'
119
+
120
+ const context = makeContext(config)
121
+ context.registerEntrypoints(entrypoints)
122
+ render(context, theme)
123
+ ```
124
+
125
+ Importing `@owlmeans/mui-panel/auth` sets MUI renderers for `AuthenticationType.BasicEd25519`,
126
+ `ReCaptcha` and `WalletConsumer` in the shared `@owlmeans/client-auth/manager` plugin registry.
127
+
128
+ ## API
129
+
130
+ ### Main entry `@owlmeans/mui-panel`
131
+
132
+ | Symbol | Kind | Purpose |
133
+ |---|---|---|
134
+ | `makeContext(cfg)` / `useContext()` | functions | Build the context; read it in React |
135
+ | `render(context, theme?, opts?)` | function | Mount the app with the language detector inside `PanelApp` |
136
+ | `PanelApp` | component (`PanelAppProps`: `AppProps` + `theme?`) | `ThemeProvider` + `I18nContext` + `<App>` + `CssBaseline` |
137
+ | `entrypoints` | array | Base declarations from `@owlmeans/web-client` and `@owlmeans/api-config-client` |
138
+ | `Block` | component (`BlockProps`) | `Card` panel with `horizontal`/`vertical` scaling, optional `Actions`, panel i18n scope, `styles` |
139
+ | `Text` | component (`TextProps`) | `Typography` with a translated `name`, `variant`, `center`, `nested`, `styles` |
140
+ | `Link` | component (`LinkProps`) | MUI link to `src` or to an entrypoint given as `module` (alias or entrypoint); `open` targets a new tab |
141
+ | `Status` | component (`StatusProps`) | `Alert` resolving `message`, a `ResilientError`, or the variant to translated text |
142
+ | `Form` | component (`WebFormProps`) | `react-hook-form` + AJV over a `Grid`; `decorate` adds card, root error and submit |
143
+ | `TextInput` | component (`TextInputProps`) | `TextField` bound to the form; `name`, `label?`, `placeholder?`, `hint?`, `type?`, `def?`, `disableAutocomplete?` |
144
+ | `Button` / `SubmitButton` | components (`ButtonProps` / `SubmitProps`) | Buttons with loader spinner and label lookup |
145
+ | `ButtonSelector` | component (`SelectorProps`) | `ButtonGroup` as a single-choice control: `current`, `options`, `onSelect` |
146
+ | `ImageUploader` | component (`ImageUploaderProps`) | Web-client uploader in a `Paper` drop target with `previewUrl` |
147
+ | `Layout` | component (`LayoutProps`) | A bare `Box` — no navigation shell |
148
+ | `scalingToStyles(h, v, theme?)` | function | `BlockScaling` → `SxProps` |
149
+ | `useBreakPoint()` | hook | Current MUI breakpoint name, or `'unknown'` |
150
+ | `useMapBreakpoint(map, def?, breakpoint?)` | hook | Value for the current breakpoint; throws `SyntaxError` when none and no `def` |
151
+ | `AppConfig`, `AppContext` | types | Web-client config/context plus flow config and `flow()` |
152
+
153
+ ### Re-exports (main entry)
154
+
155
+ | Symbols | From |
156
+ |---|---|
157
+ | everything | `@owlmeans/client-panel` (`BlockScaling`, `PanelContext`, `usePanelI18n`, `useFormRef`, `ClientForm`, …) |
158
+ | `handler`, `useNavigate`, `useValue`, `useEntrypoint` | `@owlmeans/client` |
159
+ | `bind`, `bindAll`, `bindScreen`, `clientRequestHelper`, `provideRequest`, `stab`; type `Module` | `@owlmeans/client-entrypoint` |
160
+ | `config` / `service` / `addWebService` | `@owlmeans/client-context` / `@owlmeans/config` / `@owlmeans/client-config` |
161
+ | `croute` / `route`, `frontend` | `@owlmeans/client-route` / `@owlmeans/route` |
162
+ | `DAUTH_GUARD`, `bindExternalAuthentication` | `@owlmeans/client-auth` |
163
+ | `AppType`, `HOME`, `ROOT`, `BASE`, `GUEST` | `@owlmeans/context` |
164
+ | `DISPATCHER`, `CAUTHEN_FLOW_ENTER`; type `AuthToken` | `@owlmeans/auth` |
165
+ | `composePrefix`, `useI18n`, `useI18nApp`, `useI18nLib`, `useLanguage` | `@owlmeans/client-i18n` |
166
+ | `addI18nApp`, `addI18nLib`, `i18nHelper`, `SUPPORTED_LNGS` | `@owlmeans/i18n` |
167
+ | `flow`, `configureFlows` / `FLOW_PARAM`, `SERVICE_PARAM`, `useFlow` | `@owlmeans/flow` / `@owlmeans/web-flow` |
168
+ | `Dispatcher`, `appendWebAuthService` | `@owlmeans/web-client` |
169
+
170
+ ### Subpath `@owlmeans/mui-panel/auth`
171
+
172
+ `makeContext` (client context with `extractPrimaryHost`, `appendWebDbService`, `appendWebRouter`,
173
+ `apiConfigMiddleware`, flow service), `useContext`, `render`, `plugins` (the shared registry with
174
+ the MUI renderers set), types `AppConfig` / `AppContext`, all of `@owlmeans/client-panel/auth`,
175
+ `AuthenticationHOC`, and a re-export set close to the main entry's (adds `EntrypointOutcome`,
176
+ `RouteMethod`, `CAUTHEN`, `AuthenticationType`, `FLOW_ALIAS`; types `Navigator`, `AbstractRequest`,
177
+ `Request`, `ServiceRoute`, `FlowService`).
178
+
179
+ ### Subpath `@owlmeans/mui-panel/auth/entrypoints`
180
+
181
+ `entrypoints` — the auth-manager declarations plus the API-config ones.
182
+
183
+ ## Migrating to `@owlmeans/web-panel`
184
+
185
+ | Concern | Here | In `@owlmeans/web-panel` |
186
+ |---|---|---|
187
+ | Rendering | `render(context, theme?, opts?)` | `render(context, opts?)` |
188
+ | Theme | MUI `Theme` object | CSS tokens and the `.dark` class |
189
+ | Layout | `Layout` (a `Box`) | `NavLayout`, `TopNav`, `SideNav`, `Footer` |
190
+ | Styling | `styles?: SxProps` | `className` / `style` |
191
+ | OIDC sign-in | `@owlmeans/mui-oidc-rp` | `@owlmeans/web-oidc-rp` |
192
+
193
+ The context factory, entrypoint declarations and form model carry over unchanged.
194
+
195
+ ## Common pitfalls
196
+
197
+ - `TextInput` discards a string `label`/`placeholder`/`hint` — only `true` resolves copy. Put the
198
+ wording in the form's translation bundle. (`@owlmeans/web-panel`'s `TextInput` takes strings.)
199
+ - `Link` takes the target on `module`, not `entrypoint`, and resolves `href` asynchronously — the
200
+ first paint has no `href`.
201
+ - `Form` without `decorate` renders no card, no root-error surface and no submit button; `styles`
202
+ applies only to the decorated card.
203
+ - `Form` coerces types through AJV, and with `validation` and no `defaults` it derives initial
204
+ values from the schema.
205
+ - `Status` rewrites `:` to `.` in an error message before lookup, so translation keys use dots.
206
+ - Pass `render` a stable theme object; a `createTheme(...)` inside a render body rebuilds the theme
207
+ each time.
208
+ - A second copy of `@mui/material` in the tree gives two theme contexts. Importing another family's
209
+ auth plugins replaces these renderers in the shared registry — one UI family per bundle.
210
+ - `useMapBreakpoint` throws when the breakpoint is not in `map` and no `def` is given.
211
+
212
+ ## Related packages
213
+
214
+ - [`@owlmeans/web-panel`](../web-panel) — the current browser panel family; use it for new work
215
+ - [`@owlmeans/client-panel`](../client-panel) — the cross-platform primitives both families build on
216
+ - [`@owlmeans/web-client`](../web-client) — the browser context, `<App>` mounting and uploader
217
+ - [`@owlmeans/client-entrypoint`](../client-entrypoint) — `bind`, `bindAll`, `bindScreen`
218
+ - [`@owlmeans/client-auth`](../client-auth) — the authentication manager and plugin registry
219
+ - [`@owlmeans/mui-oidc-rp`](../mui-oidc-rp) — OIDC relying party for this legacy family
5
220
 
6
221
  <!-- owlmeans:agent-guidance:start -->
7
222
  ## Agent guidance
@@ -11,7 +226,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
11
226
  your project's skill store (`.agents/skills/`):
12
227
 
13
228
  ```sh
14
- npx @owlmeans/agent-skills@^0.1.18-rc.51
229
+ npx @owlmeans/agent-skills@^0.1.18-rc.53
15
230
  ```
16
231
 
17
232
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/mui-panel",
4
- "version": "0.1.18-rc.64",
5
- "generatedAt": "2026-10-06T11:45:57.683Z",
4
+ "version": "0.1.18-rc.66",
5
+ "generatedAt": "2026-10-09T11:30:42.760Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/mui-panel
9
9
 
10
10
  **Layer:** Web (React)
11
- **Install:** `"@owlmeans/mui-panel": "^0.1.18-rc.64"` in `dependencies`
11
+ **Install:** `"@owlmeans/mui-panel": "^0.1.18-rc.66"` in `dependencies`
12
12
 
13
13
  ## This is the legacy UI layer
14
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/mui-panel",
3
- "version": "0.1.18-rc.64",
3
+ "version": "0.1.18-rc.66",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -37,31 +37,31 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@hookform/resolvers": "^5.9.1",
40
- "@owlmeans/api-config-client": "^0.1.18-rc.46",
41
- "@owlmeans/auth": "^0.1.18-rc.40",
42
- "@owlmeans/auth-common": "^0.1.18-rc.48",
43
- "@owlmeans/basic-envelope": "^0.1.18-rc.47",
44
- "@owlmeans/client": "^0.1.18-rc.52",
45
- "@owlmeans/client-auth": "^0.1.18-rc.59",
46
- "@owlmeans/client-config": "^0.1.18-rc.44",
47
- "@owlmeans/client-context": "^0.1.18-rc.49",
48
- "@owlmeans/client-flow": "^0.1.18-rc.55",
49
- "@owlmeans/client-i18n": "^0.1.18-rc.51",
50
- "@owlmeans/client-entrypoint": "^0.1.18-rc.48",
51
- "@owlmeans/client-panel": "^0.1.18-rc.59",
52
- "@owlmeans/client-route": "^0.1.18-rc.49",
40
+ "@owlmeans/api-config-client": "^0.1.18-rc.47",
41
+ "@owlmeans/auth": "^0.1.18-rc.41",
42
+ "@owlmeans/auth-common": "^0.1.18-rc.49",
43
+ "@owlmeans/basic-envelope": "^0.1.18-rc.48",
44
+ "@owlmeans/client": "^0.1.18-rc.53",
45
+ "@owlmeans/client-auth": "^0.1.18-rc.61",
46
+ "@owlmeans/client-config": "^0.1.18-rc.45",
47
+ "@owlmeans/client-context": "^0.1.18-rc.50",
48
+ "@owlmeans/client-flow": "^0.1.18-rc.56",
49
+ "@owlmeans/client-i18n": "^0.1.18-rc.52",
50
+ "@owlmeans/client-entrypoint": "^0.1.18-rc.49",
51
+ "@owlmeans/client-panel": "^0.1.18-rc.61",
52
+ "@owlmeans/client-route": "^0.1.18-rc.50",
53
53
  "@owlmeans/config": "^0.1.18-rc.44",
54
54
  "@owlmeans/context": "^0.1.18-rc.34",
55
55
  "@owlmeans/error": "^0.1.18-rc.38",
56
56
  "@owlmeans/flow": "^0.1.18-rc.45",
57
57
  "@owlmeans/i18n": "^0.1.18-rc.39",
58
58
  "@owlmeans/entrypoint": "^0.1.18-rc.41",
59
- "@owlmeans/log": "^0.1.18-rc.2",
59
+ "@owlmeans/log": "^0.1.18-rc.3",
60
60
  "@owlmeans/route": "^0.1.18-rc.35",
61
- "@owlmeans/web-client": "^0.1.18-rc.62",
62
- "@owlmeans/web-db": "^0.1.18-rc.49",
63
- "@owlmeans/web-flow": "^0.1.18-rc.54",
64
- "@owlmeans/web-router": "^0.1.18-rc.50",
61
+ "@owlmeans/web-client": "^0.1.18-rc.64",
62
+ "@owlmeans/web-db": "^0.1.18-rc.50",
63
+ "@owlmeans/web-flow": "^0.1.18-rc.55",
64
+ "@owlmeans/web-router": "^0.1.18-rc.51",
65
65
  "i18next-browser-languagedetector": "^8.2.1",
66
66
  "qrcode.react": "^4.2.0",
67
67
  "react-google-recaptcha": "^3.1.0"
@@ -78,7 +78,7 @@
78
78
  },
79
79
  "devDependencies": {
80
80
  "@owlmeans/dep-config": "workspace:*",
81
- "@owlmeans/test-ui": "^0.1.18-rc.50",
81
+ "@owlmeans/test-ui": "^0.1.18-rc.51",
82
82
  "@emotion/react": "^11.14.0",
83
83
  "@emotion/styled": "^11.14.1",
84
84
  "@mui/icons-material": "^9.4.0",