@cascivo/mcp 0.1.2 → 0.1.5
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 +13 -11
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +272 -7
- package/dist/index.mjs.map +1 -1
- package/dist/registry.json +1836 -59
- package/package.json +1 -1
- package/readme.body.md +13 -11
package/dist/registry.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.0.0",
|
|
3
|
-
"generatedAt": "2026-06-
|
|
3
|
+
"generatedAt": "2026-06-23",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "accordion",
|
|
@@ -107,6 +107,147 @@
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
|
+
{
|
|
111
|
+
"name": "action-sheet",
|
|
112
|
+
"type": "component",
|
|
113
|
+
"description": "Bottom-rising sheet of discrete actions (iOS action-sheet pattern) with a Cancel button",
|
|
114
|
+
"category": "overlay",
|
|
115
|
+
"version": "0.0.0",
|
|
116
|
+
"files": [
|
|
117
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/action-sheet/action-sheet.tsx",
|
|
118
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/action-sheet/action-sheet.module.css"
|
|
119
|
+
],
|
|
120
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
121
|
+
"tags": ["overlay", "action-sheet", "menu", "mobile", "sheet"],
|
|
122
|
+
"meta": {
|
|
123
|
+
"name": "ActionSheet",
|
|
124
|
+
"description": "Bottom-rising sheet of discrete actions (iOS action-sheet pattern) with a Cancel button",
|
|
125
|
+
"category": "overlay",
|
|
126
|
+
"states": ["open", "closed"],
|
|
127
|
+
"variants": [],
|
|
128
|
+
"sizes": [],
|
|
129
|
+
"props": [
|
|
130
|
+
{
|
|
131
|
+
"name": "open",
|
|
132
|
+
"type": "boolean",
|
|
133
|
+
"required": false
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"name": "defaultOpen",
|
|
137
|
+
"type": "boolean",
|
|
138
|
+
"required": false
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"name": "onOpenChange",
|
|
142
|
+
"type": "(open: boolean) => void",
|
|
143
|
+
"required": false
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"name": "actions",
|
|
147
|
+
"type": "ActionSheetAction[]",
|
|
148
|
+
"required": true,
|
|
149
|
+
"description": "Choices, each with a label, onSelect, and optional destructive/disabled flags"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "title",
|
|
153
|
+
"type": "React.ReactNode",
|
|
154
|
+
"required": false
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "description",
|
|
158
|
+
"type": "React.ReactNode",
|
|
159
|
+
"required": false
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"name": "showCancel",
|
|
163
|
+
"type": "boolean",
|
|
164
|
+
"required": false,
|
|
165
|
+
"default": "true"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"name": "labels",
|
|
169
|
+
"type": "{ cancel?: string; label?: string }",
|
|
170
|
+
"required": false
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "className",
|
|
174
|
+
"type": "string",
|
|
175
|
+
"required": false
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"tokens": [
|
|
179
|
+
"--cascivo-color-surface",
|
|
180
|
+
"--cascivo-color-border",
|
|
181
|
+
"--cascivo-color-accent",
|
|
182
|
+
"--cascivo-color-destructive",
|
|
183
|
+
"--cascivo-color-text",
|
|
184
|
+
"--cascivo-color-text-subtle",
|
|
185
|
+
"--cascivo-color-text-muted",
|
|
186
|
+
"--cascivo-radius-overlay",
|
|
187
|
+
"--cascivo-shadow-overlay",
|
|
188
|
+
"--cascivo-motion-enter",
|
|
189
|
+
"--cascivo-motion-exit",
|
|
190
|
+
"--cascivo-z-overlay"
|
|
191
|
+
],
|
|
192
|
+
"accessibility": {
|
|
193
|
+
"role": "menu",
|
|
194
|
+
"wcag": "2.2-AA",
|
|
195
|
+
"keyboard": ["ArrowUp", "ArrowDown", "Home", "End", "Enter", "Space", "Escape"]
|
|
196
|
+
},
|
|
197
|
+
"examples": [],
|
|
198
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
199
|
+
"tags": ["overlay", "action-sheet", "menu", "mobile", "sheet"],
|
|
200
|
+
"intent": {
|
|
201
|
+
"whenToUse": [
|
|
202
|
+
"A short list of discrete actions on a touch surface, rising from the bottom",
|
|
203
|
+
"Confirming or choosing among a few operations (e.g. Share, Edit, Delete) on mobile",
|
|
204
|
+
"A mobile-first alternative to an anchored dropdown menu when there is no trigger anchor"
|
|
205
|
+
],
|
|
206
|
+
"whenNotToUse": [
|
|
207
|
+
"A single yes/no confirmation — use AlertDialog",
|
|
208
|
+
"A form or scrollable content — use BottomSheet or Sheet",
|
|
209
|
+
"A menu anchored to a trigger on desktop — use Menu or Dropdown"
|
|
210
|
+
],
|
|
211
|
+
"antiPatterns": [
|
|
212
|
+
{
|
|
213
|
+
"bad": "<ActionSheet actions={[{ label: \"OK\", onSelect }]} />",
|
|
214
|
+
"good": "<AlertDialog title=\"Delete item?\" />",
|
|
215
|
+
"why": "A one-action sheet is a confirmation; AlertDialog states the decision clearly"
|
|
216
|
+
}
|
|
217
|
+
],
|
|
218
|
+
"related": [
|
|
219
|
+
{
|
|
220
|
+
"name": "BottomSheet",
|
|
221
|
+
"relationship": "alternative",
|
|
222
|
+
"reason": "Use BottomSheet for rich/resizable content; ActionSheet is a fixed list of actions"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"name": "Menu",
|
|
226
|
+
"relationship": "alternative",
|
|
227
|
+
"reason": "Use Menu for a trigger-anchored dropdown on pointer-first surfaces"
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
"a11yRationale": "Renders role=\"menu\" with role=\"menuitem\" buttons under vertical roving focus (Arrow keys, Home/End, wrapping). The title labels the menu via aria-labelledby (or a built-in label otherwise) and the description via aria-describedby. FocusScope traps and restores focus; DismissableLayer handles Escape and outside-pointer dismissal; a separate Cancel button provides an explicit non-destructive exit.",
|
|
231
|
+
"flexibility": [
|
|
232
|
+
{
|
|
233
|
+
"area": "actions",
|
|
234
|
+
"level": "flexible",
|
|
235
|
+
"note": "Any number of actions; each may be destructive or disabled"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"area": "open state",
|
|
239
|
+
"level": "flexible",
|
|
240
|
+
"note": "Controlled (open/onOpenChange) or uncontrolled (defaultOpen)"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"area": "cancel",
|
|
244
|
+
"level": "flexible",
|
|
245
|
+
"note": "showCancel toggles the separate Cancel button (Escape/outside press still dismiss)"
|
|
246
|
+
}
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
},
|
|
110
251
|
{
|
|
111
252
|
"name": "alert",
|
|
112
253
|
"type": "component",
|
|
@@ -1018,6 +1159,159 @@
|
|
|
1018
1159
|
}
|
|
1019
1160
|
}
|
|
1020
1161
|
},
|
|
1162
|
+
{
|
|
1163
|
+
"name": "bottom-sheet",
|
|
1164
|
+
"type": "component",
|
|
1165
|
+
"description": "Mobile bottom sheet with drag-to-resize detents, velocity-projected snapping, and drag-to-dismiss",
|
|
1166
|
+
"category": "overlay",
|
|
1167
|
+
"version": "0.0.0",
|
|
1168
|
+
"files": [
|
|
1169
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/bottom-sheet/bottom-sheet.tsx",
|
|
1170
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/bottom-sheet/bottom-sheet.module.css"
|
|
1171
|
+
],
|
|
1172
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
1173
|
+
"tags": ["overlay", "sheet", "bottom-sheet", "mobile", "drag", "detent", "gesture"],
|
|
1174
|
+
"meta": {
|
|
1175
|
+
"name": "BottomSheet",
|
|
1176
|
+
"description": "Mobile bottom sheet with drag-to-resize detents, velocity-projected snapping, and drag-to-dismiss",
|
|
1177
|
+
"category": "overlay",
|
|
1178
|
+
"states": ["open", "closed", "dragging"],
|
|
1179
|
+
"variants": [],
|
|
1180
|
+
"sizes": [],
|
|
1181
|
+
"props": [
|
|
1182
|
+
{
|
|
1183
|
+
"name": "open",
|
|
1184
|
+
"type": "boolean",
|
|
1185
|
+
"required": false
|
|
1186
|
+
},
|
|
1187
|
+
{
|
|
1188
|
+
"name": "defaultOpen",
|
|
1189
|
+
"type": "boolean",
|
|
1190
|
+
"required": false
|
|
1191
|
+
},
|
|
1192
|
+
{
|
|
1193
|
+
"name": "onOpenChange",
|
|
1194
|
+
"type": "(open: boolean) => void",
|
|
1195
|
+
"required": false
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
"name": "snapPoints",
|
|
1199
|
+
"type": "number[]",
|
|
1200
|
+
"required": false,
|
|
1201
|
+
"default": "[0.5, 0.92]",
|
|
1202
|
+
"description": "Detent heights as ascending fractions of the viewport (0–1)"
|
|
1203
|
+
},
|
|
1204
|
+
{
|
|
1205
|
+
"name": "activeSnap",
|
|
1206
|
+
"type": "number",
|
|
1207
|
+
"required": false
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
"name": "defaultSnap",
|
|
1211
|
+
"type": "number",
|
|
1212
|
+
"required": false,
|
|
1213
|
+
"default": "0"
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
"name": "onSnapChange",
|
|
1217
|
+
"type": "(index: number) => void",
|
|
1218
|
+
"required": false
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
"name": "title",
|
|
1222
|
+
"type": "React.ReactNode",
|
|
1223
|
+
"required": false
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
"name": "description",
|
|
1227
|
+
"type": "React.ReactNode",
|
|
1228
|
+
"required": false
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
"name": "children",
|
|
1232
|
+
"type": "React.ReactNode",
|
|
1233
|
+
"required": false
|
|
1234
|
+
},
|
|
1235
|
+
{
|
|
1236
|
+
"name": "labels",
|
|
1237
|
+
"type": "{ close?: string; handle?: string }",
|
|
1238
|
+
"required": false
|
|
1239
|
+
},
|
|
1240
|
+
{
|
|
1241
|
+
"name": "className",
|
|
1242
|
+
"type": "string",
|
|
1243
|
+
"required": false
|
|
1244
|
+
}
|
|
1245
|
+
],
|
|
1246
|
+
"tokens": [
|
|
1247
|
+
"--cascivo-color-surface",
|
|
1248
|
+
"--cascivo-color-border",
|
|
1249
|
+
"--cascivo-radius-overlay",
|
|
1250
|
+
"--cascivo-shadow-overlay",
|
|
1251
|
+
"--cascivo-motion-enter",
|
|
1252
|
+
"--cascivo-motion-exit",
|
|
1253
|
+
"--cascivo-target-min-coarse",
|
|
1254
|
+
"--cascivo-z-overlay"
|
|
1255
|
+
],
|
|
1256
|
+
"accessibility": {
|
|
1257
|
+
"role": "dialog",
|
|
1258
|
+
"wcag": "2.2-AA",
|
|
1259
|
+
"keyboard": ["Escape", "Tab", "Shift+Tab"]
|
|
1260
|
+
},
|
|
1261
|
+
"examples": [],
|
|
1262
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
1263
|
+
"tags": ["overlay", "sheet", "bottom-sheet", "mobile", "drag", "detent", "gesture"],
|
|
1264
|
+
"intent": {
|
|
1265
|
+
"whenToUse": [
|
|
1266
|
+
"A mobile surface that rises from the bottom and can be resized between detents by dragging",
|
|
1267
|
+
"Showing secondary content, filters, or a form where the user can peek at half height then expand",
|
|
1268
|
+
"A touch-first overlay that dismisses by flinging or dragging it down past the lowest detent"
|
|
1269
|
+
],
|
|
1270
|
+
"whenNotToUse": [
|
|
1271
|
+
"A short yes/no confirmation — use AlertDialog",
|
|
1272
|
+
"A non-resizable edge panel without gestures — use Drawer or Sheet",
|
|
1273
|
+
"A desktop-first side panel for navigation — use Drawer"
|
|
1274
|
+
],
|
|
1275
|
+
"antiPatterns": [
|
|
1276
|
+
{
|
|
1277
|
+
"bad": "<BottomSheet title=\"Delete item?\">Are you sure?</BottomSheet>",
|
|
1278
|
+
"good": "<AlertDialog title=\"Delete item?\" />",
|
|
1279
|
+
"why": "A resizable gesture surface is overkill for a focused yes/no decision"
|
|
1280
|
+
}
|
|
1281
|
+
],
|
|
1282
|
+
"related": [
|
|
1283
|
+
{
|
|
1284
|
+
"name": "Sheet",
|
|
1285
|
+
"relationship": "alternative",
|
|
1286
|
+
"reason": "Use Sheet for a fixed-height panel from any edge; BottomSheet adds resize detents"
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
"name": "Drawer",
|
|
1290
|
+
"relationship": "alternative",
|
|
1291
|
+
"reason": "Use Drawer for a plain edge dialog without resize detents"
|
|
1292
|
+
}
|
|
1293
|
+
],
|
|
1294
|
+
"a11yRationale": "Renders role=\"dialog\" with aria-modal; the title labels it via aria-labelledby and the description via aria-describedby. FocusScope traps Tab focus and restores it on close; DismissableLayer handles Escape and outside-pointer dismissal. The grab handle is a labelled separator and a Close button gives a non-gesture dismissal path so the sheet stays keyboard-operable.",
|
|
1295
|
+
"flexibility": [
|
|
1296
|
+
{
|
|
1297
|
+
"area": "snapPoints",
|
|
1298
|
+
"level": "flexible",
|
|
1299
|
+
"note": "Any ascending list of viewport fractions; the sheet snaps between them"
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
"area": "open state",
|
|
1303
|
+
"level": "flexible",
|
|
1304
|
+
"note": "Controlled (open/onOpenChange) or uncontrolled (defaultOpen)"
|
|
1305
|
+
},
|
|
1306
|
+
{
|
|
1307
|
+
"area": "active detent",
|
|
1308
|
+
"level": "flexible",
|
|
1309
|
+
"note": "Controlled (activeSnap/onSnapChange) or uncontrolled (defaultSnap)"
|
|
1310
|
+
}
|
|
1311
|
+
]
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
},
|
|
1021
1315
|
{
|
|
1022
1316
|
"name": "breadcrumb",
|
|
1023
1317
|
"type": "component",
|
|
@@ -4741,38 +5035,180 @@
|
|
|
4741
5035
|
}
|
|
4742
5036
|
},
|
|
4743
5037
|
{
|
|
4744
|
-
"name": "
|
|
5038
|
+
"name": "fab",
|
|
4745
5039
|
"type": "component",
|
|
4746
|
-
"description": "
|
|
5040
|
+
"description": "Floating action button anchored to a screen corner, with an optional speed-dial of secondary actions",
|
|
4747
5041
|
"category": "inputs",
|
|
4748
5042
|
"version": "0.0.0",
|
|
4749
5043
|
"files": [
|
|
4750
|
-
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/
|
|
4751
|
-
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/
|
|
5044
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/fab/fab.tsx",
|
|
5045
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/fab/fab.module.css"
|
|
4752
5046
|
],
|
|
4753
5047
|
"dependencies": ["@cascivo/core"],
|
|
4754
|
-
"tags": ["
|
|
5048
|
+
"tags": ["inputs", "fab", "floating-action-button", "mobile", "speed-dial"],
|
|
4755
5049
|
"meta": {
|
|
4756
|
-
"name": "
|
|
4757
|
-
"description": "
|
|
5050
|
+
"name": "Fab",
|
|
5051
|
+
"description": "Floating action button anchored to a screen corner, with an optional speed-dial of secondary actions",
|
|
4758
5052
|
"category": "inputs",
|
|
4759
|
-
"states": ["default", "
|
|
5053
|
+
"states": ["default", "open", "closed"],
|
|
4760
5054
|
"variants": [],
|
|
4761
5055
|
"sizes": [],
|
|
4762
5056
|
"props": [
|
|
5057
|
+
{
|
|
5058
|
+
"name": "children",
|
|
5059
|
+
"type": "React.ReactNode",
|
|
5060
|
+
"required": true,
|
|
5061
|
+
"description": "The main icon"
|
|
5062
|
+
},
|
|
4763
5063
|
{
|
|
4764
5064
|
"name": "label",
|
|
4765
|
-
"type": "
|
|
4766
|
-
"required":
|
|
5065
|
+
"type": "string",
|
|
5066
|
+
"required": true,
|
|
5067
|
+
"description": "Accessible name for the button"
|
|
4767
5068
|
},
|
|
4768
5069
|
{
|
|
4769
|
-
"name": "
|
|
4770
|
-
"type": "
|
|
5070
|
+
"name": "onClick",
|
|
5071
|
+
"type": "() => void",
|
|
4771
5072
|
"required": false
|
|
4772
5073
|
},
|
|
4773
5074
|
{
|
|
4774
|
-
"name": "
|
|
4775
|
-
"type": "
|
|
5075
|
+
"name": "actions",
|
|
5076
|
+
"type": "FabAction[]",
|
|
5077
|
+
"required": false,
|
|
5078
|
+
"description": "Speed-dial actions; each has a label, icon, onSelect, and optional disabled"
|
|
5079
|
+
},
|
|
5080
|
+
{
|
|
5081
|
+
"name": "position",
|
|
5082
|
+
"type": "'bottom-end' | 'bottom-start'",
|
|
5083
|
+
"required": false,
|
|
5084
|
+
"default": "bottom-end"
|
|
5085
|
+
},
|
|
5086
|
+
{
|
|
5087
|
+
"name": "open",
|
|
5088
|
+
"type": "boolean",
|
|
5089
|
+
"required": false
|
|
5090
|
+
},
|
|
5091
|
+
{
|
|
5092
|
+
"name": "defaultOpen",
|
|
5093
|
+
"type": "boolean",
|
|
5094
|
+
"required": false
|
|
5095
|
+
},
|
|
5096
|
+
{
|
|
5097
|
+
"name": "onOpenChange",
|
|
5098
|
+
"type": "(open: boolean) => void",
|
|
5099
|
+
"required": false
|
|
5100
|
+
},
|
|
5101
|
+
{
|
|
5102
|
+
"name": "className",
|
|
5103
|
+
"type": "string",
|
|
5104
|
+
"required": false
|
|
5105
|
+
}
|
|
5106
|
+
],
|
|
5107
|
+
"tokens": [
|
|
5108
|
+
"--cascivo-color-accent",
|
|
5109
|
+
"--cascivo-color-accent-content",
|
|
5110
|
+
"--cascivo-color-accent-hover",
|
|
5111
|
+
"--cascivo-color-surface",
|
|
5112
|
+
"--cascivo-color-border",
|
|
5113
|
+
"--cascivo-radius-full",
|
|
5114
|
+
"--cascivo-shadow-overlay",
|
|
5115
|
+
"--cascivo-target-min-coarse",
|
|
5116
|
+
"--cascivo-motion-enter",
|
|
5117
|
+
"--cascivo-motion-exit",
|
|
5118
|
+
"--cascivo-z-dropdown"
|
|
5119
|
+
],
|
|
5120
|
+
"accessibility": {
|
|
5121
|
+
"role": "button",
|
|
5122
|
+
"wcag": "2.2-AA",
|
|
5123
|
+
"keyboard": ["Enter", "Space", "ArrowUp", "ArrowDown", "Home", "End", "Escape"]
|
|
5124
|
+
},
|
|
5125
|
+
"examples": [],
|
|
5126
|
+
"dependencies": ["@cascivo/core"],
|
|
5127
|
+
"tags": ["inputs", "fab", "floating-action-button", "mobile", "speed-dial"],
|
|
5128
|
+
"intent": {
|
|
5129
|
+
"whenToUse": [
|
|
5130
|
+
"A single, high-emphasis primary action that floats above scrolling content (e.g. Compose, Add)",
|
|
5131
|
+
"A small cluster of related create actions revealed from one corner via a speed-dial",
|
|
5132
|
+
"Touch-first screens where the primary action should stay reachable at the thumb"
|
|
5133
|
+
],
|
|
5134
|
+
"whenNotToUse": [
|
|
5135
|
+
"Ordinary form or toolbar buttons — use Button or IconButton in the layout flow",
|
|
5136
|
+
"More than a handful of actions — use a Menu, Drawer, or full navigation",
|
|
5137
|
+
"Primary navigation between top-level destinations — use Dock"
|
|
5138
|
+
],
|
|
5139
|
+
"antiPatterns": [
|
|
5140
|
+
{
|
|
5141
|
+
"bad": "<Fab label=\"Save\"><SaveIcon /></Fab> next to a form submit button",
|
|
5142
|
+
"good": "<Button type=\"submit\">Save</Button>",
|
|
5143
|
+
"why": "A floating button competes with the in-flow submit and hides the action off the form"
|
|
5144
|
+
}
|
|
5145
|
+
],
|
|
5146
|
+
"related": [
|
|
5147
|
+
{
|
|
5148
|
+
"name": "IconButton",
|
|
5149
|
+
"relationship": "alternative",
|
|
5150
|
+
"reason": "Use IconButton for an in-flow icon control; Fab floats and is high-emphasis"
|
|
5151
|
+
},
|
|
5152
|
+
{
|
|
5153
|
+
"name": "Dock",
|
|
5154
|
+
"relationship": "alternative",
|
|
5155
|
+
"reason": "Use Dock for bottom navigation between destinations rather than a single action"
|
|
5156
|
+
}
|
|
5157
|
+
],
|
|
5158
|
+
"a11yRationale": "The main button is icon-only and requires a `label` that becomes its aria-label. With a speed-dial it exposes aria-haspopup=\"menu\", aria-expanded, and aria-controls; the dial is a role=\"menu\" of role=\"menuitem\" buttons under vertical roving focus (Arrow keys, Home/End, wrapping). Opening moves focus to the first action and closing (Escape, outside press, or selection via DismissableLayer) returns focus to the button.",
|
|
5159
|
+
"flexibility": [
|
|
5160
|
+
{
|
|
5161
|
+
"area": "actions",
|
|
5162
|
+
"level": "flexible",
|
|
5163
|
+
"note": "Omit for a single-action button, or provide a speed-dial of secondary actions"
|
|
5164
|
+
},
|
|
5165
|
+
{
|
|
5166
|
+
"area": "position",
|
|
5167
|
+
"level": "strict",
|
|
5168
|
+
"note": "Anchored to bottom-end or bottom-start; honours safe-area insets"
|
|
5169
|
+
},
|
|
5170
|
+
{
|
|
5171
|
+
"area": "open state",
|
|
5172
|
+
"level": "flexible",
|
|
5173
|
+
"note": "Speed-dial is controlled (open/onOpenChange) or uncontrolled (defaultOpen)"
|
|
5174
|
+
}
|
|
5175
|
+
]
|
|
5176
|
+
}
|
|
5177
|
+
}
|
|
5178
|
+
},
|
|
5179
|
+
{
|
|
5180
|
+
"name": "field",
|
|
5181
|
+
"type": "component",
|
|
5182
|
+
"description": "Form-field wrapper composing label, control, description, and error",
|
|
5183
|
+
"category": "inputs",
|
|
5184
|
+
"version": "0.0.0",
|
|
5185
|
+
"files": [
|
|
5186
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/field/field.tsx",
|
|
5187
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/field/field.module.css"
|
|
5188
|
+
],
|
|
5189
|
+
"dependencies": ["@cascivo/core"],
|
|
5190
|
+
"tags": ["form", "layout", "validation", "accessibility"],
|
|
5191
|
+
"meta": {
|
|
5192
|
+
"name": "Field",
|
|
5193
|
+
"description": "Form-field wrapper composing label, control, description, and error",
|
|
5194
|
+
"category": "inputs",
|
|
5195
|
+
"states": ["default", "disabled", "invalid"],
|
|
5196
|
+
"variants": [],
|
|
5197
|
+
"sizes": [],
|
|
5198
|
+
"props": [
|
|
5199
|
+
{
|
|
5200
|
+
"name": "label",
|
|
5201
|
+
"type": "ReactNode",
|
|
5202
|
+
"required": false
|
|
5203
|
+
},
|
|
5204
|
+
{
|
|
5205
|
+
"name": "description",
|
|
5206
|
+
"type": "ReactNode",
|
|
5207
|
+
"required": false
|
|
5208
|
+
},
|
|
5209
|
+
{
|
|
5210
|
+
"name": "error",
|
|
5211
|
+
"type": "ReactNode",
|
|
4776
5212
|
"required": false
|
|
4777
5213
|
},
|
|
4778
5214
|
{
|
|
@@ -9577,6 +10013,114 @@
|
|
|
9577
10013
|
}
|
|
9578
10014
|
}
|
|
9579
10015
|
},
|
|
10016
|
+
{
|
|
10017
|
+
"name": "pull-to-refresh",
|
|
10018
|
+
"type": "component",
|
|
10019
|
+
"description": "Wraps a scrollable region and triggers a refresh when pulled down past a threshold at the top",
|
|
10020
|
+
"category": "feedback",
|
|
10021
|
+
"version": "0.0.0",
|
|
10022
|
+
"files": [
|
|
10023
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/pull-to-refresh/pull-to-refresh.tsx",
|
|
10024
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/pull-to-refresh/pull-to-refresh.module.css"
|
|
10025
|
+
],
|
|
10026
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
10027
|
+
"tags": ["feedback", "pull-to-refresh", "mobile", "gesture", "scroll", "refresh"],
|
|
10028
|
+
"meta": {
|
|
10029
|
+
"name": "PullToRefresh",
|
|
10030
|
+
"description": "Wraps a scrollable region and triggers a refresh when pulled down past a threshold at the top",
|
|
10031
|
+
"category": "feedback",
|
|
10032
|
+
"states": ["idle", "pulling", "ready", "refreshing"],
|
|
10033
|
+
"variants": [],
|
|
10034
|
+
"sizes": [],
|
|
10035
|
+
"props": [
|
|
10036
|
+
{
|
|
10037
|
+
"name": "onRefresh",
|
|
10038
|
+
"type": "() => Promise<unknown> | unknown",
|
|
10039
|
+
"required": true,
|
|
10040
|
+
"description": "Called when the pull passes the threshold; the spinner shows until it settles"
|
|
10041
|
+
},
|
|
10042
|
+
{
|
|
10043
|
+
"name": "children",
|
|
10044
|
+
"type": "React.ReactNode",
|
|
10045
|
+
"required": true
|
|
10046
|
+
},
|
|
10047
|
+
{
|
|
10048
|
+
"name": "threshold",
|
|
10049
|
+
"type": "number",
|
|
10050
|
+
"required": false,
|
|
10051
|
+
"default": "64"
|
|
10052
|
+
},
|
|
10053
|
+
{
|
|
10054
|
+
"name": "disabled",
|
|
10055
|
+
"type": "boolean",
|
|
10056
|
+
"required": false
|
|
10057
|
+
},
|
|
10058
|
+
{
|
|
10059
|
+
"name": "labels",
|
|
10060
|
+
"type": "{ pull?: string; release?: string; refreshing?: string }",
|
|
10061
|
+
"required": false
|
|
10062
|
+
},
|
|
10063
|
+
{
|
|
10064
|
+
"name": "className",
|
|
10065
|
+
"type": "string",
|
|
10066
|
+
"required": false
|
|
10067
|
+
}
|
|
10068
|
+
],
|
|
10069
|
+
"tokens": ["--cascivo-color-text-muted", "--cascivo-motion-enter"],
|
|
10070
|
+
"accessibility": {
|
|
10071
|
+
"role": "status",
|
|
10072
|
+
"wcag": "2.2-AA",
|
|
10073
|
+
"keyboard": []
|
|
10074
|
+
},
|
|
10075
|
+
"examples": [],
|
|
10076
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
10077
|
+
"tags": ["feedback", "pull-to-refresh", "mobile", "gesture", "scroll", "refresh"],
|
|
10078
|
+
"intent": {
|
|
10079
|
+
"whenToUse": [
|
|
10080
|
+
"A scrollable list or feed on touch devices that the user refreshes by pulling down from the top",
|
|
10081
|
+
"Mobile screens where a dedicated refresh button would be redundant or out of reach",
|
|
10082
|
+
"Content that updates on demand and benefits from a familiar pull gesture"
|
|
10083
|
+
],
|
|
10084
|
+
"whenNotToUse": [
|
|
10085
|
+
"Desktop, pointer-first surfaces — provide an explicit Refresh button",
|
|
10086
|
+
"Content that auto-refreshes or paginates on scroll — use infinite scroll instead",
|
|
10087
|
+
"Regions that are not the primary scroll container of the screen"
|
|
10088
|
+
],
|
|
10089
|
+
"antiPatterns": [
|
|
10090
|
+
{
|
|
10091
|
+
"bad": "Wrapping a non-scrolling element and relying on pull as the only refresh path",
|
|
10092
|
+
"good": "Wrap the scroll container and also expose a Refresh control for non-touch users",
|
|
10093
|
+
"why": "Pull-to-refresh is touch-only; keyboard and pointer users need an explicit control"
|
|
10094
|
+
}
|
|
10095
|
+
],
|
|
10096
|
+
"related": [
|
|
10097
|
+
{
|
|
10098
|
+
"name": "Spinner",
|
|
10099
|
+
"relationship": "contains",
|
|
10100
|
+
"reason": "Shows the Spinner while the refresh promise settles"
|
|
10101
|
+
},
|
|
10102
|
+
{
|
|
10103
|
+
"name": "ScrollArea",
|
|
10104
|
+
"relationship": "pairs-with",
|
|
10105
|
+
"reason": "Wraps a scrollable region; pair with the app’s scroll container"
|
|
10106
|
+
}
|
|
10107
|
+
],
|
|
10108
|
+
"a11yRationale": "The gesture is a touch-only enhancement: it arms only at scrollTop 0 and uses touch-action/overscroll containment so normal scrolling and keyboard use are unaffected. A polite aria-live status region announces the pull, release, and refreshing states (strings from the i18n catalog), and the Spinner exposes role=\"status\" while loading. Because pull-to-refresh cannot be performed without a pointer, apps should also offer an explicit refresh control for keyboard users.",
|
|
10109
|
+
"flexibility": [
|
|
10110
|
+
{
|
|
10111
|
+
"area": "threshold",
|
|
10112
|
+
"level": "flexible",
|
|
10113
|
+
"note": "Pull distance required to trigger is configurable (default 64px)"
|
|
10114
|
+
},
|
|
10115
|
+
{
|
|
10116
|
+
"area": "onRefresh",
|
|
10117
|
+
"level": "flexible",
|
|
10118
|
+
"note": "May return a promise; the spinner persists until it settles"
|
|
10119
|
+
}
|
|
10120
|
+
]
|
|
10121
|
+
}
|
|
10122
|
+
}
|
|
10123
|
+
},
|
|
9580
10124
|
{
|
|
9581
10125
|
"name": "qr-code",
|
|
9582
10126
|
"type": "component",
|
|
@@ -11338,7 +11882,7 @@
|
|
|
11338
11882
|
"name": "items",
|
|
11339
11883
|
"type": "SideNavItem[]",
|
|
11340
11884
|
"required": true,
|
|
11341
|
-
"description": "{ label, href?, icon?, active?, items? } —
|
|
11885
|
+
"description": "{ label, href?, icon?, active?, items?, onClick?, disabled?, tone?, trailing?, render? } — an onClick-only item renders a focusable <button>; nested items render expandable menus (links, action sub-items with onSelect/selected, separators, labels); render() is an alignment-preserving escape hatch"
|
|
11342
11886
|
},
|
|
11343
11887
|
{
|
|
11344
11888
|
"name": "collapsed",
|
|
@@ -11382,6 +11926,12 @@
|
|
|
11382
11926
|
"default": "false",
|
|
11383
11927
|
"description": "Widens the rail as an overlay on hover/focus-within; suppresses tooltips/flyouts"
|
|
11384
11928
|
},
|
|
11929
|
+
{
|
|
11930
|
+
"name": "header",
|
|
11931
|
+
"type": "ReactNode",
|
|
11932
|
+
"required": false,
|
|
11933
|
+
"description": "Content rendered above the items, inside the item padding context (e.g. app-context pickers)"
|
|
11934
|
+
},
|
|
11385
11935
|
{
|
|
11386
11936
|
"name": "footer",
|
|
11387
11937
|
"type": "ReactNode",
|
|
@@ -11405,6 +11955,9 @@
|
|
|
11405
11955
|
"--cascivo-color-bg-subtle",
|
|
11406
11956
|
"--cascivo-color-accent",
|
|
11407
11957
|
"--cascivo-color-accent-subtle",
|
|
11958
|
+
"--cascivo-color-destructive",
|
|
11959
|
+
"--cascivo-color-warning",
|
|
11960
|
+
"--cascivo-color-success",
|
|
11408
11961
|
"--cascivo-focus-ring",
|
|
11409
11962
|
"--cascivo-motion-enter",
|
|
11410
11963
|
"--cascivo-motion-exit",
|
|
@@ -12650,36 +13203,42 @@
|
|
|
12650
13203
|
}
|
|
12651
13204
|
},
|
|
12652
13205
|
{
|
|
12653
|
-
"name": "
|
|
13206
|
+
"name": "swipe-item",
|
|
12654
13207
|
"type": "component",
|
|
12655
|
-
"description": "
|
|
12656
|
-
"category": "
|
|
13208
|
+
"description": "List row whose leading/trailing actions are revealed by a horizontal swipe, with keyboard parity",
|
|
13209
|
+
"category": "display",
|
|
12657
13210
|
"version": "0.0.0",
|
|
12658
13211
|
"files": [
|
|
12659
|
-
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/
|
|
12660
|
-
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/
|
|
13212
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/swipe-item/swipe-item.tsx",
|
|
13213
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/swipe-item/swipe-item.module.css"
|
|
12661
13214
|
],
|
|
12662
|
-
"dependencies": ["@cascivo/core"
|
|
12663
|
-
"tags": ["
|
|
13215
|
+
"dependencies": ["@cascivo/core"],
|
|
13216
|
+
"tags": ["display", "swipe", "list", "mobile", "gesture", "actions"],
|
|
12664
13217
|
"meta": {
|
|
12665
|
-
"name": "
|
|
12666
|
-
"description": "
|
|
12667
|
-
"category": "
|
|
12668
|
-
"states": ["
|
|
13218
|
+
"name": "SwipeItem",
|
|
13219
|
+
"description": "List row whose leading/trailing actions are revealed by a horizontal swipe, with keyboard parity",
|
|
13220
|
+
"category": "display",
|
|
13221
|
+
"states": ["closed", "leading", "trailing"],
|
|
12669
13222
|
"variants": [],
|
|
12670
13223
|
"sizes": [],
|
|
12671
13224
|
"props": [
|
|
12672
13225
|
{
|
|
12673
|
-
"name": "
|
|
12674
|
-
"type": "
|
|
13226
|
+
"name": "children",
|
|
13227
|
+
"type": "React.ReactNode",
|
|
12675
13228
|
"required": true,
|
|
12676
|
-
"description": "
|
|
13229
|
+
"description": "The row content"
|
|
12677
13230
|
},
|
|
12678
13231
|
{
|
|
12679
|
-
"name": "
|
|
12680
|
-
"type": "
|
|
13232
|
+
"name": "leadingActions",
|
|
13233
|
+
"type": "SwipeAction[]",
|
|
12681
13234
|
"required": false,
|
|
12682
|
-
"
|
|
13235
|
+
"description": "Actions revealed by dragging toward the end edge (shown on the start edge)"
|
|
13236
|
+
},
|
|
13237
|
+
{
|
|
13238
|
+
"name": "trailingActions",
|
|
13239
|
+
"type": "SwipeAction[]",
|
|
13240
|
+
"required": false,
|
|
13241
|
+
"description": "Actions revealed by dragging toward the start edge (shown on the end edge)"
|
|
12683
13242
|
},
|
|
12684
13243
|
{
|
|
12685
13244
|
"name": "className",
|
|
@@ -12688,48 +13247,149 @@
|
|
|
12688
13247
|
}
|
|
12689
13248
|
],
|
|
12690
13249
|
"tokens": [
|
|
12691
|
-
"--cascivo-color-
|
|
12692
|
-
"--cascivo-color-bg-subtle",
|
|
13250
|
+
"--cascivo-color-surface",
|
|
12693
13251
|
"--cascivo-color-accent",
|
|
12694
|
-
"--cascivo-color-accent-
|
|
12695
|
-
"--cascivo-color-
|
|
12696
|
-
"--cascivo-
|
|
13252
|
+
"--cascivo-color-accent-content",
|
|
13253
|
+
"--cascivo-color-destructive",
|
|
13254
|
+
"--cascivo-color-text-on-destructive",
|
|
13255
|
+
"--cascivo-target-min-coarse",
|
|
13256
|
+
"--cascivo-motion-enter"
|
|
12697
13257
|
],
|
|
12698
13258
|
"accessibility": {
|
|
12699
|
-
"role": "
|
|
13259
|
+
"role": "group",
|
|
12700
13260
|
"wcag": "2.2-AA",
|
|
12701
|
-
"keyboard": ["Tab", "Enter"]
|
|
13261
|
+
"keyboard": ["Tab", "Enter", "Space", "Escape"]
|
|
12702
13262
|
},
|
|
12703
|
-
"examples": [
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
"code": "<Switcher\n items={[\n { label: 'Console', href: '/console', active: true },\n { label: 'Billing', href: '/billing' },\n { divider: true },\n { label: 'Docs', href: 'https://docs.example.com' },\n ]}\n/>",
|
|
12707
|
-
"description": "Place inside a HeaderPanel opened by a Grid action in ShellHeader"
|
|
12708
|
-
}
|
|
12709
|
-
],
|
|
12710
|
-
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
12711
|
-
"tags": ["navigation", "switcher", "shell", "console", "app-switcher"],
|
|
13263
|
+
"examples": [],
|
|
13264
|
+
"dependencies": ["@cascivo/core"],
|
|
13265
|
+
"tags": ["display", "swipe", "list", "mobile", "gesture", "actions"],
|
|
12712
13266
|
"intent": {
|
|
12713
13267
|
"whenToUse": [
|
|
12714
|
-
"
|
|
12715
|
-
"
|
|
12716
|
-
"
|
|
13268
|
+
"List rows on touch surfaces where secondary actions (archive, delete) should hide until swiped",
|
|
13269
|
+
"Mail/inbox-style rows that reveal contextual actions behind the content",
|
|
13270
|
+
"Compact lists where always-visible action buttons would crowd each row"
|
|
12717
13271
|
],
|
|
12718
13272
|
"whenNotToUse": [
|
|
12719
|
-
"
|
|
12720
|
-
"
|
|
13273
|
+
"A single primary action per row — render it inline as a Button",
|
|
13274
|
+
"Destructive actions that need confirmation — pair with an AlertDialog instead of swipe-only",
|
|
13275
|
+
"Non-list, free-form content — swipe-to-reveal is a list-row affordance"
|
|
12721
13276
|
],
|
|
12722
13277
|
"antiPatterns": [
|
|
12723
13278
|
{
|
|
12724
|
-
"bad": "
|
|
12725
|
-
"good": "
|
|
12726
|
-
"why": "
|
|
13279
|
+
"bad": "Relying on the swipe gesture as the only way to reach Delete",
|
|
13280
|
+
"good": "Action buttons stay in the DOM and a11y tree; focusing one reveals its side",
|
|
13281
|
+
"why": "Gesture-only actions are unreachable by keyboard and screen-reader users"
|
|
12727
13282
|
}
|
|
12728
13283
|
],
|
|
12729
13284
|
"related": [
|
|
12730
13285
|
{
|
|
12731
|
-
"name": "
|
|
12732
|
-
"relationship": "
|
|
13286
|
+
"name": "ActionSheet",
|
|
13287
|
+
"relationship": "alternative",
|
|
13288
|
+
"reason": "Use an ActionSheet when a row tap should present a fuller list of actions"
|
|
13289
|
+
},
|
|
13290
|
+
{
|
|
13291
|
+
"name": "List",
|
|
13292
|
+
"relationship": "contained-by",
|
|
13293
|
+
"reason": "SwipeItem wraps individual rows within a list"
|
|
13294
|
+
}
|
|
13295
|
+
],
|
|
13296
|
+
"a11yRationale": "The action buttons are always rendered in the DOM and the accessibility tree, never gesture-only. Focusing an action (via keyboard) reveals its side so it is visible, Enter/Space activate it, and Escape closes the row — giving full keyboard and screen-reader parity with the swipe gesture. The drag uses touch-action: pan-y so vertical scrolling is unaffected.",
|
|
13297
|
+
"flexibility": [
|
|
13298
|
+
{
|
|
13299
|
+
"area": "actions",
|
|
13300
|
+
"level": "flexible",
|
|
13301
|
+
"note": "Any number of leading and/or trailing actions; each may be destructive"
|
|
13302
|
+
},
|
|
13303
|
+
{
|
|
13304
|
+
"area": "reveal direction",
|
|
13305
|
+
"level": "strict",
|
|
13306
|
+
"note": "Leading reveals on the start edge, trailing on the end edge (physical-axis drag)"
|
|
13307
|
+
}
|
|
13308
|
+
]
|
|
13309
|
+
}
|
|
13310
|
+
}
|
|
13311
|
+
},
|
|
13312
|
+
{
|
|
13313
|
+
"name": "switcher",
|
|
13314
|
+
"type": "component",
|
|
13315
|
+
"description": "App/product switcher list — lives inside HeaderPanel, renders links with active indicator and optional dividers",
|
|
13316
|
+
"category": "navigation",
|
|
13317
|
+
"version": "0.0.0",
|
|
13318
|
+
"files": [
|
|
13319
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/switcher/switcher.tsx",
|
|
13320
|
+
"https://raw.githubusercontent.com/cascivo/cascivo/main/packages/components/src/switcher/switcher.module.css"
|
|
13321
|
+
],
|
|
13322
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
13323
|
+
"tags": ["navigation", "switcher", "shell", "console", "app-switcher"],
|
|
13324
|
+
"meta": {
|
|
13325
|
+
"name": "Switcher",
|
|
13326
|
+
"description": "App/product switcher list — lives inside HeaderPanel, renders links with active indicator and optional dividers",
|
|
13327
|
+
"category": "navigation",
|
|
13328
|
+
"states": ["default"],
|
|
13329
|
+
"variants": [],
|
|
13330
|
+
"sizes": [],
|
|
13331
|
+
"props": [
|
|
13332
|
+
{
|
|
13333
|
+
"name": "items",
|
|
13334
|
+
"type": "SwitcherEntry[]",
|
|
13335
|
+
"required": true,
|
|
13336
|
+
"description": "SwitcherLink ({ label, href, active?, icon? }) or divider ({ divider: true })"
|
|
13337
|
+
},
|
|
13338
|
+
{
|
|
13339
|
+
"name": "label",
|
|
13340
|
+
"type": "string",
|
|
13341
|
+
"required": false,
|
|
13342
|
+
"default": "Switch application"
|
|
13343
|
+
},
|
|
13344
|
+
{
|
|
13345
|
+
"name": "className",
|
|
13346
|
+
"type": "string",
|
|
13347
|
+
"required": false
|
|
13348
|
+
}
|
|
13349
|
+
],
|
|
13350
|
+
"tokens": [
|
|
13351
|
+
"--cascivo-color-text",
|
|
13352
|
+
"--cascivo-color-bg-subtle",
|
|
13353
|
+
"--cascivo-color-accent",
|
|
13354
|
+
"--cascivo-color-accent-subtle",
|
|
13355
|
+
"--cascivo-color-border",
|
|
13356
|
+
"--cascivo-focus-ring"
|
|
13357
|
+
],
|
|
13358
|
+
"accessibility": {
|
|
13359
|
+
"role": "list",
|
|
13360
|
+
"wcag": "2.2-AA",
|
|
13361
|
+
"keyboard": ["Tab", "Enter"]
|
|
13362
|
+
},
|
|
13363
|
+
"examples": [
|
|
13364
|
+
{
|
|
13365
|
+
"title": "App switcher",
|
|
13366
|
+
"code": "<Switcher\n items={[\n { label: 'Console', href: '/console', active: true },\n { label: 'Billing', href: '/billing' },\n { divider: true },\n { label: 'Docs', href: 'https://docs.example.com' },\n ]}\n/>",
|
|
13367
|
+
"description": "Place inside a HeaderPanel opened by a Grid action in ShellHeader"
|
|
13368
|
+
}
|
|
13369
|
+
],
|
|
13370
|
+
"dependencies": ["@cascivo/core", "@cascivo/i18n"],
|
|
13371
|
+
"tags": ["navigation", "switcher", "shell", "console", "app-switcher"],
|
|
13372
|
+
"intent": {
|
|
13373
|
+
"whenToUse": [
|
|
13374
|
+
"Listing sibling apps/products the user can switch between",
|
|
13375
|
+
"Rendering switch destinations inside a HeaderPanel opened from the shell header",
|
|
13376
|
+
"Grouping switch targets with dividers and marking the active one"
|
|
13377
|
+
],
|
|
13378
|
+
"whenNotToUse": [
|
|
13379
|
+
"Primary in-app navigation — use SideNav",
|
|
13380
|
+
"A small action menu attached to a control — use Dropdown"
|
|
13381
|
+
],
|
|
13382
|
+
"antiPatterns": [
|
|
13383
|
+
{
|
|
13384
|
+
"bad": "Using Switcher as the main page navigation",
|
|
13385
|
+
"good": "<SideNav> for primary navigation; Switcher only for app/product switching",
|
|
13386
|
+
"why": "Switcher models cross-app jumps, not navigation within the current app"
|
|
13387
|
+
}
|
|
13388
|
+
],
|
|
13389
|
+
"related": [
|
|
13390
|
+
{
|
|
13391
|
+
"name": "HeaderPanel",
|
|
13392
|
+
"relationship": "contained-by",
|
|
12733
13393
|
"reason": "Switcher is placed inside a HeaderPanel opened by a ShellHeader action"
|
|
12734
13394
|
}
|
|
12735
13395
|
],
|
|
@@ -19166,6 +19826,1123 @@
|
|
|
19166
19826
|
"flexibility": []
|
|
19167
19827
|
}
|
|
19168
19828
|
}
|
|
19829
|
+
},
|
|
19830
|
+
{
|
|
19831
|
+
"name": "flow/flow",
|
|
19832
|
+
"type": "flow",
|
|
19833
|
+
"description": "The declarative, AI-first flow surface — render a node/edge graph from plain serializable data.",
|
|
19834
|
+
"category": "display",
|
|
19835
|
+
"version": "0.0.0",
|
|
19836
|
+
"files": [],
|
|
19837
|
+
"dependencies": ["@cascivo/core"],
|
|
19838
|
+
"tags": ["flow", "graph", "declarative", "diagram", "ai-first"],
|
|
19839
|
+
"meta": {
|
|
19840
|
+
"name": "Flow",
|
|
19841
|
+
"description": "The declarative, AI-first flow surface — render a node/edge graph from plain serializable data.",
|
|
19842
|
+
"category": "display",
|
|
19843
|
+
"states": [],
|
|
19844
|
+
"variants": [],
|
|
19845
|
+
"sizes": [],
|
|
19846
|
+
"props": [
|
|
19847
|
+
{
|
|
19848
|
+
"name": "nodes",
|
|
19849
|
+
"type": "FlowNode[]",
|
|
19850
|
+
"required": true,
|
|
19851
|
+
"description": "Initial nodes (serializable)."
|
|
19852
|
+
},
|
|
19853
|
+
{
|
|
19854
|
+
"name": "edges",
|
|
19855
|
+
"type": "FlowEdge[]",
|
|
19856
|
+
"required": true,
|
|
19857
|
+
"description": "Initial edges (serializable)."
|
|
19858
|
+
},
|
|
19859
|
+
{
|
|
19860
|
+
"name": "onNodesChange",
|
|
19861
|
+
"type": "(nodes: FlowNode[]) => void",
|
|
19862
|
+
"required": false
|
|
19863
|
+
},
|
|
19864
|
+
{
|
|
19865
|
+
"name": "onEdgesChange",
|
|
19866
|
+
"type": "(edges: FlowEdge[]) => void",
|
|
19867
|
+
"required": false
|
|
19868
|
+
},
|
|
19869
|
+
{
|
|
19870
|
+
"name": "onConnect",
|
|
19871
|
+
"type": "(connection: Connection) => void",
|
|
19872
|
+
"required": false
|
|
19873
|
+
},
|
|
19874
|
+
{
|
|
19875
|
+
"name": "nodeTypes",
|
|
19876
|
+
"type": "Record<string, NodeRenderer>",
|
|
19877
|
+
"required": false,
|
|
19878
|
+
"description": "Custom node renderers keyed by node.type."
|
|
19879
|
+
},
|
|
19880
|
+
{
|
|
19881
|
+
"name": "fitView",
|
|
19882
|
+
"type": "boolean",
|
|
19883
|
+
"required": false,
|
|
19884
|
+
"default": "true"
|
|
19885
|
+
},
|
|
19886
|
+
{
|
|
19887
|
+
"name": "background",
|
|
19888
|
+
"type": "boolean | FlowBackgroundProps",
|
|
19889
|
+
"required": false,
|
|
19890
|
+
"default": "false"
|
|
19891
|
+
},
|
|
19892
|
+
{
|
|
19893
|
+
"name": "controls",
|
|
19894
|
+
"type": "boolean",
|
|
19895
|
+
"required": false,
|
|
19896
|
+
"default": "false"
|
|
19897
|
+
},
|
|
19898
|
+
{
|
|
19899
|
+
"name": "minimap",
|
|
19900
|
+
"type": "boolean",
|
|
19901
|
+
"required": false,
|
|
19902
|
+
"default": "false"
|
|
19903
|
+
},
|
|
19904
|
+
{
|
|
19905
|
+
"name": "layout",
|
|
19906
|
+
"type": "'grid' | 'layered' | ((nodes, edges) => FlowNode[])",
|
|
19907
|
+
"required": false,
|
|
19908
|
+
"description": "Optional dependency-free layout."
|
|
19909
|
+
},
|
|
19910
|
+
{
|
|
19911
|
+
"name": "interactive",
|
|
19912
|
+
"type": "boolean",
|
|
19913
|
+
"required": false,
|
|
19914
|
+
"default": "true",
|
|
19915
|
+
"description": "When false (view mode), nodes cannot be selected, dragged, or connected and handles are hidden; pan/zoom still work."
|
|
19916
|
+
},
|
|
19917
|
+
{
|
|
19918
|
+
"name": "className",
|
|
19919
|
+
"type": "string",
|
|
19920
|
+
"required": false
|
|
19921
|
+
}
|
|
19922
|
+
],
|
|
19923
|
+
"tokens": ["--cascivo-color-bg", "--cascivo-color-surface", "--cascivo-color-accent"],
|
|
19924
|
+
"accessibility": {
|
|
19925
|
+
"role": "application",
|
|
19926
|
+
"wcag": "2.1-AA",
|
|
19927
|
+
"keyboard": [
|
|
19928
|
+
"Tab (focus nodes)",
|
|
19929
|
+
"Enter/Space (select)",
|
|
19930
|
+
"Drag (pan/move)",
|
|
19931
|
+
"Wheel (zoom)"
|
|
19932
|
+
]
|
|
19933
|
+
},
|
|
19934
|
+
"examples": [
|
|
19935
|
+
{
|
|
19936
|
+
"title": "Declarative pipeline",
|
|
19937
|
+
"description": "A flow from plain serializable data, with background, controls, and an animated edge.",
|
|
19938
|
+
"code": "() => (\n <Flow\n style={{ height: 280 }}\n background\n controls\n nodes={[\n { id: 'a', position: { x: 0, y: 60 }, data: { label: 'Client' } },\n { id: 'b', position: { x: 240, y: 60 }, data: { label: 'Gateway' } },\n { id: 'c', position: { x: 480, y: 60 }, data: { label: 'Service' } },\n ]}\n edges={[\n { id: 'ab', source: 'a', target: 'b', animated: true, label: 'request' },\n { id: 'bc', source: 'b', target: 'c' },\n ]}\n />\n)"
|
|
19939
|
+
},
|
|
19940
|
+
{
|
|
19941
|
+
"title": "Layered layout",
|
|
19942
|
+
"description": "Let the dependency-free layered layout arrange a small DAG.",
|
|
19943
|
+
"code": "() => (\n <Flow\n style={{ height: 300 }}\n layout=\"layered\"\n background\n minimap\n nodes={[\n { id: 'a', position: { x: 0, y: 0 }, data: { label: 'Ingest' } },\n { id: 'b', position: { x: 0, y: 0 }, data: { label: 'Transform' } },\n { id: 'c', position: { x: 0, y: 0 }, data: { label: 'Validate' } },\n { id: 'd', position: { x: 0, y: 0 }, data: { label: 'Load' } },\n ]}\n edges={[\n { id: 'ab', source: 'a', target: 'b' },\n { id: 'ac', source: 'a', target: 'c' },\n { id: 'bd', source: 'b', target: 'd' },\n { id: 'cd', source: 'c', target: 'd' },\n ]}\n />\n)"
|
|
19944
|
+
}
|
|
19945
|
+
],
|
|
19946
|
+
"dependencies": ["@cascivo/core"],
|
|
19947
|
+
"tags": ["flow", "graph", "declarative", "diagram", "ai-first"],
|
|
19948
|
+
"intent": {
|
|
19949
|
+
"whenToUse": [
|
|
19950
|
+
"Rendering a graph from data — the common case and the agent-emittable surface",
|
|
19951
|
+
"Flowcharts, DAGs, pipelines, and mind-maps from plain nodes/edges arrays"
|
|
19952
|
+
],
|
|
19953
|
+
"whenNotToUse": [
|
|
19954
|
+
"A scripted, sequenced walkthrough — use FlowStory",
|
|
19955
|
+
"Heavy graph editing (undo/redo, resize/rotate) — out of scope"
|
|
19956
|
+
],
|
|
19957
|
+
"antiPatterns": [
|
|
19958
|
+
{
|
|
19959
|
+
"bad": "Imperatively building the graph with graph.addNode(...)",
|
|
19960
|
+
"good": "<Flow nodes={…} edges={…} />",
|
|
19961
|
+
"why": "Declarative serializable data is what an agent can emit and what stays in sync with props."
|
|
19962
|
+
}
|
|
19963
|
+
],
|
|
19964
|
+
"related": [
|
|
19965
|
+
{
|
|
19966
|
+
"name": "FlowStory",
|
|
19967
|
+
"relationship": "alternative",
|
|
19968
|
+
"reason": "Scripted, captioned storyline animation."
|
|
19969
|
+
},
|
|
19970
|
+
{
|
|
19971
|
+
"name": "FlowNode",
|
|
19972
|
+
"relationship": "contains",
|
|
19973
|
+
"reason": "Renders a node per entry."
|
|
19974
|
+
},
|
|
19975
|
+
{
|
|
19976
|
+
"name": "FlowEdge",
|
|
19977
|
+
"relationship": "contains",
|
|
19978
|
+
"reason": "Renders an edge per entry."
|
|
19979
|
+
}
|
|
19980
|
+
],
|
|
19981
|
+
"a11yRationale": "role=\"application\" canvas; nodes are focusable groups; controls are real i18n-labeled buttons.",
|
|
19982
|
+
"flexibility": [
|
|
19983
|
+
{
|
|
19984
|
+
"area": "rendering",
|
|
19985
|
+
"level": "flexible",
|
|
19986
|
+
"note": "Custom node renderers via nodeTypes."
|
|
19987
|
+
},
|
|
19988
|
+
{
|
|
19989
|
+
"area": "layout",
|
|
19990
|
+
"level": "flexible",
|
|
19991
|
+
"note": "grid | layered | bring-your-own positions."
|
|
19992
|
+
},
|
|
19993
|
+
{
|
|
19994
|
+
"area": "chrome",
|
|
19995
|
+
"level": "flexible",
|
|
19996
|
+
"note": "Optional background / controls / minimap."
|
|
19997
|
+
}
|
|
19998
|
+
]
|
|
19999
|
+
}
|
|
20000
|
+
},
|
|
20001
|
+
"install": "@cascivo/flow"
|
|
20002
|
+
},
|
|
20003
|
+
{
|
|
20004
|
+
"name": "flow/flow-background",
|
|
20005
|
+
"type": "flow",
|
|
20006
|
+
"description": "Decorative dots / grid / cross canvas background, drawn purely in CSS gradients.",
|
|
20007
|
+
"category": "display",
|
|
20008
|
+
"version": "0.0.0",
|
|
20009
|
+
"files": [],
|
|
20010
|
+
"dependencies": ["@cascivo/core"],
|
|
20011
|
+
"tags": ["flow", "background", "grid", "dots", "canvas"],
|
|
20012
|
+
"meta": {
|
|
20013
|
+
"name": "FlowBackground",
|
|
20014
|
+
"description": "Decorative dots / grid / cross canvas background, drawn purely in CSS gradients.",
|
|
20015
|
+
"category": "display",
|
|
20016
|
+
"states": [],
|
|
20017
|
+
"variants": ["dots", "grid", "cross"],
|
|
20018
|
+
"sizes": [],
|
|
20019
|
+
"props": [
|
|
20020
|
+
{
|
|
20021
|
+
"name": "variant",
|
|
20022
|
+
"type": "'dots' | 'grid' | 'cross'",
|
|
20023
|
+
"required": false,
|
|
20024
|
+
"default": "dots",
|
|
20025
|
+
"description": "Pattern style."
|
|
20026
|
+
},
|
|
20027
|
+
{
|
|
20028
|
+
"name": "gap",
|
|
20029
|
+
"type": "number",
|
|
20030
|
+
"required": false,
|
|
20031
|
+
"default": "20",
|
|
20032
|
+
"description": "Cell spacing (px)."
|
|
20033
|
+
},
|
|
20034
|
+
{
|
|
20035
|
+
"name": "size",
|
|
20036
|
+
"type": "number",
|
|
20037
|
+
"required": false,
|
|
20038
|
+
"default": "1",
|
|
20039
|
+
"description": "Dot radius / line thickness (px)."
|
|
20040
|
+
},
|
|
20041
|
+
{
|
|
20042
|
+
"name": "color",
|
|
20043
|
+
"type": "string",
|
|
20044
|
+
"required": false,
|
|
20045
|
+
"description": "Pattern color (defaults to the border token)."
|
|
20046
|
+
},
|
|
20047
|
+
{
|
|
20048
|
+
"name": "className",
|
|
20049
|
+
"type": "string",
|
|
20050
|
+
"required": false
|
|
20051
|
+
}
|
|
20052
|
+
],
|
|
20053
|
+
"tokens": ["--cascivo-color-border"],
|
|
20054
|
+
"accessibility": {
|
|
20055
|
+
"role": "presentation",
|
|
20056
|
+
"wcag": "2.1-AA",
|
|
20057
|
+
"keyboard": []
|
|
20058
|
+
},
|
|
20059
|
+
"examples": [
|
|
20060
|
+
{
|
|
20061
|
+
"title": "Dotted background",
|
|
20062
|
+
"description": "A dotted grid behind a flow canvas.",
|
|
20063
|
+
"code": "() => (\n <div style={{ position: 'relative', height: 220, overflow: 'hidden' }}>\n <FlowBackground variant=\"dots\" gap={24} />\n </div>\n)"
|
|
20064
|
+
},
|
|
20065
|
+
{
|
|
20066
|
+
"title": "Grid and cross",
|
|
20067
|
+
"description": "The grid and cross variants.",
|
|
20068
|
+
"code": "() => (\n <div style={{ display: 'grid', gap: 16, gridTemplateColumns: '1fr 1fr' }}>\n <div style={{ position: 'relative', height: 180, overflow: 'hidden' }}>\n <FlowBackground variant=\"grid\" gap={28} />\n </div>\n <div style={{ position: 'relative', height: 180, overflow: 'hidden' }}>\n <FlowBackground variant=\"cross\" gap={28} size={4} />\n </div>\n </div>\n)"
|
|
20069
|
+
}
|
|
20070
|
+
],
|
|
20071
|
+
"dependencies": ["@cascivo/core"],
|
|
20072
|
+
"tags": ["flow", "background", "grid", "dots", "canvas"],
|
|
20073
|
+
"intent": {
|
|
20074
|
+
"whenToUse": [
|
|
20075
|
+
"Giving a flow canvas a sense of space and scale with a dotted or grid backdrop",
|
|
20076
|
+
"Reinforcing pan/zoom by letting the pattern move and scale with the viewport"
|
|
20077
|
+
],
|
|
20078
|
+
"whenNotToUse": [
|
|
20079
|
+
"As a page background — this is a flow-canvas decoration, not a general surface"
|
|
20080
|
+
],
|
|
20081
|
+
"antiPatterns": [
|
|
20082
|
+
{
|
|
20083
|
+
"bad": "Rendering a DOM node per grid cell",
|
|
20084
|
+
"good": "A single CSS gradient layer",
|
|
20085
|
+
"why": "Per-cell DOM is needlessly expensive; one repeating gradient costs nothing."
|
|
20086
|
+
}
|
|
20087
|
+
],
|
|
20088
|
+
"related": [
|
|
20089
|
+
{
|
|
20090
|
+
"name": "FlowCanvas",
|
|
20091
|
+
"relationship": "contained-by",
|
|
20092
|
+
"reason": "Lives inside the canvas pane."
|
|
20093
|
+
}
|
|
20094
|
+
],
|
|
20095
|
+
"a11yRationale": "Purely decorative — marked aria-hidden and presentation, never in the a11y tree.",
|
|
20096
|
+
"flexibility": [
|
|
20097
|
+
{
|
|
20098
|
+
"area": "pattern",
|
|
20099
|
+
"level": "flexible",
|
|
20100
|
+
"note": "dots | grid | cross with configurable gap/size."
|
|
20101
|
+
}
|
|
20102
|
+
]
|
|
20103
|
+
}
|
|
20104
|
+
},
|
|
20105
|
+
"install": "@cascivo/flow"
|
|
20106
|
+
},
|
|
20107
|
+
{
|
|
20108
|
+
"name": "flow/flow-controls",
|
|
20109
|
+
"type": "flow",
|
|
20110
|
+
"description": "Zoom in / out / fit-view controls for a flow canvas — real, i18n-labeled buttons.",
|
|
20111
|
+
"category": "display",
|
|
20112
|
+
"version": "0.0.0",
|
|
20113
|
+
"files": [],
|
|
20114
|
+
"dependencies": ["@cascivo/core"],
|
|
20115
|
+
"tags": ["flow", "controls", "zoom", "chrome"],
|
|
20116
|
+
"meta": {
|
|
20117
|
+
"name": "FlowControls",
|
|
20118
|
+
"description": "Zoom in / out / fit-view controls for a flow canvas — real, i18n-labeled buttons.",
|
|
20119
|
+
"category": "display",
|
|
20120
|
+
"states": [],
|
|
20121
|
+
"variants": [],
|
|
20122
|
+
"sizes": [],
|
|
20123
|
+
"props": [
|
|
20124
|
+
{
|
|
20125
|
+
"name": "position",
|
|
20126
|
+
"type": "'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'",
|
|
20127
|
+
"required": false,
|
|
20128
|
+
"default": "bottom-left"
|
|
20129
|
+
},
|
|
20130
|
+
{
|
|
20131
|
+
"name": "showZoom",
|
|
20132
|
+
"type": "boolean",
|
|
20133
|
+
"required": false,
|
|
20134
|
+
"default": "true"
|
|
20135
|
+
},
|
|
20136
|
+
{
|
|
20137
|
+
"name": "showFitView",
|
|
20138
|
+
"type": "boolean",
|
|
20139
|
+
"required": false,
|
|
20140
|
+
"default": "true"
|
|
20141
|
+
},
|
|
20142
|
+
{
|
|
20143
|
+
"name": "onZoomIn",
|
|
20144
|
+
"type": "() => void",
|
|
20145
|
+
"required": false
|
|
20146
|
+
},
|
|
20147
|
+
{
|
|
20148
|
+
"name": "onZoomOut",
|
|
20149
|
+
"type": "() => void",
|
|
20150
|
+
"required": false
|
|
20151
|
+
},
|
|
20152
|
+
{
|
|
20153
|
+
"name": "onFitView",
|
|
20154
|
+
"type": "() => void",
|
|
20155
|
+
"required": false
|
|
20156
|
+
},
|
|
20157
|
+
{
|
|
20158
|
+
"name": "labels",
|
|
20159
|
+
"type": "FlowControlsLabels",
|
|
20160
|
+
"required": false
|
|
20161
|
+
},
|
|
20162
|
+
{
|
|
20163
|
+
"name": "className",
|
|
20164
|
+
"type": "string",
|
|
20165
|
+
"required": false
|
|
20166
|
+
}
|
|
20167
|
+
],
|
|
20168
|
+
"tokens": [
|
|
20169
|
+
"--cascivo-color-surface",
|
|
20170
|
+
"--cascivo-color-border",
|
|
20171
|
+
"--cascivo-target-min-coarse"
|
|
20172
|
+
],
|
|
20173
|
+
"accessibility": {
|
|
20174
|
+
"role": "group",
|
|
20175
|
+
"wcag": "2.1-AA",
|
|
20176
|
+
"keyboard": ["Tab (focus)", "Enter/Space (activate)"]
|
|
20177
|
+
},
|
|
20178
|
+
"examples": [
|
|
20179
|
+
{
|
|
20180
|
+
"title": "Canvas controls",
|
|
20181
|
+
"code": "() => (\n <div style={{ position: 'relative', height: 200, border: '1px solid var(--cascivo-color-border)' }}>\n <FlowControls onZoomIn={() => {}} onZoomOut={() => {}} onFitView={() => {}} />\n </div>\n)"
|
|
20182
|
+
}
|
|
20183
|
+
],
|
|
20184
|
+
"dependencies": ["@cascivo/core"],
|
|
20185
|
+
"tags": ["flow", "controls", "zoom", "chrome"],
|
|
20186
|
+
"intent": {
|
|
20187
|
+
"whenToUse": ["Giving users explicit zoom/fit controls on a flow canvas"],
|
|
20188
|
+
"whenNotToUse": ["When the canvas is static/non-interactive"],
|
|
20189
|
+
"antiPatterns": [],
|
|
20190
|
+
"related": [
|
|
20191
|
+
{
|
|
20192
|
+
"name": "FlowCanvas",
|
|
20193
|
+
"relationship": "pairs-with",
|
|
20194
|
+
"reason": "Calls its viewport actions."
|
|
20195
|
+
},
|
|
20196
|
+
{
|
|
20197
|
+
"name": "FlowMiniMap",
|
|
20198
|
+
"relationship": "pairs-with",
|
|
20199
|
+
"reason": "Complementary navigation chrome."
|
|
20200
|
+
}
|
|
20201
|
+
],
|
|
20202
|
+
"a11yRationale": "Real <button>s with i18n-defaulted aria-labels; ≥44px coarse targets.",
|
|
20203
|
+
"flexibility": [
|
|
20204
|
+
{
|
|
20205
|
+
"area": "position",
|
|
20206
|
+
"level": "flexible",
|
|
20207
|
+
"note": "Four corners."
|
|
20208
|
+
},
|
|
20209
|
+
{
|
|
20210
|
+
"area": "buttons",
|
|
20211
|
+
"level": "flexible",
|
|
20212
|
+
"note": "Zoom / fit toggleable."
|
|
20213
|
+
}
|
|
20214
|
+
]
|
|
20215
|
+
}
|
|
20216
|
+
},
|
|
20217
|
+
"install": "@cascivo/flow"
|
|
20218
|
+
},
|
|
20219
|
+
{
|
|
20220
|
+
"name": "flow/flow-edge",
|
|
20221
|
+
"type": "flow",
|
|
20222
|
+
"description": "An SVG edge with bezier/straight/smoothstep paths, an arrowhead, an optional label, and animation.",
|
|
20223
|
+
"category": "display",
|
|
20224
|
+
"version": "0.0.0",
|
|
20225
|
+
"files": [],
|
|
20226
|
+
"dependencies": ["@cascivo/core"],
|
|
20227
|
+
"tags": ["flow", "edge", "connector", "animated", "svg"],
|
|
20228
|
+
"meta": {
|
|
20229
|
+
"name": "FlowEdge",
|
|
20230
|
+
"description": "An SVG edge with bezier/straight/smoothstep paths, an arrowhead, an optional label, and animation.",
|
|
20231
|
+
"category": "display",
|
|
20232
|
+
"states": ["default", "selected", "animated"],
|
|
20233
|
+
"variants": ["bezier", "straight", "smoothstep"],
|
|
20234
|
+
"sizes": [],
|
|
20235
|
+
"props": [
|
|
20236
|
+
{
|
|
20237
|
+
"name": "sourceX",
|
|
20238
|
+
"type": "number",
|
|
20239
|
+
"required": true,
|
|
20240
|
+
"description": "Source anchor x (flow coords)."
|
|
20241
|
+
},
|
|
20242
|
+
{
|
|
20243
|
+
"name": "sourceY",
|
|
20244
|
+
"type": "number",
|
|
20245
|
+
"required": true
|
|
20246
|
+
},
|
|
20247
|
+
{
|
|
20248
|
+
"name": "targetX",
|
|
20249
|
+
"type": "number",
|
|
20250
|
+
"required": true
|
|
20251
|
+
},
|
|
20252
|
+
{
|
|
20253
|
+
"name": "targetY",
|
|
20254
|
+
"type": "number",
|
|
20255
|
+
"required": true
|
|
20256
|
+
},
|
|
20257
|
+
{
|
|
20258
|
+
"name": "type",
|
|
20259
|
+
"type": "'bezier' | 'straight' | 'smoothstep'",
|
|
20260
|
+
"required": false,
|
|
20261
|
+
"default": "bezier"
|
|
20262
|
+
},
|
|
20263
|
+
{
|
|
20264
|
+
"name": "animated",
|
|
20265
|
+
"type": "boolean",
|
|
20266
|
+
"required": false,
|
|
20267
|
+
"default": "false"
|
|
20268
|
+
},
|
|
20269
|
+
{
|
|
20270
|
+
"name": "label",
|
|
20271
|
+
"type": "ReactNode",
|
|
20272
|
+
"required": false
|
|
20273
|
+
},
|
|
20274
|
+
{
|
|
20275
|
+
"name": "selected",
|
|
20276
|
+
"type": "boolean",
|
|
20277
|
+
"required": false,
|
|
20278
|
+
"default": "false"
|
|
20279
|
+
},
|
|
20280
|
+
{
|
|
20281
|
+
"name": "markerStart",
|
|
20282
|
+
"type": "boolean",
|
|
20283
|
+
"required": false,
|
|
20284
|
+
"default": "false",
|
|
20285
|
+
"description": "Arrowhead at the source (points back toward the source) — set both for bidirectional."
|
|
20286
|
+
},
|
|
20287
|
+
{
|
|
20288
|
+
"name": "markerEnd",
|
|
20289
|
+
"type": "boolean",
|
|
20290
|
+
"required": false,
|
|
20291
|
+
"default": "true",
|
|
20292
|
+
"description": "Arrowhead at the target. Set false for an undirected line."
|
|
20293
|
+
},
|
|
20294
|
+
{
|
|
20295
|
+
"name": "className",
|
|
20296
|
+
"type": "string",
|
|
20297
|
+
"required": false
|
|
20298
|
+
}
|
|
20299
|
+
],
|
|
20300
|
+
"tokens": [
|
|
20301
|
+
"--cascivo-color-border-strong",
|
|
20302
|
+
"--cascivo-color-accent",
|
|
20303
|
+
"--cascivo-color-surface"
|
|
20304
|
+
],
|
|
20305
|
+
"accessibility": {
|
|
20306
|
+
"role": "presentation",
|
|
20307
|
+
"wcag": "2.1-AA",
|
|
20308
|
+
"keyboard": [],
|
|
20309
|
+
"reducedMotion": true
|
|
20310
|
+
},
|
|
20311
|
+
"examples": [
|
|
20312
|
+
{
|
|
20313
|
+
"title": "Edge path types",
|
|
20314
|
+
"description": "Bezier, straight, smoothstep, and an animated edge.",
|
|
20315
|
+
"code": "() => (\n <div style={{ position: 'relative', height: 220 }}>\n <FlowEdge sourceX={20} sourceY={30} targetX={260} targetY={30} type=\"bezier\" label=\"bezier\" />\n <FlowEdge sourceX={20} sourceY={90} targetX={260} targetY={90} type=\"smoothstep\" label=\"step\" />\n <FlowEdge sourceX={20} sourceY={150} targetX={260} targetY={150} animated label=\"animated\" />\n </div>\n)"
|
|
20316
|
+
},
|
|
20317
|
+
{
|
|
20318
|
+
"title": "Arrow direction",
|
|
20319
|
+
"description": "Forward (default), backward, bidirectional, or undirected — via markerStart/markerEnd.",
|
|
20320
|
+
"code": "() => (\n <div style={{ position: 'relative', height: 260 }}>\n <FlowEdge sourceX={20} sourceY={30} targetX={260} targetY={30} label=\"forward\" />\n <FlowEdge sourceX={20} sourceY={90} targetX={260} targetY={90} markerEnd={false} markerStart label=\"backward\" />\n <FlowEdge sourceX={20} sourceY={150} targetX={260} targetY={150} markerStart label=\"both\" />\n <FlowEdge sourceX={20} sourceY={210} targetX={260} targetY={210} markerEnd={false} label=\"undirected\" />\n </div>\n)"
|
|
20321
|
+
}
|
|
20322
|
+
],
|
|
20323
|
+
"dependencies": ["@cascivo/core"],
|
|
20324
|
+
"tags": ["flow", "edge", "connector", "animated", "svg"],
|
|
20325
|
+
"intent": {
|
|
20326
|
+
"whenToUse": [
|
|
20327
|
+
"Connecting two nodes with a directed path and arrowhead",
|
|
20328
|
+
"Animating flow direction along a connection (\"marching ants\")"
|
|
20329
|
+
],
|
|
20330
|
+
"whenNotToUse": [
|
|
20331
|
+
"For undirected relationships where an arrowhead would mislead — set markerEnd={false}"
|
|
20332
|
+
],
|
|
20333
|
+
"antiPatterns": [
|
|
20334
|
+
{
|
|
20335
|
+
"bad": "A requestAnimationFrame loop to animate the dash",
|
|
20336
|
+
"good": "A CSS stroke-dashoffset keyframe",
|
|
20337
|
+
"why": "The compositor animates CSS for free; a JS loop re-renders every frame."
|
|
20338
|
+
}
|
|
20339
|
+
],
|
|
20340
|
+
"related": [
|
|
20341
|
+
{
|
|
20342
|
+
"name": "FlowNode",
|
|
20343
|
+
"relationship": "pairs-with",
|
|
20344
|
+
"reason": "Edges connect nodes."
|
|
20345
|
+
},
|
|
20346
|
+
{
|
|
20347
|
+
"name": "FlowStory",
|
|
20348
|
+
"relationship": "pairs-with",
|
|
20349
|
+
"reason": "Storylines animate edges in sequence."
|
|
20350
|
+
}
|
|
20351
|
+
],
|
|
20352
|
+
"a11yRationale": "Decorative SVG (aria-hidden); animation is disabled under prefers-reduced-motion.",
|
|
20353
|
+
"flexibility": [
|
|
20354
|
+
{
|
|
20355
|
+
"area": "path",
|
|
20356
|
+
"level": "flexible",
|
|
20357
|
+
"note": "bezier | straight | smoothstep."
|
|
20358
|
+
},
|
|
20359
|
+
{
|
|
20360
|
+
"area": "animation",
|
|
20361
|
+
"level": "flexible",
|
|
20362
|
+
"note": "Optional, reduced-motion-safe."
|
|
20363
|
+
}
|
|
20364
|
+
]
|
|
20365
|
+
}
|
|
20366
|
+
},
|
|
20367
|
+
"install": "@cascivo/flow"
|
|
20368
|
+
},
|
|
20369
|
+
{
|
|
20370
|
+
"name": "flow/flow-handle",
|
|
20371
|
+
"type": "flow",
|
|
20372
|
+
"description": "A connection port on a node edge — where edges attach and interactive connect starts.",
|
|
20373
|
+
"category": "display",
|
|
20374
|
+
"version": "0.0.0",
|
|
20375
|
+
"files": [],
|
|
20376
|
+
"dependencies": ["@cascivo/core"],
|
|
20377
|
+
"tags": ["flow", "handle", "port", "connect"],
|
|
20378
|
+
"meta": {
|
|
20379
|
+
"name": "FlowHandle",
|
|
20380
|
+
"description": "A connection port on a node edge — where edges attach and interactive connect starts.",
|
|
20381
|
+
"category": "display",
|
|
20382
|
+
"states": ["default", "hover", "focus"],
|
|
20383
|
+
"variants": ["source", "target"],
|
|
20384
|
+
"sizes": [],
|
|
20385
|
+
"props": [
|
|
20386
|
+
{
|
|
20387
|
+
"name": "type",
|
|
20388
|
+
"type": "'source' | 'target'",
|
|
20389
|
+
"required": true
|
|
20390
|
+
},
|
|
20391
|
+
{
|
|
20392
|
+
"name": "position",
|
|
20393
|
+
"type": "'top' | 'right' | 'bottom' | 'left'",
|
|
20394
|
+
"required": false,
|
|
20395
|
+
"description": "Edge of the node (defaults: source→right, target→left)."
|
|
20396
|
+
},
|
|
20397
|
+
{
|
|
20398
|
+
"name": "id",
|
|
20399
|
+
"type": "string",
|
|
20400
|
+
"required": false,
|
|
20401
|
+
"description": "Handle id for multi-handle nodes."
|
|
20402
|
+
},
|
|
20403
|
+
{
|
|
20404
|
+
"name": "isConnectable",
|
|
20405
|
+
"type": "boolean",
|
|
20406
|
+
"required": false,
|
|
20407
|
+
"default": "true"
|
|
20408
|
+
},
|
|
20409
|
+
{
|
|
20410
|
+
"name": "className",
|
|
20411
|
+
"type": "string",
|
|
20412
|
+
"required": false
|
|
20413
|
+
}
|
|
20414
|
+
],
|
|
20415
|
+
"tokens": [
|
|
20416
|
+
"--cascivo-color-accent",
|
|
20417
|
+
"--cascivo-color-surface",
|
|
20418
|
+
"--cascivo-target-min-coarse"
|
|
20419
|
+
],
|
|
20420
|
+
"accessibility": {
|
|
20421
|
+
"role": "button",
|
|
20422
|
+
"wcag": "2.1-AA",
|
|
20423
|
+
"keyboard": ["Tab (focus the port)"]
|
|
20424
|
+
},
|
|
20425
|
+
"examples": [
|
|
20426
|
+
{
|
|
20427
|
+
"title": "Source and target ports",
|
|
20428
|
+
"code": "() => (\n <div style={{ position: 'relative', height: 160 }}>\n <FlowNode id=\"api\" defaultPosition={{ x: 70, y: 55 }}>\n API\n <FlowHandle type=\"target\" position=\"left\" />\n <FlowHandle type=\"source\" position=\"right\" />\n </FlowNode>\n </div>\n)"
|
|
20429
|
+
}
|
|
20430
|
+
],
|
|
20431
|
+
"dependencies": ["@cascivo/core"],
|
|
20432
|
+
"tags": ["flow", "handle", "port", "connect"],
|
|
20433
|
+
"intent": {
|
|
20434
|
+
"whenToUse": [
|
|
20435
|
+
"Marking where edges connect to a node",
|
|
20436
|
+
"Enabling interactive connect (drag from a source to a target)"
|
|
20437
|
+
],
|
|
20438
|
+
"whenNotToUse": ["On nodes that are never connected"],
|
|
20439
|
+
"antiPatterns": [],
|
|
20440
|
+
"related": [
|
|
20441
|
+
{
|
|
20442
|
+
"name": "FlowNode",
|
|
20443
|
+
"relationship": "contained-by",
|
|
20444
|
+
"reason": "Ports live inside a node."
|
|
20445
|
+
},
|
|
20446
|
+
{
|
|
20447
|
+
"name": "FlowEdge",
|
|
20448
|
+
"relationship": "pairs-with",
|
|
20449
|
+
"reason": "Edges anchor to handles."
|
|
20450
|
+
}
|
|
20451
|
+
],
|
|
20452
|
+
"a11yRationale": "Focusable with a ≥44px coarse-pointer hit area around the visible dot.",
|
|
20453
|
+
"flexibility": [
|
|
20454
|
+
{
|
|
20455
|
+
"area": "position",
|
|
20456
|
+
"level": "flexible",
|
|
20457
|
+
"note": "top | right | bottom | left."
|
|
20458
|
+
}
|
|
20459
|
+
]
|
|
20460
|
+
}
|
|
20461
|
+
},
|
|
20462
|
+
"install": "@cascivo/flow"
|
|
20463
|
+
},
|
|
20464
|
+
{
|
|
20465
|
+
"name": "flow/flow-minimap",
|
|
20466
|
+
"type": "flow",
|
|
20467
|
+
"description": "A scaled SVG overview of the graph with a draggable viewport rectangle.",
|
|
20468
|
+
"category": "display",
|
|
20469
|
+
"version": "0.0.0",
|
|
20470
|
+
"files": [],
|
|
20471
|
+
"dependencies": ["@cascivo/core"],
|
|
20472
|
+
"tags": ["flow", "minimap", "overview", "chrome"],
|
|
20473
|
+
"meta": {
|
|
20474
|
+
"name": "FlowMiniMap",
|
|
20475
|
+
"description": "A scaled SVG overview of the graph with a draggable viewport rectangle.",
|
|
20476
|
+
"category": "display",
|
|
20477
|
+
"states": [],
|
|
20478
|
+
"variants": [],
|
|
20479
|
+
"sizes": [],
|
|
20480
|
+
"props": [
|
|
20481
|
+
{
|
|
20482
|
+
"name": "nodes",
|
|
20483
|
+
"type": "FlowNode[]",
|
|
20484
|
+
"required": true
|
|
20485
|
+
},
|
|
20486
|
+
{
|
|
20487
|
+
"name": "viewport",
|
|
20488
|
+
"type": "Viewport",
|
|
20489
|
+
"required": true
|
|
20490
|
+
},
|
|
20491
|
+
{
|
|
20492
|
+
"name": "containerWidth",
|
|
20493
|
+
"type": "number",
|
|
20494
|
+
"required": false
|
|
20495
|
+
},
|
|
20496
|
+
{
|
|
20497
|
+
"name": "containerHeight",
|
|
20498
|
+
"type": "number",
|
|
20499
|
+
"required": false
|
|
20500
|
+
},
|
|
20501
|
+
{
|
|
20502
|
+
"name": "width",
|
|
20503
|
+
"type": "number",
|
|
20504
|
+
"required": false,
|
|
20505
|
+
"default": "200"
|
|
20506
|
+
},
|
|
20507
|
+
{
|
|
20508
|
+
"name": "height",
|
|
20509
|
+
"type": "number",
|
|
20510
|
+
"required": false,
|
|
20511
|
+
"default": "150"
|
|
20512
|
+
},
|
|
20513
|
+
{
|
|
20514
|
+
"name": "position",
|
|
20515
|
+
"type": "'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'",
|
|
20516
|
+
"required": false,
|
|
20517
|
+
"default": "bottom-right"
|
|
20518
|
+
},
|
|
20519
|
+
{
|
|
20520
|
+
"name": "onViewportChange",
|
|
20521
|
+
"type": "(viewport: Viewport) => void",
|
|
20522
|
+
"required": false
|
|
20523
|
+
},
|
|
20524
|
+
{
|
|
20525
|
+
"name": "className",
|
|
20526
|
+
"type": "string",
|
|
20527
|
+
"required": false
|
|
20528
|
+
}
|
|
20529
|
+
],
|
|
20530
|
+
"tokens": [
|
|
20531
|
+
"--cascivo-color-surface",
|
|
20532
|
+
"--cascivo-color-border-strong",
|
|
20533
|
+
"--cascivo-color-accent"
|
|
20534
|
+
],
|
|
20535
|
+
"accessibility": {
|
|
20536
|
+
"role": "img",
|
|
20537
|
+
"wcag": "2.1-AA",
|
|
20538
|
+
"keyboard": []
|
|
20539
|
+
},
|
|
20540
|
+
"examples": [
|
|
20541
|
+
{
|
|
20542
|
+
"title": "Graph overview",
|
|
20543
|
+
"code": "() => (\n <FlowMiniMap\n nodes={[\n { id: 'a', position: { x: 0, y: 0 } },\n { id: 'b', position: { x: 220, y: 120 } },\n { id: 'c', position: { x: 440, y: 0 } },\n ]}\n viewport={{ x: 0, y: 0, zoom: 1 }}\n containerWidth={400}\n containerHeight={300}\n />\n)"
|
|
20544
|
+
}
|
|
20545
|
+
],
|
|
20546
|
+
"dependencies": ["@cascivo/core"],
|
|
20547
|
+
"tags": ["flow", "minimap", "overview", "chrome"],
|
|
20548
|
+
"intent": {
|
|
20549
|
+
"whenToUse": [
|
|
20550
|
+
"Orienting users in a large graph",
|
|
20551
|
+
"Letting users jump around by dragging the view rect"
|
|
20552
|
+
],
|
|
20553
|
+
"whenNotToUse": ["Tiny graphs that fit on screen"],
|
|
20554
|
+
"antiPatterns": [],
|
|
20555
|
+
"related": [
|
|
20556
|
+
{
|
|
20557
|
+
"name": "FlowControls",
|
|
20558
|
+
"relationship": "pairs-with",
|
|
20559
|
+
"reason": "Complementary navigation chrome."
|
|
20560
|
+
}
|
|
20561
|
+
],
|
|
20562
|
+
"a11yRationale": "role=\"img\" with an i18n-defaulted label describing the overview.",
|
|
20563
|
+
"flexibility": [
|
|
20564
|
+
{
|
|
20565
|
+
"area": "size",
|
|
20566
|
+
"level": "flexible",
|
|
20567
|
+
"note": "Configurable width/height."
|
|
20568
|
+
}
|
|
20569
|
+
]
|
|
20570
|
+
}
|
|
20571
|
+
},
|
|
20572
|
+
"install": "@cascivo/flow"
|
|
20573
|
+
},
|
|
20574
|
+
{
|
|
20575
|
+
"name": "flow/flow-node",
|
|
20576
|
+
"type": "flow",
|
|
20577
|
+
"description": "An HTML node box positioned in the viewport pane — draggable, selectable, with arbitrary children.",
|
|
20578
|
+
"category": "display",
|
|
20579
|
+
"version": "0.0.0",
|
|
20580
|
+
"files": [],
|
|
20581
|
+
"dependencies": ["@cascivo/core"],
|
|
20582
|
+
"tags": ["flow", "node", "draggable", "graph"],
|
|
20583
|
+
"meta": {
|
|
20584
|
+
"name": "FlowNode",
|
|
20585
|
+
"description": "An HTML node box positioned in the viewport pane — draggable, selectable, with arbitrary children.",
|
|
20586
|
+
"category": "display",
|
|
20587
|
+
"states": ["default", "dragging", "selected", "focus"],
|
|
20588
|
+
"variants": [],
|
|
20589
|
+
"sizes": [],
|
|
20590
|
+
"props": [
|
|
20591
|
+
{
|
|
20592
|
+
"name": "id",
|
|
20593
|
+
"type": "string",
|
|
20594
|
+
"required": true,
|
|
20595
|
+
"description": "Stable node id."
|
|
20596
|
+
},
|
|
20597
|
+
{
|
|
20598
|
+
"name": "position",
|
|
20599
|
+
"type": "{ x: number; y: number }",
|
|
20600
|
+
"required": false,
|
|
20601
|
+
"description": "Position in flow coords (controllable)."
|
|
20602
|
+
},
|
|
20603
|
+
{
|
|
20604
|
+
"name": "onPositionChange",
|
|
20605
|
+
"type": "(position: XYPosition) => void",
|
|
20606
|
+
"required": false,
|
|
20607
|
+
"description": "Fired while dragging."
|
|
20608
|
+
},
|
|
20609
|
+
{
|
|
20610
|
+
"name": "zoom",
|
|
20611
|
+
"type": "number",
|
|
20612
|
+
"required": false,
|
|
20613
|
+
"default": "1",
|
|
20614
|
+
"description": "Current zoom (drag deltas are divided by it)."
|
|
20615
|
+
},
|
|
20616
|
+
{
|
|
20617
|
+
"name": "selected",
|
|
20618
|
+
"type": "boolean",
|
|
20619
|
+
"required": false,
|
|
20620
|
+
"default": "false"
|
|
20621
|
+
},
|
|
20622
|
+
{
|
|
20623
|
+
"name": "draggable",
|
|
20624
|
+
"type": "boolean",
|
|
20625
|
+
"required": false,
|
|
20626
|
+
"default": "true"
|
|
20627
|
+
},
|
|
20628
|
+
{
|
|
20629
|
+
"name": "interactive",
|
|
20630
|
+
"type": "boolean",
|
|
20631
|
+
"required": false,
|
|
20632
|
+
"default": "true",
|
|
20633
|
+
"description": "When false, the node is view-only: not draggable, selectable, or focusable."
|
|
20634
|
+
},
|
|
20635
|
+
{
|
|
20636
|
+
"name": "onSelect",
|
|
20637
|
+
"type": "(id: string) => void",
|
|
20638
|
+
"required": false
|
|
20639
|
+
},
|
|
20640
|
+
{
|
|
20641
|
+
"name": "children",
|
|
20642
|
+
"type": "ReactNode",
|
|
20643
|
+
"required": false,
|
|
20644
|
+
"description": "Any cascivo content."
|
|
20645
|
+
},
|
|
20646
|
+
{
|
|
20647
|
+
"name": "className",
|
|
20648
|
+
"type": "string",
|
|
20649
|
+
"required": false
|
|
20650
|
+
}
|
|
20651
|
+
],
|
|
20652
|
+
"tokens": [
|
|
20653
|
+
"--cascivo-color-surface",
|
|
20654
|
+
"--cascivo-color-border",
|
|
20655
|
+
"--cascivo-color-accent",
|
|
20656
|
+
"--cascivo-radius-md",
|
|
20657
|
+
"--cascivo-shadow-sm"
|
|
20658
|
+
],
|
|
20659
|
+
"accessibility": {
|
|
20660
|
+
"role": "group",
|
|
20661
|
+
"wcag": "2.1-AA",
|
|
20662
|
+
"keyboard": ["Tab (focus)", "Enter/Space (select)"]
|
|
20663
|
+
},
|
|
20664
|
+
"examples": [
|
|
20665
|
+
{
|
|
20666
|
+
"title": "A draggable node",
|
|
20667
|
+
"code": "() => (\n <div style={{ position: 'relative', height: 160 }}>\n <FlowNode id=\"a\" defaultPosition={{ x: 40, y: 50 }}>Service A</FlowNode>\n </div>\n)"
|
|
20668
|
+
}
|
|
20669
|
+
],
|
|
20670
|
+
"dependencies": ["@cascivo/core"],
|
|
20671
|
+
"tags": ["flow", "node", "draggable", "graph"],
|
|
20672
|
+
"intent": {
|
|
20673
|
+
"whenToUse": [
|
|
20674
|
+
"Representing a unit in a graph that holds arbitrary themed content",
|
|
20675
|
+
"When you hand-compose a flow and need draggable, selectable boxes"
|
|
20676
|
+
],
|
|
20677
|
+
"whenNotToUse": ["For the common case — the declarative <Flow> renders nodes for you"],
|
|
20678
|
+
"antiPatterns": [
|
|
20679
|
+
{
|
|
20680
|
+
"bad": "Rendering node content into an SVG",
|
|
20681
|
+
"good": "HTML node boxes",
|
|
20682
|
+
"why": "HTML nodes inherit the data-theme scope and can contain any cascivo component."
|
|
20683
|
+
}
|
|
20684
|
+
],
|
|
20685
|
+
"related": [
|
|
20686
|
+
{
|
|
20687
|
+
"name": "FlowHandle",
|
|
20688
|
+
"relationship": "contains",
|
|
20689
|
+
"reason": "Connection ports live inside a node."
|
|
20690
|
+
},
|
|
20691
|
+
{
|
|
20692
|
+
"name": "FlowEdge",
|
|
20693
|
+
"relationship": "pairs-with",
|
|
20694
|
+
"reason": "Edges route between nodes."
|
|
20695
|
+
}
|
|
20696
|
+
],
|
|
20697
|
+
"a11yRationale": "Focusable group; Enter/Space select. Visual states (hover/focus/selected) are CSS.",
|
|
20698
|
+
"flexibility": [
|
|
20699
|
+
{
|
|
20700
|
+
"area": "content",
|
|
20701
|
+
"level": "flexible",
|
|
20702
|
+
"note": "Renders any children."
|
|
20703
|
+
},
|
|
20704
|
+
{
|
|
20705
|
+
"area": "position",
|
|
20706
|
+
"level": "flexible",
|
|
20707
|
+
"note": "Controllable; draggable toggleable."
|
|
20708
|
+
}
|
|
20709
|
+
]
|
|
20710
|
+
}
|
|
20711
|
+
},
|
|
20712
|
+
"install": "@cascivo/flow"
|
|
20713
|
+
},
|
|
20714
|
+
{
|
|
20715
|
+
"name": "flow/flow-panel",
|
|
20716
|
+
"type": "flow",
|
|
20717
|
+
"description": "An absolutely-positioned slot for custom flow-canvas UI (legend, toolbar).",
|
|
20718
|
+
"category": "display",
|
|
20719
|
+
"version": "0.0.0",
|
|
20720
|
+
"files": [],
|
|
20721
|
+
"dependencies": ["@cascivo/core"],
|
|
20722
|
+
"tags": ["flow", "panel", "slot", "chrome"],
|
|
20723
|
+
"meta": {
|
|
20724
|
+
"name": "FlowPanel",
|
|
20725
|
+
"description": "An absolutely-positioned slot for custom flow-canvas UI (legend, toolbar).",
|
|
20726
|
+
"category": "display",
|
|
20727
|
+
"states": [],
|
|
20728
|
+
"variants": [],
|
|
20729
|
+
"sizes": [],
|
|
20730
|
+
"props": [
|
|
20731
|
+
{
|
|
20732
|
+
"name": "position",
|
|
20733
|
+
"type": "'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'",
|
|
20734
|
+
"required": false,
|
|
20735
|
+
"default": "top-right"
|
|
20736
|
+
},
|
|
20737
|
+
{
|
|
20738
|
+
"name": "children",
|
|
20739
|
+
"type": "ReactNode",
|
|
20740
|
+
"required": false
|
|
20741
|
+
},
|
|
20742
|
+
{
|
|
20743
|
+
"name": "className",
|
|
20744
|
+
"type": "string",
|
|
20745
|
+
"required": false
|
|
20746
|
+
}
|
|
20747
|
+
],
|
|
20748
|
+
"tokens": ["--cascivo-space-3"],
|
|
20749
|
+
"accessibility": {
|
|
20750
|
+
"role": "group",
|
|
20751
|
+
"wcag": "2.1-AA",
|
|
20752
|
+
"keyboard": []
|
|
20753
|
+
},
|
|
20754
|
+
"examples": [
|
|
20755
|
+
{
|
|
20756
|
+
"title": "A legend panel",
|
|
20757
|
+
"code": "() => (\n <div style={{ position: 'relative', height: 160, border: '1px solid var(--cascivo-color-border)' }}>\n <FlowPanel position=\"top-right\">Legend</FlowPanel>\n </div>\n)"
|
|
20758
|
+
}
|
|
20759
|
+
],
|
|
20760
|
+
"dependencies": ["@cascivo/core"],
|
|
20761
|
+
"tags": ["flow", "panel", "slot", "chrome"],
|
|
20762
|
+
"intent": {
|
|
20763
|
+
"whenToUse": ["Overlaying custom UI (a legend, a toolbar) on a flow canvas"],
|
|
20764
|
+
"whenNotToUse": ["For zoom/fit controls — use FlowControls"],
|
|
20765
|
+
"antiPatterns": [],
|
|
20766
|
+
"related": [
|
|
20767
|
+
{
|
|
20768
|
+
"name": "FlowControls",
|
|
20769
|
+
"relationship": "alternative",
|
|
20770
|
+
"reason": "Purpose-built zoom/fit chrome."
|
|
20771
|
+
}
|
|
20772
|
+
],
|
|
20773
|
+
"a11yRationale": "A plain positioned container; semantics come from its children.",
|
|
20774
|
+
"flexibility": [
|
|
20775
|
+
{
|
|
20776
|
+
"area": "position",
|
|
20777
|
+
"level": "flexible",
|
|
20778
|
+
"note": "Six anchor positions."
|
|
20779
|
+
}
|
|
20780
|
+
]
|
|
20781
|
+
}
|
|
20782
|
+
},
|
|
20783
|
+
"install": "@cascivo/flow"
|
|
20784
|
+
},
|
|
20785
|
+
{
|
|
20786
|
+
"name": "flow/flow-story",
|
|
20787
|
+
"type": "flow",
|
|
20788
|
+
"description": "A scripted, sequenced, looping flow animation — walks a graph step by step with fade-in captions.",
|
|
20789
|
+
"category": "display",
|
|
20790
|
+
"version": "0.0.0",
|
|
20791
|
+
"files": [],
|
|
20792
|
+
"dependencies": ["@cascivo/core"],
|
|
20793
|
+
"tags": ["flow", "animation", "storyline", "walkthrough", "sequence"],
|
|
20794
|
+
"meta": {
|
|
20795
|
+
"name": "FlowStory",
|
|
20796
|
+
"description": "A scripted, sequenced, looping flow animation — walks a graph step by step with fade-in captions.",
|
|
20797
|
+
"category": "display",
|
|
20798
|
+
"states": ["playing", "paused"],
|
|
20799
|
+
"variants": [],
|
|
20800
|
+
"sizes": [],
|
|
20801
|
+
"props": [
|
|
20802
|
+
{
|
|
20803
|
+
"name": "nodes",
|
|
20804
|
+
"type": "FlowNode[]",
|
|
20805
|
+
"required": true
|
|
20806
|
+
},
|
|
20807
|
+
{
|
|
20808
|
+
"name": "edges",
|
|
20809
|
+
"type": "FlowEdge[]",
|
|
20810
|
+
"required": true
|
|
20811
|
+
},
|
|
20812
|
+
{
|
|
20813
|
+
"name": "script",
|
|
20814
|
+
"type": "StoryStep[]",
|
|
20815
|
+
"required": true,
|
|
20816
|
+
"description": "Ordered steps: { from, to, label? } or { edge, reverse? }."
|
|
20817
|
+
},
|
|
20818
|
+
{
|
|
20819
|
+
"name": "loop",
|
|
20820
|
+
"type": "boolean",
|
|
20821
|
+
"required": false,
|
|
20822
|
+
"default": "true"
|
|
20823
|
+
},
|
|
20824
|
+
{
|
|
20825
|
+
"name": "stepDuration",
|
|
20826
|
+
"type": "number",
|
|
20827
|
+
"required": false,
|
|
20828
|
+
"default": "1500"
|
|
20829
|
+
},
|
|
20830
|
+
{
|
|
20831
|
+
"name": "stepGap",
|
|
20832
|
+
"type": "number",
|
|
20833
|
+
"required": false,
|
|
20834
|
+
"default": "0",
|
|
20835
|
+
"description": "Extra pause after each step before advancing (ms) — makes the story easier to follow."
|
|
20836
|
+
},
|
|
20837
|
+
{
|
|
20838
|
+
"name": "playing",
|
|
20839
|
+
"type": "boolean",
|
|
20840
|
+
"required": false
|
|
20841
|
+
},
|
|
20842
|
+
{
|
|
20843
|
+
"name": "currentStep",
|
|
20844
|
+
"type": "number",
|
|
20845
|
+
"required": false
|
|
20846
|
+
},
|
|
20847
|
+
{
|
|
20848
|
+
"name": "onStepChange",
|
|
20849
|
+
"type": "(step: number) => void",
|
|
20850
|
+
"required": false
|
|
20851
|
+
},
|
|
20852
|
+
{
|
|
20853
|
+
"name": "controls",
|
|
20854
|
+
"type": "boolean",
|
|
20855
|
+
"required": false,
|
|
20856
|
+
"default": "true"
|
|
20857
|
+
},
|
|
20858
|
+
{
|
|
20859
|
+
"name": "autoPlay",
|
|
20860
|
+
"type": "boolean",
|
|
20861
|
+
"required": false,
|
|
20862
|
+
"default": "true"
|
|
20863
|
+
},
|
|
20864
|
+
{
|
|
20865
|
+
"name": "interactive",
|
|
20866
|
+
"type": "boolean",
|
|
20867
|
+
"required": false,
|
|
20868
|
+
"default": "false",
|
|
20869
|
+
"description": "A storyline is a view by default — set true to allow selecting/dragging/connecting."
|
|
20870
|
+
},
|
|
20871
|
+
{
|
|
20872
|
+
"name": "className",
|
|
20873
|
+
"type": "string",
|
|
20874
|
+
"required": false
|
|
20875
|
+
}
|
|
20876
|
+
],
|
|
20877
|
+
"tokens": [
|
|
20878
|
+
"--cascivo-color-surface",
|
|
20879
|
+
"--cascivo-color-accent",
|
|
20880
|
+
"--cascivo-color-text-muted"
|
|
20881
|
+
],
|
|
20882
|
+
"accessibility": {
|
|
20883
|
+
"role": "group",
|
|
20884
|
+
"wcag": "2.1-AA",
|
|
20885
|
+
"keyboard": ["Tab (focus controls)", "Enter/Space (play/pause, prev, next)"],
|
|
20886
|
+
"reducedMotion": true
|
|
20887
|
+
},
|
|
20888
|
+
"examples": [
|
|
20889
|
+
{
|
|
20890
|
+
"title": "A request/response storyboard",
|
|
20891
|
+
"description": "A<->B-->C: animate A→B, B→A, A→B, B→C, looping — each step fades in its caption.",
|
|
20892
|
+
"code": "() => (\n <FlowStory\n style={{ height: 340 }}\n nodes={[\n { id: 'A', position: { x: 0, y: 100 }, data: { label: 'Client' } },\n { id: 'B', position: { x: 240, y: 100 }, data: { label: 'Gateway' } },\n { id: 'C', position: { x: 480, y: 100 }, data: { label: 'Service' } },\n ]}\n edges={[\n { id: 'ab', source: 'A', target: 'B' },\n { id: 'bc', source: 'B', target: 'C' },\n ]}\n script={[\n { from: 'A', to: 'B', label: 'Request sent' },\n { from: 'B', to: 'A', label: 'Acknowledged' },\n { from: 'A', to: 'B', label: 'Payload streamed' },\n { from: 'B', to: 'C', label: 'Forwarded to Service' },\n ]}\n loop\n />\n)"
|
|
20893
|
+
},
|
|
20894
|
+
{
|
|
20895
|
+
"title": "A linear pipeline",
|
|
20896
|
+
"description": "Each stage animates and is captioned in turn.",
|
|
20897
|
+
"code": "() => (\n <FlowStory\n style={{ height: 320 }}\n nodes={[\n { id: 'ingest', position: { x: 0, y: 100 }, data: { label: 'Ingest' } },\n { id: 'transform', position: { x: 240, y: 100 }, data: { label: 'Transform' } },\n { id: 'load', position: { x: 480, y: 100 }, data: { label: 'Load' } },\n ]}\n edges={[\n { id: 'it', source: 'ingest', target: 'transform' },\n { id: 'tl', source: 'transform', target: 'load' },\n ]}\n script={[\n { from: 'ingest', to: 'transform', label: 'Records ingested', description: 'Raw events read from the source' },\n { from: 'transform', to: 'load', label: 'Transformed', description: 'Cleaned and enriched' },\n ]}\n />\n)"
|
|
20898
|
+
}
|
|
20899
|
+
],
|
|
20900
|
+
"dependencies": ["@cascivo/core"],
|
|
20901
|
+
"tags": ["flow", "animation", "storyline", "walkthrough", "sequence"],
|
|
20902
|
+
"intent": {
|
|
20903
|
+
"whenToUse": [
|
|
20904
|
+
"Explaining how a flow works step by step, not just showing a static diagram",
|
|
20905
|
+
"Onboarding, architecture walkthroughs, and request/response narratives"
|
|
20906
|
+
],
|
|
20907
|
+
"whenNotToUse": [
|
|
20908
|
+
"A static or freely-explorable graph — use <Flow>",
|
|
20909
|
+
"A single always-on animated edge — set animated on a FlowEdge"
|
|
20910
|
+
],
|
|
20911
|
+
"antiPatterns": [
|
|
20912
|
+
{
|
|
20913
|
+
"bad": "A requestAnimationFrame loop to sequence steps",
|
|
20914
|
+
"good": "A currentStep signal advanced by a timer in useSignalEffect",
|
|
20915
|
+
"why": "CLAUDE.md bans the useEffect-style loop; the signal+timer idiom is deterministic + testable."
|
|
20916
|
+
}
|
|
20917
|
+
],
|
|
20918
|
+
"related": [
|
|
20919
|
+
{
|
|
20920
|
+
"name": "Flow",
|
|
20921
|
+
"relationship": "contains",
|
|
20922
|
+
"reason": "Renders the graph the storyline animates."
|
|
20923
|
+
},
|
|
20924
|
+
{
|
|
20925
|
+
"name": "FlowEdge",
|
|
20926
|
+
"relationship": "pairs-with",
|
|
20927
|
+
"reason": "Reuses the animated-edge keyframe per step."
|
|
20928
|
+
}
|
|
20929
|
+
],
|
|
20930
|
+
"a11yRationale": "The caption is an aria-live region announced each step; play/pause/prev/next make it keyboard-operable; travel motion is disabled under prefers-reduced-motion while captions are preserved.",
|
|
20931
|
+
"flexibility": [
|
|
20932
|
+
{
|
|
20933
|
+
"area": "script",
|
|
20934
|
+
"level": "flexible",
|
|
20935
|
+
"note": "Serializable steps — { from, to } or { edge, reverse }."
|
|
20936
|
+
},
|
|
20937
|
+
{
|
|
20938
|
+
"area": "playback",
|
|
20939
|
+
"level": "flexible",
|
|
20940
|
+
"note": "Controllable playing/currentStep; loop + per-step duration."
|
|
20941
|
+
}
|
|
20942
|
+
]
|
|
20943
|
+
}
|
|
20944
|
+
},
|
|
20945
|
+
"install": "@cascivo/flow"
|
|
19169
20946
|
}
|
|
19170
20947
|
],
|
|
19171
20948
|
"blocks": [
|