@north-light/crouter 0.3.197 → 0.3.198
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/api/client.d.ts +2 -2
- package/dist/api/dto/inbox.d.ts +46 -0
- package/dist/builtin-memory/00-runtime-base.md +3 -3
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/storage-tiers.md +1 -1
- package/dist/builtin-memory/wedged-child-on-runaway-bash.md +1 -1
- package/dist/clients/attach/render/chat-view.d.ts +3 -8
- package/dist/clients/attach/render/chat-view.js +3 -24
- package/dist/clients/attach/render/markdown-source.js +0 -6
- package/dist/clients/attach/render/tool-calls.js +16 -2
- package/dist/clients/attach/viewer.js +613 -602
- package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +2 -2
- package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +11 -4
- package/dist/clients/inbox/controller.js +4 -4
- package/dist/clients/inbox/page-adapter.d.ts +2 -1
- package/dist/clients/inbox/tui/render.js +46 -25
- package/dist/clients/inbox/tui/slots.d.ts +1 -3
- package/dist/clients/inbox/tui/slots.js +8 -37
- package/dist/clients/inbox/tui/types.d.ts +4 -3
- package/dist/commands/__tests__/human.test.js +160 -23
- package/dist/commands/canvas-browse.js +1 -1
- package/dist/commands/human/doc.js +21 -74
- package/dist/commands/human/html.d.ts +2 -0
- package/dist/commands/human/html.js +81 -0
- package/dist/commands/human/prompts.d.ts +5 -4
- package/dist/commands/human/prompts.js +81 -153
- package/dist/commands/human/shared.d.ts +5 -6
- package/dist/commands/human/shared.js +13 -61
- package/dist/commands/human.js +7 -2
- package/dist/core/__tests__/daemon-boot.test.js +7 -4
- package/dist/core/__tests__/dead-node-policy-table.test.js +20 -36
- package/dist/core/__tests__/human-deliver.test.js +28 -37
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +13 -11
- package/dist/core/__tests__/seam/dormancy-release.test.js +63 -4
- package/dist/core/__tests__/serial/human-deliver-e2e.test.js +3 -13
- package/dist/core/canvas/__tests__/attention.test.js +2 -2
- package/dist/core/canvas/__tests__/render-remote.test.js +2 -2
- package/dist/core/canvas/browse/app.d.ts +1 -1
- package/dist/core/canvas/browse/app.js +21 -3
- package/dist/core/canvas/browse/render.d.ts +4 -0
- package/dist/core/canvas/browse/render.js +5 -1
- package/dist/core/canvas/canvas.d.ts +26 -0
- package/dist/core/canvas/canvas.js +55 -0
- package/dist/core/command.js +6 -11
- package/dist/core/config.js +3 -2
- package/dist/core/help.d.ts +3 -0
- package/dist/core/human/__tests__/html-markdown.test.d.ts +1 -0
- package/dist/core/human/__tests__/html-markdown.test.js +52 -0
- package/dist/core/human/__tests__/page-catalog.test.d.ts +1 -0
- package/dist/core/human/__tests__/page-catalog.test.js +16 -0
- package/dist/core/human/__tests__/page-render.test.js +40 -23
- package/dist/core/human/__tests__/page-tickets.test.js +48 -27
- package/dist/core/human/__tests__/page.test.js +48 -65
- package/dist/core/human/__tests__/serial/inbox-core.test.js +5 -15
- package/dist/core/human/answer-text.d.ts +3 -0
- package/dist/core/human/answer-text.js +98 -0
- package/dist/core/human/answer.d.ts +51 -0
- package/dist/core/human/answer.js +125 -0
- package/dist/core/human/component-docs.d.ts +14 -0
- package/dist/core/human/component-docs.js +161 -0
- package/dist/core/human/html-markdown.d.ts +3 -0
- package/dist/core/human/html-markdown.js +288 -0
- package/dist/core/human/page-catalog.d.ts +19 -3
- package/dist/core/human/page-catalog.js +73 -16
- package/dist/core/human/page-render.d.ts +3 -2
- package/dist/core/human/page-render.js +19 -45
- package/dist/core/human/page-schema.d.ts +108 -8
- package/dist/core/human/page-schema.js +88 -31
- package/dist/core/human/page-synth.d.ts +2 -4
- package/dist/core/human/page-synth.js +23 -7
- package/dist/core/human/page.d.ts +14 -7
- package/dist/core/human/page.js +178 -90
- package/dist/core/human/review-schema.d.ts +1 -0
- package/dist/core/human/review-schema.js +1 -1
- package/dist/core/human/scan.d.ts +3 -2
- package/dist/core/human/scan.js +7 -8
- package/dist/core/human/summary.d.ts +4 -7
- package/dist/core/human/summary.js +4 -60
- package/dist/core/human/tickets.d.ts +10 -9
- package/dist/core/human/tickets.js +5 -3
- package/dist/core/human/types.d.ts +4 -0
- package/dist/core/keybindings/catalog.d.ts +2 -2
- package/dist/core/keybindings/catalog.js +1 -0
- package/dist/core/review/realize.js +9 -1
- package/dist/core/runtime/boot-root.js +6 -1
- package/dist/core/runtime/broker.js +8 -6
- package/dist/core/runtime/busy.d.ts +4 -3
- package/dist/core/runtime/busy.js +4 -3
- package/dist/core/runtime/spawn.js +4 -4
- package/dist/core/user-settings.d.ts +17 -2
- package/dist/core/user-settings.js +32 -11
- package/dist/daemon/api/handlers/human.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +22 -7
- package/dist/daemon/cron-run.js +16 -2
- package/dist/daemon/crtrd.js +1 -1
- package/dist/daemon/fleet.d.ts +22 -10
- package/dist/daemon/fleet.js +43 -24
- package/dist/daemon/human/finish.d.ts +2 -1
- package/dist/daemon/human/finish.js +45 -28
- package/dist/daemon/human/sweep.js +4 -2
- package/dist/daemon/reconcilers/broker-supervision.js +11 -8
- package/dist/daemon/reconcilers/dormant-inbox.js +11 -6
- package/dist/daemon/reconcilers/live-obligation.d.ts +21 -1
- package/dist/daemon/reconcilers/live-obligation.js +30 -2
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +28 -1
- package/dist/daemon/review/sweep.js +12 -1
- package/dist/pages/bundle.css +1 -1
- package/dist/pages/bundle.js +1008 -577
- package/dist/pages/comments.d.ts +29 -0
- package/dist/pages/comments.js +51 -0
- package/dist/pages/controls.d.ts +98 -0
- package/dist/pages/controls.js +261 -0
- package/dist/pages/elements/cards.d.ts +15 -4
- package/dist/pages/elements/cards.js +299 -186
- package/dist/pages/elements/chart.d.ts +22 -0
- package/dist/pages/elements/chart.js +107 -91
- package/dist/pages/elements/options.d.ts +9 -0
- package/dist/pages/elements/options.js +268 -155
- package/dist/pages/elements/pages.d.ts +6 -0
- package/dist/pages/elements/pages.js +60 -38
- package/dist/pages/elements/slot.d.ts +5 -0
- package/dist/pages/elements/slot.js +17 -10
- package/dist/pages/elements/table.d.ts +17 -0
- package/dist/pages/elements/table.js +336 -228
- package/dist/pages/elements/text.d.ts +9 -3
- package/dist/pages/elements/text.js +350 -143
- package/dist/pages/host.d.ts +0 -24
- package/dist/pages/host.js +0 -17
- package/dist/pages/readonly.d.ts +24 -0
- package/dist/pages/readonly.js +31 -0
- package/dist/pages/responses.d.ts +37 -0
- package/dist/pages/responses.js +56 -0
- package/dist/pi-extensions/canvas-bash-valve.d.ts +9 -1
- package/dist/pi-extensions/canvas-bash-valve.js +12 -8
- package/dist/types.d.ts +19 -5
- package/dist/types.js +2 -1
- package/package.json +1 -1
- package/runtime.lock.json +2 -2
- package/scripts/install-runtime.mjs +19 -24
- package/dist/clients/attach/render/html-markdown.d.ts +0 -13
- package/dist/clients/attach/render/html-markdown.js +0 -206
- package/dist/core/human/markdown-html.d.ts +0 -8
- package/dist/core/human/markdown-html.js +0 -581
|
@@ -1 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<crtr-chart>` — the line, bar and area plots the page bundle draws.
|
|
3
|
+
*
|
|
4
|
+
* ## Every value here is a `--crtr-chart-*` token
|
|
5
|
+
*
|
|
6
|
+
* The frame, the legend, the axes and the marks themselves are painted through
|
|
7
|
+
* `var(--crtr-chart-<part>-<knob>, <kit default>)`, so a host restyles this element by setting
|
|
8
|
+
* properties on the document root — custom properties inherit into shadow roots, which is the
|
|
9
|
+
* whole mechanism. Series colour keeps coming from the bundle-wide `--crtr-chart-1..5` ramp,
|
|
10
|
+
* which is the theme layer rather than a component knob.
|
|
11
|
+
*
|
|
12
|
+
* Mark paint that SVG would otherwise carry as a presentation attribute — the grid's stroke,
|
|
13
|
+
* the line's width and caps, the area's fill opacity, the point radius, the bar's corner
|
|
14
|
+
* radius — is written as CSS instead, because an attribute cannot hold a `var()` chain and so
|
|
15
|
+
* cannot be overridden. The rendered plot height is styling and reads
|
|
16
|
+
* `--crtr-chart-plot-height`; what stays in TypeScript is the coordinate system's layout
|
|
17
|
+
* arithmetic — the drawing height, margins, tick budget and label metrics are inputs to the
|
|
18
|
+
* geometry this element computes, not declarations a stylesheet could carry.
|
|
19
|
+
*
|
|
20
|
+
* Defaults stay inline at the rule that spends them and no `--crtr-chart-*` component token is
|
|
21
|
+
* ever declared: an unset token is what carries the kit default down the chain.
|
|
22
|
+
*/
|
|
1
23
|
export {};
|
|
@@ -1,4 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `<crtr-chart>` — the line, bar and area plots the page bundle draws.
|
|
3
|
+
*
|
|
4
|
+
* ## Every value here is a `--crtr-chart-*` token
|
|
5
|
+
*
|
|
6
|
+
* The frame, the legend, the axes and the marks themselves are painted through
|
|
7
|
+
* `var(--crtr-chart-<part>-<knob>, <kit default>)`, so a host restyles this element by setting
|
|
8
|
+
* properties on the document root — custom properties inherit into shadow roots, which is the
|
|
9
|
+
* whole mechanism. Series colour keeps coming from the bundle-wide `--crtr-chart-1..5` ramp,
|
|
10
|
+
* which is the theme layer rather than a component knob.
|
|
11
|
+
*
|
|
12
|
+
* Mark paint that SVG would otherwise carry as a presentation attribute — the grid's stroke,
|
|
13
|
+
* the line's width and caps, the area's fill opacity, the point radius, the bar's corner
|
|
14
|
+
* radius — is written as CSS instead, because an attribute cannot hold a `var()` chain and so
|
|
15
|
+
* cannot be overridden. The rendered plot height is styling and reads
|
|
16
|
+
* `--crtr-chart-plot-height`; what stays in TypeScript is the coordinate system's layout
|
|
17
|
+
* arithmetic — the drawing height, margins, tick budget and label metrics are inputs to the
|
|
18
|
+
* geometry this element computes, not declarations a stylesheet could carry.
|
|
19
|
+
*
|
|
20
|
+
* Defaults stay inline at the rule that spends them and no `--crtr-chart-*` component token is
|
|
21
|
+
* ever declared: an unset token is what carries the kit default down the chain.
|
|
22
|
+
*/
|
|
2
23
|
import { registerElement } from '../register.js';
|
|
3
24
|
import { readSlotConfig } from '../slot-config.js';
|
|
4
25
|
/** The five chart tokens, cycled when a config declares more than five series. */
|
|
@@ -30,36 +51,38 @@ const STYLE = `
|
|
|
30
51
|
[part="container"] {
|
|
31
52
|
display: flex;
|
|
32
53
|
flex-direction: column;
|
|
33
|
-
gap: var(--crtr-space-2);
|
|
54
|
+
gap: var(--crtr-chart-container-gap, var(--crtr-space-2));
|
|
34
55
|
width: 100%;
|
|
35
56
|
}
|
|
36
57
|
|
|
37
58
|
[part="title"] {
|
|
38
|
-
color: var(--crtr-color-text);
|
|
39
|
-
font-weight: 500;
|
|
59
|
+
color: var(--crtr-chart-title-text-color, var(--crtr-color-text));
|
|
60
|
+
font-weight: var(--crtr-chart-title-font-weight, 500);
|
|
40
61
|
}
|
|
41
62
|
|
|
42
63
|
[part="legend"] {
|
|
43
64
|
display: flex;
|
|
44
65
|
flex-wrap: wrap;
|
|
45
66
|
align-items: center;
|
|
46
|
-
gap: var(--crtr-space-1) var(--crtr-space-4);
|
|
47
|
-
color: var(--crtr-color-text-muted);
|
|
48
|
-
font-size:
|
|
67
|
+
gap: var(--crtr-chart-legend-gap, var(--crtr-space-1) var(--crtr-space-4));
|
|
68
|
+
color: var(--crtr-chart-legend-text-color, var(--crtr-color-text-muted));
|
|
69
|
+
font-size: var(--crtr-chart-legend-font-size, 0.875em);
|
|
49
70
|
}
|
|
50
71
|
|
|
51
72
|
[part="legend-item"] {
|
|
52
73
|
display: flex;
|
|
53
74
|
align-items: center;
|
|
54
|
-
gap: var(--crtr-space-1);
|
|
75
|
+
gap: var(--crtr-chart-legend-item-gap, var(--crtr-space-1));
|
|
55
76
|
min-width: 0;
|
|
56
77
|
}
|
|
57
78
|
|
|
79
|
+
/* Sized against the legend's own text, not a spacing token doing a sizing job. One knob:
|
|
80
|
+
the swatch is a square, so its width and height are the same value. */
|
|
58
81
|
[part="legend-swatch"] {
|
|
59
82
|
flex: none;
|
|
60
|
-
width:
|
|
61
|
-
height:
|
|
62
|
-
border-radius:
|
|
83
|
+
width: var(--crtr-chart-legend-swatch-size, 0.75em);
|
|
84
|
+
height: var(--crtr-chart-legend-swatch-size, 0.75em);
|
|
85
|
+
border-radius: var(--crtr-chart-legend-swatch-radius, calc(var(--crtr-radius-small) * 0.5));
|
|
63
86
|
}
|
|
64
87
|
|
|
65
88
|
[part="legend-label"] {
|
|
@@ -74,51 +97,91 @@ const STYLE = `
|
|
|
74
97
|
|
|
75
98
|
[part="chart"] {
|
|
76
99
|
display: block;
|
|
100
|
+
height: var(--crtr-chart-plot-height, 260px);
|
|
77
101
|
overflow: visible;
|
|
78
102
|
}
|
|
79
103
|
|
|
104
|
+
/* Waiting for data and having none hold the same space, but each stays in its own scope:
|
|
105
|
+
one scope never names two different parts. */
|
|
80
106
|
[part="empty"] {
|
|
81
107
|
display: flex;
|
|
82
108
|
align-items: center;
|
|
83
109
|
justify-content: center;
|
|
84
|
-
padding: 0 var(--crtr-space-4);
|
|
85
|
-
color: var(--crtr-color-text-muted);
|
|
86
|
-
|
|
87
|
-
border
|
|
110
|
+
padding: var(--crtr-chart-empty-padding, 0 var(--crtr-space-4));
|
|
111
|
+
color: var(--crtr-chart-empty-text-color, var(--crtr-color-text-muted));
|
|
112
|
+
font-size: var(--crtr-chart-empty-font-size, 0.875em);
|
|
113
|
+
border: var(--crtr-chart-empty-border-width, 1px)
|
|
114
|
+
var(--crtr-chart-empty-border-style, dashed)
|
|
115
|
+
var(--crtr-chart-empty-border-color, var(--crtr-color-border));
|
|
116
|
+
border-radius: var(--crtr-chart-empty-radius, var(--crtr-radius-medium));
|
|
88
117
|
}
|
|
89
118
|
|
|
90
119
|
[part="status"] {
|
|
91
120
|
display: flex;
|
|
92
121
|
align-items: center;
|
|
93
122
|
justify-content: center;
|
|
94
|
-
padding: 0 var(--crtr-space-4);
|
|
95
|
-
color: var(--crtr-color-text-muted);
|
|
96
|
-
|
|
97
|
-
border
|
|
123
|
+
padding: var(--crtr-chart-status-padding, 0 var(--crtr-space-4));
|
|
124
|
+
color: var(--crtr-chart-status-text-color, var(--crtr-color-text-muted));
|
|
125
|
+
font-size: var(--crtr-chart-status-font-size, 0.875em);
|
|
126
|
+
border: var(--crtr-chart-status-border-width, 1px)
|
|
127
|
+
var(--crtr-chart-status-border-style, dashed)
|
|
128
|
+
var(--crtr-chart-status-border-color, var(--crtr-color-border));
|
|
129
|
+
border-radius: var(--crtr-chart-status-radius, var(--crtr-radius-medium));
|
|
98
130
|
}
|
|
99
131
|
|
|
132
|
+
/* Flat: this sits in the flow of the page. A shadow in this bundle means floating. */
|
|
100
133
|
[part="unavailable"] {
|
|
101
|
-
padding: var(--crtr-space-3);
|
|
102
|
-
color: var(--crtr-color-text-muted);
|
|
103
|
-
background: var(--crtr-color-surface);
|
|
104
|
-
border:
|
|
105
|
-
|
|
106
|
-
|
|
134
|
+
padding: var(--crtr-chart-unavailable-padding, var(--crtr-space-3));
|
|
135
|
+
color: var(--crtr-chart-unavailable-text-color, var(--crtr-color-text-muted));
|
|
136
|
+
background: var(--crtr-chart-unavailable-fill, var(--crtr-color-surface));
|
|
137
|
+
border: var(--crtr-chart-unavailable-border-width, 1px)
|
|
138
|
+
var(--crtr-chart-unavailable-border-style, solid)
|
|
139
|
+
var(--crtr-chart-unavailable-border-color, var(--crtr-color-border));
|
|
140
|
+
border-radius: var(--crtr-chart-unavailable-radius, var(--crtr-radius-medium));
|
|
107
141
|
}
|
|
108
142
|
|
|
109
143
|
[part="reason"] {
|
|
110
|
-
color: var(--crtr-color-text);
|
|
111
|
-
font-family: var(--crtr-font-mono);
|
|
144
|
+
color: var(--crtr-chart-reason-text-color, var(--crtr-color-text));
|
|
145
|
+
font-family: var(--crtr-chart-reason-font-family, var(--crtr-font-mono));
|
|
112
146
|
}
|
|
113
147
|
|
|
114
148
|
.grid {
|
|
115
|
-
stroke: var(--crtr-color-border);
|
|
116
|
-
stroke-width: 1;
|
|
149
|
+
stroke: var(--crtr-chart-grid-stroke-color, var(--crtr-color-border));
|
|
150
|
+
stroke-width: var(--crtr-chart-grid-stroke-width, 1);
|
|
151
|
+
opacity: var(--crtr-chart-grid-opacity, 0.45);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* The gridline the marks are read against carries more weight than the rest. */
|
|
155
|
+
.grid.baseline {
|
|
156
|
+
opacity: var(--crtr-chart-grid-baseline-opacity, 0.9);
|
|
117
157
|
}
|
|
118
158
|
|
|
119
159
|
.tick {
|
|
120
|
-
fill: var(--crtr-color-text-muted);
|
|
121
|
-
font-size:
|
|
160
|
+
fill: var(--crtr-chart-tick-text-color, var(--crtr-color-text-muted));
|
|
161
|
+
font-size: var(--crtr-chart-tick-font-size, 0.75em);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Mark paint. Series colour arrives per node from the theme's chart ramp; everything
|
|
165
|
+
these marks are drawn WITH is a knob, which is why none of it is an SVG attribute. */
|
|
166
|
+
[part="line"] {
|
|
167
|
+
stroke-width: var(--crtr-chart-line-stroke-width, 2);
|
|
168
|
+
stroke-linecap: var(--crtr-chart-line-line-cap, round);
|
|
169
|
+
stroke-linejoin: var(--crtr-chart-line-line-join, round);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
[part="area"] {
|
|
173
|
+
fill-opacity: var(--crtr-chart-area-fill-opacity, 0.18);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
[part="point"] {
|
|
177
|
+
r: var(--crtr-chart-point-radius, 2.5);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* A bar never rounds away more than a third of its own width, and --bar-max-radius is
|
|
181
|
+
that width — the one number here the stylesheet cannot know, so the plot writes it onto
|
|
182
|
+
the SVG and the knob is clamped against it. */
|
|
183
|
+
[part="bar"] {
|
|
184
|
+
rx: min(var(--crtr-chart-bar-radius, 2px), var(--bar-max-radius));
|
|
122
185
|
}
|
|
123
186
|
`;
|
|
124
187
|
function normalizeConfig(raw) {
|
|
@@ -149,9 +212,6 @@ function normalizeConfig(raw) {
|
|
|
149
212
|
if (raw.title !== undefined && typeof raw.title !== 'string') {
|
|
150
213
|
return { status: 'invalid', reason: 'chart title is not a string' };
|
|
151
214
|
}
|
|
152
|
-
if (raw.source !== undefined && typeof raw.source !== 'string') {
|
|
153
|
-
return { status: 'invalid', reason: 'chart source is not a string' };
|
|
154
|
-
}
|
|
155
215
|
return {
|
|
156
216
|
status: 'ok',
|
|
157
217
|
config: {
|
|
@@ -160,7 +220,6 @@ function normalizeConfig(raw) {
|
|
|
160
220
|
y,
|
|
161
221
|
title: raw.title,
|
|
162
222
|
data: raw.data,
|
|
163
|
-
source: raw.source,
|
|
164
223
|
},
|
|
165
224
|
};
|
|
166
225
|
}
|
|
@@ -329,7 +388,7 @@ class CrtrChartElement extends HTMLElement {
|
|
|
329
388
|
root.append(style, this.#container);
|
|
330
389
|
}
|
|
331
390
|
connectedCallback() {
|
|
332
|
-
|
|
391
|
+
++this.#generation;
|
|
333
392
|
this.#config = null;
|
|
334
393
|
this.#rows = null;
|
|
335
394
|
const read = readSlotConfig(this);
|
|
@@ -345,45 +404,19 @@ class CrtrChartElement extends HTMLElement {
|
|
|
345
404
|
this.#config = normalized.config;
|
|
346
405
|
this.#renderFrame();
|
|
347
406
|
this.#observe();
|
|
348
|
-
const { data
|
|
349
|
-
if (data !== undefined) {
|
|
350
|
-
|
|
351
|
-
this.#renderUnavailable('chart data is not a list of rows');
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
this.#rows = data;
|
|
355
|
-
this.#renderPlot();
|
|
407
|
+
const { data } = normalized.config;
|
|
408
|
+
if (data !== undefined && !isRows(data)) {
|
|
409
|
+
this.#renderUnavailable('chart data is not a list of rows');
|
|
356
410
|
return;
|
|
357
411
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
this.#renderPlot();
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
this.#renderStatus('Loading chart data…');
|
|
364
|
-
void this.#resolveSource(source, generation);
|
|
412
|
+
this.#rows = data ?? [];
|
|
413
|
+
this.#renderPlot();
|
|
365
414
|
}
|
|
366
415
|
disconnectedCallback() {
|
|
367
416
|
this.#generation += 1;
|
|
368
417
|
this.#observer?.disconnect();
|
|
369
418
|
this.#observer = null;
|
|
370
419
|
}
|
|
371
|
-
/** The host bridge resolves `source`; this element never touches the network. */
|
|
372
|
-
async #resolveSource(source, generation) {
|
|
373
|
-
const result = await artifactData(source);
|
|
374
|
-
if (generation !== this.#generation)
|
|
375
|
-
return;
|
|
376
|
-
if (result.status !== 'ok') {
|
|
377
|
-
this.#renderUnavailable(`chart source "${source}" is ${result.status}: ${result.reason}`);
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
if (!isRows(result.data)) {
|
|
381
|
-
this.#renderUnavailable(`chart source "${source}" is not a list of rows`);
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
this.#rows = result.data;
|
|
385
|
-
this.#renderPlot();
|
|
386
|
-
}
|
|
387
420
|
#observe() {
|
|
388
421
|
this.#observer?.disconnect();
|
|
389
422
|
this.#width = this.#plot.getBoundingClientRect().width;
|
|
@@ -409,16 +442,7 @@ class CrtrChartElement extends HTMLElement {
|
|
|
409
442
|
box.append('Chart unavailable: ', detail);
|
|
410
443
|
this.#container.replaceChildren(box);
|
|
411
444
|
}
|
|
412
|
-
/**
|
|
413
|
-
#renderStatus(text) {
|
|
414
|
-
const box = document.createElement('div');
|
|
415
|
-
box.part.add('status');
|
|
416
|
-
box.setAttribute('role', 'status');
|
|
417
|
-
box.style.height = `${HEIGHT}px`;
|
|
418
|
-
box.textContent = text;
|
|
419
|
-
this.#plot.replaceChildren(box);
|
|
420
|
-
}
|
|
421
|
-
/** Title and legend come from the config alone, so they survive a pending source. */
|
|
445
|
+
/** Title and legend come from the config alone. */
|
|
422
446
|
#renderFrame() {
|
|
423
447
|
const config = this.#config;
|
|
424
448
|
if (config === null)
|
|
@@ -495,7 +519,7 @@ class CrtrChartElement extends HTMLElement {
|
|
|
495
519
|
if (plotted === 0 || rows.length === 0) {
|
|
496
520
|
const empty = document.createElement('div');
|
|
497
521
|
empty.part.add('empty');
|
|
498
|
-
empty.style.height =
|
|
522
|
+
empty.style.height = 'var(--crtr-chart-plot-height, 260px)';
|
|
499
523
|
empty.textContent = 'No data to chart';
|
|
500
524
|
this.#plot.replaceChildren(empty);
|
|
501
525
|
return;
|
|
@@ -505,7 +529,7 @@ class CrtrChartElement extends HTMLElement {
|
|
|
505
529
|
// First paint, before the container has been measured: hold the height so
|
|
506
530
|
// the surrounding document does not reflow when the SVG arrives.
|
|
507
531
|
const spacer = document.createElement('div');
|
|
508
|
-
spacer.style.height =
|
|
532
|
+
spacer.style.height = 'var(--crtr-chart-plot-height, 260px)';
|
|
509
533
|
this.#plot.replaceChildren(spacer);
|
|
510
534
|
return;
|
|
511
535
|
}
|
|
@@ -527,13 +551,12 @@ class CrtrChartElement extends HTMLElement {
|
|
|
527
551
|
svg.setAttribute('aria-label', `${config.kind} chart of ${series.map((entry) => entry.label).join(', ')} by ${titleCaseHeader(config.x)}`);
|
|
528
552
|
ticks.forEach((tick, tickIndex) => {
|
|
529
553
|
const line = svgNode('line');
|
|
530
|
-
line.setAttribute('class', 'grid');
|
|
554
|
+
line.setAttribute('class', tick === baselineValue ? 'grid baseline' : 'grid');
|
|
531
555
|
setAttributes(line, {
|
|
532
556
|
x1: marginLeft,
|
|
533
557
|
x2: marginLeft + plotWidth,
|
|
534
558
|
y1: yOf(tick),
|
|
535
559
|
y2: yOf(tick),
|
|
536
|
-
opacity: tick === baselineValue ? 0.9 : 0.45,
|
|
537
560
|
});
|
|
538
561
|
const label = svgNode('text');
|
|
539
562
|
label.setAttribute('class', 'tick');
|
|
@@ -582,6 +605,7 @@ class CrtrChartElement extends HTMLElement {
|
|
|
582
605
|
const groupWidth = band * 0.72;
|
|
583
606
|
const slot = groupWidth / series.length;
|
|
584
607
|
const barWidth = Math.max(1, slot - (slot > 4 ? 1 : 0));
|
|
608
|
+
svg.style.setProperty('--bar-max-radius', `${barWidth / 3}px`);
|
|
585
609
|
series.forEach((entry, seriesIndex) => {
|
|
586
610
|
const group = svgNode('g');
|
|
587
611
|
for (const point of entry.points) {
|
|
@@ -592,7 +616,6 @@ class CrtrChartElement extends HTMLElement {
|
|
|
592
616
|
y: Math.min(y, baselineY),
|
|
593
617
|
width: barWidth,
|
|
594
618
|
height: Math.max(1, Math.abs(baselineY - y)),
|
|
595
|
-
rx: Math.min(2, barWidth / 3),
|
|
596
619
|
});
|
|
597
620
|
bar.style.fill = entry.color;
|
|
598
621
|
bar.append(tooltip(`${entry.label} · ${categories[point.index] ?? point.index}: ${formatExact(point.value)}`));
|
|
@@ -614,26 +637,19 @@ class CrtrChartElement extends HTMLElement {
|
|
|
614
637
|
const area = svgNode('path', 'area');
|
|
615
638
|
setAttributes(area, {
|
|
616
639
|
d: `M ${xOf(first.index)},${baselineY} L ${trace} L ${xOf(last.index)},${baselineY} Z`,
|
|
617
|
-
'fill-opacity': 0.18,
|
|
618
640
|
});
|
|
619
641
|
area.style.fill = entry.color;
|
|
620
642
|
group.append(area);
|
|
621
643
|
}
|
|
622
644
|
const line = svgNode('path', 'line');
|
|
623
|
-
setAttributes(line, {
|
|
624
|
-
d: `M ${trace}`,
|
|
625
|
-
fill: 'none',
|
|
626
|
-
'stroke-width': 2,
|
|
627
|
-
'stroke-linecap': 'round',
|
|
628
|
-
'stroke-linejoin': 'round',
|
|
629
|
-
});
|
|
645
|
+
setAttributes(line, { d: `M ${trace}`, fill: 'none' });
|
|
630
646
|
line.style.stroke = entry.color;
|
|
631
647
|
group.append(line);
|
|
632
648
|
if (!showDots && segment.length > 1)
|
|
633
649
|
continue;
|
|
634
650
|
for (const point of segment) {
|
|
635
651
|
const dot = svgNode('circle', 'point');
|
|
636
|
-
setAttributes(dot, { cx: xOf(point.index), cy: yOf(point.value)
|
|
652
|
+
setAttributes(dot, { cx: xOf(point.index), cy: yOf(point.value) });
|
|
637
653
|
dot.style.fill = entry.color;
|
|
638
654
|
dot.append(tooltip(`${entry.label} · ${categories[point.index] ?? point.index}: ${formatExact(point.value)}`));
|
|
639
655
|
group.append(dot);
|
|
@@ -17,5 +17,14 @@
|
|
|
17
17
|
* Selection is kept in the agent's authored order, never click order, so the response reads
|
|
18
18
|
* the way the question did. `freetext` is absent rather than empty: the response says whether
|
|
19
19
|
* the user wrote something, not whether the box existed.
|
|
20
|
+
*
|
|
21
|
+
* Every styling value this element paints is read through a `--crtr-options-*` component
|
|
22
|
+
* token, so a host restyles the question without touching crtr. Paint that the bundle shares —
|
|
23
|
+
* the option controls, the two writing boxes, the focus ring on every button — chains through
|
|
24
|
+
* the `--crtr-control-*` family behind its element token, which is what keeps a comment box
|
|
25
|
+
* here identical to one in `<crtr-text>` unless a host deliberately parts them. Each anatomy
|
|
26
|
+
* part carries its own scope: the option row and the control inside it, the comment trigger
|
|
27
|
+
* and the box it opens, and the two buttons in that box are five things a person can point at,
|
|
28
|
+
* so they are five scopes rather than one shared name meaning two different rectangles.
|
|
20
29
|
*/
|
|
21
30
|
export {};
|