@actdim/dynstruct-mui 1.5.13 → 1.5.15
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/AGENTS.md +158 -0
- package/CLAUDE.md +1 -0
- package/README.md +6 -2
- package/docs/INDEX.md +3 -3
- package/llms-full.txt +391 -0
- package/llms.txt +15 -0
- package/package.json +22 -7
package/AGENTS.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
<!-- BEGIN ALONG-PROTOCOL ref=../../../AGENTS.md (managed by along-init - do not edit by hand) -->
|
|
2
|
+
This folder belongs to a repository that uses the ALONG structure. The full working
|
|
3
|
+
guidance + agent-context protocol live once in the nearest ancestor `AGENTS.md` (`../../../AGENTS.md`) -
|
|
4
|
+
read it there. This folder keeps its OWN `.along/` state; use the nearest one.
|
|
5
|
+
Only this folder's specifics follow.
|
|
6
|
+
<!-- END ALONG-PROTOCOL --># AI Agent Guide for `@actdim/dynstruct-mui`
|
|
7
|
+
|
|
8
|
+
MUI wrappers for `@actdim/dynstruct`. Each file wraps one MUI component into a dynstruct hook-constructor.
|
|
9
|
+
|
|
10
|
+
## Tech Stack
|
|
11
|
+
|
|
12
|
+
- TypeScript · React · MobX · `@actdim/dynstruct` · `@mui/material` · Vite
|
|
13
|
+
|
|
14
|
+
## Component Authoring Pattern
|
|
15
|
+
|
|
16
|
+
Every component follows this exact structure (see `src/Button.tsx` as the reference):
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { type ComponentStruct, type ComponentDef, type ComponentParams,
|
|
20
|
+
type Component, type ComponentModel } from '@actdim/dynstruct/componentModel/contracts';
|
|
21
|
+
import { useComponent, toReact } from '@actdim/dynstruct/componentModel/react/hooks';
|
|
22
|
+
import { type BaseAppMsgStruct } from '@actdim/dynstruct/appDomain/appContracts';
|
|
23
|
+
|
|
24
|
+
// 1. Local Struct type — generic but private to file, default = BaseAppMsgStruct
|
|
25
|
+
type Struct<TMsgStruct extends BaseAppMsgStruct = BaseAppMsgStruct> = ComponentStruct<
|
|
26
|
+
TMsgStruct,
|
|
27
|
+
{
|
|
28
|
+
props: { /* ... */ };
|
|
29
|
+
}
|
|
30
|
+
>;
|
|
31
|
+
|
|
32
|
+
// 2. Hook-constructor — NOT generic, uses Struct with default
|
|
33
|
+
export const useXxx = (params: ComponentParams<Struct>): Component<Struct> => {
|
|
34
|
+
let c: Component<Struct>;
|
|
35
|
+
let m: ComponentModel<Struct>;
|
|
36
|
+
|
|
37
|
+
const def: ComponentDef<Struct> = {
|
|
38
|
+
regType: 'Xxx',
|
|
39
|
+
props: { /* defaults */ },
|
|
40
|
+
view: () => ( /* JSX using m.* and m.$.* */ ),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
c = useComponent(def, params);
|
|
44
|
+
m = c.model;
|
|
45
|
+
return c;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// 3. Exported type — concrete (non-generic) alias
|
|
49
|
+
export type XxxStruct = Struct;
|
|
50
|
+
|
|
51
|
+
// 4. React adapter — no explicit type params needed
|
|
52
|
+
export const Xxx = toReact(useXxx);
|
|
53
|
+
Xxx.displayName = 'Xxx';
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Rules
|
|
57
|
+
|
|
58
|
+
- **`Struct` stays local** — generic with `TMsgStruct` default, never exported directly.
|
|
59
|
+
- **Hook-constructor is non-generic** — `useXxx(params: ComponentParams<Struct>): Component<Struct>`.
|
|
60
|
+
- **`XxxStruct` export is non-generic** — `export type XxxStruct = Struct`.
|
|
61
|
+
- **`toReact` needs no type params** — `toReact(useXxx)` works because the hook is non-generic.
|
|
62
|
+
- **`displayName`** — always set `Xxx.displayName = 'Xxx'` after `toReact(...)` so Storybook and React DevTools show the correct name.
|
|
63
|
+
- **Disabled state** — use `m.$.isDisabled` (from `ComponentState`), not a dedicated `disabled` prop.
|
|
64
|
+
- **Loading state** — use explicit `loading?: boolean` prop or wire to `m.$.pendingRequestCount > 0`.
|
|
65
|
+
- **`m.$.isVisible`** — hide/show via component state, not a prop.
|
|
66
|
+
|
|
67
|
+
## Import Paths
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
// Contracts (types only)
|
|
71
|
+
import { ... } from '@actdim/dynstruct/componentModel/contracts';
|
|
72
|
+
|
|
73
|
+
// React utilities (useComponent, toReact)
|
|
74
|
+
import { ... } from '@actdim/dynstruct/componentModel/react/hooks';
|
|
75
|
+
// ^^^^^^^^^^^
|
|
76
|
+
// Note: the file lives at dist/componentModel/react/react.d.ts
|
|
77
|
+
// NOT dist/componentModel/react.d.ts — that file does not exist
|
|
78
|
+
|
|
79
|
+
// App domain
|
|
80
|
+
import { ... } from '@actdim/dynstruct/appDomain/appContracts';
|
|
81
|
+
import { ... } from '@actdim/dynstruct/appDomain/commonContracts';
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## MUI Composition Rules
|
|
85
|
+
|
|
86
|
+
Always follow the **official MUI website patterns** — use composable building blocks, not convenience shorthands:
|
|
87
|
+
|
|
88
|
+
| Component | Correct pattern |
|
|
89
|
+
|---|---|
|
|
90
|
+
| Select | `FormControl` + `InputLabel` + `Select` + `FormHelperText` |
|
|
91
|
+
| Checkbox (with label/error) | `FormControl` + `FormControlLabel` wrapping `Checkbox` + `FormHelperText` |
|
|
92
|
+
| Switch (with label/error) | `FormControl` + `FormControlLabel` wrapping `Switch` + `FormHelperText` |
|
|
93
|
+
| TextField | `TextField` (this IS the official atomic component, not a shorthand) |
|
|
94
|
+
| Button / IconButton | Use directly |
|
|
95
|
+
| Dialog | `Dialog` + `DialogTitle` + `DialogContent` + `DialogActions` |
|
|
96
|
+
| Alert | `Alert` directly (`onClose` for close button) |
|
|
97
|
+
|
|
98
|
+
- **`disabled`** always goes on the outermost container (`FormControl`, `Button`, etc.) — not inside, not as a duplicate.
|
|
99
|
+
- **`error`** and **`helperText`** always use `FormControl error={}` + `FormHelperText` — not ad-hoc inline text.
|
|
100
|
+
- **`sx`** type: when `FormControl` is the root, use `FormControlProps['sx']`, otherwise `MuiXxxProps['sx']`.
|
|
101
|
+
- For `labelId` (Select, etc.) use `c.id` from the dynstruct component instance to ensure uniqueness.
|
|
102
|
+
|
|
103
|
+
## Props Convention
|
|
104
|
+
|
|
105
|
+
- Map MUI prop types via `MuiXxxProps['propName']` — e.g. `MuiButtonProps['variant']`.
|
|
106
|
+
- Include `sx?` typed from the **outermost MUI element** (see MUI Composition Rules above).
|
|
107
|
+
- Reactive `ReactNode` props (icons, content, `React.FC`) are fine — MobX handles them as observable refs.
|
|
108
|
+
- Provide sensible defaults for all props in `def.props`.
|
|
109
|
+
|
|
110
|
+
## Storybook Stories
|
|
111
|
+
|
|
112
|
+
Every story file uses `AppContextProvider` + `StorageService` as the decorator. See `src/_stories/Button.stories.tsx` as the reference.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { AppContextProvider, appMsgBus } from './bootstrap';
|
|
116
|
+
import { StorageService } from '@actdim/dynstruct/services/react/StorageService';
|
|
117
|
+
|
|
118
|
+
const meta: Meta<typeof Xxx> = {
|
|
119
|
+
title: 'Controls/Xxx',
|
|
120
|
+
component: Xxx,
|
|
121
|
+
decorators: [
|
|
122
|
+
(Story) => (
|
|
123
|
+
<AppContextProvider value={{ msgBus: appMsgBus }}>
|
|
124
|
+
<StorageService storeName={'test'} />
|
|
125
|
+
<Story />
|
|
126
|
+
</AppContextProvider>
|
|
127
|
+
),
|
|
128
|
+
],
|
|
129
|
+
// ...
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- Always use `Meta<typeof Xxx>` explicit annotation (not `satisfies`) — avoids TS2742 from pnpm MUI path references.
|
|
134
|
+
- `argTypes` for `startIcon`, `endIcon`, `sx`: set `control: false` (not Storybook-controllable).
|
|
135
|
+
- `FullWidth` story should use `parameters: { layout: 'padded' }`.
|
|
136
|
+
|
|
137
|
+
## File Layout
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
src/
|
|
141
|
+
Button.tsx ← one file per MUI component
|
|
142
|
+
TextField.tsx
|
|
143
|
+
...
|
|
144
|
+
_stories/
|
|
145
|
+
bootstrap.ts ← AppMsgStruct, appMsgBus, AppContextProvider
|
|
146
|
+
Button.stories.tsx
|
|
147
|
+
...
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Import from the package: `import { useButton, ButtonStruct } from '@actdim/dynstruct-mui/Button'`.
|
|
151
|
+
|
|
152
|
+
## Project specifics
|
|
153
|
+
|
|
154
|
+
<!-- BEGIN ALONG-RULES -->
|
|
155
|
+
See the following engineering guidelines:
|
|
156
|
+
- `[languages/typescript.md](.along/rules/languages/typescript.md)`
|
|
157
|
+
- `[platforms/web.md](.along/rules/platforms/web.md)`
|
|
158
|
+
<!-- END ALONG-RULES -->
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
See @AGENTS.md for project instructions and guidance.
|
package/README.md
CHANGED
|
@@ -82,10 +82,14 @@ pnpm lint # lint
|
|
|
82
82
|
pnpm format # format
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
## AI-Assisted Development
|
|
86
|
+
|
|
87
|
+
Developed with [Along](https://github.com/actdim/along) - a provider-agnostic context and memory system for AI coding agents.
|
|
88
|
+
|
|
85
89
|
## License
|
|
86
90
|
|
|
87
|
-
Proprietary
|
|
91
|
+
Proprietary - see [LICENSE](LICENSE) for details.
|
|
88
92
|
|
|
89
93
|
## Author
|
|
90
94
|
|
|
91
|
-
Pavel Borodaev
|
|
95
|
+
Pavel Borodaev - [github.com/actdim/dynstruct-mui](https://github.com/actdim/dynstruct-mui)
|
package/docs/INDEX.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
protocol: along
|
|
3
|
-
protocol_version: "2.2.
|
|
3
|
+
protocol_version: "2.2.25"
|
|
4
4
|
slug: INDEX
|
|
5
5
|
title: Knowledge Base Topic Index
|
|
6
6
|
type: index
|
|
7
|
-
created: 2026-09-
|
|
8
|
-
updated: 2026-09-
|
|
7
|
+
created: 2026-09-07
|
|
8
|
+
updated: 2026-09-07
|
|
9
9
|
tags: [index, kb, topics, map]
|
|
10
10
|
---
|
|
11
11
|
|
package/llms-full.txt
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
# @actdim/dynstruct-mui - Full Documentation Context
|
|
2
|
+
|
|
3
|
+
> Knowledge Base and documentation index for dynstruct-mui.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Document: README.md (Overview)
|
|
8
|
+
|
|
9
|
+
# @actdim/dynstruct-mui
|
|
10
|
+
|
|
11
|
+
MUI component wrappers for [@actdim/dynstruct](https://github.com/actdim/dynstruct). Each component is a dynstruct hook-constructor — observable props, reactive rendering, MobX-backed state out of the box.
|
|
12
|
+
|
|
13
|
+
[](https://www.npmjs.com/package/@actdim/dynstruct-mui)
|
|
14
|
+
[](https://www.typescriptlang.org/)
|
|
15
|
+
[](LICENSE)
|
|
16
|
+
|
|
17
|
+
## Components
|
|
18
|
+
|
|
19
|
+
| Component | Import |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Accordion | `@actdim/dynstruct-mui/Accordion` |
|
|
22
|
+
| Alert | `@actdim/dynstruct-mui/Alert` |
|
|
23
|
+
| Autocomplete | `@actdim/dynstruct-mui/Autocomplete` |
|
|
24
|
+
| Avatar | `@actdim/dynstruct-mui/Avatar` |
|
|
25
|
+
| Badge | `@actdim/dynstruct-mui/Badge` |
|
|
26
|
+
| Breadcrumbs | `@actdim/dynstruct-mui/Breadcrumbs` |
|
|
27
|
+
| Button | `@actdim/dynstruct-mui/Button` |
|
|
28
|
+
| Card | `@actdim/dynstruct-mui/Card` |
|
|
29
|
+
| Checkbox | `@actdim/dynstruct-mui/Checkbox` |
|
|
30
|
+
| Chip | `@actdim/dynstruct-mui/Chip` |
|
|
31
|
+
| CircularProgress | `@actdim/dynstruct-mui/CircularProgress` |
|
|
32
|
+
| Dialog | `@actdim/dynstruct-mui/Dialog` |
|
|
33
|
+
| Drawer | `@actdim/dynstruct-mui/Drawer` |
|
|
34
|
+
| Fab | `@actdim/dynstruct-mui/Fab` |
|
|
35
|
+
| IconButton | `@actdim/dynstruct-mui/IconButton` |
|
|
36
|
+
| LinearProgress | `@actdim/dynstruct-mui/LinearProgress` |
|
|
37
|
+
| List | `@actdim/dynstruct-mui/List` |
|
|
38
|
+
| Menu | `@actdim/dynstruct-mui/Menu` |
|
|
39
|
+
| Pagination | `@actdim/dynstruct-mui/Pagination` |
|
|
40
|
+
| RadioGroup | `@actdim/dynstruct-mui/RadioGroup` |
|
|
41
|
+
| Rating | `@actdim/dynstruct-mui/Rating` |
|
|
42
|
+
| Select | `@actdim/dynstruct-mui/Select` |
|
|
43
|
+
| Skeleton | `@actdim/dynstruct-mui/Skeleton` |
|
|
44
|
+
| Slider | `@actdim/dynstruct-mui/Slider` |
|
|
45
|
+
| Snackbar | `@actdim/dynstruct-mui/Snackbar` |
|
|
46
|
+
| SpeedDial | `@actdim/dynstruct-mui/SpeedDial` |
|
|
47
|
+
| Stepper | `@actdim/dynstruct-mui/Stepper` |
|
|
48
|
+
| Switch | `@actdim/dynstruct-mui/Switch` |
|
|
49
|
+
| Table | `@actdim/dynstruct-mui/Table` |
|
|
50
|
+
| Tabs | `@actdim/dynstruct-mui/Tabs` |
|
|
51
|
+
| TextField | `@actdim/dynstruct-mui/TextField` |
|
|
52
|
+
| ToggleButtonGroup | `@actdim/dynstruct-mui/ToggleButtonGroup` |
|
|
53
|
+
| Tooltip | `@actdim/dynstruct-mui/Tooltip` |
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install @actdim/dynstruct-mui
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Peer dependencies: `@actdim/dynstruct`, `@mui/material`, `react`, `mobx`, `mobx-react-lite` — see `package.json` for full list.
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { useButton } from '@actdim/dynstruct-mui/Button';
|
|
67
|
+
|
|
68
|
+
const saveBtn = useButton({
|
|
69
|
+
props: {
|
|
70
|
+
label: 'Save',
|
|
71
|
+
variant: 'contained',
|
|
72
|
+
onClick: () => handleSave(),
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// In JSX:
|
|
77
|
+
// <saveBtn.view />
|
|
78
|
+
// or via React adapter:
|
|
79
|
+
import { Button } from '@actdim/dynstruct-mui/Button';
|
|
80
|
+
// <Button label="Save" variant="contained" onClick={handleSave} />
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Development
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pnpm storybook # run Storybook
|
|
87
|
+
pnpm build # build
|
|
88
|
+
pnpm typecheck # type check
|
|
89
|
+
pnpm lint # lint
|
|
90
|
+
pnpm format # format
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## AI-Assisted Development
|
|
94
|
+
|
|
95
|
+
Developed with [Along](https://github.com/actdim/along) - a provider-agnostic context and memory system for AI coding agents.
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
Proprietary - see [LICENSE](LICENSE) for details.
|
|
100
|
+
|
|
101
|
+
## Author
|
|
102
|
+
|
|
103
|
+
Pavel Borodaev - [github.com/actdim/dynstruct-mui](https://github.com/actdim/dynstruct-mui)
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Document: AGENTS.md (Agent Conventions & Protocol)
|
|
108
|
+
|
|
109
|
+
<!-- BEGIN ALONG-PROTOCOL ref=../../../AGENTS.md (managed by along-init - do not edit by hand) -->
|
|
110
|
+
This folder belongs to a repository that uses the ALONG structure. The full working
|
|
111
|
+
guidance + agent-context protocol live once in the nearest ancestor `AGENTS.md` (`../../../AGENTS.md`) -
|
|
112
|
+
read it there. This folder keeps its OWN `.along/` state; use the nearest one.
|
|
113
|
+
Only this folder's specifics follow.
|
|
114
|
+
<!-- END ALONG-PROTOCOL --># AI Agent Guide for `@actdim/dynstruct-mui`
|
|
115
|
+
|
|
116
|
+
MUI wrappers for `@actdim/dynstruct`. Each file wraps one MUI component into a dynstruct hook-constructor.
|
|
117
|
+
|
|
118
|
+
## Tech Stack
|
|
119
|
+
|
|
120
|
+
- TypeScript · React · MobX · `@actdim/dynstruct` · `@mui/material` · Vite
|
|
121
|
+
|
|
122
|
+
## Component Authoring Pattern
|
|
123
|
+
|
|
124
|
+
Every component follows this exact structure (see `src/Button.tsx` as the reference):
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { type ComponentStruct, type ComponentDef, type ComponentParams,
|
|
128
|
+
type Component, type ComponentModel } from '@actdim/dynstruct/componentModel/contracts';
|
|
129
|
+
import { useComponent, toReact } from '@actdim/dynstruct/componentModel/react/hooks';
|
|
130
|
+
import { type BaseAppMsgStruct } from '@actdim/dynstruct/appDomain/appContracts';
|
|
131
|
+
|
|
132
|
+
// 1. Local Struct type — generic but private to file, default = BaseAppMsgStruct
|
|
133
|
+
type Struct<TMsgStruct extends BaseAppMsgStruct = BaseAppMsgStruct> = ComponentStruct<
|
|
134
|
+
TMsgStruct,
|
|
135
|
+
{
|
|
136
|
+
props: { /* ... */ };
|
|
137
|
+
}
|
|
138
|
+
>;
|
|
139
|
+
|
|
140
|
+
// 2. Hook-constructor — NOT generic, uses Struct with default
|
|
141
|
+
export const useXxx = (params: ComponentParams<Struct>): Component<Struct> => {
|
|
142
|
+
let c: Component<Struct>;
|
|
143
|
+
let m: ComponentModel<Struct>;
|
|
144
|
+
|
|
145
|
+
const def: ComponentDef<Struct> = {
|
|
146
|
+
regType: 'Xxx',
|
|
147
|
+
props: { /* defaults */ },
|
|
148
|
+
view: () => ( /* JSX using m.* and m.$.* */ ),
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
c = useComponent(def, params);
|
|
152
|
+
m = c.model;
|
|
153
|
+
return c;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// 3. Exported type — concrete (non-generic) alias
|
|
157
|
+
export type XxxStruct = Struct;
|
|
158
|
+
|
|
159
|
+
// 4. React adapter — no explicit type params needed
|
|
160
|
+
export const Xxx = toReact(useXxx);
|
|
161
|
+
Xxx.displayName = 'Xxx';
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Rules
|
|
165
|
+
|
|
166
|
+
- **`Struct` stays local** — generic with `TMsgStruct` default, never exported directly.
|
|
167
|
+
- **Hook-constructor is non-generic** — `useXxx(params: ComponentParams<Struct>): Component<Struct>`.
|
|
168
|
+
- **`XxxStruct` export is non-generic** — `export type XxxStruct = Struct`.
|
|
169
|
+
- **`toReact` needs no type params** — `toReact(useXxx)` works because the hook is non-generic.
|
|
170
|
+
- **`displayName`** — always set `Xxx.displayName = 'Xxx'` after `toReact(...)` so Storybook and React DevTools show the correct name.
|
|
171
|
+
- **Disabled state** — use `m.$.isDisabled` (from `ComponentState`), not a dedicated `disabled` prop.
|
|
172
|
+
- **Loading state** — use explicit `loading?: boolean` prop or wire to `m.$.pendingRequestCount > 0`.
|
|
173
|
+
- **`m.$.isVisible`** — hide/show via component state, not a prop.
|
|
174
|
+
|
|
175
|
+
## Import Paths
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
// Contracts (types only)
|
|
179
|
+
import { ... } from '@actdim/dynstruct/componentModel/contracts';
|
|
180
|
+
|
|
181
|
+
// React utilities (useComponent, toReact)
|
|
182
|
+
import { ... } from '@actdim/dynstruct/componentModel/react/hooks';
|
|
183
|
+
// ^^^^^^^^^^^
|
|
184
|
+
// Note: the file lives at dist/componentModel/react/react.d.ts
|
|
185
|
+
// NOT dist/componentModel/react.d.ts — that file does not exist
|
|
186
|
+
|
|
187
|
+
// App domain
|
|
188
|
+
import { ... } from '@actdim/dynstruct/appDomain/appContracts';
|
|
189
|
+
import { ... } from '@actdim/dynstruct/appDomain/commonContracts';
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## MUI Composition Rules
|
|
193
|
+
|
|
194
|
+
Always follow the **official MUI website patterns** — use composable building blocks, not convenience shorthands:
|
|
195
|
+
|
|
196
|
+
| Component | Correct pattern |
|
|
197
|
+
|---|---|
|
|
198
|
+
| Select | `FormControl` + `InputLabel` + `Select` + `FormHelperText` |
|
|
199
|
+
| Checkbox (with label/error) | `FormControl` + `FormControlLabel` wrapping `Checkbox` + `FormHelperText` |
|
|
200
|
+
| Switch (with label/error) | `FormControl` + `FormControlLabel` wrapping `Switch` + `FormHelperText` |
|
|
201
|
+
| TextField | `TextField` (this IS the official atomic component, not a shorthand) |
|
|
202
|
+
| Button / IconButton | Use directly |
|
|
203
|
+
| Dialog | `Dialog` + `DialogTitle` + `DialogContent` + `DialogActions` |
|
|
204
|
+
| Alert | `Alert` directly (`onClose` for close button) |
|
|
205
|
+
|
|
206
|
+
- **`disabled`** always goes on the outermost container (`FormControl`, `Button`, etc.) — not inside, not as a duplicate.
|
|
207
|
+
- **`error`** and **`helperText`** always use `FormControl error={}` + `FormHelperText` — not ad-hoc inline text.
|
|
208
|
+
- **`sx`** type: when `FormControl` is the root, use `FormControlProps['sx']`, otherwise `MuiXxxProps['sx']`.
|
|
209
|
+
- For `labelId` (Select, etc.) use `c.id` from the dynstruct component instance to ensure uniqueness.
|
|
210
|
+
|
|
211
|
+
## Props Convention
|
|
212
|
+
|
|
213
|
+
- Map MUI prop types via `MuiXxxProps['propName']` — e.g. `MuiButtonProps['variant']`.
|
|
214
|
+
- Include `sx?` typed from the **outermost MUI element** (see MUI Composition Rules above).
|
|
215
|
+
- Reactive `ReactNode` props (icons, content, `React.FC`) are fine — MobX handles them as observable refs.
|
|
216
|
+
- Provide sensible defaults for all props in `def.props`.
|
|
217
|
+
|
|
218
|
+
## Storybook Stories
|
|
219
|
+
|
|
220
|
+
Every story file uses `AppContextProvider` + `StorageService` as the decorator. See `src/_stories/Button.stories.tsx` as the reference.
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { AppContextProvider, appMsgBus } from './bootstrap';
|
|
224
|
+
import { StorageService } from '@actdim/dynstruct/services/react/StorageService';
|
|
225
|
+
|
|
226
|
+
const meta: Meta<typeof Xxx> = {
|
|
227
|
+
title: 'Controls/Xxx',
|
|
228
|
+
component: Xxx,
|
|
229
|
+
decorators: [
|
|
230
|
+
(Story) => (
|
|
231
|
+
<AppContextProvider value={{ msgBus: appMsgBus }}>
|
|
232
|
+
<StorageService storeName={'test'} />
|
|
233
|
+
<Story />
|
|
234
|
+
</AppContextProvider>
|
|
235
|
+
),
|
|
236
|
+
],
|
|
237
|
+
// ...
|
|
238
|
+
};
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
- Always use `Meta<typeof Xxx>` explicit annotation (not `satisfies`) — avoids TS2742 from pnpm MUI path references.
|
|
242
|
+
- `argTypes` for `startIcon`, `endIcon`, `sx`: set `control: false` (not Storybook-controllable).
|
|
243
|
+
- `FullWidth` story should use `parameters: { layout: 'padded' }`.
|
|
244
|
+
|
|
245
|
+
## File Layout
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
src/
|
|
249
|
+
Button.tsx ← one file per MUI component
|
|
250
|
+
TextField.tsx
|
|
251
|
+
...
|
|
252
|
+
_stories/
|
|
253
|
+
bootstrap.ts ← AppMsgStruct, appMsgBus, AppContextProvider
|
|
254
|
+
Button.stories.tsx
|
|
255
|
+
...
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Import from the package: `import { useButton, ButtonStruct } from '@actdim/dynstruct-mui/Button'`.
|
|
259
|
+
|
|
260
|
+
## Project specifics
|
|
261
|
+
|
|
262
|
+
<!-- BEGIN ALONG-RULES -->
|
|
263
|
+
See the following engineering guidelines:
|
|
264
|
+
- `[languages/typescript.md](.along/rules/languages/typescript.md)`
|
|
265
|
+
- `[platforms/web.md](.along/rules/platforms/web.md)`
|
|
266
|
+
<!-- END ALONG-RULES -->
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Document: docs/topic--architecture.md (01 Architecture)
|
|
271
|
+
|
|
272
|
+
# @actdim/dynstruct-mui Architecture
|
|
273
|
+
|
|
274
|
+
## 1. System Overview
|
|
275
|
+
|
|
276
|
+
`@actdim/dynstruct-mui` provides Material UI (MUI v5/v6) component adapters specifically engineered for the `@actdim/dynstruct` component system. It bridges Material UI widgets with the dynstruct reactive component model, two-way bindings (`bind`, `bindProp`), and message bus integration.
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
+---------------------------------------------------------------------------------------------------+
|
|
280
|
+
| @actdim/dynstruct-mui |
|
|
281
|
+
+---------------------------------------------------------------------------------------------------+
|
|
282
|
+
| MUI Component Adapters |
|
|
283
|
+
| - Input & Form: TextField, Select, Autocomplete, Checkbox, Switch, RadioGroup, Slider, Rating |
|
|
284
|
+
| - Actions: Button, IconButton, Fab, ToggleButtonGroup, SpeedDial |
|
|
285
|
+
| - Layout & Containers: Card, Accordion, Dialog, Drawer, Menu, List, Table, Tabs, Stepper |
|
|
286
|
+
| - Feedback & Display: Alert, Snackbar, CircularProgress, LinearProgress, Skeleton, Badge, Avatar|
|
|
287
|
+
| - Navigation: Breadcrumbs, Pagination, Tooltip |
|
|
288
|
+
+---------------------------------------------------------------------------------------------------+
|
|
289
|
+
| Dynstruct Integration Layer |
|
|
290
|
+
| - Hook-Constructors: useButton, useTextField, useDialog, useSelect, etc. |
|
|
291
|
+
| - Two-way Data Binding: Seamless connection with bind(() => m.field, v => m.field = v) |
|
|
292
|
+
| - React Exports: Standard toReact() wrappers for direct JSX usage |
|
|
293
|
+
+---------------------------------------------------------------------------------------------------+
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## 2. Cross-Links
|
|
297
|
+
- [[INDEX.md]] - Knowledge Base Root
|
|
298
|
+
- [[02-domain-model.md]] - Domain Model & Component Catalog
|
|
299
|
+
- [[03-setup-and-workflow.md]] - Setup, Build & Storybook Workflow
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Document: docs/topic--domain-model.md (02 Domain Model)
|
|
304
|
+
|
|
305
|
+
# @actdim/dynstruct-mui Domain Model & Component Catalog
|
|
306
|
+
|
|
307
|
+
## 1. Domain Overview
|
|
308
|
+
|
|
309
|
+
`@actdim/dynstruct-mui` exposes typed component structures and hook-constructors wrapping `@mui/material` components.
|
|
310
|
+
|
|
311
|
+
## 2. Component Catalog
|
|
312
|
+
|
|
313
|
+
### 2.1. Form & Input Components
|
|
314
|
+
- **`useTextField` / `TextField`**: Material UI text field with label, helperText, error state, and two-way string binding.
|
|
315
|
+
- **`useSelect` / `Select`**: Select dropdown supporting single and multi-selection with options mapping.
|
|
316
|
+
- **`useAutocomplete` / `Autocomplete`**: Searchable combobox and autocomplete input.
|
|
317
|
+
- **`useCheckbox` / `Checkbox`**: Boolean checkbox toggle with label.
|
|
318
|
+
- **`useSwitch` / `Switch`**: On/off toggle switch.
|
|
319
|
+
- **`useRadioGroup` / `RadioGroup`**: Radio button selection group.
|
|
320
|
+
- **`useSlider` / `Slider`**: Continuous or discrete numeric slider.
|
|
321
|
+
- **`useRating` / `Rating`**: Star rating input widget.
|
|
322
|
+
|
|
323
|
+
### 2.2. Actions & Buttons
|
|
324
|
+
- **`useButton` / `Button`**: Primary, secondary, text, and contained button variants with click handlers.
|
|
325
|
+
- **`useIconButton` / `IconButton`**: Icon-only button wrapper.
|
|
326
|
+
- **`useFab` / `Fab`**: Floating Action Button.
|
|
327
|
+
- **`useToggleButtonGroup` / `ToggleButtonGroup`**: Segmented button group.
|
|
328
|
+
- **`useSpeedDial` / `SpeedDial`**: Expandable floating action speed dial.
|
|
329
|
+
|
|
330
|
+
### 2.3. Dialogs, Drawers & Layouts
|
|
331
|
+
- **`useDialog` / `Dialog`**: Modal dialog with title, content, actions, and open/close state.
|
|
332
|
+
- **`useDrawer` / `Drawer`**: Side sliding drawer container.
|
|
333
|
+
- **`useCard` / `Card`**: Container card with header, media, content, and action sections.
|
|
334
|
+
- **`useAccordion` / `Accordion`**: Expandable panel accordion.
|
|
335
|
+
- **`useTable` / `Table`**: Data table with sorting and pagination headers.
|
|
336
|
+
- **`useTabs` / `Tabs`**: Tab navigation bar.
|
|
337
|
+
- **`useStepper` / `Stepper`**: Multi-step wizard navigation.
|
|
338
|
+
|
|
339
|
+
### 2.4. Feedback & Indicators
|
|
340
|
+
- **`useAlert` / `Alert`**: Severity banner (`error`, `warning`, `info`, `success`).
|
|
341
|
+
- **`useSnackbar` / `Snackbar`**: Floating toast notification with auto-hide duration.
|
|
342
|
+
- **`useCircularProgress` / `CircularProgress`** & **`useLinearProgress` / `LinearProgress`**: Loading spinners.
|
|
343
|
+
- **`useSkeleton` / `Skeleton`**: Content placeholder loading skeleton.
|
|
344
|
+
- **`useTooltip` / `Tooltip`**: Hover tooltip popup.
|
|
345
|
+
|
|
346
|
+
## 3. Cross-Links
|
|
347
|
+
- [[INDEX.md]] - Knowledge Base Root
|
|
348
|
+
- [[01-architecture.md]] - System Architecture
|
|
349
|
+
- [[03-setup-and-workflow.md]] - Setup, Build & Storybook Workflow
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Document: docs/topic--setup-and-workflow.md (03 Setup And Workflow)
|
|
354
|
+
|
|
355
|
+
# @actdim/dynstruct-mui Setup, Build & Storybook Workflow
|
|
356
|
+
|
|
357
|
+
## 1. Prerequisites & Installation
|
|
358
|
+
|
|
359
|
+
- **Node.js**: >= 20.0.0
|
|
360
|
+
- **Package Manager**: `pnpm` (version ~10.21.0)
|
|
361
|
+
- **TypeScript**: >= 5.9.3
|
|
362
|
+
|
|
363
|
+
Install dependencies:
|
|
364
|
+
```bash
|
|
365
|
+
pnpm install
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Peer Dependencies
|
|
369
|
+
```bash
|
|
370
|
+
pnpm add @actdim/dynstruct @actdim/msgmesh @actdim/utico @mui/material @emotion/react @emotion/styled react react-dom mobx mobx-react-lite
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## 2. Scripts & Workflows
|
|
374
|
+
|
|
375
|
+
| Command | Action | Description |
|
|
376
|
+
|---|---|---|
|
|
377
|
+
| `pnpm run build` | `tsc -b tsconfig.json && vite build` | Compiles ESM packages with `.d.ts` declaration maps |
|
|
378
|
+
| `pnpm run storybook` | `storybook dev -p 6006` | Launches Storybook with all Material UI component stories |
|
|
379
|
+
| `pnpm run build-storybook` | `storybook build` | Builds static Storybook bundle |
|
|
380
|
+
| `pnpm run test` | `npx vitest --config=vitest.node.config.ts --no-cache` | Runs unit tests |
|
|
381
|
+
| `pnpm run typecheck` | `tsc -b tsconfig.json` | Runs strict TypeScript verification |
|
|
382
|
+
| `pnpm run lint` | `eslint "./**/*.{ts,tsx}"` | Lints codebase |
|
|
383
|
+
| `pnpm run format` | `prettier --write .` | Formats all files |
|
|
384
|
+
|
|
385
|
+
## 3. Storybook Catalog (`src/_stories/`)
|
|
386
|
+
Interactive stories exist for every wrapped Material UI component: `Button.stories.tsx`, `Dialog.stories.tsx`, `TextField.stories.tsx`, `Select.stories.tsx`, `Card.stories.tsx`, `Accordion.stories.tsx`, `Table.stories.tsx`, `Tabs.stories.tsx`, etc.
|
|
387
|
+
|
|
388
|
+
## 4. Cross-Links
|
|
389
|
+
- [[INDEX.md]] - Knowledge Base Root
|
|
390
|
+
- [[01-architecture.md]] - Architecture
|
|
391
|
+
- [[02-domain-model.md]] - Domain Model
|
package/llms.txt
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @actdim/dynstruct-mui
|
|
2
|
+
|
|
3
|
+
> Knowledge Base and documentation index for dynstruct-mui.
|
|
4
|
+
|
|
5
|
+
## Documentation Links
|
|
6
|
+
- [README.md](README.md): Overview, quick installation, and full skill list.
|
|
7
|
+
- [AGENTS.md](AGENTS.md): Active ALONG-PROTOCOL conventions and instructions.
|
|
8
|
+
- [docs/INDEX.md](docs/INDEX.md): Central Knowledge Base topic catalog.
|
|
9
|
+
- [docs/topic--architecture.md](docs/topic--architecture.md): 01 Architecture.
|
|
10
|
+
- [docs/topic--domain-model.md](docs/topic--domain-model.md): 02 Domain Model.
|
|
11
|
+
- [docs/topic--setup-and-workflow.md](docs/topic--setup-and-workflow.md): 03 Setup And Workflow.
|
|
12
|
+
|
|
13
|
+
## Optional
|
|
14
|
+
- [Full Documentation Context](llms-full.txt): Complete concatenated documentation in a single file.
|
|
15
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actdim/dynstruct-mui",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.15",
|
|
4
4
|
"description": "MUI component wrappers for @actdim/dynstruct",
|
|
5
5
|
"author": "Pavel Borodaev",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,13 +27,28 @@
|
|
|
27
27
|
"dist",
|
|
28
28
|
"docs",
|
|
29
29
|
"README.md",
|
|
30
|
-
"LICENSE"
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"AGENTS.md",
|
|
32
|
+
"CLAUDE.md",
|
|
33
|
+
"llms.txt",
|
|
34
|
+
"llms-full.txt"
|
|
31
35
|
],
|
|
36
|
+
"ai": {
|
|
37
|
+
"instructions": "./AGENTS.md",
|
|
38
|
+
"docs": "./docs",
|
|
39
|
+
"llms": "./llms.txt",
|
|
40
|
+
"llms-full": "./llms-full.txt"
|
|
41
|
+
},
|
|
42
|
+
"llms": "./llms.txt",
|
|
32
43
|
"files(src)": [
|
|
33
44
|
"src",
|
|
34
45
|
"docs",
|
|
35
46
|
"README.md",
|
|
36
|
-
"LICENSE"
|
|
47
|
+
"LICENSE",
|
|
48
|
+
"AGENTS.md",
|
|
49
|
+
"CLAUDE.md",
|
|
50
|
+
"llms.txt",
|
|
51
|
+
"llms-full.txt"
|
|
37
52
|
],
|
|
38
53
|
"exports": {
|
|
39
54
|
"./*": {
|
|
@@ -53,6 +68,9 @@
|
|
|
53
68
|
},
|
|
54
69
|
"sideEffects": false,
|
|
55
70
|
"peerDependencies": {
|
|
71
|
+
"@actdim/dynstruct": ">=1.5.15",
|
|
72
|
+
"@actdim/msgmesh": ">=1.5.15",
|
|
73
|
+
"@actdim/utico": ">=1.5.15",
|
|
56
74
|
"@emotion/react": ">=11.14.0",
|
|
57
75
|
"@emotion/styled": ">=11.14.1",
|
|
58
76
|
"@mui/material": ">=9.0.1",
|
|
@@ -67,10 +85,7 @@
|
|
|
67
85
|
"react-router": ">=7.9.3",
|
|
68
86
|
"react-router-dom": ">=7.9.4",
|
|
69
87
|
"rxjs": ">=7.8.2",
|
|
70
|
-
"uuid": ">=13.0.0"
|
|
71
|
-
"@actdim/dynstruct": "1.5.13",
|
|
72
|
-
"@actdim/msgmesh": "1.5.13",
|
|
73
|
-
"@actdim/utico": "1.5.13"
|
|
88
|
+
"uuid": ">=13.0.0"
|
|
74
89
|
},
|
|
75
90
|
"devDependencies": {
|
|
76
91
|
"@faker-js/faker": "^10.4.0",
|