gbs-add-block 2.1.0 → 2.3.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/.gbs/skills/gbs-components/SKILL.md +190 -134
- package/.gbs/skills/gbs-components/references/install.md +25 -3
- package/.gbs/skills/gbs-components/references/styling.md +246 -207
- package/CHANGELOG.md +74 -0
- package/README.md +154 -23
- package/index.cjs +212 -3
- package/package.json +41 -10
- package/schema/passport-v1.schema.json +204 -0
- package/source/beta-components/accordion/passport.json +259 -0
- package/source/beta-components/accordion/styles.css +207 -208
- package/source/beta-components/alert/passport.json +250 -0
- package/source/beta-components/alert/styles.css +154 -155
- package/source/beta-components/avatar/passport.json +294 -0
- package/source/beta-components/avatar/styles.css +225 -226
- package/source/beta-components/badge/passport.json +332 -0
- package/source/beta-components/badge/styles.css +203 -204
- package/source/beta-components/breadcrumb/passport.json +243 -0
- package/source/beta-components/breadcrumb/styles.css +138 -140
- package/source/beta-components/button/passport.json +402 -0
- package/source/beta-components/button/passport.manual.json +31 -0
- package/source/beta-components/button/styles.css +232 -234
- package/source/beta-components/card/passport.json +337 -0
- package/source/beta-components/card/styles.css +230 -232
- package/source/beta-components/checkbox/passport.json +456 -0
- package/source/beta-components/checkbox/styles.css +211 -213
- package/source/beta-components/combobox/passport.json +456 -0
- package/source/beta-components/combobox/styles.css +419 -417
- package/source/beta-components/data-grid/agent/coerce.ts +368 -0
- package/source/beta-components/data-grid/agent/contract.ts +410 -0
- package/source/beta-components/data-grid/agent/dataset.ts +92 -0
- package/source/beta-components/data-grid/agent/engine.ts +470 -0
- package/source/beta-components/data-grid/agent/executors.ts +155 -0
- package/source/beta-components/data-grid/agent/index.ts +79 -0
- package/source/beta-components/data-grid/agent/intent.ts +324 -0
- package/source/beta-components/data-grid/agent/operations.ts +335 -0
- package/source/beta-components/data-grid/agent/validate.ts +630 -0
- package/source/beta-components/data-grid/agent/webmcp.ts +107 -0
- package/source/beta-components/data-grid/index.ts +14 -7
- package/source/beta-components/data-grid/passport.json +1051 -0
- package/source/beta-components/data-grid/passport.manual.json +255 -0
- package/source/beta-components/data-grid/react/AskGrid.tsx +164 -0
- package/source/beta-components/data-grid/react/DataGrid.tsx +39 -0
- package/source/beta-components/data-grid/styles.css +874 -716
- package/source/beta-components/date-picker/passport.json +407 -0
- package/source/beta-components/date-picker/styles.css +445 -446
- package/source/beta-components/dialog/passport.json +344 -0
- package/source/beta-components/dialog/styles.css +280 -279
- package/source/beta-components/file-uploader/passport.json +518 -0
- package/source/beta-components/file-uploader/styles.css +394 -396
- package/source/beta-components/input/passport.json +536 -0
- package/source/beta-components/input/styles.css +295 -297
- package/source/beta-components/menu/passport.json +322 -0
- package/source/beta-components/menu/styles.css +224 -223
- package/source/beta-components/modal/passport.json +289 -0
- package/source/beta-components/modal/styles.css +241 -240
- package/source/beta-components/number-input/passport.json +541 -0
- package/source/beta-components/number-input/styles.css +230 -231
- package/source/beta-components/popover/passport.json +238 -0
- package/source/beta-components/popover/styles.css +148 -147
- package/source/beta-components/progress/passport.json +270 -0
- package/source/beta-components/progress/styles.css +200 -201
- package/source/beta-components/radio-group/passport.json +477 -0
- package/source/beta-components/radio-group/styles.css +269 -270
- package/source/beta-components/shared/core/agent/adapter.ts +65 -0
- package/source/beta-components/shared/core/agent/history.ts +120 -0
- package/source/beta-components/shared/core/agent/index.ts +46 -0
- package/source/beta-components/shared/core/agent/numbers.ts +217 -0
- package/source/beta-components/shared/core/agent/schema.ts +180 -0
- package/source/beta-components/shared/core/agent/types.ts +169 -0
- package/source/beta-components/shared/core/agent/webmcp.ts +328 -0
- package/source/beta-components/shared/index.ts +9 -0
- package/source/beta-components/shared/react/GramproAIProvider.tsx +50 -0
- package/source/beta-components/shared/react/useAskAgent.ts +217 -0
- package/source/beta-components/shared/styles.css +79 -0
- package/source/beta-components/shared/version.json +4 -4
- package/source/beta-components/shared/version.ts +6 -6
- package/source/beta-components/skeleton/passport.json +251 -0
- package/source/beta-components/skeleton/styles.css +185 -187
- package/source/beta-components/spinner/passport.json +245 -0
- package/source/beta-components/spinner/styles.css +173 -174
- package/source/beta-components/switch/passport.json +421 -0
- package/source/beta-components/switch/styles.css +227 -229
- package/source/beta-components/tabs/passport.json +315 -0
- package/source/beta-components/tabs/styles.css +263 -264
- package/source/beta-components/textarea/passport.json +382 -0
- package/source/beta-components/textarea/styles.css +158 -160
- package/source/beta-components/toaster/passport.json +221 -0
- package/source/beta-components/toaster/styles.css +282 -282
- package/source/beta-components/tooltip/passport.json +170 -0
- package/source/beta-components/tooltip/styles.css +71 -73
- package/tools/env.cjs +61 -0
- package/tools/passport/cli.cjs +79 -0
- package/tools/passport/extract.cjs +493 -0
- package/tools/passport/index.cjs +185 -0
- package/tools/passport/merge.cjs +131 -0
- package/tools/passport/policy.cjs +65 -0
- package/tools/passport/validate.cjs +277 -0
- package/tools/ts-require.cjs +79 -0
- package/source/beta-components/accordion/__tests__/core.test.ts +0 -58
- package/source/beta-components/alert/__tests__/core.test.ts +0 -17
- package/source/beta-components/avatar/__tests__/core.test.ts +0 -88
- package/source/beta-components/badge/__tests__/core.test.ts +0 -46
- package/source/beta-components/breadcrumb/__tests__/core.test.ts +0 -58
- package/source/beta-components/button/__tests__/core.test.ts +0 -31
- package/source/beta-components/card/__tests__/core.test.ts +0 -57
- package/source/beta-components/checkbox/__tests__/core.test.ts +0 -40
- package/source/beta-components/combobox/__tests__/core.test.ts +0 -134
- package/source/beta-components/data-grid/__tests__/core.test.ts +0 -356
- package/source/beta-components/data-grid/__tests__/export.test.ts +0 -70
- package/source/beta-components/data-grid/__tests__/pdf.test.ts +0 -209
- package/source/beta-components/date-picker/__tests__/core.test.ts +0 -273
- package/source/beta-components/dialog/__tests__/core.test.ts +0 -86
- package/source/beta-components/file-uploader/__tests__/core.test.ts +0 -395
- package/source/beta-components/input/__tests__/core.test.ts +0 -75
- package/source/beta-components/menu/__tests__/core.test.ts +0 -120
- package/source/beta-components/modal/__tests__/core.test.ts +0 -55
- package/source/beta-components/number-input/__tests__/core.test.ts +0 -151
- package/source/beta-components/progress/__tests__/core.test.ts +0 -56
- package/source/beta-components/radio-group/__tests__/core.test.ts +0 -64
- package/source/beta-components/shared/__tests__/boundaries.test.ts +0 -95
- package/source/beta-components/shared/__tests__/core.test.ts +0 -55
- package/source/beta-components/shared/__tests__/position.test.ts +0 -143
- package/source/beta-components/skeleton/__tests__/core.test.ts +0 -41
- package/source/beta-components/spinner/__tests__/core.test.ts +0 -48
- package/source/beta-components/switch/__tests__/core.test.ts +0 -64
- package/source/beta-components/tabs/__tests__/core.test.ts +0 -51
- package/source/beta-components/textarea/__tests__/core.test.ts +0 -38
- package/source/beta-components/toaster/__tests__/core.test.ts +0 -256
- package/source/beta-components/tooltip/__tests__/core.test.ts +0 -42
|
@@ -1,270 +1,269 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Radio and RadioGroup styles.
|
|
3
|
-
*
|
|
4
|
-
* The button is the native <input type="radio"> with `appearance: none`, so
|
|
5
|
-
*
|
|
6
|
-
* whole group validates as one required field. Tokens read the shared --gbs-*
|
|
7
|
-
* variables when they are set on an ancestor (set them on :root to theme
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Radio and RadioGroup styles.
|
|
3
|
+
*
|
|
4
|
+
* The button is the native <input type="radio"> with `appearance: none`, so it
|
|
5
|
+
* keeps native behavior: arrow keys roam the group, one tab stop, and the
|
|
6
|
+
* whole group validates as one required field. Tokens read the shared --gbs-*
|
|
7
|
+
* variables when they are set on an ancestor (set them on :root to theme every
|
|
8
|
+
* component at once). Rules are unlayered: they beat a framework reset on
|
|
9
|
+
* specificity, and lose to anything you pass through `className`. With
|
|
10
|
+
* Tailwind v4, import this file after the framework and inside its components
|
|
11
|
+
* layer - see the README.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
.rd-root,
|
|
15
|
+
.rd-group {
|
|
16
|
+
--rd-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
|
|
17
|
+
--rd-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
|
|
18
|
+
--rd-border: var(--gbs-border-control, light-dark(#a1a1aa, #52525b));
|
|
19
|
+
--rd-card-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
|
|
20
|
+
--rd-input-bg: var(--gbs-input-bg, var(--dg-input-bg, light-dark(#ffffff, #121216)));
|
|
21
|
+
--rd-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
|
|
22
|
+
--rd-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
|
|
23
|
+
--rd-accent-soft: var(--gbs-accent-soft, var(--dg-accent-soft, light-dark(#eff6ff, #172554)));
|
|
24
|
+
--rd-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
|
|
25
|
+
--rd-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
|
|
26
|
+
--rd-radius: var(--gbs-radius, var(--dg-radius, 8px));
|
|
27
|
+
--rd-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
|
|
28
|
+
--rd-size: 16px;
|
|
29
|
+
|
|
30
|
+
color-scheme: inherit;
|
|
31
|
+
font-size: var(--rd-font-size);
|
|
32
|
+
line-height: 1.4;
|
|
33
|
+
color: var(--rd-fg);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:where(.dark, [data-theme="dark"]) :is(.rd-root, .rd-group) {
|
|
37
|
+
color-scheme: dark;
|
|
38
|
+
}
|
|
39
|
+
:where(.light, [data-theme="light"]) :is(.rd-root, .rd-group) {
|
|
40
|
+
color-scheme: light;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:where(.rd-root, .rd-group) *,
|
|
44
|
+
:where(.rd-root, .rd-group) *::before,
|
|
45
|
+
:where(.rd-root, .rd-group) *::after {
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* ---------------------------------------------------------------- radio */
|
|
50
|
+
|
|
51
|
+
.rd-root {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: flex-start;
|
|
54
|
+
gap: 8px;
|
|
55
|
+
min-width: 0;
|
|
56
|
+
}
|
|
57
|
+
.rd-root[data-size="sm"] {
|
|
58
|
+
--rd-size: 14px;
|
|
59
|
+
--rd-font-size: 12px;
|
|
60
|
+
}
|
|
61
|
+
.rd-root[data-size="lg"] {
|
|
62
|
+
--rd-size: 20px;
|
|
63
|
+
--rd-font-size: 14px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.rd-control {
|
|
67
|
+
position: relative;
|
|
68
|
+
display: inline-flex;
|
|
69
|
+
flex: none;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
/* Line the button up with the first line of the label. */
|
|
73
|
+
height: calc(var(--rd-font-size) * 1.4);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.rd-input {
|
|
77
|
+
width: var(--rd-size);
|
|
78
|
+
height: var(--rd-size);
|
|
79
|
+
margin: 0;
|
|
80
|
+
border: 1px solid var(--rd-border);
|
|
81
|
+
border-radius: 50%;
|
|
82
|
+
appearance: none;
|
|
83
|
+
background: var(--rd-input-bg);
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
transition:
|
|
86
|
+
border-color 120ms ease,
|
|
87
|
+
background-color 120ms ease;
|
|
88
|
+
}
|
|
89
|
+
.rd-input:hover:not(:disabled) {
|
|
90
|
+
border-color: var(--rd-accent);
|
|
91
|
+
}
|
|
92
|
+
.rd-input:checked {
|
|
93
|
+
border-color: var(--rd-accent);
|
|
94
|
+
border-width: 2px;
|
|
95
|
+
}
|
|
96
|
+
.rd-input:focus-visible {
|
|
97
|
+
outline: 2px solid var(--rd-focus);
|
|
98
|
+
outline-offset: 2px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* The dot is a separate element rather than a border trick, so its size can
|
|
102
|
+
follow the control's and it can animate in. */
|
|
103
|
+
.rd-dot {
|
|
104
|
+
position: absolute;
|
|
105
|
+
width: calc(var(--rd-size) / 2);
|
|
106
|
+
height: calc(var(--rd-size) / 2);
|
|
107
|
+
border-radius: 50%;
|
|
108
|
+
background: var(--rd-accent);
|
|
109
|
+
scale: 0;
|
|
110
|
+
transition: scale 120ms ease;
|
|
111
|
+
pointer-events: none;
|
|
112
|
+
}
|
|
113
|
+
.rd-input:checked ~ .rd-dot {
|
|
114
|
+
scale: 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.rd-root[data-invalid] .rd-input {
|
|
118
|
+
border-color: var(--rd-danger);
|
|
119
|
+
}
|
|
120
|
+
/* Only the button dims. Fading the whole choice takes its label below the
|
|
121
|
+
contrast floor, and someone still has to be able to read the option they
|
|
122
|
+
cannot pick. */
|
|
123
|
+
.rd-input:disabled {
|
|
124
|
+
opacity: 0.5;
|
|
125
|
+
cursor: not-allowed;
|
|
126
|
+
}
|
|
127
|
+
.rd-root[data-disabled] .rd-dot {
|
|
128
|
+
opacity: 0.5;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.rd-text {
|
|
132
|
+
display: flex;
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
gap: 2px;
|
|
135
|
+
min-width: 0;
|
|
136
|
+
}
|
|
137
|
+
.rd-label {
|
|
138
|
+
font-weight: 500;
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
}
|
|
141
|
+
.rd-root[data-disabled] .rd-label {
|
|
142
|
+
color: var(--rd-muted);
|
|
143
|
+
cursor: not-allowed;
|
|
144
|
+
}
|
|
145
|
+
.rd-description {
|
|
146
|
+
color: var(--rd-muted);
|
|
147
|
+
text-wrap: pretty;
|
|
148
|
+
}
|
|
149
|
+
.rd-error {
|
|
150
|
+
color: var(--rd-danger);
|
|
151
|
+
text-wrap: pretty;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* ----------------------------------------------------------------- card */
|
|
155
|
+
|
|
156
|
+
.rd-root[data-variant="card"] {
|
|
157
|
+
position: relative;
|
|
158
|
+
align-items: flex-start;
|
|
159
|
+
padding: 12px;
|
|
160
|
+
border: 1px solid var(--rd-card-border);
|
|
161
|
+
border-radius: var(--rd-radius);
|
|
162
|
+
background: var(--rd-input-bg);
|
|
163
|
+
cursor: pointer;
|
|
164
|
+
transition:
|
|
165
|
+
border-color 120ms ease,
|
|
166
|
+
background-color 120ms ease;
|
|
167
|
+
}
|
|
168
|
+
.rd-root[data-variant="card"]:hover:not([data-disabled]) {
|
|
169
|
+
background: var(--rd-hover);
|
|
170
|
+
}
|
|
171
|
+
.rd-root[data-variant="card"][data-checked] {
|
|
172
|
+
border-color: var(--rd-accent);
|
|
173
|
+
background: var(--rd-accent-soft);
|
|
174
|
+
}
|
|
175
|
+
/* Muted grey clears 4.5:1 on white but only reaches 4.44:1 on the tinted
|
|
176
|
+
background of a selected card, so it moves a step towards the text colour
|
|
177
|
+
there rather than the description quietly failing contrast. */
|
|
178
|
+
.rd-root[data-variant="card"][data-checked] .rd-description {
|
|
179
|
+
color: color-mix(in oklab, var(--rd-muted) 72%, var(--rd-fg));
|
|
180
|
+
}
|
|
181
|
+
/* The whole tile is the target: the input covers it, so a press anywhere
|
|
182
|
+
lands on the radio itself rather than on a label that forwards it. */
|
|
183
|
+
.rd-root[data-variant="card"] .rd-input::after {
|
|
184
|
+
content: "";
|
|
185
|
+
position: absolute;
|
|
186
|
+
inset: 0;
|
|
187
|
+
border-radius: var(--rd-radius);
|
|
188
|
+
}
|
|
189
|
+
.rd-root[data-variant="card"]:has(.rd-input:focus-visible) {
|
|
190
|
+
outline: 2px solid var(--rd-focus);
|
|
191
|
+
outline-offset: 2px;
|
|
192
|
+
}
|
|
193
|
+
.rd-root[data-variant="card"] .rd-input:focus-visible {
|
|
194
|
+
outline: none;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* ---------------------------------------------------------------- group */
|
|
198
|
+
|
|
199
|
+
.rd-group {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
gap: 8px;
|
|
203
|
+
min-width: 0;
|
|
204
|
+
margin: 0;
|
|
205
|
+
padding: 0;
|
|
206
|
+
border: 0;
|
|
207
|
+
}
|
|
208
|
+
.rd-legend {
|
|
209
|
+
padding: 0;
|
|
210
|
+
font-weight: 500;
|
|
211
|
+
}
|
|
212
|
+
.rd-legend[data-required]::after {
|
|
213
|
+
content: " *";
|
|
214
|
+
color: var(--rd-danger);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.rd-items {
|
|
218
|
+
display: flex;
|
|
219
|
+
flex-direction: column;
|
|
220
|
+
gap: 8px;
|
|
221
|
+
min-width: 0;
|
|
222
|
+
}
|
|
223
|
+
.rd-group[data-orientation="horizontal"] .rd-items {
|
|
224
|
+
flex-flow: row wrap;
|
|
225
|
+
gap: 16px;
|
|
226
|
+
}
|
|
227
|
+
.rd-group[data-variant="card"][data-orientation="horizontal"] .rd-items {
|
|
228
|
+
gap: 8px;
|
|
229
|
+
}
|
|
230
|
+
.rd-group[data-variant="card"][data-orientation="horizontal"] .rd-root {
|
|
231
|
+
flex: 1 1 180px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.rd-clear {
|
|
235
|
+
align-self: flex-start;
|
|
236
|
+
padding: 0;
|
|
237
|
+
border: 0;
|
|
238
|
+
background: none;
|
|
239
|
+
color: var(--rd-accent);
|
|
240
|
+
font: inherit;
|
|
241
|
+
text-decoration: underline;
|
|
242
|
+
text-underline-offset: 2px;
|
|
243
|
+
cursor: pointer;
|
|
244
|
+
}
|
|
245
|
+
.rd-clear:focus-visible {
|
|
246
|
+
outline: 2px solid var(--rd-focus);
|
|
247
|
+
outline-offset: 2px;
|
|
248
|
+
border-radius: 3px;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
@media (prefers-reduced-motion: reduce) {
|
|
252
|
+
.rd-input,
|
|
253
|
+
.rd-dot,
|
|
254
|
+
.rd-root[data-variant="card"] {
|
|
255
|
+
transition: none;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@media (forced-colors: active) {
|
|
260
|
+
.rd-input {
|
|
261
|
+
border: 1px solid CanvasText;
|
|
262
|
+
}
|
|
263
|
+
.rd-dot {
|
|
264
|
+
background: Highlight;
|
|
265
|
+
}
|
|
266
|
+
.rd-root[data-variant="card"][data-checked] {
|
|
267
|
+
border-color: Highlight;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The socket a natural-language producer plugs into.
|
|
3
|
+
*
|
|
4
|
+
* One function. Given what a person typed and everything this component
|
|
5
|
+
* instance can do, return the response envelope a producer is held to:
|
|
6
|
+
*
|
|
7
|
+
* { "result": "command", "intents": [ … ] }
|
|
8
|
+
* { "result": "clarify", "question": "…" }
|
|
9
|
+
* { "result": "declined", "reason": "…" }
|
|
10
|
+
*
|
|
11
|
+
* What is deliberately absent is any mention of a model, a vendor, a key or a
|
|
12
|
+
* network. An adapter may call an API, run a model in a worker, apply rules, or
|
|
13
|
+
* return a canned answer in a test. The library ships none of those and
|
|
14
|
+
* depends on none of them — a host supplies one, or the feature is simply not
|
|
15
|
+
* there.
|
|
16
|
+
*
|
|
17
|
+
* The adapter's answer is untrusted. It goes to `agent.respond()`, which
|
|
18
|
+
* validates the envelope through the same five layers a form would face, and
|
|
19
|
+
* nothing reaches the component until that passes. A broken or hostile adapter
|
|
20
|
+
* can propose; it cannot act.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { JsonSchema } from "./types";
|
|
24
|
+
|
|
25
|
+
export interface AgentProposalRequest {
|
|
26
|
+
/** What the person typed, unmodified. */
|
|
27
|
+
utterance: string;
|
|
28
|
+
/**
|
|
29
|
+
* What this instance can do right now: columns, operators, options, current
|
|
30
|
+
* state, policy. The shape is the component's runtime contract.
|
|
31
|
+
*/
|
|
32
|
+
contract: unknown;
|
|
33
|
+
/** The schema the answer is held to. Hand this to a constrained decoder. */
|
|
34
|
+
responseSchema: JsonSchema;
|
|
35
|
+
/** Aborted when the person types again or the component unmounts. */
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns the raw envelope. Parsing is the adapter's job; validating is not.
|
|
41
|
+
*
|
|
42
|
+
* Throwing is a legitimate outcome — a network failure, a refused key — and is
|
|
43
|
+
* reported to the person as a failure to reach the producer, which is a
|
|
44
|
+
* different thing from the producer refusing the request.
|
|
45
|
+
*/
|
|
46
|
+
export type AgentAdapter = (request: AgentProposalRequest) => Promise<unknown>;
|
|
47
|
+
|
|
48
|
+
/** What a UI needs to show while and after a request runs. */
|
|
49
|
+
export type AskPhase = "idle" | "thinking" | "done" | "clarify" | "refused" | "error";
|
|
50
|
+
|
|
51
|
+
export interface AskOutcome {
|
|
52
|
+
phase: AskPhase;
|
|
53
|
+
/** What to show the person: an explanation, a question, or a reason. */
|
|
54
|
+
message: string;
|
|
55
|
+
/** The validator's stable code, when it refused. */
|
|
56
|
+
code?: string;
|
|
57
|
+
/** Which of the five layers refused it. */
|
|
58
|
+
layer?: string;
|
|
59
|
+
/** A better column or value, when the validator could suggest one. */
|
|
60
|
+
suggestion?: string;
|
|
61
|
+
/** Coercion notes worth surfacing: `Read "1 crore" as 10000000`. */
|
|
62
|
+
warnings?: readonly string[];
|
|
63
|
+
/** The envelope exactly as the adapter returned it, for a debug panel. */
|
|
64
|
+
raw?: unknown;
|
|
65
|
+
}
|