@bitflow/core 0.6.0 → 0.7.0
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/dist/attempt.d.ts +67 -0
- package/dist/condition.d.ts +38 -0
- package/dist/engine.d.ts +190 -0
- package/dist/errors.d.ts +28 -0
- package/dist/i18n.d.ts +35 -0
- package/dist/id.d.ts +6 -0
- package/dist/image.d.ts +40 -0
- package/dist/index.d.ts +13 -11
- package/dist/index.js +1410 -0
- package/dist/registry.d.ts +118 -0
- package/dist/schema.d.ts +431 -0
- package/dist/score.d.ts +18 -0
- package/dist/styles.d.ts +14 -0
- package/dist/theme.css +451 -0
- package/dist/validate.d.ts +19 -0
- package/dist/validateCondition.d.ts +13 -0
- package/package.json +25 -34
- package/README.md +0 -9
- package/dist/bits.d.ts +0 -128
- package/dist/bitsSchema.d.ts +0 -150
- package/dist/do.d.ts +0 -37
- package/dist/doSchema.d.ts +0 -1478
- package/dist/findLast.d.ts +0 -1
- package/dist/flow.d.ts +0 -169
- package/dist/flowSchema.d.ts +0 -2520
- package/dist/groupBy.d.ts +0 -1
- package/dist/index.cjs.js +0 -725
- package/dist/index.cjs.js.map +0 -7
- package/dist/index.esm.mjs +0 -703
- package/dist/index.esm.mjs.map +0 -7
- package/dist/lerpColor.d.ts +0 -1
- package/dist/levenshtein.d.ts +0 -1
- package/dist/uuid.d.ts +0 -1
package/dist/theme.css
ADDED
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bitflow design tokens.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the Emotion-based `@openpatch/patches` theme. Values are taken from
|
|
5
|
+
* `../branding/colors/openpatch.gpl` for colour and reconstructed from the old
|
|
6
|
+
* patches `base` theme for radii/shadows/type, so the rewrite keeps the same
|
|
7
|
+
* rounded, soft-shadowed feel.
|
|
8
|
+
*
|
|
9
|
+
* Declared on `:root` *and* `:host` on purpose. Custom properties inherit
|
|
10
|
+
* through a shadow boundary, so `:root` alone is enough whenever the host page
|
|
11
|
+
* loads this file. The `:host` copy is what makes a single bit element work
|
|
12
|
+
* when it is dropped on a page that only loaded that one bundle.
|
|
13
|
+
*/
|
|
14
|
+
:root,
|
|
15
|
+
:host {
|
|
16
|
+
/* Brand — branding/colors/openpatch.gpl */
|
|
17
|
+
--bitflow-color-primary: #017460; /* OpenPatch Green */
|
|
18
|
+
--bitflow-color-primary-dark: #004c45; /* Deep Forest */
|
|
19
|
+
--bitflow-color-primary-light: #b5e3d8; /* Fresh Mint */
|
|
20
|
+
|
|
21
|
+
--bitflow-color-neutral-900: #242428; /* Coal */
|
|
22
|
+
--bitflow-color-neutral-700: #3c3c3c; /* Charcoal */
|
|
23
|
+
--bitflow-color-neutral-400: #a4a4a4; /* Quicksilver */
|
|
24
|
+
--bitflow-color-neutral-200: #d6d6d6; /* Silver Charlice */
|
|
25
|
+
--bitflow-color-neutral-100: #f5f5f5; /* Whitesmoke */
|
|
26
|
+
--bitflow-color-black: #000000;
|
|
27
|
+
--bitflow-color-white: #ffffff;
|
|
28
|
+
|
|
29
|
+
/* Semantic feedback. Correct reuses the brand green so "right" and "action"
|
|
30
|
+
read as the same family; the rest are muted so feedback never shouts. */
|
|
31
|
+
--bitflow-color-correct: #017460;
|
|
32
|
+
--bitflow-color-correct-surface: #e6f2ef;
|
|
33
|
+
--bitflow-color-wrong: #a3282d;
|
|
34
|
+
--bitflow-color-wrong-surface: #f8eaea;
|
|
35
|
+
--bitflow-color-warning: #8a6100;
|
|
36
|
+
--bitflow-color-warning-surface: #fbf2df;
|
|
37
|
+
--bitflow-color-info: #1f5673;
|
|
38
|
+
--bitflow-color-info-surface: #e8f0f4;
|
|
39
|
+
--bitflow-color-unknown: var(--bitflow-color-neutral-400);
|
|
40
|
+
--bitflow-color-manual: #5a4b8a;
|
|
41
|
+
--bitflow-color-manual-surface: #eeebf6;
|
|
42
|
+
|
|
43
|
+
/* Surfaces */
|
|
44
|
+
--bitflow-color-background: var(--bitflow-color-neutral-100);
|
|
45
|
+
--bitflow-color-surface: var(--bitflow-color-white);
|
|
46
|
+
--bitflow-color-border: var(--bitflow-color-neutral-200);
|
|
47
|
+
--bitflow-color-text: var(--bitflow-color-neutral-900);
|
|
48
|
+
--bitflow-color-text-muted: var(--bitflow-color-neutral-700);
|
|
49
|
+
|
|
50
|
+
/* Type */
|
|
51
|
+
--bitflow-font-family: "Montserrat", system-ui, -apple-system,
|
|
52
|
+
BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
|
53
|
+
--bitflow-font-family-mono: "Ubuntu Mono", Menlo, Consolas, monospace;
|
|
54
|
+
--bitflow-font-size-small: 14px;
|
|
55
|
+
--bitflow-font-size-standard: 16px;
|
|
56
|
+
--bitflow-font-size-large: 20px;
|
|
57
|
+
--bitflow-font-size-xlarge: 24px;
|
|
58
|
+
--bitflow-font-weight-standard: 400;
|
|
59
|
+
--bitflow-font-weight-medium: 500;
|
|
60
|
+
--bitflow-font-weight-bold: 700;
|
|
61
|
+
--bitflow-line-height-standard: 1.5;
|
|
62
|
+
--bitflow-line-height-tight: 1.25;
|
|
63
|
+
|
|
64
|
+
/* Space */
|
|
65
|
+
--bitflow-space-xxsmall: 4px;
|
|
66
|
+
--bitflow-space-xsmall: 8px;
|
|
67
|
+
--bitflow-space-small: 16px;
|
|
68
|
+
--bitflow-space-medium: 24px;
|
|
69
|
+
--bitflow-space-large: 32px;
|
|
70
|
+
--bitflow-space-xlarge: 48px;
|
|
71
|
+
|
|
72
|
+
/* Shape */
|
|
73
|
+
--bitflow-radius-small: 4px;
|
|
74
|
+
--bitflow-radius-standard: 8px;
|
|
75
|
+
--bitflow-radius-large: 12px;
|
|
76
|
+
--bitflow-radius-full: 9999px;
|
|
77
|
+
--bitflow-border-width: 2px;
|
|
78
|
+
|
|
79
|
+
--bitflow-shadow-standard: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
|
80
|
+
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
|
81
|
+
--bitflow-shadow-medium: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
82
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
83
|
+
--bitflow-shadow-outline: 0 0 0 3px rgba(1, 116, 96, 0.4);
|
|
84
|
+
|
|
85
|
+
/* Layout */
|
|
86
|
+
--bitflow-max-width-content: 720px;
|
|
87
|
+
|
|
88
|
+
/* Motion. Every animation in bitflow multiplies its duration by this, so the
|
|
89
|
+
reduced-motion override below switches the whole library off at once. */
|
|
90
|
+
--bitflow-motion-scale: 1;
|
|
91
|
+
--bitflow-duration-fast: calc(120ms * var(--bitflow-motion-scale));
|
|
92
|
+
--bitflow-duration-standard: calc(200ms * var(--bitflow-motion-scale));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@media (prefers-reduced-motion: reduce) {
|
|
96
|
+
:root,
|
|
97
|
+
:host {
|
|
98
|
+
--bitflow-motion-scale: 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ---------------------------------------------------------------------------
|
|
103
|
+
* Primitives.
|
|
104
|
+
*
|
|
105
|
+
* The classes that replace the `@openpatch/patches` components the old code
|
|
106
|
+
* leaned on: `Box` (296 uses) becomes layout utilities, `Text`/`Heading` become
|
|
107
|
+
* semantic elements plus type classes, `AutoGrid` becomes one grid class, and
|
|
108
|
+
* `Input`/`Select`/`Checkbox`/`Alert`/`Card` become styled native markup.
|
|
109
|
+
*
|
|
110
|
+
* Plain classes rather than React components on purpose: bit packages must not
|
|
111
|
+
* depend on the React package (that would invert the dependency direction and
|
|
112
|
+
* break lazy loading), and a stylesheet is the one thing they can all share.
|
|
113
|
+
* ------------------------------------------------------------------------- */
|
|
114
|
+
|
|
115
|
+
.bitflow-root {
|
|
116
|
+
font-family: var(--bitflow-font-family);
|
|
117
|
+
font-size: var(--bitflow-font-size-standard);
|
|
118
|
+
line-height: var(--bitflow-line-height-standard);
|
|
119
|
+
color: var(--bitflow-color-text);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Stated outright rather than the usual `box-sizing: inherit` trick. Inherited
|
|
123
|
+
values follow the flattened tree, and `<details>` slots its children through
|
|
124
|
+
a UA shadow root that is not a `.bitflow-root` descendant — so everything
|
|
125
|
+
inside a disclosure inherited the browser's `content-box` instead, and any
|
|
126
|
+
`width: 100%` control in there overflowed its panel by its own padding. */
|
|
127
|
+
.bitflow-root,
|
|
128
|
+
.bitflow-root *,
|
|
129
|
+
.bitflow-root *::before,
|
|
130
|
+
.bitflow-root *::after {
|
|
131
|
+
box-sizing: border-box;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Layout ------------------------------------------------------------------ */
|
|
135
|
+
|
|
136
|
+
/* Vertical rhythm without margin collapsing surprises; the old `Box` with a
|
|
137
|
+
`space` prop did the same job one element at a time. */
|
|
138
|
+
.bitflow-stack {
|
|
139
|
+
display: flex;
|
|
140
|
+
flex-direction: column;
|
|
141
|
+
gap: var(--bitflow-space-small);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.bitflow-stack-small {
|
|
145
|
+
gap: var(--bitflow-space-xsmall);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.bitflow-stack-large {
|
|
149
|
+
gap: var(--bitflow-space-medium);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.bitflow-row {
|
|
153
|
+
display: flex;
|
|
154
|
+
flex-wrap: wrap;
|
|
155
|
+
align-items: center;
|
|
156
|
+
gap: var(--bitflow-space-xsmall);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.bitflow-row-end {
|
|
160
|
+
justify-content: flex-end;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.bitflow-row-between {
|
|
164
|
+
justify-content: space-between;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* The `AutoGrid` replacement: columns are as wide as they can be without
|
|
168
|
+
dropping below the minimum, so it reflows on a phone with no media query. */
|
|
169
|
+
.bitflow-grid {
|
|
170
|
+
display: grid;
|
|
171
|
+
gap: var(--bitflow-space-small);
|
|
172
|
+
grid-template-columns: repeat(
|
|
173
|
+
auto-fit,
|
|
174
|
+
minmax(var(--bitflow-grid-min, 220px), 1fr)
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.bitflow-content {
|
|
179
|
+
max-width: var(--bitflow-max-width-content);
|
|
180
|
+
margin-inline: auto;
|
|
181
|
+
width: 100%;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* Type -------------------------------------------------------------------- */
|
|
185
|
+
|
|
186
|
+
.bitflow-heading {
|
|
187
|
+
font-family: var(--bitflow-font-family);
|
|
188
|
+
font-weight: var(--bitflow-font-weight-bold);
|
|
189
|
+
line-height: var(--bitflow-line-height-tight);
|
|
190
|
+
margin: 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
h1.bitflow-heading {
|
|
194
|
+
font-size: var(--bitflow-font-size-xlarge);
|
|
195
|
+
}
|
|
196
|
+
h2.bitflow-heading {
|
|
197
|
+
font-size: var(--bitflow-font-size-large);
|
|
198
|
+
}
|
|
199
|
+
h3.bitflow-heading,
|
|
200
|
+
h4.bitflow-heading,
|
|
201
|
+
h5.bitflow-heading,
|
|
202
|
+
h6.bitflow-heading {
|
|
203
|
+
font-size: var(--bitflow-font-size-standard);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.bitflow-text {
|
|
207
|
+
margin: 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.bitflow-text-muted {
|
|
211
|
+
color: var(--bitflow-color-text-muted);
|
|
212
|
+
font-size: var(--bitflow-font-size-small);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.bitflow-visually-hidden {
|
|
216
|
+
position: absolute;
|
|
217
|
+
width: 1px;
|
|
218
|
+
height: 1px;
|
|
219
|
+
padding: 0;
|
|
220
|
+
margin: -1px;
|
|
221
|
+
overflow: hidden;
|
|
222
|
+
clip-path: inset(50%);
|
|
223
|
+
white-space: nowrap;
|
|
224
|
+
border: 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* Surfaces ---------------------------------------------------------------- */
|
|
228
|
+
|
|
229
|
+
.bitflow-card {
|
|
230
|
+
background: var(--bitflow-color-surface);
|
|
231
|
+
border: 1px solid var(--bitflow-color-border);
|
|
232
|
+
border-radius: var(--bitflow-radius-standard);
|
|
233
|
+
box-shadow: var(--bitflow-shadow-standard);
|
|
234
|
+
padding: var(--bitflow-space-medium);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.bitflow-alert {
|
|
238
|
+
display: flex;
|
|
239
|
+
gap: var(--bitflow-space-xsmall);
|
|
240
|
+
align-items: flex-start;
|
|
241
|
+
padding: var(--bitflow-space-small);
|
|
242
|
+
border-radius: var(--bitflow-radius-standard);
|
|
243
|
+
border-left: 4px solid var(--bitflow-alert-accent, var(--bitflow-color-info));
|
|
244
|
+
background: var(--bitflow-alert-surface, var(--bitflow-color-info-surface));
|
|
245
|
+
color: var(--bitflow-color-text);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* `display: flex` above beats the `hidden` attribute's UA `display: none`, so
|
|
249
|
+
an alert kept in the markup and revealed on demand — which is how every page
|
|
250
|
+
here does it — renders as an empty coloured strip until it has something to
|
|
251
|
+
say. */
|
|
252
|
+
.bitflow-alert[hidden] {
|
|
253
|
+
display: none;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.bitflow-alert-success {
|
|
257
|
+
--bitflow-alert-accent: var(--bitflow-color-correct);
|
|
258
|
+
--bitflow-alert-surface: var(--bitflow-color-correct-surface);
|
|
259
|
+
}
|
|
260
|
+
.bitflow-alert-error {
|
|
261
|
+
--bitflow-alert-accent: var(--bitflow-color-wrong);
|
|
262
|
+
--bitflow-alert-surface: var(--bitflow-color-wrong-surface);
|
|
263
|
+
}
|
|
264
|
+
.bitflow-alert-warning {
|
|
265
|
+
--bitflow-alert-accent: var(--bitflow-color-warning);
|
|
266
|
+
--bitflow-alert-surface: var(--bitflow-color-warning-surface);
|
|
267
|
+
}
|
|
268
|
+
.bitflow-alert-info {
|
|
269
|
+
--bitflow-alert-accent: var(--bitflow-color-info);
|
|
270
|
+
--bitflow-alert-surface: var(--bitflow-color-info-surface);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* Controls ---------------------------------------------------------------- */
|
|
274
|
+
|
|
275
|
+
.bitflow-button {
|
|
276
|
+
font: inherit;
|
|
277
|
+
font-weight: var(--bitflow-font-weight-medium);
|
|
278
|
+
display: inline-flex;
|
|
279
|
+
align-items: center;
|
|
280
|
+
justify-content: center;
|
|
281
|
+
gap: var(--bitflow-space-xxsmall);
|
|
282
|
+
padding: var(--bitflow-space-xsmall) var(--bitflow-space-small);
|
|
283
|
+
min-height: 44px; /* comfortable touch target */
|
|
284
|
+
border: var(--bitflow-border-width) solid transparent;
|
|
285
|
+
border-radius: var(--bitflow-radius-standard);
|
|
286
|
+
background: var(--bitflow-color-primary);
|
|
287
|
+
color: var(--bitflow-color-white);
|
|
288
|
+
cursor: pointer;
|
|
289
|
+
transition: background-color var(--bitflow-duration-fast) ease-out;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.bitflow-button:hover:not(:disabled) {
|
|
293
|
+
background: var(--bitflow-color-primary-dark);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.bitflow-button:disabled {
|
|
297
|
+
opacity: 0.5;
|
|
298
|
+
cursor: not-allowed;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.bitflow-button-secondary {
|
|
302
|
+
background: transparent;
|
|
303
|
+
color: var(--bitflow-color-primary-dark);
|
|
304
|
+
border-color: var(--bitflow-color-border);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.bitflow-button-secondary:hover:not(:disabled) {
|
|
308
|
+
background: var(--bitflow-color-neutral-100);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.bitflow-button-quiet {
|
|
312
|
+
background: transparent;
|
|
313
|
+
color: var(--bitflow-color-text-muted);
|
|
314
|
+
border-color: transparent;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.bitflow-button-quiet:hover:not(:disabled) {
|
|
318
|
+
background: var(--bitflow-color-neutral-100);
|
|
319
|
+
color: var(--bitflow-color-text);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.bitflow-input,
|
|
323
|
+
.bitflow-select,
|
|
324
|
+
.bitflow-textarea {
|
|
325
|
+
font: inherit;
|
|
326
|
+
width: 100%;
|
|
327
|
+
padding: var(--bitflow-space-xsmall);
|
|
328
|
+
min-height: 44px;
|
|
329
|
+
color: var(--bitflow-color-text);
|
|
330
|
+
background: var(--bitflow-color-surface);
|
|
331
|
+
border: var(--bitflow-border-width) solid var(--bitflow-color-border);
|
|
332
|
+
border-radius: var(--bitflow-radius-standard);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.bitflow-textarea {
|
|
336
|
+
min-height: 6em;
|
|
337
|
+
resize: vertical;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.bitflow-input:hover,
|
|
341
|
+
.bitflow-select:hover,
|
|
342
|
+
.bitflow-textarea:hover {
|
|
343
|
+
border-color: var(--bitflow-color-neutral-400);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.bitflow-input[aria-invalid="true"],
|
|
347
|
+
.bitflow-select[aria-invalid="true"],
|
|
348
|
+
.bitflow-textarea[aria-invalid="true"] {
|
|
349
|
+
border-color: var(--bitflow-color-wrong);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* One focus rule for everything, so the keyboard path is always visible. Not
|
|
353
|
+
`:focus` — a mouse click on a button should not draw a ring. */
|
|
354
|
+
.bitflow-root :focus-visible {
|
|
355
|
+
outline: none;
|
|
356
|
+
box-shadow: var(--bitflow-shadow-outline);
|
|
357
|
+
border-radius: var(--bitflow-radius-small);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/* A clickable label wrapping a native radio/checkbox: the whole row is the
|
|
361
|
+
target, and the native control keeps its own semantics and keyboard model. */
|
|
362
|
+
.bitflow-option {
|
|
363
|
+
display: flex;
|
|
364
|
+
/* Centred rather than top-aligned: nearly every choice is one line, and
|
|
365
|
+
top-aligning a control against a text block leaves it visibly high. */
|
|
366
|
+
align-items: center;
|
|
367
|
+
gap: var(--bitflow-space-xsmall);
|
|
368
|
+
padding: var(--bitflow-space-xsmall) var(--bitflow-space-small);
|
|
369
|
+
border: var(--bitflow-border-width) solid var(--bitflow-color-border);
|
|
370
|
+
border-radius: var(--bitflow-radius-standard);
|
|
371
|
+
background: var(--bitflow-color-surface);
|
|
372
|
+
cursor: pointer;
|
|
373
|
+
transition: border-color var(--bitflow-duration-fast) ease-out;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.bitflow-option:hover {
|
|
377
|
+
border-color: var(--bitflow-color-neutral-400);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.bitflow-option:has(:checked) {
|
|
381
|
+
border-color: var(--bitflow-color-primary);
|
|
382
|
+
background: var(--bitflow-color-correct-surface);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.bitflow-option:has(:disabled) {
|
|
386
|
+
cursor: default;
|
|
387
|
+
opacity: 0.75;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.bitflow-option input {
|
|
391
|
+
margin: 0;
|
|
392
|
+
width: 1.15em;
|
|
393
|
+
height: 1.15em;
|
|
394
|
+
flex-shrink: 0;
|
|
395
|
+
accent-color: var(--bitflow-color-primary);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* Fields ------------------------------------------------------------------ */
|
|
399
|
+
|
|
400
|
+
.bitflow-field {
|
|
401
|
+
display: flex;
|
|
402
|
+
flex-direction: column;
|
|
403
|
+
gap: var(--bitflow-space-xxsmall);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.bitflow-label {
|
|
407
|
+
font-weight: var(--bitflow-font-weight-medium);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* The teacher-facing hint under a field label; progressive disclosure means
|
|
411
|
+
most authoring settings carry one rather than a manual page. */
|
|
412
|
+
.bitflow-hint {
|
|
413
|
+
color: var(--bitflow-color-text-muted);
|
|
414
|
+
font-size: var(--bitflow-font-size-small);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.bitflow-field-error {
|
|
418
|
+
color: var(--bitflow-color-wrong);
|
|
419
|
+
font-size: var(--bitflow-font-size-small);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/* Result states ----------------------------------------------------------- */
|
|
423
|
+
|
|
424
|
+
.bitflow-state {
|
|
425
|
+
display: inline-flex;
|
|
426
|
+
align-items: center;
|
|
427
|
+
gap: var(--bitflow-space-xxsmall);
|
|
428
|
+
padding: var(--bitflow-space-xxsmall) var(--bitflow-space-xsmall);
|
|
429
|
+
border-radius: var(--bitflow-radius-full);
|
|
430
|
+
font-size: var(--bitflow-font-size-small);
|
|
431
|
+
font-weight: var(--bitflow-font-weight-medium);
|
|
432
|
+
background: var(--bitflow-state-surface, var(--bitflow-color-neutral-100));
|
|
433
|
+
color: var(--bitflow-state-color, var(--bitflow-color-text-muted));
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.bitflow-state-correct {
|
|
437
|
+
--bitflow-state-color: var(--bitflow-color-correct);
|
|
438
|
+
--bitflow-state-surface: var(--bitflow-color-correct-surface);
|
|
439
|
+
}
|
|
440
|
+
.bitflow-state-wrong {
|
|
441
|
+
--bitflow-state-color: var(--bitflow-color-wrong);
|
|
442
|
+
--bitflow-state-surface: var(--bitflow-color-wrong-surface);
|
|
443
|
+
}
|
|
444
|
+
.bitflow-state-manual {
|
|
445
|
+
--bitflow-state-color: var(--bitflow-color-manual);
|
|
446
|
+
--bitflow-state-surface: var(--bitflow-color-manual-surface);
|
|
447
|
+
}
|
|
448
|
+
.bitflow-state-unknown {
|
|
449
|
+
--bitflow-state-color: var(--bitflow-color-text-muted);
|
|
450
|
+
--bitflow-state-surface: var(--bitflow-color-neutral-100);
|
|
451
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Diagnostic, type Result } from "./errors";
|
|
2
|
+
import { type BitflowDocument } from "./schema";
|
|
3
|
+
export type ValidationResult = {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
diagnostics: Diagnostic[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Envelope-level parse. Bit `data` is *not* checked here — a host that has not
|
|
9
|
+
* loaded a bit package must still be able to read, edit and re-save a document
|
|
10
|
+
* containing it. `validateFlow` does the bit-aware pass.
|
|
11
|
+
*/
|
|
12
|
+
export declare const parseFlow: (input: unknown) => Result<BitflowDocument>;
|
|
13
|
+
/**
|
|
14
|
+
* The authoring-time check behind `<bitflow-flow-editor>`'s `validate()`.
|
|
15
|
+
*
|
|
16
|
+
* Every diagnostic carries the path of the field at fault so the editor can
|
|
17
|
+
* put the message next to the input the teacher has to fix.
|
|
18
|
+
*/
|
|
19
|
+
export declare const validateFlow: (doc: BitflowDocument) => ValidationResult;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Diagnostic } from "./errors";
|
|
2
|
+
import { type BitEdge, type BitflowDocument } from "./schema";
|
|
3
|
+
/**
|
|
4
|
+
* Checks a branch for the mistakes that make it silently never fire.
|
|
5
|
+
*
|
|
6
|
+
* A condition that is always false is the worst kind of authoring error: the
|
|
7
|
+
* flow still runs, the learner still gets somewhere, and the teacher never
|
|
8
|
+
* finds out that the branch they drew does nothing. Everything reported here
|
|
9
|
+
* is a condition that cannot behave the way it was written.
|
|
10
|
+
*/
|
|
11
|
+
export declare const validateCondition: (doc: BitflowDocument, edge: BitEdge, path: string) => Diagnostic[];
|
|
12
|
+
/** Exported for the editor, which shows a branch's reachable tasks. */
|
|
13
|
+
export declare const tasksBefore: (doc: BitflowDocument, nodeId: string) => string[];
|
package/package.json
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitflow/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"author": "Mike Barkmin",
|
|
5
|
+
"description": "Schema, flow engine, attempt runtime and bit registry for bitflow. Pure TypeScript, no UI.",
|
|
5
6
|
"homepage": "https://github.com/openpatch/bitflow#readme",
|
|
6
7
|
"license": "MIT",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"module": "dist/index.js",
|
|
9
11
|
"types": "dist/index.d.ts",
|
|
10
|
-
"typings": "dist/index.d.ts",
|
|
11
|
-
"sideEffects": false,
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
}
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./theme.css": "./dist/theme.css"
|
|
17
18
|
},
|
|
18
19
|
"files": [
|
|
19
|
-
"dist"
|
|
20
|
+
"dist",
|
|
21
|
+
"LICENSE"
|
|
20
22
|
],
|
|
21
23
|
"publishConfig": {
|
|
22
24
|
"access": "public"
|
|
@@ -24,39 +26,28 @@
|
|
|
24
26
|
"repository": {
|
|
25
27
|
"type": "git",
|
|
26
28
|
"url": "git+https://github.com/openpatch/bitflow.git",
|
|
27
|
-
"directory": "packages/core"
|
|
29
|
+
"directory": "packages/bitflow-core"
|
|
28
30
|
},
|
|
29
31
|
"bugs": {
|
|
30
32
|
"url": "https://github.com/openpatch/bitflow/issues"
|
|
31
33
|
},
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"@emotion/cache": "11.7.1",
|
|
35
|
-
"@emotion/react": "11.9.0",
|
|
36
|
-
"@emotion/styled": "11.8.1",
|
|
37
|
-
"@openpatch/patches": "6.0.1",
|
|
38
|
-
"@types/react": "^18.0.12",
|
|
39
|
-
"react": "^18.1.0",
|
|
40
|
-
"react-dom": "^18.1.0",
|
|
41
|
-
"react-hook-form": "^7.31.3",
|
|
42
|
-
"zod": "3.17.3"
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"zod": "^4.4.3"
|
|
43
36
|
},
|
|
44
|
-
"
|
|
45
|
-
"@
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"react-dom": "18.x",
|
|
51
|
-
"zod": "3.x"
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^26.2.0",
|
|
39
|
+
"rimraf": "^6.1.3",
|
|
40
|
+
"typescript": "^7.0.2",
|
|
41
|
+
"vite": "^7.3.6",
|
|
42
|
+
"vitest": "^4.1.10"
|
|
52
43
|
},
|
|
53
44
|
"scripts": {
|
|
54
|
-
"prebuild": "rimraf dist",
|
|
55
45
|
"version": "pnpm build",
|
|
56
46
|
"lint": "tsc --noEmit",
|
|
57
|
-
"test": "
|
|
58
|
-
"
|
|
59
|
-
"build
|
|
60
|
-
"build:types": "tsc --project tsconfig.build.json --declaration --emitDeclarationOnly"
|
|
47
|
+
"test": "vitest run",
|
|
48
|
+
"test:watch": "vitest",
|
|
49
|
+
"build": "rimraf dist && vite build && pnpm build:types",
|
|
50
|
+
"build:types": "tsc --project tsconfig.build.json --declaration --emitDeclarationOnly",
|
|
51
|
+
"dev": "vite build --watch"
|
|
61
52
|
}
|
|
62
53
|
}
|