@cratis/pi 0.0.1
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 +43 -0
- package/package.json +24 -0
- package/skills/cratis-application-react-specifications/LICENSE +2 -0
- package/skills/cratis-application-react-specifications/SKILL.md +192 -0
- package/skills/cratis-application-slice-specifications/LICENSE +2 -0
- package/skills/cratis-application-slice-specifications/SKILL.md +222 -0
- package/skills/cratis-arc-authentication-authorization-and-identity/LICENSE +2 -0
- package/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +233 -0
- package/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +140 -0
- package/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +112 -0
- package/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +102 -0
- package/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +85 -0
- package/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +87 -0
- package/skills/cratis-arc-command/LICENSE +2 -0
- package/skills/cratis-arc-command/SKILL.md +286 -0
- package/skills/cratis-arc-command/references/command-result.md +111 -0
- package/skills/cratis-arc-command/references/handler-shapes.md +135 -0
- package/skills/cratis-arc-command/references/proxy-generation.md +87 -0
- package/skills/cratis-arc-command/references/read-model-injection.md +97 -0
- package/skills/cratis-arc-command-execution/LICENSE +2 -0
- package/skills/cratis-arc-command-execution/SKILL.md +148 -0
- package/skills/cratis-arc-command-validation/LICENSE +2 -0
- package/skills/cratis-arc-command-validation/SKILL.md +230 -0
- package/skills/cratis-arc-ef-core-migration/LICENSE +2 -0
- package/skills/cratis-arc-ef-core-migration/SKILL.md +231 -0
- package/skills/cratis-arc-observable-query-http/LICENSE +2 -0
- package/skills/cratis-arc-observable-query-http/SKILL.md +157 -0
- package/skills/cratis-arc-query-paging/LICENSE +2 -0
- package/skills/cratis-arc-query-paging/SKILL.md +173 -0
- package/skills/cratis-arc-react-page/LICENSE +2 -0
- package/skills/cratis-arc-react-page/SKILL.md +291 -0
- package/skills/cratis-arc-react-page/references/data-page.md +125 -0
- package/skills/cratis-arc-react-page/references/data-tables.md +136 -0
- package/skills/cratis-arc-react-page/references/dialogs.md +238 -0
- package/skills/cratis-arc-react-page/references/mvvm.md +150 -0
- package/skills/cratis-arc-react-page/references/queries-and-commands.md +200 -0
- package/skills/cratis-chronicle-cli-operations/LICENSE +2 -0
- package/skills/cratis-chronicle-cli-operations/SKILL.md +199 -0
- package/skills/cratis-chronicle-client-dotnet/LICENSE +2 -0
- package/skills/cratis-chronicle-client-dotnet/SKILL.md +433 -0
- package/skills/cratis-chronicle-client-elixir/LICENSE +2 -0
- package/skills/cratis-chronicle-client-elixir/SKILL.md +429 -0
- package/skills/cratis-chronicle-client-kotlin/LICENSE +2 -0
- package/skills/cratis-chronicle-client-kotlin/SKILL.md +498 -0
- package/skills/cratis-chronicle-client-typescript/LICENSE +2 -0
- package/skills/cratis-chronicle-client-typescript/SKILL.md +396 -0
- package/skills/cratis-chronicle-compliance/LICENSE +2 -0
- package/skills/cratis-chronicle-compliance/SKILL.md +246 -0
- package/skills/cratis-chronicle-event-constraints/LICENSE +2 -0
- package/skills/cratis-chronicle-event-constraints/SKILL.md +227 -0
- package/skills/cratis-chronicle-event-modeling/LICENSE +2 -0
- package/skills/cratis-chronicle-event-modeling/SKILL.md +157 -0
- package/skills/cratis-chronicle-event-specifications/LICENSE +2 -0
- package/skills/cratis-chronicle-event-specifications/SKILL.md +200 -0
- package/skills/cratis-chronicle-event-type-migration/LICENSE +2 -0
- package/skills/cratis-chronicle-event-type-migration/SKILL.md +235 -0
- package/skills/cratis-chronicle-mcp-inspection/LICENSE +2 -0
- package/skills/cratis-chronicle-mcp-inspection/SKILL.md +79 -0
- package/skills/cratis-chronicle-mcp-inspection/references/blocked-tools.md +12 -0
- package/skills/cratis-chronicle-mcp-inspection/references/observational-tools.md +8 -0
- package/skills/cratis-chronicle-multi-tenancy/LICENSE +2 -0
- package/skills/cratis-chronicle-multi-tenancy/SKILL.md +198 -0
- package/skills/cratis-chronicle-projection/LICENSE +2 -0
- package/skills/cratis-chronicle-projection/SKILL.md +162 -0
- package/skills/cratis-chronicle-projection/references/fluent-builder.md +126 -0
- package/skills/cratis-chronicle-projection/references/model-bound-attributes.md +118 -0
- package/skills/cratis-chronicle-reactor/LICENSE +2 -0
- package/skills/cratis-chronicle-reactor/SKILL.md +344 -0
- package/skills/cratis-chronicle-read-model/LICENSE +2 -0
- package/skills/cratis-chronicle-read-model/SKILL.md +193 -0
- package/skills/cratis-chronicle-read-model/references/queries.md +142 -0
- package/skills/cratis-chronicle-read-model-specifications/LICENSE +2 -0
- package/skills/cratis-chronicle-read-model-specifications/SKILL.md +176 -0
- package/skills/cratis-chronicle-reducer/LICENSE +2 -0
- package/skills/cratis-chronicle-reducer/SKILL.md +173 -0
- package/skills/cratis-chronicle-web-workbench/LICENSE +2 -0
- package/skills/cratis-chronicle-web-workbench/SKILL.md +177 -0
- package/skills/cratis-cli-terminal-workbench/LICENSE +2 -0
- package/skills/cratis-cli-terminal-workbench/SKILL.md +156 -0
- package/skills/cratis-code-review/LICENSE +2 -0
- package/skills/cratis-code-review/SKILL.md +177 -0
- package/skills/cratis-components-accessibility/LICENSE +2 -0
- package/skills/cratis-components-accessibility/SKILL.md +176 -0
- package/skills/cratis-components-schema-editor/LICENSE +2 -0
- package/skills/cratis-components-schema-editor/SKILL.md +238 -0
- package/skills/cratis-components-stepper-command-dialog/LICENSE +2 -0
- package/skills/cratis-components-stepper-command-dialog/SKILL.md +209 -0
- package/skills/cratis-components-styling/LICENSE +2 -0
- package/skills/cratis-components-styling/SKILL.md +221 -0
- package/skills/cratis-components-toolbar/LICENSE +2 -0
- package/skills/cratis-components-toolbar/SKILL.md +259 -0
- package/skills/cratis-documentation-writing/LICENSE +2 -0
- package/skills/cratis-documentation-writing/SKILL.md +121 -0
- package/skills/cratis-event-model-diagram/LICENSE +2 -0
- package/skills/cratis-event-model-diagram/SKILL.md +142 -0
- package/skills/cratis-fundamentals-concept/LICENSE +2 -0
- package/skills/cratis-fundamentals-concept/SKILL.md +198 -0
- package/skills/cratis-fundamentals-type-discovery/LICENSE +2 -0
- package/skills/cratis-fundamentals-type-discovery/SKILL.md +152 -0
- package/skills/cratis-governed-release-methodology/LICENSE +2 -0
- package/skills/cratis-governed-release-methodology/SKILL.md +297 -0
- package/skills/cratis-lens-browser-extension/LICENSE +2 -0
- package/skills/cratis-lens-browser-extension/SKILL.md +239 -0
- package/skills/cratis-performance-review/LICENSE +2 -0
- package/skills/cratis-performance-review/SKILL.md +139 -0
- package/skills/cratis-screenplay-model-authoring/LICENSE +2 -0
- package/skills/cratis-screenplay-model-authoring/SKILL.md +231 -0
- package/skills/cratis-security-review/LICENSE +2 -0
- package/skills/cratis-security-review/SKILL.md +141 -0
- package/skills/cratis-specification-by-example/LICENSE +2 -0
- package/skills/cratis-specification-by-example/SKILL.md +188 -0
- package/skills/cratis-specifications-csharp/LICENSE +2 -0
- package/skills/cratis-specifications-csharp/SKILL.md +230 -0
- package/skills/cratis-specifications-csharp/references/application-scenarios.md +191 -0
- package/skills/cratis-specifications-csharp/references/csharp-patterns.md +142 -0
- package/skills/cratis-specifications-csharp/references/integration-specs.md +126 -0
- package/skills/cratis-specifications-typescript/LICENSE +2 -0
- package/skills/cratis-specifications-typescript/SKILL.md +202 -0
- package/skills/cratis-specifications-typescript/references/typescript-patterns.md +168 -0
- package/skills/cratis-stage-rendering-and-sandbox/LICENSE +2 -0
- package/skills/cratis-stage-rendering-and-sandbox/SKILL.md +230 -0
- package/skills/cratis-studio-mcp-safety-guidance/LICENSE +2 -0
- package/skills/cratis-studio-mcp-safety-guidance/SKILL.md +69 -0
- package/skills/cratis-studio-mcp-safety-guidance/references/blocked-tools.md +12 -0
- package/skills/cratis-studio-mcp-safety-guidance/references/observational-tools.md +8 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-components-toolbar
|
|
3
|
+
description: Build a canvas-style icon toolbar with the Cratis Components Toolbar family — Toolbar, ToolbarButton, ToolbarSeparator, ToolbarGroup, ToolbarSection, ToolbarContext, ToolbarFanOutItem, ToolbarFolder, and the slot components that let a distant part of the tree contribute buttons. Use when building a drawing or diagram tool palette, a zoom or mode control strip, or any icon-button group with active state, context switching, or fan-out sub-panels. Do not use for a page action menu over a data table.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Cratis Components toolbars
|
|
8
|
+
|
|
9
|
+
The `Toolbar` family builds **canvas-style tool palettes** — the pill-shaped bar
|
|
10
|
+
of icon buttons you find in a drawing or diagram editor. For a page action menu
|
|
11
|
+
over a list, use `DataPage.MenuItems` instead (see the
|
|
12
|
+
**cratis-arc-react-page** skill).
|
|
13
|
+
|
|
14
|
+
## Verified product sources
|
|
15
|
+
|
|
16
|
+
| Package | Version | Verified from |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `@cratis/components` | `3.0.0` | its package manifest and `Toolbar` component sources |
|
|
19
|
+
| `primeicons` | `^8.0.0` | peer of `@cratis/components@3.0.0` |
|
|
20
|
+
| `react` | `^19.0.0` | peer of `@cratis/components@3.0.0` |
|
|
21
|
+
|
|
22
|
+
## Import from the subpath
|
|
23
|
+
|
|
24
|
+
Every toolbar export is a flat sibling — there are **no compound members**. It
|
|
25
|
+
is `<ToolbarGroup>`, never `<Toolbar.Group>`.
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import {
|
|
29
|
+
Toolbar, ToolbarButton, ToolbarSeparator, ToolbarGroup,
|
|
30
|
+
ToolbarSection, ToolbarContext, ToolbarFanOutItem, ToolbarFolder,
|
|
31
|
+
ToolbarSlot, ToolbarSlotProvider, ToolbarLayout, useToolbarSlot,
|
|
32
|
+
} from '@cratis/components/Toolbar';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## The pieces
|
|
36
|
+
|
|
37
|
+
| Component | Purpose |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| `Toolbar` | the pill-shaped container |
|
|
40
|
+
| `ToolbarButton` | icon or text button with a tooltip and optional active state |
|
|
41
|
+
| `ToolbarSeparator` | divider between groups |
|
|
42
|
+
| `ToolbarGroup` | a sub-group inside a toolbar, optionally filled from a slot |
|
|
43
|
+
| `ToolbarSection` | animated section that morphs between named contexts |
|
|
44
|
+
| `ToolbarContext` | a named set of buttons inside a `ToolbarSection` |
|
|
45
|
+
| `ToolbarFanOutItem` | button that slides out a sub-panel of buttons |
|
|
46
|
+
| `ToolbarFolder` | button that opens a grid or list of buttons |
|
|
47
|
+
| `ToolbarSlotProvider` / `ToolbarSlot` / `useToolbarSlot` | contribute buttons from elsewhere in the tree |
|
|
48
|
+
| `ToolbarLayout` | a named region rendered from slot content |
|
|
49
|
+
|
|
50
|
+
## Step 1 — A basic toolbar
|
|
51
|
+
|
|
52
|
+
Buttons default to a vertical layout. **`title` is the required prop and it is
|
|
53
|
+
what appears in the tooltip** — there is no `tooltip` prop on `ToolbarButton`.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { Toolbar, ToolbarButton } from '@cratis/components/Toolbar';
|
|
57
|
+
|
|
58
|
+
export const DrawingToolbar = () => (
|
|
59
|
+
<Toolbar>
|
|
60
|
+
<ToolbarButton icon='pi pi-arrow-up-left' title='Select' />
|
|
61
|
+
<ToolbarButton icon='pi pi-pencil' title='Draw' />
|
|
62
|
+
<ToolbarButton icon='pi pi-stop' title='Rectangle' />
|
|
63
|
+
</Toolbar>
|
|
64
|
+
);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`icon` accepts either a PrimeIcons class string or a React node, so a custom SVG
|
|
68
|
+
component works directly: `<ToolbarButton icon={<CircleIcon />} title='Circle' />`.
|
|
69
|
+
|
|
70
|
+
## Step 2 — Active state
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
const [activeTool, setActiveTool] = useState('select');
|
|
74
|
+
|
|
75
|
+
<Toolbar>
|
|
76
|
+
<ToolbarButton icon='pi pi-pencil' title='Draw'
|
|
77
|
+
active={activeTool === 'draw'} onClick={() => setActiveTool('draw')} />
|
|
78
|
+
<ToolbarButton icon='pi pi-stop' title='Rectangle'
|
|
79
|
+
active={activeTool === 'rect'} onClick={() => setActiveTool('rect')} />
|
|
80
|
+
</Toolbar>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Step 3 — Separators and horizontal layout
|
|
84
|
+
|
|
85
|
+
Give `ToolbarSeparator` the same `orientation` as its `Toolbar`, and move
|
|
86
|
+
tooltips out of the bar's way on a horizontal toolbar:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
<Toolbar orientation='horizontal'>
|
|
90
|
+
<ToolbarButton icon='pi pi-minus' title='Zoom out' tooltipPosition='bottom' onClick={() => setZoom(z => z - 10)} />
|
|
91
|
+
<ToolbarButton text={`${zoom}%`} title='Reset zoom' tooltipPosition='bottom' onClick={() => setZoom(100)} />
|
|
92
|
+
<ToolbarButton icon='pi pi-plus' title='Zoom in' tooltipPosition='bottom' onClick={() => setZoom(z => z + 10)} />
|
|
93
|
+
<ToolbarSeparator orientation='horizontal' />
|
|
94
|
+
<ToolbarButton icon='pi pi-question-circle' title='Help' tooltipPosition='bottom' />
|
|
95
|
+
</Toolbar>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Use `text` for a button that displays a value, such as a zoom percentage.
|
|
99
|
+
|
|
100
|
+
## Step 4 — Animated context switching
|
|
101
|
+
|
|
102
|
+
`ToolbarSection` shows one `ToolbarContext` at a time. When `activeContext`
|
|
103
|
+
changes the buttons fade out, the section morphs to the new size, and the new
|
|
104
|
+
buttons fade in. Only the section transitions; buttons outside it are
|
|
105
|
+
unaffected.
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
const [mode, setMode] = useState<'drawing' | 'text'>('drawing');
|
|
109
|
+
|
|
110
|
+
<Toolbar>
|
|
111
|
+
<ToolbarButton icon='pi pi-arrow-up-left' title='Select' />
|
|
112
|
+
<ToolbarSection activeContext={mode}>
|
|
113
|
+
<ToolbarContext name='drawing'>
|
|
114
|
+
<ToolbarButton icon='pi pi-pencil' title='Draw' />
|
|
115
|
+
<ToolbarButton icon='pi pi-stop' title='Rectangle' />
|
|
116
|
+
</ToolbarContext>
|
|
117
|
+
<ToolbarContext name='text'>
|
|
118
|
+
<ToolbarButton icon='pi pi-align-left' title='Align left' />
|
|
119
|
+
<ToolbarButton icon='pi pi-align-center' title='Align center' />
|
|
120
|
+
</ToolbarContext>
|
|
121
|
+
</ToolbarSection>
|
|
122
|
+
<ToolbarButton icon='pi pi-undo' title='Undo' />
|
|
123
|
+
</Toolbar>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Step 5 — Fan-out and folders
|
|
127
|
+
|
|
128
|
+
`ToolbarFanOutItem` slides a strip of extra buttons out of its trigger. It is
|
|
129
|
+
the one component whose label prop **is** called `tooltip`, and both `icon` and
|
|
130
|
+
`tooltip` are required.
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
<ToolbarFanOutItem icon='pi pi-th-large' tooltip='Shapes' fanOutDirection='left'>
|
|
134
|
+
<ToolbarButton icon='pi pi-stop' title='Rectangle' />
|
|
135
|
+
<ToolbarButton icon='pi pi-circle' title='Circle' />
|
|
136
|
+
</ToolbarFanOutItem>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`fanOutDirection` is `'right'` (default), `'left'`, `'up'`, or `'down'` — fan
|
|
140
|
+
away from the screen edge the toolbar sits against.
|
|
141
|
+
|
|
142
|
+
`ToolbarFolder` opens a larger panel of buttons as a grid or a list:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
<ToolbarFolder icon='pi pi-th-large' title='Tools' mode='list'>
|
|
146
|
+
<ToolbarButton icon='pi pi-pencil' title='Draw' />
|
|
147
|
+
<ToolbarButton icon='pi pi-eraser' title='Erase' />
|
|
148
|
+
</ToolbarFolder>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`mode` is `'grid'` (default) or `'list'`; `maxColumns` (default `5`) applies to
|
|
152
|
+
grid mode only, and `folderDirection` is `'right'` or `'left'`.
|
|
153
|
+
|
|
154
|
+
## Step 6 — Contributing buttons from elsewhere
|
|
155
|
+
|
|
156
|
+
A slot lets a component far from the toolbar contribute buttons without prop
|
|
157
|
+
drilling. Wrap the region in `ToolbarSlotProvider`, publish content with
|
|
158
|
+
`ToolbarSlot`, and consume it either by giving a `ToolbarGroup` a `slotName` or
|
|
159
|
+
by rendering a named `ToolbarLayout`.
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
<ToolbarSlotProvider>
|
|
163
|
+
{mode === 'draw' && <ToolbarSlot slotName='tool-options' order={10}>{drawTools}</ToolbarSlot>}
|
|
164
|
+
<Toolbar>
|
|
165
|
+
<ToolbarGroup>
|
|
166
|
+
<ToolbarButton icon='pi pi-arrow-up-left' title='Select' />
|
|
167
|
+
</ToolbarGroup>
|
|
168
|
+
<ToolbarGroup slotName='tool-options' />
|
|
169
|
+
</Toolbar>
|
|
170
|
+
</ToolbarSlotProvider>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`ToolbarSlot` renders nothing where it sits; its children appear in the matching
|
|
174
|
+
consumer, ordered ascending by `order` (default `0`). `useToolbarSlot(slotName)`
|
|
175
|
+
returns the current content for a custom consumer. `ToolbarContext` also accepts
|
|
176
|
+
a `slotName`.
|
|
177
|
+
|
|
178
|
+
## Props
|
|
179
|
+
|
|
180
|
+
### `Toolbar`
|
|
181
|
+
|
|
182
|
+
| Prop | Type | Default |
|
|
183
|
+
| --- | --- | --- |
|
|
184
|
+
| `children` | `ReactNode` | required |
|
|
185
|
+
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` |
|
|
186
|
+
| `draggable` | `boolean` | `false` — makes child buttons draggable |
|
|
187
|
+
| `onItemDragStart` | `(data: unknown, event: React.DragEvent) => void` | — |
|
|
188
|
+
|
|
189
|
+
### `ToolbarButton`
|
|
190
|
+
|
|
191
|
+
| Prop | Type | Default |
|
|
192
|
+
| --- | --- | --- |
|
|
193
|
+
| `title` | `string` | **required** — the accessible name and the tooltip text |
|
|
194
|
+
| `icon` | `string \| ReactNode` | — |
|
|
195
|
+
| `text` | `string` | — |
|
|
196
|
+
| `active` | `boolean` | `false` |
|
|
197
|
+
| `onClick` | `() => void` | — |
|
|
198
|
+
| `tooltipPosition` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` |
|
|
199
|
+
| `draggable` | `boolean` | inherited from the enclosing `Toolbar` |
|
|
200
|
+
| `data` | `unknown` | payload handed to the drag handler |
|
|
201
|
+
| `onDragStart` | `(data: unknown, event: React.DragEvent<HTMLButtonElement>) => void` | — |
|
|
202
|
+
|
|
203
|
+
### `ToolbarSeparator`
|
|
204
|
+
|
|
205
|
+
`orientation`: `'vertical' \| 'horizontal'`, default `'vertical'`.
|
|
206
|
+
|
|
207
|
+
### `ToolbarGroup`
|
|
208
|
+
|
|
209
|
+
`children?: ReactNode` · `slotName?: string` · `orientation?: 'vertical' | 'horizontal'` (default `'vertical'`).
|
|
210
|
+
|
|
211
|
+
### `ToolbarSection`
|
|
212
|
+
|
|
213
|
+
`activeContext?: string` · `children: ReactNode` · `orientation?: 'vertical' | 'horizontal'` (default `'vertical'`).
|
|
214
|
+
|
|
215
|
+
### `ToolbarContext`
|
|
216
|
+
|
|
217
|
+
`name: string` (**required**) · `children: ReactNode` · `slotName?: string`.
|
|
218
|
+
Renders nothing itself — it is a marker `ToolbarSection` reads.
|
|
219
|
+
|
|
220
|
+
### `ToolbarFanOutItem`
|
|
221
|
+
|
|
222
|
+
`icon: string | ReactNode` (**required**) · `tooltip: string` (**required**) ·
|
|
223
|
+
`tooltipPosition?` (default `'right'`) ·
|
|
224
|
+
`fanOutDirection?: 'right' | 'left' | 'up' | 'down'` (default `'right'`) ·
|
|
225
|
+
`children: ReactNode`.
|
|
226
|
+
|
|
227
|
+
### `ToolbarFolder`
|
|
228
|
+
|
|
229
|
+
`icon: string | ReactNode` (**required**) · `title: string` (**required**) ·
|
|
230
|
+
`tooltipPosition?` (default `'right'`) ·
|
|
231
|
+
`folderDirection?: 'right' | 'left'` (default `'right'`) ·
|
|
232
|
+
`mode?: 'grid' | 'list'` (default `'grid'`) · `maxColumns?: number` (default `5`) ·
|
|
233
|
+
`children: ReactNode`.
|
|
234
|
+
|
|
235
|
+
### `ToolbarSlot` / `ToolbarSlotProvider` / `ToolbarLayout`
|
|
236
|
+
|
|
237
|
+
`ToolbarSlot`: `slotName: string` · `order?: number` (default `0`) · `children: ReactNode`.
|
|
238
|
+
`ToolbarSlotProvider`: `children: ReactNode`.
|
|
239
|
+
`ToolbarLayout`: `name: string` · `children?: ReactNode` (the fallback when the
|
|
240
|
+
slot is empty) · `orientation?: 'vertical' | 'horizontal'` (default `'vertical'`).
|
|
241
|
+
|
|
242
|
+
## Multiple groups
|
|
243
|
+
|
|
244
|
+
Render separate `Toolbar` instances for visually distinct bars, or use
|
|
245
|
+
`ToolbarGroup` inside one bar when the groups belong together.
|
|
246
|
+
|
|
247
|
+
## Verify
|
|
248
|
+
|
|
249
|
+
- Every import comes from `@cratis/components/Toolbar`, not the root barrel.
|
|
250
|
+
- Every `ToolbarButton` has a `title` — it is required and it is the accessible
|
|
251
|
+
name, not decoration.
|
|
252
|
+
- `ToolbarSeparator` orientation matches its `Toolbar`.
|
|
253
|
+
- Horizontal toolbars set `tooltipPosition` to `'top'` or `'bottom'`.
|
|
254
|
+
- Each `ToolbarContext` inside a `ToolbarSection` has a unique `name` and the
|
|
255
|
+
section's `activeContext` matches one of them.
|
|
256
|
+
- `ToolbarFanOutItem` and `ToolbarFolder` fan away from the nearest screen edge.
|
|
257
|
+
- Slot names match between the `ToolbarSlot` and its consumer, and both sit
|
|
258
|
+
inside the same `ToolbarSlotProvider`.
|
|
259
|
+
- Lint and the TypeScript build pass.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-documentation-writing
|
|
3
|
+
description: Write and structure documentation using the Diátaxis framework — decide whether a page is a Tutorial, a How-to guide, Reference, or Explanation, then draft it in that style with complete runnable examples. Use when creating or reworking documentation pages for a Cratis-based project, its product, or its samples. Do not use for code generation, release operations, or inventing API facts the code does not show.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Documentation writing
|
|
8
|
+
|
|
9
|
+
Documentation fails when it is written for the writer instead of the reader.
|
|
10
|
+
The [Diátaxis framework](https://diataxis.fr/) fixes that by separating
|
|
11
|
+
documentation into four types, each serving one distinct user need — and by
|
|
12
|
+
refusing to mix them. A page that teaches, instructs, describes, and explains
|
|
13
|
+
at once serves none of those needs well.
|
|
14
|
+
|
|
15
|
+
This skill is documentation-system-agnostic: it applies to a docs site, a
|
|
16
|
+
`docs/` folder in a repository, a wiki, or README files. Where a page goes and
|
|
17
|
+
how navigation is wired is your project's own convention; this skill governs
|
|
18
|
+
the *classification*, *structure*, and *prose* of what you write.
|
|
19
|
+
|
|
20
|
+
## Classify before writing
|
|
21
|
+
|
|
22
|
+
Determine which quadrant the page belongs to before drafting:
|
|
23
|
+
|
|
24
|
+
| Type | Orientation | Analogy | When to use |
|
|
25
|
+
| --- | --- | --- | --- |
|
|
26
|
+
| **Tutorial** | Learning | A lesson | Guide a newcomer step-by-step to a successful first outcome |
|
|
27
|
+
| **How-to guide** | Problem-solving | A recipe | Show an experienced user how to accomplish a specific task |
|
|
28
|
+
| **Reference** | Information | A dictionary | Describe the technical machinery — APIs, attributes, configuration |
|
|
29
|
+
| **Explanation** | Understanding | A discussion | Clarify *why* something works the way it does, trade-offs, architecture |
|
|
30
|
+
|
|
31
|
+
Rules per type:
|
|
32
|
+
|
|
33
|
+
- **Tutorial** — never explain *why*; focus on *do this, then this*. Each step
|
|
34
|
+
must produce a visible, verifiable result. The reader must succeed even
|
|
35
|
+
while not yet understanding the concepts.
|
|
36
|
+
- **How-to guide** — assume competence. State the goal, list prerequisites,
|
|
37
|
+
give the steps, done. No teaching.
|
|
38
|
+
- **Reference** — exhaustive and terse. Tables, signatures, attribute lists.
|
|
39
|
+
No narrative.
|
|
40
|
+
- **Explanation** — no steps. Discuss concepts, trade-offs, and design
|
|
41
|
+
decisions. Diagrams are welcome here.
|
|
42
|
+
|
|
43
|
+
If a request seems to need two types at once, that is two pages linked to each
|
|
44
|
+
other. If the type cannot be determined from the request, ask before writing.
|
|
45
|
+
|
|
46
|
+
## Workflow
|
|
47
|
+
|
|
48
|
+
1. **Clarify** — decide the document type, the target audience (newcomer,
|
|
49
|
+
experienced contributor, framework consumer, operator), the reader's goal,
|
|
50
|
+
and the scope: what to include *and* what to exclude.
|
|
51
|
+
2. **Propose structure** — present an outline (headings plus a one-line
|
|
52
|
+
description each) before writing full content.
|
|
53
|
+
3. **Write** — produce the full page in well-formatted Markdown, following the
|
|
54
|
+
style rules below.
|
|
55
|
+
4. **Verify** — run the completion checklist at the end of this skill.
|
|
56
|
+
|
|
57
|
+
## Writing style
|
|
58
|
+
|
|
59
|
+
The voice is **direct, practical, and opinionated** — an experienced colleague
|
|
60
|
+
explaining something to a capable developer, confident but never condescending.
|
|
61
|
+
|
|
62
|
+
- **Active voice, present tense.** "Chronicle appends the event", not "The
|
|
63
|
+
event is appended by Chronicle."
|
|
64
|
+
- **Second person.** "You configure…", not "One configures…" or "It is
|
|
65
|
+
possible to configure…".
|
|
66
|
+
- **Lead with the most important information.** Do not bury the key point
|
|
67
|
+
after three paragraphs of context.
|
|
68
|
+
- Use headings, lists, and code blocks to organize content; dense paragraphs
|
|
69
|
+
lose readers.
|
|
70
|
+
- Focus on public APIs and features, never internal implementation.
|
|
71
|
+
- Do not document third-party libraries; link to their own docs instead.
|
|
72
|
+
- **American English only**: `color` not `colour`, `behavior` not `behaviour`,
|
|
73
|
+
`organize` not `organise`, `initialize` not `initialise`.
|
|
74
|
+
|
|
75
|
+
## Code examples
|
|
76
|
+
|
|
77
|
+
Examples are where documentation credibility is won or lost.
|
|
78
|
+
|
|
79
|
+
- Every example must be **complete, correct, and runnable** — no pseudo-code,
|
|
80
|
+
no `// ...` elisions. If it cannot be shown complete, show a smaller thing
|
|
81
|
+
that can.
|
|
82
|
+
- Never copy code verbatim from a repository — APIs change under copied
|
|
83
|
+
examples. Write purpose-built examples that demonstrate the documented
|
|
84
|
+
behavior.
|
|
85
|
+
- Prefer the framework's canonical shapes. In a Cratis context that means
|
|
86
|
+
`record` types for commands, events, and read models; attributes as the
|
|
87
|
+
framework applies them; and the vertical-slice layout the project already
|
|
88
|
+
uses.
|
|
89
|
+
- Show the outcome: expected output, the state change, or the query result an
|
|
90
|
+
example produces, so the reader can verify their attempt.
|
|
91
|
+
|
|
92
|
+
## Diagrams
|
|
93
|
+
|
|
94
|
+
Use [Mermaid](https://mermaid-js.github.io/mermaid/#/) for architecture
|
|
95
|
+
(`graph TD` / `graph LR`), sequence flows (`sequenceDiagram`), and state
|
|
96
|
+
transitions (`stateDiagram-v2`). A diagram replaces a paragraph of topology
|
|
97
|
+
prose; it does not decorate one.
|
|
98
|
+
|
|
99
|
+
## Contextual awareness
|
|
100
|
+
|
|
101
|
+
- Read the existing documentation around the page you are writing first, and
|
|
102
|
+
match its tone, style, and terminology. If it is "event source" there, it is
|
|
103
|
+
"event source" everywhere.
|
|
104
|
+
- Do not copy content from existing pages unless explicitly asked; link
|
|
105
|
+
instead.
|
|
106
|
+
- Do not fabricate URLs or version numbers — link only to resources you can
|
|
107
|
+
verify exist.
|
|
108
|
+
|
|
109
|
+
## Completion checklist
|
|
110
|
+
|
|
111
|
+
A page is done when:
|
|
112
|
+
|
|
113
|
+
- The Diátaxis type is chosen deliberately and the page holds to that one
|
|
114
|
+
type, linking out to the other types instead of drifting into them.
|
|
115
|
+
- The audience and their goal were identified before writing, and the first
|
|
116
|
+
screen serves that goal.
|
|
117
|
+
- Every code example is complete, runnable, and purpose-built.
|
|
118
|
+
- Terminology is consistent with the surrounding documentation.
|
|
119
|
+
- All internal links resolve; all external links are real.
|
|
120
|
+
- Mermaid blocks are syntactically valid.
|
|
121
|
+
- The file ends with a single trailing newline.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-event-model-diagram
|
|
3
|
+
description: Create and maintain Mermaid eventmodeling diagrams for a Cratis module or feature, and keep them in sync with the code. Use when adding, renaming, moving, or deleting a module, feature, behavior, command, event, read model, automation, translation, or cross-module flow. Do not use to decide the event vocabulary or stream boundaries - settle the model first, then render it here.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Event model diagrams
|
|
8
|
+
|
|
9
|
+
Render an already-decided event model as a Mermaid `eventmodeling` diagram that
|
|
10
|
+
lives beside the code and is updated in the same change. If the event vocabulary
|
|
11
|
+
or the stream boundaries are not yet decided, model first; this skill draws a
|
|
12
|
+
chosen model, it does not choose one.
|
|
13
|
+
|
|
14
|
+
## Source authority
|
|
15
|
+
|
|
16
|
+
Diagrams use **Mermaid's native `eventmodeling` diagram type** (Mermaid v11.15
|
|
17
|
+
and later). The grammar is owned by Mermaid, and
|
|
18
|
+
<https://mermaid.js.org/syntax/eventmodeling.html> is the authority whenever this
|
|
19
|
+
file and Mermaid disagree. Confirm the Mermaid version available to the renderer
|
|
20
|
+
before relying on a construct.
|
|
21
|
+
|
|
22
|
+
The Cratis artifacts a diagram refers to are verified against `Cratis.Chronicle`
|
|
23
|
+
`16.45.2` and the Arc query and command surface it is used with.
|
|
24
|
+
|
|
25
|
+
## What an event model is
|
|
26
|
+
|
|
27
|
+
It arranges a module's commands, events, read models, and automations on a
|
|
28
|
+
left-to-right business-flow timeline, answering *"what happens in this module,
|
|
29
|
+
and in what order?"*.
|
|
30
|
+
|
|
31
|
+
One file per module or feature, alongside the code, with the diagram in a fenced
|
|
32
|
+
`mermaid` block. A system-overview file at the source root shows only
|
|
33
|
+
cross-module flows.
|
|
34
|
+
|
|
35
|
+
## Grammar cheat sheet
|
|
36
|
+
|
|
37
|
+
**Frame prefix:** `tf` (timeframe — auto-connects to the previous frame) and
|
|
38
|
+
`rf` (resetframe — breaks the chain; start each independent flow with it). `rf`
|
|
39
|
+
*replaces* `tf`; `tf N rf Name` is invalid.
|
|
40
|
+
|
|
41
|
+
**Frame:** `<prefix> <number> <type> <EntityName>`. The number is unique;
|
|
42
|
+
declaration order does not matter because frames position by reference.
|
|
43
|
+
|
|
44
|
+
| Type | Swimlane | Represents |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| `ui` | UI / Automation | the persona interacting — a persona name, never a screen name |
|
|
47
|
+
| `pcr` | UI / Automation | a reactor or automation processor |
|
|
48
|
+
| `cmd` | Command / Read Model | a command |
|
|
49
|
+
| `rmo` | Command / Read Model | a read model |
|
|
50
|
+
| `evt` | Events | an event type, using the exact self-describing type name |
|
|
51
|
+
|
|
52
|
+
**Multiple sources (`->>`).** A read model or fan-in reactor fed by several
|
|
53
|
+
frames references them by frame number:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
tf 10 rmo <ReadModelName> ->> 03 ->> 06 ->> 09
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Namespaces.** A `Module.` prefix creates a sub-swimlane. Use it for
|
|
60
|
+
cross-module entities and throughout the system overview.
|
|
61
|
+
|
|
62
|
+
**Comments.** `%% -- Section --`. A section header is a comment, never a frame.
|
|
63
|
+
|
|
64
|
+
## Behavior type to pattern
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
%% -- State change: <CommandName> --------------------
|
|
68
|
+
rf 01 ui <Persona>
|
|
69
|
+
tf 02 cmd <CommandName>
|
|
70
|
+
tf 03 evt <EntityName><PastTenseVerb>
|
|
71
|
+
|
|
72
|
+
%% -- State view: <ReadModelName> (consumed by <Persona>) --
|
|
73
|
+
rf 04 rmo <ReadModelName> ->> 03
|
|
74
|
+
tf 05 ui <Persona>
|
|
75
|
+
|
|
76
|
+
%% -- Automation: <ReactorName> (external side effect only) --
|
|
77
|
+
rf 06 evt <EntityName><PastTenseVerb>
|
|
78
|
+
tf 07 pcr <ReactorName>
|
|
79
|
+
|
|
80
|
+
%% -- Translation: <Source>.<Event> -> <Target>.<Reactor> --
|
|
81
|
+
rf 08 evt <SourceModule>.<EventName>
|
|
82
|
+
tf 09 pcr <TargetModule>.<ReactorName>
|
|
83
|
+
tf 10 evt <TargetModule>.<EventName>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- A state view's `rmo` references the event frames it projects from by number;
|
|
87
|
+
its consumer `ui` frame auto-chains after it. A passive read model has no
|
|
88
|
+
consumer UI — emit only the `rmo ... ->>` line with a `%% passive` comment.
|
|
89
|
+
- Translation flows are reactor-only: `evt` to `pcr` to `evt`, with no
|
|
90
|
+
intermediate `cmd`. If you draw a `cmd` between the `pcr` and the resulting
|
|
91
|
+
event, it is an **automation**, not a translation — reclassify it.
|
|
92
|
+
- Several consumers of one read model: declare each consumer `ui` as its own
|
|
93
|
+
`rf` frame with an explicit `->>` back to the `rmo`.
|
|
94
|
+
|
|
95
|
+
## The command rules table
|
|
96
|
+
|
|
97
|
+
Mermaid's eventmodeling grammar has no shape for validation or guards. After the
|
|
98
|
+
diagram, add a `## Command rules` section: a table with **Command**, **Rules**,
|
|
99
|
+
and **Emits / result**, summarizing validator, value-invariant, provider,
|
|
100
|
+
concurrency, and authorization rules plus no-op and diff behavior, in human
|
|
101
|
+
language. Include commands that emit no event.
|
|
102
|
+
|
|
103
|
+
## Process
|
|
104
|
+
|
|
105
|
+
1. **Discover** the behaviors by scanning the module for the artifacts that
|
|
106
|
+
define them: command records for state changes, read models without a command
|
|
107
|
+
handler for state views, `IReactor` implementations that call out of the
|
|
108
|
+
system for automations, and `IReactor` implementations that return events for
|
|
109
|
+
translations. Use the exact type names.
|
|
110
|
+
2. **Order** frames by domain causality — what must happen before what. Put state
|
|
111
|
+
views after the events they project from. Use `rf` only between independent
|
|
112
|
+
flows, never between sibling events of one flow, or the diagram becomes a
|
|
113
|
+
tall tower one event wide.
|
|
114
|
+
3. **Write** the diagram and the command-rules table.
|
|
115
|
+
4. **Verify** it renders without a syntax-error banner, then reconcile it against
|
|
116
|
+
the source: every behavior appears, classified by the marker it actually
|
|
117
|
+
contains. A clean render proves valid Mermaid, not completeness — close the
|
|
118
|
+
gaps against the code, never from memory.
|
|
119
|
+
|
|
120
|
+
## Common mistakes
|
|
121
|
+
|
|
122
|
+
- **A command that emits several events** chains them with consecutive
|
|
123
|
+
`tf ... evt ...` frames. Do not fight the auto-chain with `rf`.
|
|
124
|
+
- **The same event emitted from several commands** gets its own `tf evt` frame at
|
|
125
|
+
each emit point. Do not merge them into one.
|
|
126
|
+
- **Several consumers of one read model** — the first auto-chains; each
|
|
127
|
+
additional consumer needs an explicit `rf <n> ui <Persona> ->> <rmo-number>`.
|
|
128
|
+
- **A screen name in the `ui` lane.** The `ui` lane is the persona.
|
|
129
|
+
- **A section header written as a frame.** Section headers are `%%` comments.
|
|
130
|
+
- **A cross-module flow updated in one place.** It needs three: the overview
|
|
131
|
+
diagram, the source module's outputs, and the target module's inputs.
|
|
132
|
+
|
|
133
|
+
## Verify
|
|
134
|
+
|
|
135
|
+
- The diagram renders with no syntax-error banner.
|
|
136
|
+
- Every behavior in the module appears, with the type its code actually has.
|
|
137
|
+
- Every event frame uses the exact event type name from the source.
|
|
138
|
+
- Independent flows start with `rf`; sibling events within a flow do not.
|
|
139
|
+
- Passive read models have no consumer `ui` frame.
|
|
140
|
+
- The command-rules table covers every command, including those that emit
|
|
141
|
+
nothing.
|
|
142
|
+
- Cross-module flows are reflected in all three places.
|