@calliopelabs/ui 0.7.0 → 0.11.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 +253 -3
- package/dist/appearance/AppearancePicker.js +4 -2
- package/dist/appearance/AppearanceProvider.d.ts +10 -2
- package/dist/appearance/AppearanceProvider.js +6 -2
- package/dist/appearance/AppearanceScript.d.ts +15 -4
- package/dist/appearance/AppearanceScript.js +11 -5
- package/dist/appearance/appearance.js +1 -1
- package/dist/appearance/boot.d.ts +13 -2
- package/dist/appearance/boot.js +35 -5
- package/dist/appearance/product.d.ts +13 -0
- package/dist/appearance/product.js +2 -2
- package/dist/appearance/runtime-brand.d.ts +106 -0
- package/dist/appearance/runtime-brand.js +420 -0
- package/dist/css/appearance.js +147 -0
- package/dist/css/calliope.css +1221 -0
- package/dist/css/components.css +729 -0
- package/dist/css/tokens.css +491 -0
- package/dist/data/DefinitionList.d.ts +16 -0
- package/dist/data/DefinitionList.js +9 -0
- package/dist/data/Stat.d.ts +25 -0
- package/dist/data/Stat.js +19 -0
- package/dist/data/Tag.d.ts +21 -0
- package/dist/data/Tag.js +18 -0
- package/dist/data/types.d.ts +3 -2
- package/dist/data/use-local-table.d.ts +36 -0
- package/dist/data/use-local-table.js +127 -0
- package/dist/index.d.ts +42 -3
- package/dist/index.js +39 -1
- package/dist/nav/Nav.d.ts +2 -1
- package/dist/nav/Nav.js +34 -15
- package/dist/nav/model.d.ts +21 -0
- package/dist/page/PageHeader.d.ts +5 -3
- package/dist/page/PageHeader.js +5 -4
- package/dist/page/Panel.d.ts +19 -0
- package/dist/page/Panel.js +12 -0
- package/dist/primitives/Avatar.d.ts +37 -0
- package/dist/primitives/Avatar.js +43 -0
- package/dist/primitives/Field.d.ts +33 -0
- package/dist/primitives/Field.js +30 -0
- package/dist/primitives/Segmented.d.ts +30 -0
- package/dist/primitives/Segmented.js +20 -0
- package/dist/primitives/Select.d.ts +40 -0
- package/dist/primitives/Select.js +47 -0
- package/dist/primitives/Switch.d.ts +7 -0
- package/dist/primitives/Switch.js +8 -0
- package/dist/primitives/Textarea.d.ts +3 -0
- package/dist/primitives/Textarea.js +6 -0
- package/dist/provider/messages.d.ts +412 -0
- package/dist/provider/messages.js +633 -0
- package/dist/shell/BrandMark.d.ts +25 -3
- package/dist/shell/BrandMark.js +34 -4
- package/dist/shell/RailPanel.js +2 -2
- package/dist/shell/RailTree.js +2 -2
- package/dist/shell/Sidebar.d.ts +9 -2
- package/dist/shell/Sidebar.js +10 -4
- package/dist/shell/UserMenu.d.ts +3 -1
- package/dist/shell/UserMenu.js +3 -11
- package/dist/shell/rail-boot.d.ts +28 -0
- package/dist/shell/rail-boot.js +45 -0
- package/dist/shell/rail-state.d.ts +6 -1
- package/dist/shell/rail-state.js +18 -2
- package/dist/styles/preset.css +4 -0
- package/dist/styles/theme.css +36 -13
- package/dist/theme/css-layer.d.ts +19 -0
- package/dist/theme/css-layer.js +171 -0
- package/dist/theme/css.d.ts +1 -0
- package/dist/theme/css.js +45 -9
- package/dist/workflow/ArtifactCard.d.ts +47 -0
- package/dist/workflow/ArtifactCard.js +45 -0
- package/dist/workflow/DocumentReview.d.ts +74 -0
- package/dist/workflow/DocumentReview.js +54 -0
- package/dist/workflow/FormReview.d.ts +53 -0
- package/dist/workflow/FormReview.js +83 -0
- package/dist/workflow/GateBadge.d.ts +11 -0
- package/dist/workflow/GateBadge.js +14 -0
- package/dist/workflow/MediaReview.d.ts +63 -0
- package/dist/workflow/MediaReview.js +166 -0
- package/dist/workflow/ReviewPanel.d.ts +41 -0
- package/dist/workflow/ReviewPanel.js +59 -0
- package/dist/workflow/RunTimeline.d.ts +25 -0
- package/dist/workflow/RunTimeline.js +56 -0
- package/dist/workflow/WorkflowCard.d.ts +39 -0
- package/dist/workflow/WorkflowCard.js +56 -0
- package/dist/workflow/WorkflowGallery.d.ts +43 -0
- package/dist/workflow/WorkflowGallery.js +69 -0
- package/dist/workflow/canvas/WorkflowCanvas.d.ts +39 -0
- package/dist/workflow/canvas/WorkflowCanvas.js +648 -0
- package/dist/workflow/definition.d.ts +408 -0
- package/dist/workflow/definition.js +411 -0
- package/dist/workflow/editor/WorkflowDiff.d.ts +17 -0
- package/dist/workflow/editor/WorkflowDiff.js +25 -0
- package/dist/workflow/editor/WorkflowImportPreview.d.ts +19 -0
- package/dist/workflow/editor/WorkflowImportPreview.js +50 -0
- package/dist/workflow/editor/WorkflowInspector.d.ts +40 -0
- package/dist/workflow/editor/WorkflowInspector.js +349 -0
- package/dist/workflow/editor/WorkflowJsonView.d.ts +16 -0
- package/dist/workflow/editor/WorkflowJsonView.js +40 -0
- package/dist/workflow/editor/WorkflowPalette.d.ts +16 -0
- package/dist/workflow/editor/WorkflowPalette.js +36 -0
- package/dist/workflow/editor/WorkflowProblems.d.ts +20 -0
- package/dist/workflow/editor/WorkflowProblems.js +51 -0
- package/dist/workflow/editor/WorkflowWorkspace.d.ts +49 -0
- package/dist/workflow/editor/WorkflowWorkspace.js +154 -0
- package/dist/workflow/gallery.d.ts +21 -0
- package/dist/workflow/gallery.js +29 -0
- package/dist/workflow/layout.d.ts +49 -0
- package/dist/workflow/layout.js +162 -0
- package/dist/workflow/model.d.ts +50 -0
- package/dist/workflow/model.js +7 -0
- package/dist/workflow/palette.d.ts +34 -0
- package/dist/workflow/palette.js +70 -0
- package/dist/workflow/portable.d.ts +162 -0
- package/dist/workflow/portable.js +547 -0
- package/dist/workflow/problems.d.ts +38 -0
- package/dist/workflow/problems.js +409 -0
- package/dist/workflow/run.d.ts +94 -0
- package/dist/workflow/run.js +31 -0
- package/dist/workflow/workspace.d.ts +33 -0
- package/dist/workflow/workspace.js +17 -0
- package/package.json +6 -1
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @calliopelabs/ui CSS layer: tokens.
|
|
3
|
+
* Generated by `npm run theme` from src/theme/tokens.ts and the product
|
|
4
|
+
* brands. Do not edit by hand.
|
|
5
|
+
*
|
|
6
|
+
* The same values as the Tailwind preset (theme.css plus each product's brand
|
|
7
|
+
* tokens), for pages without React or Tailwind. Every axis is an attribute,
|
|
8
|
+
* on <html> or on any subtree:
|
|
9
|
+
* data-product the brand: its sidebar and its own accent
|
|
10
|
+
* data-mode dark | light (follows the ground)
|
|
11
|
+
* data-ground the surface ramp
|
|
12
|
+
* data-accent a family accent or the product's own; "custom" with an inline --brand-primary
|
|
13
|
+
* data-density compact | cards
|
|
14
|
+
* data-corners 0 | 2 | 4 | 10 (appearance.js sets --radius inline instead)
|
|
15
|
+
* appearance.js stamps all of them before first paint, or a server that
|
|
16
|
+
* keeps the preference renders them itself.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/* Mode-independent tokens */
|
|
20
|
+
:root {
|
|
21
|
+
--radius: 2px;
|
|
22
|
+
--motion-fast: 120ms;
|
|
23
|
+
--motion-base: 200ms;
|
|
24
|
+
--motion-slow: 320ms;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Dark: black ground, green accent */
|
|
28
|
+
:root,
|
|
29
|
+
[data-mode="dark"] {
|
|
30
|
+
color-scheme: dark;
|
|
31
|
+
--background: #000000;
|
|
32
|
+
--card: #0a0a0a;
|
|
33
|
+
--popover: #141414;
|
|
34
|
+
--secondary: #161616;
|
|
35
|
+
--muted: #111111;
|
|
36
|
+
--accent: #1b1b1b;
|
|
37
|
+
--muted-foreground: #848b88;
|
|
38
|
+
--border: rgba(255, 255, 255, 0.1);
|
|
39
|
+
--input: rgba(255, 255, 255, 0.1);
|
|
40
|
+
--sidebar: var(--brand-sidebar, #0a0a0a);
|
|
41
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #f0f2f1);
|
|
42
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
43
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #848b88);
|
|
44
|
+
--sidebar-accent: color-mix(in oklab, var(--primary) 16%, transparent);
|
|
45
|
+
--sidebar-border: rgba(255, 255, 255, 0.08);
|
|
46
|
+
--foreground: #f0f2f1;
|
|
47
|
+
--card-foreground: #f0f2f1;
|
|
48
|
+
--popover-foreground: #f0f2f1;
|
|
49
|
+
--secondary-foreground: #f0f2f1;
|
|
50
|
+
--accent-foreground: #f0f2f1;
|
|
51
|
+
--brand-primary: #2f9e52;
|
|
52
|
+
--brand-on-primary: #04241b;
|
|
53
|
+
--primary: var(--brand-primary);
|
|
54
|
+
--primary-foreground: var(--brand-on-primary);
|
|
55
|
+
--destructive: #ff6b6b;
|
|
56
|
+
--ring: var(--brand-primary);
|
|
57
|
+
--chart-1: var(--brand-primary);
|
|
58
|
+
--chart-2: #8fd82a;
|
|
59
|
+
--chart-3: #cbf39d;
|
|
60
|
+
--chart-4: #e0b34a;
|
|
61
|
+
--chart-5: #0b6644;
|
|
62
|
+
--sidebar-primary-foreground: var(--brand-on-primary);
|
|
63
|
+
--sidebar-accent-foreground: #f0f2f1;
|
|
64
|
+
--sidebar-ring: var(--brand-primary);
|
|
65
|
+
--surface-0: var(--background);
|
|
66
|
+
--surface-1: var(--card);
|
|
67
|
+
--surface-2: var(--popover);
|
|
68
|
+
--success: #8fd82a;
|
|
69
|
+
--success-fg: #a6e34d;
|
|
70
|
+
--success-bg: rgba(143, 216, 42, 0.1);
|
|
71
|
+
--success-border: rgba(143, 216, 42, 0.35);
|
|
72
|
+
--warning: #f0c34e;
|
|
73
|
+
--warning-fg: #f0c34e;
|
|
74
|
+
--warning-bg: rgba(240, 195, 78, 0.1);
|
|
75
|
+
--warning-border: rgba(240, 195, 78, 0.35);
|
|
76
|
+
--info: #2f9e52;
|
|
77
|
+
--info-fg: #5cbb79;
|
|
78
|
+
--info-bg: rgba(47, 158, 82, 0.14);
|
|
79
|
+
--info-border: rgba(47, 158, 82, 0.4);
|
|
80
|
+
--danger: #ff6b6b;
|
|
81
|
+
--danger-fg: #ff8a8a;
|
|
82
|
+
--danger-bg: rgba(255, 107, 107, 0.1);
|
|
83
|
+
--danger-border: rgba(255, 107, 107, 0.35);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Light: neutral ground, green accent */
|
|
87
|
+
[data-mode="light"] {
|
|
88
|
+
color-scheme: light;
|
|
89
|
+
--background: #fafaf9;
|
|
90
|
+
--card: #ffffff;
|
|
91
|
+
--popover: #ffffff;
|
|
92
|
+
--secondary: #f1f1f0;
|
|
93
|
+
--muted: #f1f1f0;
|
|
94
|
+
--accent: #f3ebe5;
|
|
95
|
+
--muted-foreground: #5c5b58;
|
|
96
|
+
--border: #dfdedc;
|
|
97
|
+
--input: #dfdedc;
|
|
98
|
+
--sidebar: var(--brand-sidebar-light, #f4f3f1);
|
|
99
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #1e1d1b);
|
|
100
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
101
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #5c5b58);
|
|
102
|
+
--sidebar-accent: var(--brand-sidebar-accent, #f3ebe5);
|
|
103
|
+
--sidebar-border: var(--brand-sidebar-border, #dfdedc);
|
|
104
|
+
--foreground: #1e1d1b;
|
|
105
|
+
--card-foreground: #1e1d1b;
|
|
106
|
+
--popover-foreground: #1e1d1b;
|
|
107
|
+
--secondary-foreground: #1e1d1b;
|
|
108
|
+
--accent-foreground: #1e1d1b;
|
|
109
|
+
--brand-primary: #26803f;
|
|
110
|
+
--brand-on-primary: #f3fbf7;
|
|
111
|
+
--primary: var(--brand-primary);
|
|
112
|
+
--primary-foreground: var(--brand-on-primary);
|
|
113
|
+
--destructive: #d40c1a;
|
|
114
|
+
--ring: var(--brand-primary);
|
|
115
|
+
--chart-1: var(--brand-primary);
|
|
116
|
+
--chart-2: #5c9c1a;
|
|
117
|
+
--chart-3: #8a7a5c;
|
|
118
|
+
--chart-4: #b8860b;
|
|
119
|
+
--chart-5: #26803f;
|
|
120
|
+
--sidebar-primary-foreground: var(--brand-on-primary);
|
|
121
|
+
--sidebar-accent-foreground: #1e1d1b;
|
|
122
|
+
--sidebar-ring: var(--brand-primary);
|
|
123
|
+
--surface-0: var(--background);
|
|
124
|
+
--surface-1: var(--card);
|
|
125
|
+
--surface-2: var(--popover);
|
|
126
|
+
--success: #508d23;
|
|
127
|
+
--success-fg: #305a12;
|
|
128
|
+
--success-bg: #e3f5da;
|
|
129
|
+
--success-border: #b4d7a2;
|
|
130
|
+
--warning: #cb7a00;
|
|
131
|
+
--warning-fg: #824c12;
|
|
132
|
+
--warning-bg: #fef0d4;
|
|
133
|
+
--warning-border: #e8c184;
|
|
134
|
+
--info: #2f8543;
|
|
135
|
+
--info-fg: #1b622d;
|
|
136
|
+
--info-bg: #e2f4e3;
|
|
137
|
+
--info-border: #acd8b1;
|
|
138
|
+
--danger: #df2225;
|
|
139
|
+
--danger-fg: #bb0916;
|
|
140
|
+
--danger-bg: #ffeae9;
|
|
141
|
+
--danger-border: #ffb1aa;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Ground: Black (dark) */
|
|
145
|
+
[data-mode="dark"][data-ground="black"] {
|
|
146
|
+
--background: #000000;
|
|
147
|
+
--card: #0a0a0a;
|
|
148
|
+
--popover: #141414;
|
|
149
|
+
--secondary: #161616;
|
|
150
|
+
--muted: #111111;
|
|
151
|
+
--accent: #1b1b1b;
|
|
152
|
+
--muted-foreground: #848b88;
|
|
153
|
+
--border: rgba(255, 255, 255, 0.1);
|
|
154
|
+
--input: rgba(255, 255, 255, 0.1);
|
|
155
|
+
--sidebar: var(--brand-sidebar, #0a0a0a);
|
|
156
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #f0f2f1);
|
|
157
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
158
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #848b88);
|
|
159
|
+
--sidebar-accent: color-mix(in oklab, var(--primary) 16%, transparent);
|
|
160
|
+
--sidebar-border: rgba(255, 255, 255, 0.08);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* Ground: Charcoal (dark) */
|
|
164
|
+
[data-mode="dark"][data-ground="charcoal"] {
|
|
165
|
+
--background: #0e0f10;
|
|
166
|
+
--card: #161819;
|
|
167
|
+
--popover: #1e2022;
|
|
168
|
+
--secondary: #202325;
|
|
169
|
+
--muted: #191b1c;
|
|
170
|
+
--accent: #232628;
|
|
171
|
+
--muted-foreground: #8b9194;
|
|
172
|
+
--border: rgba(255, 255, 255, 0.1);
|
|
173
|
+
--input: rgba(255, 255, 255, 0.1);
|
|
174
|
+
--sidebar: var(--brand-sidebar, #161819);
|
|
175
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #f0f2f1);
|
|
176
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
177
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #8b9194);
|
|
178
|
+
--sidebar-accent: color-mix(in oklab, var(--primary) 16%, transparent);
|
|
179
|
+
--sidebar-border: rgba(255, 255, 255, 0.08);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* Ground: Graphite (dark) */
|
|
183
|
+
[data-mode="dark"][data-ground="graphite"] {
|
|
184
|
+
--background: #111214;
|
|
185
|
+
--card: #18191b;
|
|
186
|
+
--popover: #202124;
|
|
187
|
+
--secondary: #222326;
|
|
188
|
+
--muted: #1b1c1e;
|
|
189
|
+
--accent: #26272a;
|
|
190
|
+
--muted-foreground: #8e9296;
|
|
191
|
+
--border: rgba(255, 255, 255, 0.09);
|
|
192
|
+
--input: rgba(255, 255, 255, 0.1);
|
|
193
|
+
--sidebar: #161719;
|
|
194
|
+
--sidebar-foreground: #f0f2f1;
|
|
195
|
+
--sidebar-primary: var(--brand-primary);
|
|
196
|
+
--sidebar-muted-foreground: #8e9296;
|
|
197
|
+
--sidebar-accent: color-mix(in oklab, var(--primary) 14%, transparent);
|
|
198
|
+
--sidebar-border: rgba(255, 255, 255, 0.07);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Ground: Emerald (dark) */
|
|
202
|
+
[data-mode="dark"][data-ground="emerald"] {
|
|
203
|
+
--background: #050b08;
|
|
204
|
+
--card: #0a1310;
|
|
205
|
+
--popover: #0d1814;
|
|
206
|
+
--secondary: #121d18;
|
|
207
|
+
--muted: #101a15;
|
|
208
|
+
--accent: #16261f;
|
|
209
|
+
--muted-foreground: #8ba199;
|
|
210
|
+
--border: rgba(255, 255, 255, 0.1);
|
|
211
|
+
--input: rgba(255, 255, 255, 0.1);
|
|
212
|
+
--sidebar: var(--brand-sidebar, #0a1310);
|
|
213
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #f0f2f1);
|
|
214
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
215
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #8ba199);
|
|
216
|
+
--sidebar-accent: color-mix(in oklab, var(--primary) 16%, transparent);
|
|
217
|
+
--sidebar-border: rgba(255, 255, 255, 0.08);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Ground: Navy (dark) */
|
|
221
|
+
[data-mode="dark"][data-ground="navy"] {
|
|
222
|
+
--background: #0b1120;
|
|
223
|
+
--card: #152141;
|
|
224
|
+
--popover: #1a284a;
|
|
225
|
+
--secondary: #1d2b50;
|
|
226
|
+
--muted: #182545;
|
|
227
|
+
--accent: #213157;
|
|
228
|
+
--muted-foreground: #97a6c2;
|
|
229
|
+
--border: rgba(255, 255, 255, 0.1);
|
|
230
|
+
--input: rgba(255, 255, 255, 0.1);
|
|
231
|
+
--sidebar: var(--brand-sidebar, #152141);
|
|
232
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #f0f2f1);
|
|
233
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
234
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #97a6c2);
|
|
235
|
+
--sidebar-accent: color-mix(in oklab, var(--primary) 16%, transparent);
|
|
236
|
+
--sidebar-border: rgba(255, 255, 255, 0.08);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* Ground: Paper (light) */
|
|
240
|
+
[data-mode="light"][data-ground="paper"] {
|
|
241
|
+
--background: #faf6ee;
|
|
242
|
+
--card: #fffdf9;
|
|
243
|
+
--popover: #fffdf9;
|
|
244
|
+
--secondary: #f3eee4;
|
|
245
|
+
--muted: #f3eee4;
|
|
246
|
+
--accent: #f0e6da;
|
|
247
|
+
--muted-foreground: #5c5b58;
|
|
248
|
+
--border: #dedad2;
|
|
249
|
+
--input: #dedad2;
|
|
250
|
+
--sidebar: var(--brand-sidebar-light, #f5f0e4);
|
|
251
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #1e1d1b);
|
|
252
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
253
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #5c5b58);
|
|
254
|
+
--sidebar-accent: var(--brand-sidebar-accent, #f0e6da);
|
|
255
|
+
--sidebar-border: var(--brand-sidebar-border, #dedad2);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* Ground: Mist (light) */
|
|
259
|
+
[data-mode="light"][data-ground="mist"] {
|
|
260
|
+
--background: #f2f7f9;
|
|
261
|
+
--card: #ffffff;
|
|
262
|
+
--popover: #ffffff;
|
|
263
|
+
--secondary: #e9eff2;
|
|
264
|
+
--muted: #e9eff2;
|
|
265
|
+
--accent: #dfeaf0;
|
|
266
|
+
--muted-foreground: #5c5b58;
|
|
267
|
+
--border: #d6dcdf;
|
|
268
|
+
--input: #d6dcdf;
|
|
269
|
+
--sidebar: var(--brand-sidebar-light, #e9f1f5);
|
|
270
|
+
--sidebar-foreground: var(--brand-sidebar-foreground, #1e1d1b);
|
|
271
|
+
--sidebar-primary: var(--brand-sidebar-primary, var(--brand-primary));
|
|
272
|
+
--sidebar-muted-foreground: var(--brand-sidebar-muted-foreground, #5c5b58);
|
|
273
|
+
--sidebar-accent: var(--brand-sidebar-accent, #dfeaf0);
|
|
274
|
+
--sidebar-border: var(--brand-sidebar-border, #d6dcdf);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/* Accent: Green (dark) */
|
|
278
|
+
[data-mode="dark"][data-accent="green"] {
|
|
279
|
+
--brand-primary: #2f9e52;
|
|
280
|
+
--brand-on-primary: #04241b;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* Accent: Green (light) */
|
|
284
|
+
[data-mode="light"][data-accent="green"] {
|
|
285
|
+
--brand-primary: #26803f;
|
|
286
|
+
--brand-on-primary: #f3fbf7;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* Accent: Copper (dark) */
|
|
290
|
+
[data-mode="dark"][data-accent="copper"] {
|
|
291
|
+
--brand-primary: #c97b4a;
|
|
292
|
+
--brand-on-primary: #140a04;
|
|
293
|
+
--chart-3: #d9c7a3;
|
|
294
|
+
--chart-5: #2f9e52;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/* Accent: Copper (light) */
|
|
298
|
+
[data-mode="light"][data-accent="copper"] {
|
|
299
|
+
--brand-primary: #9c5730;
|
|
300
|
+
--brand-on-primary: #f3fbf7;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* Accent: Ice (dark) */
|
|
304
|
+
[data-mode="dark"][data-accent="ice"] {
|
|
305
|
+
--brand-primary: #6e9fc4;
|
|
306
|
+
--brand-on-primary: #06131c;
|
|
307
|
+
--chart-3: #b9d4e4;
|
|
308
|
+
--chart-5: #2f9e52;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* Accent: Ice (light) */
|
|
312
|
+
[data-mode="light"][data-accent="ice"] {
|
|
313
|
+
--brand-primary: #3d6f95;
|
|
314
|
+
--brand-on-primary: #f3fbf7;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* Accent: Periwinkle (dark) */
|
|
318
|
+
[data-mode="dark"][data-accent="periwinkle"] {
|
|
319
|
+
--brand-primary: #8b8fd9;
|
|
320
|
+
--brand-on-primary: #0b0c1a;
|
|
321
|
+
--chart-3: #c3c5ec;
|
|
322
|
+
--chart-5: #2f9e52;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Accent: Periwinkle (light) */
|
|
326
|
+
[data-mode="light"][data-accent="periwinkle"] {
|
|
327
|
+
--brand-primary: #5a5fae;
|
|
328
|
+
--brand-on-primary: #f3fbf7;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* Accent: Amber (dark) */
|
|
332
|
+
[data-mode="dark"][data-accent="amber"] {
|
|
333
|
+
--brand-primary: #e0b34a;
|
|
334
|
+
--brand-on-primary: #1a1204;
|
|
335
|
+
--chart-4: #c97b4a;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/* Accent: Amber (light) */
|
|
339
|
+
[data-mode="light"][data-accent="amber"] {
|
|
340
|
+
--brand-primary: #8a6410;
|
|
341
|
+
--brand-on-primary: #f3fbf7;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* Density: Compact, dense rows with hairline dividers */
|
|
345
|
+
:root,
|
|
346
|
+
[data-density="compact"] {
|
|
347
|
+
--row-pad-y: 0.5rem;
|
|
348
|
+
--row-pad-x: 0.75rem;
|
|
349
|
+
--stack-gap: 0.75rem;
|
|
350
|
+
--panel-pad: 1rem;
|
|
351
|
+
--list-columns: minmax(0, 1fr);
|
|
352
|
+
--list-gap: 0px;
|
|
353
|
+
--list-frame-border: 1px;
|
|
354
|
+
--list-frame-radius: var(--radius);
|
|
355
|
+
--list-item-border: 0px;
|
|
356
|
+
--list-item-radius: 0px;
|
|
357
|
+
--list-item-bg: transparent;
|
|
358
|
+
--list-item-pad: var(--row-pad-y) var(--row-pad-x);
|
|
359
|
+
--list-item-direction: row;
|
|
360
|
+
--list-item-align: center;
|
|
361
|
+
--list-item-trail: auto;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/* Density: Cards, boxed items that flow into columns */
|
|
365
|
+
[data-density="cards"] {
|
|
366
|
+
--row-pad-y: 0.9rem;
|
|
367
|
+
--row-pad-x: 1rem;
|
|
368
|
+
--stack-gap: 1rem;
|
|
369
|
+
--panel-pad: 1.25rem;
|
|
370
|
+
--list-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
|
|
371
|
+
--list-gap: var(--stack-gap);
|
|
372
|
+
--list-frame-border: 0px;
|
|
373
|
+
--list-frame-radius: 0px;
|
|
374
|
+
--list-item-border: 1px;
|
|
375
|
+
--list-item-radius: var(--radius);
|
|
376
|
+
--list-item-bg: var(--card);
|
|
377
|
+
--list-item-pad: var(--panel-pad);
|
|
378
|
+
--list-item-direction: column;
|
|
379
|
+
--list-item-align: stretch;
|
|
380
|
+
--list-item-trail: 0px;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/* Corners: 0px */
|
|
384
|
+
[data-corners="0"] {
|
|
385
|
+
--radius: 0px;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/* Corners: 2px */
|
|
389
|
+
[data-corners="2"] {
|
|
390
|
+
--radius: 2px;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/* Corners: 4px */
|
|
394
|
+
[data-corners="4"] {
|
|
395
|
+
--radius: 4px;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* Corners: 10px */
|
|
399
|
+
[data-corners="10"] {
|
|
400
|
+
--radius: 10px;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/* Product: Astrolift AI */
|
|
404
|
+
[data-product="astrolift"] {
|
|
405
|
+
--brand-sidebar: #04231a;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/* Product: Zentinelle AI */
|
|
409
|
+
[data-product="zentinelle"] {
|
|
410
|
+
--brand-sidebar: #0b0b19;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* Accent: Teal (Zentinelle AI, dark) */
|
|
414
|
+
[data-mode="dark"][data-accent="teal"] {
|
|
415
|
+
--brand-primary: #37efed;
|
|
416
|
+
--brand-on-primary: #0b0b19;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/* Accent: Teal (Zentinelle AI, light) */
|
|
420
|
+
[data-mode="light"][data-accent="teal"] {
|
|
421
|
+
--brand-primary: #0d7470;
|
|
422
|
+
--brand-on-primary: #f3fbf7;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/* Product: Calliope AI Workbench */
|
|
426
|
+
[data-product="workbench"] {
|
|
427
|
+
--brand-sidebar: #0e1730;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/* Accent: Workbench blue (Calliope AI Workbench, dark) */
|
|
431
|
+
[data-mode="dark"][data-accent="workbench-blue"] {
|
|
432
|
+
--brand-primary: #8fb8e8;
|
|
433
|
+
--brand-on-primary: #0b1120;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/* Accent: Workbench blue (Calliope AI Workbench, light) */
|
|
437
|
+
[data-mode="light"][data-accent="workbench-blue"] {
|
|
438
|
+
--brand-primary: #2f5d94;
|
|
439
|
+
--brand-on-primary: #f3fbf7;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* Product: Calliope AI Chat Studio */
|
|
443
|
+
[data-product="chat-studio"] {
|
|
444
|
+
--brand-sidebar: #080808;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/* Accent: Studio blue (Calliope AI Chat Studio, dark) */
|
|
448
|
+
[data-mode="dark"][data-accent="studio-blue"] {
|
|
449
|
+
--brand-primary: #8ab4f8;
|
|
450
|
+
--brand-on-primary: #0c0c0c;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* Accent: Studio blue (Calliope AI Chat Studio, light) */
|
|
454
|
+
[data-mode="light"][data-accent="studio-blue"] {
|
|
455
|
+
--brand-primary: #1d4ed8;
|
|
456
|
+
--brand-on-primary: #ffffff;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* Product: Calliope AI Loadr */
|
|
460
|
+
[data-product="loadr"] {
|
|
461
|
+
--brand-sidebar: #181825;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* Accent: Loadr blue (Calliope AI Loadr, dark) */
|
|
465
|
+
[data-mode="dark"][data-accent="loadr-blue"] {
|
|
466
|
+
--brand-primary: #89b4fa;
|
|
467
|
+
--brand-on-primary: #11111b;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/* Accent: Loadr blue (Calliope AI Loadr, light) */
|
|
471
|
+
[data-mode="light"][data-accent="loadr-blue"] {
|
|
472
|
+
--brand-primary: #1e66f5;
|
|
473
|
+
--brand-on-primary: #ffffff;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/* Product: Cykick */
|
|
477
|
+
[data-product="cykick"] {
|
|
478
|
+
--brand-sidebar: #07090e;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/* Accent: Cykick cyan (Cykick, dark) */
|
|
482
|
+
[data-mode="dark"][data-accent="cykick-cyan"] {
|
|
483
|
+
--brand-primary: #22d3ee;
|
|
484
|
+
--brand-on-primary: #07090e;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/* Accent: Cykick cyan (Cykick, light) */
|
|
488
|
+
[data-mode="light"][data-accent="cykick-cyan"] {
|
|
489
|
+
--brand-primary: #0e7490;
|
|
490
|
+
--brand-on-primary: #ffffff;
|
|
491
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
export interface Definition {
|
|
3
|
+
term: React.ReactNode;
|
|
4
|
+
/** Stable identity when `term` is not a string. */
|
|
5
|
+
key?: string;
|
|
6
|
+
/** `null` or `undefined` draws "Not set", so an empty field reads as empty. */
|
|
7
|
+
description: React.ReactNode | null | undefined;
|
|
8
|
+
}
|
|
9
|
+
export interface DefinitionListProps {
|
|
10
|
+
items: readonly Definition[];
|
|
11
|
+
/** Two columns of pairs on a wide page. */
|
|
12
|
+
columns?: 1 | 2;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/** The facts of a thing as term and value pairs, in hairline rows. */
|
|
16
|
+
export declare function DefinitionList({ items, columns, className }: DefinitionListProps): React.JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { useUI } from "../provider/UIProvider.js";
|
|
5
|
+
/** The facts of a thing as term and value pairs, in hairline rows. */
|
|
6
|
+
export function DefinitionList({ items, columns = 1, className }) {
|
|
7
|
+
const { messages } = useUI();
|
|
8
|
+
return (_jsx("dl", { "data-slot": "definition-list", className: cn("grid min-w-0 gap-x-8 text-sm", columns === 2 && "md:grid-cols-2", className), children: items.map((item, i) => (_jsxs("div", { className: "flex min-w-0 flex-col gap-0.5 border-b py-2 sm:flex-row sm:gap-4", children: [_jsx("dt", { className: "shrink-0 text-muted-foreground sm:w-40", children: item.term }), _jsx("dd", { className: "min-w-0 [overflow-wrap:anywhere]", children: item.description ?? (_jsx("span", { className: "text-muted-foreground", children: messages.data.notSet })) })] }, item.key ?? (typeof item.term === "string" ? item.term : i)))) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
import type { StatusTone } from "../status/tones.js";
|
|
3
|
+
export interface StatProps {
|
|
4
|
+
label: React.ReactNode;
|
|
5
|
+
/** The figure. `null` or `undefined` draws a dash: the server did not say. */
|
|
6
|
+
value: React.ReactNode | null | undefined;
|
|
7
|
+
/** One line under the figure: a unit, a comparison, a scope, a trend. */
|
|
8
|
+
hint?: React.ReactNode;
|
|
9
|
+
/** A status beside the label. Colour is never the only carrier, so the hint says why. */
|
|
10
|
+
tone?: StatusTone;
|
|
11
|
+
/** The list the figure counts. The whole tile is the link's target. */
|
|
12
|
+
href?: string;
|
|
13
|
+
loading?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One figure with its label: the top row of an overview. Figures come from
|
|
18
|
+
* the server's aggregates, never from counting a fetched page.
|
|
19
|
+
*/
|
|
20
|
+
export declare function Stat({ label, value, hint, tone, href, loading, className }: StatProps): React.JSX.Element;
|
|
21
|
+
/** Stats in a row that wraps: four across on a wide page, two on a narrow one. */
|
|
22
|
+
export declare function StatGrid({ children, className, }: {
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
className?: string;
|
|
25
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { Skeleton } from "../primitives/Skeleton.js";
|
|
5
|
+
import { useUI } from "../provider/UIProvider.js";
|
|
6
|
+
import { StatusDot } from "../status/StatusDot.js";
|
|
7
|
+
/**
|
|
8
|
+
* One figure with its label: the top row of an overview. Figures come from
|
|
9
|
+
* the server's aggregates, never from counting a fetched page.
|
|
10
|
+
*/
|
|
11
|
+
export function Stat({ label, value, hint, tone, href, loading = false, className }) {
|
|
12
|
+
const { Link, messages } = useUI();
|
|
13
|
+
const missing = value === null || value === undefined;
|
|
14
|
+
return (_jsxs("div", { "data-slot": "stat", "aria-busy": loading || undefined, className: cn("relative flex min-w-0 flex-col gap-1 rounded-lg border bg-card p-(--panel-pad) text-card-foreground", href && "transition-colors hover:border-ring", className), children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2 text-sm text-muted-foreground", children: [tone && _jsx(StatusDot, { tone: tone }), href ? (_jsx(Link, { href: href, className: "truncate outline-none after:absolute after:inset-0 after:rounded-lg focus-visible:after:ring-2 focus-visible:after:ring-ring", children: label })) : (_jsx("span", { className: "truncate", children: label }))] }), loading ? (_jsx(Skeleton, { className: "h-7 w-16" })) : (_jsx("span", { className: "font-mono text-2xl font-semibold [overflow-wrap:anywhere] tabular-nums", children: missing ? (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": true, children: "-" }), _jsx("span", { className: "sr-only", children: messages.data.noValue })] })) : (value) })), hint && !loading && (_jsx("span", { className: "text-xs [overflow-wrap:anywhere] text-muted-foreground", children: hint }))] }));
|
|
15
|
+
}
|
|
16
|
+
/** Stats in a row that wraps: four across on a wide page, two on a narrow one. */
|
|
17
|
+
export function StatGrid({ children, className, }) {
|
|
18
|
+
return (_jsx("div", { className: cn("grid grid-cols-2 gap-(--stack-gap) lg:grid-cols-4", className), children: children }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
export interface TagProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
/** Shows a remove button. */
|
|
5
|
+
onRemove?: () => void;
|
|
6
|
+
/** The tag's name for the remove button, when `children` is not plain text. */
|
|
7
|
+
label?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A neutral label on a thing: a topic, an owner, an environment. Not a
|
|
12
|
+
* status (StatusBadge is), so it never takes a status colour.
|
|
13
|
+
*/
|
|
14
|
+
export declare function Tag({ children, onRemove, label, className }: TagProps): React.JSX.Element;
|
|
15
|
+
/** Tags in a row that wraps, as a list. */
|
|
16
|
+
export declare function TagList({ children, label, className, }: {
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
/** Names the list ("Topics"), when nothing beside it does. */
|
|
19
|
+
label?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
}): React.JSX.Element;
|
package/dist/data/Tag.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { XIcon } from "lucide-react";
|
|
4
|
+
import { cn } from "../lib/cn.js";
|
|
5
|
+
import { useUI } from "../provider/UIProvider.js";
|
|
6
|
+
/**
|
|
7
|
+
* A neutral label on a thing: a topic, an owner, an environment. Not a
|
|
8
|
+
* status (StatusBadge is), so it never takes a status colour.
|
|
9
|
+
*/
|
|
10
|
+
export function Tag({ children, onRemove, label, className }) {
|
|
11
|
+
const { messages } = useUI();
|
|
12
|
+
const name = label ?? (typeof children === "string" ? children : "");
|
|
13
|
+
return (_jsxs("span", { "data-slot": "tag", className: cn("inline-flex h-5 max-w-full min-w-0 items-center gap-1 rounded-md border bg-secondary px-1.5 text-xs text-secondary-foreground", onRemove && "pr-0.5", className), children: [_jsx("span", { className: "truncate", children: children }), onRemove && (_jsx("button", { type: "button", onClick: onRemove, "aria-label": messages.data.removeTag(name), className: "flex size-4 shrink-0 items-center justify-center rounded-sm text-muted-foreground hover:bg-foreground/10 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none", children: _jsx(XIcon, { className: "size-3", "aria-hidden": true }) }))] }));
|
|
14
|
+
}
|
|
15
|
+
/** Tags in a row that wraps, as a list. */
|
|
16
|
+
export function TagList({ children, label, className, }) {
|
|
17
|
+
return (_jsx("ul", { "aria-label": label, className: cn("flex min-w-0 flex-wrap gap-1", className), children: (Array.isArray(children) ? children : [children]).map((child, i) => child ? (_jsx("li", { className: "flex min-w-0", children: child }, i)) : null) }));
|
|
18
|
+
}
|
package/dist/data/types.d.ts
CHANGED
|
@@ -28,8 +28,9 @@ export interface Column<TRow> {
|
|
|
28
28
|
cellClassName?: string;
|
|
29
29
|
/**
|
|
30
30
|
* The server's sort key. Present, the header is a sort control; absent, a
|
|
31
|
-
* plain header. There is no client sort: reordering one page while
|
|
32
|
-
* of the result set sits on the server is wrong at every page
|
|
31
|
+
* plain header. There is no client sort of a page: reordering one page while
|
|
32
|
+
* the rest of the result set sits on the server is wrong at every page
|
|
33
|
+
* boundary. Rows wholly in memory sort through `useLocalTable`'s `sortBy`.
|
|
33
34
|
*/
|
|
34
35
|
sortKey?: string;
|
|
35
36
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type SortState, type TableController } from "./types.js";
|
|
2
|
+
/** A value a column sorts by. `null` and `undefined` sort last, whichever the direction. */
|
|
3
|
+
export type SortValue = string | number | boolean | Date | null | undefined;
|
|
4
|
+
export interface LocalTableOptions<TRow> {
|
|
5
|
+
/** How each `Column.sortKey` reads a row. A key with no accessor is not sortable. */
|
|
6
|
+
sortBy?: Readonly<Record<string, (row: TRow) => SortValue>>;
|
|
7
|
+
/** The sort before anyone chooses: one key, or the ordered keys of a multi-key sort. */
|
|
8
|
+
initialSort?: SortState | readonly SortState[];
|
|
9
|
+
/** The text the search box matches, case-insensitively. Absent, there is no search box. */
|
|
10
|
+
searchText?: (row: TRow) => string;
|
|
11
|
+
/**
|
|
12
|
+
* The app's own filters (a status chip, a toggle), already applied by the
|
|
13
|
+
* predicate. Present, the list counts as filtered: an empty result reads as
|
|
14
|
+
* "nothing matches", and "clear filters" calls `onClearFilters`.
|
|
15
|
+
*/
|
|
16
|
+
filter?: (row: TRow) => boolean;
|
|
17
|
+
onClearFilters?: () => void;
|
|
18
|
+
/** Defaults to 25. */
|
|
19
|
+
pageSize?: number;
|
|
20
|
+
/** Defaults to 10, 25, 50 and 100. */
|
|
21
|
+
pageSizes?: readonly number[];
|
|
22
|
+
/** The rows are still arriving: the table shows its loading state. */
|
|
23
|
+
loading?: boolean;
|
|
24
|
+
/** The rows could not be had: the table shows its error state, with `retry`. */
|
|
25
|
+
error?: {
|
|
26
|
+
message: string;
|
|
27
|
+
} | null;
|
|
28
|
+
retry?: () => void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A TableController over rows already in memory, for DataTable: search,
|
|
32
|
+
* the app's filters, sort and paging, all over the whole set, so a page
|
|
33
|
+
* boundary is never wrong. For a list the server pages, implement the
|
|
34
|
+
* controller over the server (Astrolift's `useCursorTable`) instead.
|
|
35
|
+
*/
|
|
36
|
+
export declare function useLocalTable<TRow>(rows: readonly TRow[], options?: LocalTableOptions<TRow>): TableController<TRow>;
|