@fungi.computer/caps 0.3.1 → 0.5.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/README.md +9 -6
- package/dist/blocks/composer.d.ts +18 -13
- package/dist/blocks/composer.js +10 -11
- package/dist/blocks/faq-chat.js +4 -4
- package/dist/blocks/status-tray.d.ts +8 -2
- package/dist/blocks/status-tray.js +26 -10
- package/dist/components/dropdown-menu.js +4 -4
- package/dist/components/field.d.ts +20 -0
- package/dist/components/field.js +8 -8
- package/dist/components/send-action.d.ts +9 -8
- package/dist/components/send-action.js +10 -8
- package/dist/form-fields.d.ts +3 -1
- package/dist/form-fields.js +25 -18
- package/dist/lib/format-money.d.ts +8 -2
- package/dist/lib/format-money.js +10 -7
- package/dist/schema-form.d.ts +13 -1
- package/dist/schema-form.js +46 -13
- package/dist/styles.css +353 -78
- package/docs/api/blocks/composer.md +10 -7
- package/docs/api/blocks/release-tag.md +7 -7
- package/docs/api/blocks/status-tray.md +11 -10
- package/docs/api/components/field.md +12 -9
- package/docs/api/components/send-action.md +25 -6
- package/docs/api/form.md +48 -8
- package/docs/api/lib/format-money.md +8 -6
- package/package.json +3 -3
- package/src/app-status-bar.css +21 -0
- package/src/styles.css +451 -114
|
@@ -33,11 +33,11 @@ Props accepted by ReleaseTag.
|
|
|
33
33
|
|
|
34
34
|
#### Type Declaration
|
|
35
35
|
|
|
36
|
-
| Name
|
|
37
|
-
|
|
|
38
|
-
| `title`
|
|
39
|
-
| `label?`
|
|
40
|
-
| `entries
|
|
36
|
+
| Name | Type | Description |
|
|
37
|
+
| ---------- | ------------------------------------------------ | --------------------------------------------------------------------------- |
|
|
38
|
+
| `title` | readonly `string`[] | One or two short lines printed large on the tag, such as ["Fungi", "Beta"]. |
|
|
39
|
+
| `label?` | `ReactNode` | A small accent strip under the title, such as "Update". |
|
|
40
|
+
| `entries?` | readonly [`ReleaseTagEntry`](#releasetagentry)[] | Names and versions ruled under the page; omit for a tag with none. |
|
|
41
41
|
|
|
42
42
|
## Functions
|
|
43
43
|
|
|
@@ -48,8 +48,8 @@ function ReleaseTag(__namedParameters): Element;
|
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
A release badge: a torn-off calendar page with binder rings, a stacked title,
|
|
51
|
-
one accent strip and
|
|
52
|
-
only; the caller supplies every word.
|
|
51
|
+
one accent strip and an optional ruled list of names and versions below.
|
|
52
|
+
Presentation only; the caller supplies every word.
|
|
53
53
|
|
|
54
54
|
#### Parameters
|
|
55
55
|
|
|
@@ -45,16 +45,17 @@ Controlled selection and structural slots for a row of footer trays.
|
|
|
45
45
|
|
|
46
46
|
#### Type Declaration
|
|
47
47
|
|
|
48
|
-
| Name
|
|
49
|
-
|
|
|
50
|
-
| `items`
|
|
51
|
-
| `openId`
|
|
52
|
-
| `onOpenChange()`
|
|
53
|
-
| `leading?`
|
|
54
|
-
| `trailing?`
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
48
|
+
| Name | Type | Description |
|
|
49
|
+
| ------------------ | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
50
|
+
| `items` | readonly [`StatusTrayItem`](#statustrayitem)[] | Readouts and their tray contents in display order. |
|
|
51
|
+
| `openId` | `string` \| `null` | Which tray is open. The host owns this state. |
|
|
52
|
+
| `onOpenChange()` | (`id`) => `void` | Requests a selection change or dismissal. |
|
|
53
|
+
| `leading?` | `ReactNode` | Leading readouts that never open a tray (connection state, etc.). |
|
|
54
|
+
| `trailing?` | `ReactNode` | Trailing controls after the chips (Send, Expand, …). |
|
|
55
|
+
| `renderTrigger()?` | (`props`) => `ReactNode` | Compose a native button trigger, forwarding these attributes, children and ref. StatusTray still owns disclosure, dismissal and return focus. Omit to retain the default chip and its theme-owned finish. |
|
|
56
|
+
| `placement?` | `"housing"` \| `"screen"` \| `"host"` | Structural seat. `housing` sits on the plastic below a screen; `screen` sits inside a Display as flat, screen-native text (the wiki's screen material rule); `host` means a host's own chrome draws the chips, so only the open tray renders here. The look of each seat is theme-owned. |
|
|
57
|
+
| `align?` | `"start"` \| `"end"` | Which edge the tray aligns to. |
|
|
58
|
+
| `hostInset?` | `number` | For `host` placement: where the host's trigger starts, in CSS pixels from this tray's inline start, so the open tray sits above it. |
|
|
58
59
|
|
|
59
60
|
## Functions
|
|
60
61
|
|
|
@@ -39,9 +39,10 @@ Props accepted by Form.
|
|
|
39
39
|
|
|
40
40
|
#### Type Declaration
|
|
41
41
|
|
|
42
|
-
| Name
|
|
43
|
-
|
|
|
44
|
-
| `busy?`
|
|
42
|
+
| Name | Type | Description |
|
|
43
|
+
| --------- | ----------- | ----------------------------------------------------------------- |
|
|
44
|
+
| `busy?` | `boolean` | Disables every control while a submission is in flight. |
|
|
45
|
+
| `layout?` | `"columns"` | Opt-in label/control grid; the default field rhythm is unchanged. |
|
|
45
46
|
|
|
46
47
|
---
|
|
47
48
|
|
|
@@ -55,12 +56,13 @@ Props accepted by FormSection.
|
|
|
55
56
|
|
|
56
57
|
#### Type Declaration
|
|
57
58
|
|
|
58
|
-
| Name | Type | Description
|
|
59
|
-
| -------------- | ----------------- |
|
|
60
|
-
| `title` | `ReactNode` | -
|
|
61
|
-
| `description?` | `ReactNode` | -
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
59
|
+
| Name | Type | Description |
|
|
60
|
+
| -------------- | ----------------- | ---------------------------------------------------------- |
|
|
61
|
+
| `title` | `ReactNode` | - |
|
|
62
|
+
| `description?` | `ReactNode` | - |
|
|
63
|
+
| `layout?` | `"columns"` | Opt-in label/control grid when used without a Form parent. |
|
|
64
|
+
| `level?` | `2` \| `3` \| `4` | Heading level inside the page outline. |
|
|
65
|
+
| `children` | `ReactNode` | - |
|
|
64
66
|
|
|
65
67
|
---
|
|
66
68
|
|
|
@@ -78,6 +80,7 @@ Props accepted by FieldSet.
|
|
|
78
80
|
| -------------- | ----------- | ----------------------------------------------------------------- |
|
|
79
81
|
| `legend` | `ReactNode` | - |
|
|
80
82
|
| `description?` | `ReactNode` | - |
|
|
83
|
+
| `layout?` | `"columns"` | Opt-in label/control grid when used without a Form parent. |
|
|
81
84
|
| `error?` | `ReactNode` | The group's announced error, such as "Choose at least one right". |
|
|
82
85
|
| `children` | `ReactNode` | - |
|
|
83
86
|
|
|
@@ -24,7 +24,16 @@ Where a composer's send action is: nothing to send, ready, or working.
|
|
|
24
24
|
|
|
25
25
|
```ts
|
|
26
26
|
type SendActionProps = object &
|
|
27
|
-
Omit<
|
|
27
|
+
Omit<
|
|
28
|
+
KeycapButtonProps,
|
|
29
|
+
| "label"
|
|
30
|
+
| "icon"
|
|
31
|
+
| "readout"
|
|
32
|
+
| "shortcut"
|
|
33
|
+
| "pressed"
|
|
34
|
+
| "expanded"
|
|
35
|
+
| "aria-label"
|
|
36
|
+
>;
|
|
28
37
|
```
|
|
29
38
|
|
|
30
39
|
Props accepted by SendAction.
|
|
@@ -46,13 +55,23 @@ Props accepted by SendAction.
|
|
|
46
55
|
```ts
|
|
47
56
|
const SendAction: ForwardRefExoticComponent<
|
|
48
57
|
object &
|
|
49
|
-
Omit<
|
|
58
|
+
Omit<
|
|
59
|
+
KeycapButtonProps,
|
|
60
|
+
| "aria-label"
|
|
61
|
+
| "label"
|
|
62
|
+
| "icon"
|
|
63
|
+
| "readout"
|
|
64
|
+
| "expanded"
|
|
65
|
+
| "pressed"
|
|
66
|
+
| "shortcut"
|
|
67
|
+
> &
|
|
50
68
|
RefAttributes<HTMLButtonElement>
|
|
51
69
|
>;
|
|
52
70
|
```
|
|
53
71
|
|
|
54
|
-
A composer's send key. Empty, it rests disabled; given
|
|
55
|
-
wakes with a small pop; sending, its arrow launches away
|
|
56
|
-
(or, with `onStop`, a stop square) takes its place
|
|
57
|
-
|
|
72
|
+
A composer's one send key, on the Caps keycap. Empty, it rests disabled; given
|
|
73
|
+
something to send it wakes with a small pop; sending, its arrow launches away
|
|
74
|
+
and a working indicator (or, with `onStop`, a stop square) takes its place in
|
|
75
|
+
the same key; when the work ends the arrow drops back in. It never grows a
|
|
76
|
+
second button. All timing comes from the theme's motion tokens, and reduced
|
|
58
77
|
motion keeps short fades only.
|
package/docs/api/form.md
CHANGED
|
@@ -155,6 +155,14 @@ Props accepted by FormFields.
|
|
|
155
155
|
model: SchemaFormModel<V>;
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
+
##### layout?
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
optional layout?: "columns";
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Opt-in label/control grid for generated sections and groups.
|
|
165
|
+
|
|
158
166
|
##### names?
|
|
159
167
|
|
|
160
168
|
```ts
|
|
@@ -1286,6 +1294,32 @@ Receives the parsed value, never the raw input.
|
|
|
1286
1294
|
\| `Promise`\<[`SubmitResult`](#submitresult)\<`V`\> \| `undefined`\> \|
|
|
1287
1295
|
`Promise`\<`void`\> \| [`SubmitResult`](#submitresult)\<`V`\> \| `undefined`
|
|
1288
1296
|
|
|
1297
|
+
##### onSaved?
|
|
1298
|
+
|
|
1299
|
+
```ts
|
|
1300
|
+
optional onSaved?: (values) => void;
|
|
1301
|
+
```
|
|
1302
|
+
|
|
1303
|
+
Called only after a saved result, with the new raw-value baseline.
|
|
1304
|
+
|
|
1305
|
+
###### Parameters
|
|
1306
|
+
|
|
1307
|
+
| Parameter | Type |
|
|
1308
|
+
| --------- | ---- |
|
|
1309
|
+
| `values` | `V` |
|
|
1310
|
+
|
|
1311
|
+
###### Returns
|
|
1312
|
+
|
|
1313
|
+
`void`
|
|
1314
|
+
|
|
1315
|
+
##### failure?
|
|
1316
|
+
|
|
1317
|
+
```ts
|
|
1318
|
+
optional failure?: string;
|
|
1319
|
+
```
|
|
1320
|
+
|
|
1321
|
+
Safe message for a thrown submit; the cause is logged, never shown.
|
|
1322
|
+
|
|
1289
1323
|
---
|
|
1290
1324
|
|
|
1291
1325
|
### Validator
|
|
@@ -1508,14 +1542,16 @@ How a SchemaForm presents its actions and state.
|
|
|
1508
1542
|
|
|
1509
1543
|
#### Type Declaration
|
|
1510
1544
|
|
|
1511
|
-
| Name | Type
|
|
1512
|
-
| --------------- |
|
|
1513
|
-
| `submitLabel?` | `ReactNode`
|
|
1514
|
-
| `discardLabel?` | `ReactNode`
|
|
1515
|
-
| `
|
|
1516
|
-
| `
|
|
1517
|
-
| `
|
|
1518
|
-
| `
|
|
1545
|
+
| Name | Type | Description |
|
|
1546
|
+
| --------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
1547
|
+
| `submitLabel?` | `ReactNode` | The primary action's label; defaults to "Save changes". |
|
|
1548
|
+
| `discardLabel?` | `ReactNode` | Show a Discard action while there are unsaved changes. |
|
|
1549
|
+
| `onCancel()?` | () => `void` | A secondary exit action, shown even when clean; never submits or discards. |
|
|
1550
|
+
| `cancelLabel?` | `ReactNode` | - |
|
|
1551
|
+
| `allowClean?` | `boolean` | Keep the primary action available on a clean form (create forms). |
|
|
1552
|
+
| `footer?` | `ReactNode` | Replaces the SaveBar, such as a footer with a retry key; `null` drops it. |
|
|
1553
|
+
| `children?` | `ReactNode` | Replaces the generated field list, for custom layouts such as Screen cells: place fields with `<FormFields model names={[…]} />`. |
|
|
1554
|
+
| `disabled?` | `boolean` | Disable every field, such as while an uncertain request is retried. |
|
|
1519
1555
|
|
|
1520
1556
|
---
|
|
1521
1557
|
|
|
@@ -1525,6 +1561,8 @@ How a SchemaForm presents its actions and state.
|
|
|
1525
1561
|
type SchemaFormProps<V, Out> = SchemaFormPresentation &
|
|
1526
1562
|
| {
|
|
1527
1563
|
model: SchemaFormModel<V>;
|
|
1564
|
+
onSaved?: never;
|
|
1565
|
+
failure?: never;
|
|
1528
1566
|
}
|
|
1529
1567
|
| SchemaFormOptions<V, Out>;
|
|
1530
1568
|
```
|
|
@@ -1585,6 +1623,8 @@ Props accepted by SaveBar.
|
|
|
1585
1623
|
| `model` | [`SchemaFormModel`](#schemaformmodel)\<`V`\> | - |
|
|
1586
1624
|
| `label` | `ReactNode` | The primary action, such as "Save changes" or "Create Team". |
|
|
1587
1625
|
| `discardLabel?` | `ReactNode` | Show a Discard action while there are unsaved changes. |
|
|
1626
|
+
| `onCancel()?` | () => `void` | A secondary exit action that never submits or resets the form. |
|
|
1627
|
+
| `cancelLabel?` | `ReactNode` | - |
|
|
1588
1628
|
| `allowClean?` | `boolean` | Keep the primary action available on a clean form (create forms that may submit their defaults). By default a clean form has nothing to save. |
|
|
1589
1629
|
| `dirtyLabel?` | `ReactNode` | The quiet readout while there are unsaved changes. |
|
|
1590
1630
|
| `buttonProps?` | `Omit`\<[`ButtonProps`](components/button.md#buttonprops), `"type"` \| `"disabled"` \| `"loading"` \| `"children"` \| `"onClick"` \| `"asChild"`\> | - |
|
|
@@ -13,17 +13,19 @@
|
|
|
13
13
|
### formatMoney()
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
|
-
function formatMoney(amount): string;
|
|
16
|
+
function formatMoney(amount, options?): string;
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Format USD
|
|
20
|
-
|
|
19
|
+
Format USD to cents, marking non-zero sub-cent amounts rather than rounding them
|
|
20
|
+
to zero. Callers needing the supported five-decimal precision opt in with
|
|
21
|
+
`precision: "exact"`.
|
|
21
22
|
|
|
22
23
|
#### Parameters
|
|
23
24
|
|
|
24
|
-
| Parameter
|
|
25
|
-
|
|
|
26
|
-
| `amount`
|
|
25
|
+
| Parameter | Type |
|
|
26
|
+
| ---------- | ------------------------------------------- |
|
|
27
|
+
| `amount` | `number` |
|
|
28
|
+
| `options?` | `Readonly`\<\{ `precision`: `"exact"`; \}\> |
|
|
27
29
|
|
|
28
30
|
#### Returns
|
|
29
31
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fungi.computer/caps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"author": "Levi <levi@technomancy.dev>",
|
|
5
5
|
"description": "Product-neutral React primitives and blocks for Fungi interfaces",
|
|
6
6
|
"type": "module",
|
|
@@ -476,7 +476,7 @@
|
|
|
476
476
|
"devDependencies": {
|
|
477
477
|
"@fungi.computer/maosaico": "0.1.0",
|
|
478
478
|
"@fungi.computer/sprite": "0.2.0",
|
|
479
|
-
"@fungi.computer/sprite-zdog": "0.
|
|
479
|
+
"@fungi.computer/sprite-zdog": "0.3.0",
|
|
480
480
|
"@ladle/react": "5.1.1",
|
|
481
481
|
"@tailwindcss/cli": "4.2.1",
|
|
482
482
|
"@types/react": "18.3.3",
|
|
@@ -588,7 +588,7 @@
|
|
|
588
588
|
"format:check": "node ../../tooling/repository/scripts/format-package-check.mjs",
|
|
589
589
|
"lint:anti-slop": "node ../../tooling/repository/scripts/lint-package-anti-slop.mjs",
|
|
590
590
|
"build:workbench": "node scripts/workbench-build.mjs --prepared",
|
|
591
|
-
"test:nightly": "node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/caps-workbench --origin-env CAPS_WORKBENCH_URL test/screen-theme.browser.mjs test/scroll-area.browser.mjs test/display-density.browser.mjs && node test/scroll-gutter.browser.mjs",
|
|
591
|
+
"test:nightly": "node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/caps-workbench --origin-env CAPS_WORKBENCH_URL test/screen-theme.browser.mjs test/scroll-area.browser.mjs test/display-density.browser.mjs test/resize-handle.browser.mjs && node test/scroll-gutter.browser.mjs",
|
|
592
592
|
"test:code-input": "node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/caps-code-input --origin-env CAPS_WORKBENCH_URL test/code-input.browser.mjs",
|
|
593
593
|
"test:icon-choice": "node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/caps-icon-choice --origin-env CAPS_WORKBENCH_URL test/icon-choice.browser.mjs",
|
|
594
594
|
"test:choice-label-alignment": "node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/caps-choice-alignment --origin-env CAPS_WORKBENCH_URL test/choice-label-alignment.browser.mjs",
|
package/src/app-status-bar.css
CHANGED
|
@@ -134,6 +134,27 @@
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
/*
|
|
138
|
+
* A count in a bar key is a quiet readout beside its label: plain muted
|
|
139
|
+
* numerals below the label's cap height, never a filled pill as tall as
|
|
140
|
+
* the key. Every key's CountBadge draws this way.
|
|
141
|
+
*/
|
|
142
|
+
.caps-app-status-bar .badge {
|
|
143
|
+
height: auto;
|
|
144
|
+
min-width: 0;
|
|
145
|
+
padding: 0;
|
|
146
|
+
border: 0;
|
|
147
|
+
background: none;
|
|
148
|
+
color: var(--stipe-fg-muted);
|
|
149
|
+
font-size: 0.625rem;
|
|
150
|
+
font-weight: 600;
|
|
151
|
+
line-height: 1;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.caps-app-status-bar .badge-warning {
|
|
155
|
+
color: var(--color-warning);
|
|
156
|
+
}
|
|
157
|
+
|
|
137
158
|
.caps-status-bar-picker-list {
|
|
138
159
|
min-width: min(18rem, calc(100vw - 1.5rem));
|
|
139
160
|
}
|