@lotics/ui 5.7.0 → 5.9.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/AGENTS.md +102 -42
- package/examples/tpl_approvals.tsx +10 -10
- package/examples/tpl_convert.tsx +11 -23
- package/examples/tpl_crm_desk.tsx +3 -3
- package/examples/tpl_dieline.tsx +7 -6
- package/examples/tpl_directory.tsx +3 -3
- package/examples/tpl_dossier.tsx +7 -7
- package/examples/tpl_draft.tsx +4 -4
- package/examples/tpl_extract.tsx +7 -7
- package/examples/tpl_inventory.tsx +3 -3
- package/examples/tpl_lookup.tsx +4 -3
- package/examples/tpl_match.tsx +1 -1
- package/examples/tpl_order.tsx +1 -1
- package/examples/tpl_ratedesk.tsx +12 -12
- package/examples/tpl_record.tsx +1 -1
- package/examples/tpl_report.tsx +3 -3
- package/examples/tpl_stock.tsx +3 -3
- package/examples/tpl_triage.tsx +1 -1
- package/package.json +12 -4
- package/src/agent_progress.tsx +14 -12
- package/src/agent_run.tsx +253 -66
- package/src/back_button.tsx +3 -2
- package/src/badge.tsx +2 -1
- package/src/button.tsx +11 -32
- package/src/button_colors.ts +23 -0
- package/src/calendar/calendar_view.tsx +2 -2
- package/src/card_select_item.tsx +2 -1
- package/src/change_review.tsx +5 -6
- package/src/{pill_button.tsx → chip.tsx} +7 -7
- package/src/chip_group.tsx +2 -2
- package/src/column_filter.tsx +4 -4
- package/src/combobox.tsx +2 -9
- package/src/composer.tsx +4 -3
- package/src/control_surface.ts +15 -15
- package/src/date_field.tsx +2 -1
- package/src/date_filter.tsx +2 -1
- package/src/date_range_filter_field.tsx +2 -1
- package/src/dialog.tsx +2 -2
- package/src/discrepancy.tsx +1 -1
- package/src/drawer.tsx +1 -2
- package/src/file_gallery_modal.tsx +220 -133
- package/src/file_grid.tsx +184 -0
- package/src/file_preview.web.tsx +329 -6
- package/src/file_preview_types.ts +40 -0
- package/src/file_row.tsx +114 -0
- package/src/file_rows.tsx +105 -0
- package/src/file_thumbnail.tsx +121 -79
- package/src/file_thumbnail_grid.tsx +130 -55
- package/src/{filter_pill.tsx → filter_chip.tsx} +8 -8
- package/src/finding.tsx +1 -1
- package/src/gantt/gantt_view.tsx +2 -2
- package/src/icon_button.tsx +49 -14
- package/src/image_gallery.tsx +0 -4
- package/src/inline_edit.tsx +2 -2
- package/src/link_button.tsx +2 -1
- package/src/menu_button.tsx +2 -1
- package/src/menu_list_item.tsx +2 -1
- package/src/number_input.tsx +2 -1
- package/src/pdfjs_worker.d.ts +5 -0
- package/src/picker.tsx +3 -3
- package/src/popover_header.tsx +2 -2
- package/src/radio_picker.tsx +2 -1
- package/src/range_slider.tsx +1 -1
- package/src/review_card.tsx +2 -2
- package/src/scan_field.tsx +2 -1
- package/src/scored_option.tsx +0 -1
- package/src/search_input.tsx +3 -2
- package/src/segmented_control.tsx +2 -1
- package/src/status_badge.tsx +2 -1
- package/src/stepper.tsx +3 -2
- package/src/switch_button.tsx +2 -1
- package/src/switcher.tsx +3 -2
- package/src/tabs.tsx +2 -1
- package/src/tag_input.tsx +2 -1
- package/src/text_input_field.tsx +2 -1
- package/src/time_field.tsx +2 -1
- package/src/time_picker.tsx +2 -1
- package/src/triage_row.tsx +3 -3
- package/src/uploading_thumbnail.tsx +212 -0
- package/src/hover_action.tsx +0 -54
package/examples/tpl_extract.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import { Text } from "@lotics/ui/text";
|
|
|
5
5
|
import { Button } from "@lotics/ui/button";
|
|
6
6
|
import { Card, CardBody, CardHeader, CardHeaderTitle } from "@lotics/ui/card";
|
|
7
7
|
import { FileDropzone } from "@lotics/ui/file_dropzone";
|
|
8
|
-
import { AgentRun, type AgentRunStep } from "@lotics/ui/agent_run";
|
|
8
|
+
import { AgentRun, type AgentRunStep, type AgentRunItem } from "@lotics/ui/agent_run";
|
|
9
9
|
import { ReviewCard } from "@lotics/ui/review_card";
|
|
10
10
|
import { RecordFields, type RecordField } from "@lotics/ui/record_fields";
|
|
11
11
|
import { Sources } from "@lotics/ui/sources";
|
|
@@ -81,7 +81,8 @@ export function TplExtract() {
|
|
|
81
81
|
return () => clearTimeout(t);
|
|
82
82
|
}, [streaming, revealed]);
|
|
83
83
|
|
|
84
|
-
const
|
|
84
|
+
const items: AgentRunItem[] = EXTRACT.slice(0, revealed).map((s, i) => ({
|
|
85
|
+
type: "step",
|
|
85
86
|
...s,
|
|
86
87
|
status: streaming && revealed < EXTRACT.length && i === revealed - 1 ? "running" : "done",
|
|
87
88
|
}));
|
|
@@ -119,7 +120,7 @@ export function TplExtract() {
|
|
|
119
120
|
<Text size="xl" weight="semibold">Capture packing list</Text>
|
|
120
121
|
<Text size="sm" color="muted">Drop a photo; the agent extracts each line, you review and edit, then save them all to the table.</Text>
|
|
121
122
|
</View>
|
|
122
|
-
{phase !== "intake" ? <Button title="Start over" color="muted"
|
|
123
|
+
{phase !== "intake" ? <Button title="Start over" color="muted" onPress={reset} /> : null}
|
|
123
124
|
</View>
|
|
124
125
|
|
|
125
126
|
{phase === "intake" ? (
|
|
@@ -133,7 +134,7 @@ export function TplExtract() {
|
|
|
133
134
|
|
|
134
135
|
{phase === "extracting" ? (
|
|
135
136
|
<Card>
|
|
136
|
-
<AgentRun
|
|
137
|
+
<AgentRun items={items} state={streaming ? "streaming" : "done"} />
|
|
137
138
|
</Card>
|
|
138
139
|
) : null}
|
|
139
140
|
|
|
@@ -167,12 +168,11 @@ export function TplExtract() {
|
|
|
167
168
|
))}
|
|
168
169
|
</View>
|
|
169
170
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
|
170
|
-
<Button title="Confirm all" color="muted"
|
|
171
|
+
<Button title="Confirm all" color="muted" onPress={() => setStatuses(Object.fromEntries(RECORDS.map((r) => [r.id, "confirmed" as Status])))} />
|
|
171
172
|
<View style={{ flex: 1 }} />
|
|
172
173
|
<Button
|
|
173
174
|
title={`Save ${confirmedCount} ${confirmedCount === 1 ? "line" : "lines"}`}
|
|
174
175
|
color="primary"
|
|
175
|
-
shape="rounded"
|
|
176
176
|
disabled={confirmedCount === 0}
|
|
177
177
|
onPress={() => setPhase("done")}
|
|
178
178
|
/>
|
|
@@ -183,7 +183,7 @@ export function TplExtract() {
|
|
|
183
183
|
{phase === "done" ? (
|
|
184
184
|
<Card>
|
|
185
185
|
<CompletionState title={`${confirmedCount} lines saved`} summary="The confirmed lines were written to the shipment table.">
|
|
186
|
-
<Button title="Capture another" color="secondary"
|
|
186
|
+
<Button title="Capture another" color="secondary" onPress={reset} />
|
|
187
187
|
</CompletionState>
|
|
188
188
|
</Card>
|
|
189
189
|
) : null}
|
|
@@ -5,7 +5,7 @@ import { colors, solid } from "@lotics/ui/colors";
|
|
|
5
5
|
import { Badge } from "@lotics/ui/badge";
|
|
6
6
|
import { Button } from "@lotics/ui/button";
|
|
7
7
|
import { ChipGroup } from "@lotics/ui/chip_group";
|
|
8
|
-
import {
|
|
8
|
+
import { FilterChip } from "@lotics/ui/filter_chip";
|
|
9
9
|
import { RangeSlider, rangeSummary } from "@lotics/ui/range_slider";
|
|
10
10
|
import { cycleSort, sortBy, type SortState } from "@lotics/ui/sort_header";
|
|
11
11
|
import { Card } from "@lotics/ui/card";
|
|
@@ -259,9 +259,9 @@ export function TplInventory() {
|
|
|
259
259
|
value={loc}
|
|
260
260
|
onValueChange={setLoc}
|
|
261
261
|
/>
|
|
262
|
-
<
|
|
262
|
+
<FilterChip label="Stock value" summary={amtSummary} onClear={() => setAmt([0, AMT_MAX])} clearLabel="Clear stock value filter">
|
|
263
263
|
<RangeSlider min={0} max={AMT_MAX} step={5_000_000} value={amt} onValueChange={setAmt} format={fmtAmt} accessibilityLabel="Stock value" />
|
|
264
|
-
</
|
|
264
|
+
</FilterChip>
|
|
265
265
|
</View>
|
|
266
266
|
|
|
267
267
|
{/* the stock register: eyebrow band → Divider-separated SKU rows */}
|
package/examples/tpl_lookup.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { Divider } from "@lotics/ui/divider";
|
|
|
6
6
|
import { Callout, CalloutText, CalloutTitle } from "@lotics/ui/callout";
|
|
7
7
|
import { PressableHighlight } from "@lotics/ui/pressable_highlight";
|
|
8
8
|
import { Composer } from "@lotics/ui/composer";
|
|
9
|
-
import { AgentRun, type AgentRunStep } from "@lotics/ui/agent_run";
|
|
9
|
+
import { AgentRun, type AgentRunStep, type AgentRunItem } from "@lotics/ui/agent_run";
|
|
10
10
|
import { SpecList, type SpecRow } from "@lotics/ui/spec_list";
|
|
11
11
|
import { Confidence, type ConfidenceLevel } from "@lotics/ui/confidence";
|
|
12
12
|
import { Badge } from "@lotics/ui/badge";
|
|
@@ -184,7 +184,8 @@ export function TplLookup() {
|
|
|
184
184
|
};
|
|
185
185
|
|
|
186
186
|
const streaming = phase === "running" && revealed < SCRIPT.length;
|
|
187
|
-
const
|
|
187
|
+
const items: AgentRunItem[] = SCRIPT.slice(0, revealed).map((s, i) => ({
|
|
188
|
+
type: "step",
|
|
188
189
|
...s,
|
|
189
190
|
status: streaming && i === revealed - 1 ? "running" : "done",
|
|
190
191
|
}));
|
|
@@ -201,7 +202,7 @@ export function TplLookup() {
|
|
|
201
202
|
|
|
202
203
|
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 16 }}>
|
|
203
204
|
{/* current run */}
|
|
204
|
-
<AgentRun
|
|
205
|
+
<AgentRun items={items} state={streaming ? "streaming" : "done"} />
|
|
205
206
|
|
|
206
207
|
<View style={{ gap: 8 }}>
|
|
207
208
|
<Text size="xs" color="muted" weight="medium">Nearest matches</Text>
|
package/examples/tpl_match.tsx
CHANGED
|
@@ -72,7 +72,7 @@ export function TplMatch() {
|
|
|
72
72
|
<Text size="sm" color="muted">The agent pairs incoming payments to open invoices — you confirm, reassign, or reject</Text>
|
|
73
73
|
</View>
|
|
74
74
|
{tab === "open" && highOpen > 0 ? (
|
|
75
|
-
<Button title={`Accept ${highOpen} high-confidence`} color="secondary"
|
|
75
|
+
<Button title={`Accept ${highOpen} high-confidence`} color="secondary" onPress={acceptAllHigh} />
|
|
76
76
|
) : null}
|
|
77
77
|
</View>
|
|
78
78
|
|
package/examples/tpl_order.tsx
CHANGED
|
@@ -477,7 +477,7 @@ export function TplOrder() {
|
|
|
477
477
|
</Screen>
|
|
478
478
|
</Dialog>
|
|
479
479
|
|
|
480
|
-
<FileGalleryModal files={files} activeIndex={activeFile} onIndexChange={setActiveFile}
|
|
480
|
+
<FileGalleryModal files={files} activeIndex={activeFile} onIndexChange={setActiveFile} />
|
|
481
481
|
</ScrollView>
|
|
482
482
|
);
|
|
483
483
|
}
|
|
@@ -13,7 +13,7 @@ import { FileDropzone } from "@lotics/ui/file_dropzone";
|
|
|
13
13
|
import { FileThumbnailGrid } from "@lotics/ui/file_thumbnail_grid";
|
|
14
14
|
import { FileGalleryModal } from "@lotics/ui/file_gallery_modal";
|
|
15
15
|
import { type DisplayFile } from "@lotics/ui/file_thumbnail";
|
|
16
|
-
import { AgentRun, type
|
|
16
|
+
import { AgentRun, type AgentRunItem } from "@lotics/ui/agent_run";
|
|
17
17
|
import { Table, TableRow, TableCell, type TableColumn } from "@lotics/ui/table";
|
|
18
18
|
import { InlineNumberInput } from "@lotics/ui/inline_number_input";
|
|
19
19
|
import { CompletionState } from "@lotics/ui/completion_state";
|
|
@@ -167,8 +167,8 @@ export function TplRatedesk() {
|
|
|
167
167
|
setPhase("done");
|
|
168
168
|
}, [lines, decisions]);
|
|
169
169
|
|
|
170
|
-
const
|
|
171
|
-
id: `r${i}`, label: s.label, kind: s.kind, status: i < revealed ? "done" : "running",
|
|
170
|
+
const runItems: AgentRunItem[] = READ_STEPS.slice(0, Math.min(revealed + 1, READ_STEPS.length)).map((s, i) => ({
|
|
171
|
+
type: "step", id: `r${i}`, label: s.label, kind: s.kind, status: i < revealed ? "done" : "running",
|
|
172
172
|
}));
|
|
173
173
|
const newCount = lines.filter((l) => l.status === "new").length;
|
|
174
174
|
|
|
@@ -181,7 +181,7 @@ export function TplRatedesk() {
|
|
|
181
181
|
<Text size="xl" weight="semibold">Rate desk</Text>
|
|
182
182
|
<Text size="sm" color="muted">Look up any route, carrier or container. Prices come from carrier sheets — re-ingest to refresh.</Text>
|
|
183
183
|
</View>
|
|
184
|
-
<Button title="Import prices" color="primary"
|
|
184
|
+
<Button title="Import prices" color="primary" onPress={() => setImportOpen(true)} />
|
|
185
185
|
</View>
|
|
186
186
|
|
|
187
187
|
{/* REGISTER — the live rate card, filter to anything */}
|
|
@@ -193,11 +193,11 @@ export function TplRatedesk() {
|
|
|
193
193
|
<View style={{ flexDirection: "row", alignItems: "center", flexWrap: "wrap", gap: 8 }}>
|
|
194
194
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 6, flexGrow: 1, flexBasis: 360, minWidth: 280 }}>
|
|
195
195
|
<View style={{ flex: 1, minWidth: 120 }}>
|
|
196
|
-
<Combobox
|
|
196
|
+
<Combobox icon="map-pin" options={originOpts} recentOptions={originOpts} recentsLabel="Origin" value={fromV} onValueChange={setFromV} clearable onClear={() => setFromV(null)} placeholder="From" accessibilityLabel="Origin port" />
|
|
197
197
|
</View>
|
|
198
198
|
<Icon name="arrow-right" size={14} color={colors.zinc[400]} />
|
|
199
199
|
<View style={{ flex: 1, minWidth: 120 }}>
|
|
200
|
-
<Combobox
|
|
200
|
+
<Combobox icon="map-pin" options={destOpts} recentOptions={destOpts} recentsLabel="Destination" value={toV} onValueChange={setToV} clearable onClear={() => setToV(null)} placeholder="To" accessibilityLabel="Destination port" />
|
|
201
201
|
</View>
|
|
202
202
|
</View>
|
|
203
203
|
<ColumnFilter column={carrierCol} value={carrierF} onChange={setCarrierF} clearLabel="Clear carrier" />
|
|
@@ -238,7 +238,7 @@ export function TplRatedesk() {
|
|
|
238
238
|
</View>
|
|
239
239
|
) : null}
|
|
240
240
|
|
|
241
|
-
{phase === "reading" ? <AgentRun
|
|
241
|
+
{phase === "reading" ? <AgentRun items={runItems} state="streaming" /> : null}
|
|
242
242
|
|
|
243
243
|
{phase === "review" ? (
|
|
244
244
|
<ChangeReview
|
|
@@ -270,8 +270,8 @@ export function TplRatedesk() {
|
|
|
270
270
|
away inside the list. */}
|
|
271
271
|
{phase === "idle" ? (
|
|
272
272
|
<DialogFooter>
|
|
273
|
-
{files.length > 0 ? <Button title="Clear" color="muted"
|
|
274
|
-
<Button title={files.length ? `Read ${files.length} sheets` : "Read sheets"} color="primary"
|
|
273
|
+
{files.length > 0 ? <Button title="Clear" color="muted" onPress={() => setFiles([])} /> : null}
|
|
274
|
+
<Button title={files.length ? `Read ${files.length} sheets` : "Read sheets"} color="primary" disabled={!files.length} onPress={() => { setRevealed(0); setPhase("reading"); }} />
|
|
275
275
|
</DialogFooter>
|
|
276
276
|
) : phase === "review" ? (
|
|
277
277
|
<DialogFooter>
|
|
@@ -286,13 +286,13 @@ export function TplRatedesk() {
|
|
|
286
286
|
</DialogFooter>
|
|
287
287
|
) : phase === "done" ? (
|
|
288
288
|
<DialogFooter>
|
|
289
|
-
<Button title="Import more" color="secondary"
|
|
290
|
-
<Button title="Done" color="primary"
|
|
289
|
+
<Button title="Import more" color="secondary" onPress={reset} />
|
|
290
|
+
<Button title="Done" color="primary" onPress={closeImport} />
|
|
291
291
|
</DialogFooter>
|
|
292
292
|
) : null}
|
|
293
293
|
</Dialog>
|
|
294
294
|
|
|
295
|
-
<FileGalleryModal files={files} activeIndex={activeFile} onIndexChange={setActiveFile}
|
|
295
|
+
<FileGalleryModal files={files} activeIndex={activeFile} onIndexChange={setActiveFile} />
|
|
296
296
|
</>
|
|
297
297
|
);
|
|
298
298
|
}
|
package/examples/tpl_record.tsx
CHANGED
|
@@ -295,7 +295,7 @@ export function TplRecord() {
|
|
|
295
295
|
</Card>
|
|
296
296
|
</View>
|
|
297
297
|
|
|
298
|
-
<FileGalleryModal files={docs} activeIndex={activeDoc} onIndexChange={setActiveDoc}
|
|
298
|
+
<FileGalleryModal files={docs} activeIndex={activeDoc} onIndexChange={setActiveDoc} />
|
|
299
299
|
</ScrollView>
|
|
300
300
|
);
|
|
301
301
|
}
|
package/examples/tpl_report.tsx
CHANGED
|
@@ -15,7 +15,7 @@ import { EmptyState } from "@lotics/ui/empty_state";
|
|
|
15
15
|
import { KPIStrip } from "@lotics/ui/kpi_strip";
|
|
16
16
|
import { Link } from "@lotics/ui/link";
|
|
17
17
|
import { Pagination } from "@lotics/ui/pagination";
|
|
18
|
-
import {
|
|
18
|
+
import { Chip } from "@lotics/ui/chip";
|
|
19
19
|
import { SegmentedControl, type SegmentOption } from "@lotics/ui/segmented_control";
|
|
20
20
|
import { formatMoney } from "@lotics/ui/format_money";
|
|
21
21
|
import { formatDate, parseDate } from "@lotics/ui/format_date";
|
|
@@ -311,9 +311,9 @@ export function TplReport() {
|
|
|
311
311
|
{chips.length > 0 ? (
|
|
312
312
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
|
|
313
313
|
{chips.map((c) => (
|
|
314
|
-
<
|
|
314
|
+
<Chip key={c.key} onDismiss={c.clear} dismissTooltip="Clear filter">
|
|
315
315
|
<Text size="xs" weight="medium" color="muted">{c.label}</Text>
|
|
316
|
-
</
|
|
316
|
+
</Chip>
|
|
317
317
|
))}
|
|
318
318
|
</View>
|
|
319
319
|
) : null}
|
package/examples/tpl_stock.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import { Drawer } from "@lotics/ui/drawer";
|
|
|
12
12
|
import { EmptyState } from "@lotics/ui/empty_state";
|
|
13
13
|
import { KPIStrip } from "@lotics/ui/kpi_strip";
|
|
14
14
|
import { Pagination } from "@lotics/ui/pagination";
|
|
15
|
-
import {
|
|
15
|
+
import { Chip } from "@lotics/ui/chip";
|
|
16
16
|
import { PressableRow } from "@lotics/ui/pressable_row";
|
|
17
17
|
import { SearchInput } from "@lotics/ui/search_input";
|
|
18
18
|
import { formatMoney } from "@lotics/ui/format_money";
|
|
@@ -266,9 +266,9 @@ export function TplStock() {
|
|
|
266
266
|
</CardHeaderTitle>
|
|
267
267
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
|
|
268
268
|
{chips.map((c) => (
|
|
269
|
-
<
|
|
269
|
+
<Chip key={c.key} onDismiss={c.clear} dismissTooltip="Clear filter">
|
|
270
270
|
<Text size="xs" weight="medium" color="muted">{c.label}</Text>
|
|
271
|
-
</
|
|
271
|
+
</Chip>
|
|
272
272
|
))}
|
|
273
273
|
<View style={{ width: 240 }}>
|
|
274
274
|
<SearchInput
|
package/examples/tpl_triage.tsx
CHANGED
|
@@ -62,7 +62,7 @@ export function TplTriage() {
|
|
|
62
62
|
<Text size="sm" color="muted">The agent classifies and routes each item — accept the call, override, or dismiss</Text>
|
|
63
63
|
</View>
|
|
64
64
|
{tab === "open" && highOpen > 0 ? (
|
|
65
|
-
<Button title={`Accept ${highOpen} high-confidence`} color="secondary"
|
|
65
|
+
<Button title={`Accept ${highOpen} high-confidence`} color="secondary" onPress={acceptAllHigh} />
|
|
66
66
|
) : null}
|
|
67
67
|
</View>
|
|
68
68
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lotics/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./tokens": "./src/tokens.ts",
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
"./file_badge": "./src/file_badge.tsx",
|
|
19
19
|
"./file_dropzone": "./src/file_dropzone.tsx",
|
|
20
20
|
"./file_thumbnail": "./src/file_thumbnail.tsx",
|
|
21
|
+
"./file_row": "./src/file_row.tsx",
|
|
22
|
+
"./file_rows": "./src/file_rows.tsx",
|
|
21
23
|
"./file_preview": {
|
|
22
24
|
"react-native": "./src/file_preview.tsx",
|
|
23
25
|
"default": "./src/file_preview.web.tsx"
|
|
@@ -29,6 +31,8 @@
|
|
|
29
31
|
"./use_image_rotation": "./src/use_image_rotation.ts",
|
|
30
32
|
"./use_selection_mode": "./src/use_selection_mode.ts",
|
|
31
33
|
"./file_thumbnail_grid": "./src/file_thumbnail_grid.tsx",
|
|
34
|
+
"./uploading_thumbnail": "./src/uploading_thumbnail.tsx",
|
|
35
|
+
"./file_grid": "./src/file_grid.tsx",
|
|
32
36
|
"./pagination": "./src/pagination.tsx",
|
|
33
37
|
"./bar_chart": "./src/bar_chart.tsx",
|
|
34
38
|
"./line_chart": "./src/line_chart.tsx",
|
|
@@ -133,8 +137,8 @@
|
|
|
133
137
|
"./radio_picker": "./src/radio_picker.tsx",
|
|
134
138
|
"./form_text_input": "./src/form_text_input.tsx",
|
|
135
139
|
"./form_switch": "./src/form_switch.tsx",
|
|
136
|
-
"./
|
|
137
|
-
"./
|
|
140
|
+
"./chip": "./src/chip.tsx",
|
|
141
|
+
"./filter_chip": "./src/filter_chip.tsx",
|
|
138
142
|
"./range_slider": "./src/range_slider.tsx",
|
|
139
143
|
"./counter": "./src/counter.tsx",
|
|
140
144
|
"./link": "./src/link.tsx",
|
|
@@ -192,7 +196,6 @@
|
|
|
192
196
|
},
|
|
193
197
|
"./use_async_fn": "./src/use_async_fn.ts",
|
|
194
198
|
"./use_form": "./src/use_form.ts",
|
|
195
|
-
"./hover_action": "./src/hover_action.tsx",
|
|
196
199
|
"./scroll_to_bottom": "./src/scroll_to_bottom.tsx",
|
|
197
200
|
"./animation_fade_in": "./src/animation_fade_in.tsx",
|
|
198
201
|
"./json_panel": "./src/json_panel.tsx",
|
|
@@ -233,6 +236,7 @@
|
|
|
233
236
|
"expo-image": ">=3.0.0",
|
|
234
237
|
"lucide-react": ">=0.460.0",
|
|
235
238
|
"lucide-react-native": ">=0.460.0",
|
|
239
|
+
"pdfjs-dist": ">=6.0.0",
|
|
236
240
|
"react": "^19.2.0",
|
|
237
241
|
"react-dom": "^19.2.0",
|
|
238
242
|
"react-native": ">=0.85.0",
|
|
@@ -246,6 +250,9 @@
|
|
|
246
250
|
"@lotics/xlsx": {
|
|
247
251
|
"optional": true
|
|
248
252
|
},
|
|
253
|
+
"pdfjs-dist": {
|
|
254
|
+
"optional": true
|
|
255
|
+
},
|
|
249
256
|
"expo-image": {
|
|
250
257
|
"optional": true
|
|
251
258
|
},
|
|
@@ -271,6 +278,7 @@
|
|
|
271
278
|
"@types/react-dom": "~19.2.2",
|
|
272
279
|
"@vitejs/plugin-react": "^4.3.4",
|
|
273
280
|
"lucide-react": "^0.562.0",
|
|
281
|
+
"pdfjs-dist": "^6.0.227",
|
|
274
282
|
"react-dom": "^19.2.0",
|
|
275
283
|
"react-native-web": "^0.21.0",
|
|
276
284
|
"vite": "^7.2.4"
|
package/src/agent_progress.tsx
CHANGED
|
@@ -4,19 +4,20 @@ import { colors } from "./colors";
|
|
|
4
4
|
import { Text } from "./text";
|
|
5
5
|
import { WaveAvatar } from "./wave_avatar";
|
|
6
6
|
import { PressableHighlight } from "./pressable_highlight";
|
|
7
|
-
import { AgentRun, resolveToolMeta, type
|
|
7
|
+
import { AgentRun, resolveToolMeta, type AgentRunItem } from "./agent_run";
|
|
8
8
|
|
|
9
9
|
export interface AgentProgressProps {
|
|
10
|
-
|
|
10
|
+
/** The ordered transcript — same shape `AgentRun` takes. */
|
|
11
|
+
items: AgentRunItem[];
|
|
11
12
|
state?: "streaming" | "done" | "error";
|
|
12
13
|
/** The collapsed-pill label. Defaults to the running step's label (or
|
|
13
14
|
* "Working…" / "Done"). */
|
|
14
15
|
label?: string;
|
|
15
|
-
/** The agent's streamed text — forwarded to the expanded `AgentRun`. */
|
|
16
|
-
text?: string;
|
|
17
16
|
/** Localize / override a tool step's label by raw tool name — applied to both
|
|
18
17
|
* the collapsed pill and the expanded feed. */
|
|
19
18
|
labelForTool?: (toolName: string) => string | undefined;
|
|
19
|
+
/** Localized "{n} steps" suffix, forwarded to the expanded feed. */
|
|
20
|
+
stepsLabel?: (n: number) => string;
|
|
20
21
|
defaultExpanded?: boolean;
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -29,15 +30,16 @@ export interface AgentProgressProps {
|
|
|
29
30
|
* label, so the surface stays calm until you ask to see the steps.
|
|
30
31
|
*/
|
|
31
32
|
export function AgentProgress(props: AgentProgressProps) {
|
|
32
|
-
const {
|
|
33
|
+
const { items, state = "streaming", label, labelForTool, stepsLabel, defaultExpanded } = props;
|
|
33
34
|
const [expanded, setExpanded] = useState(defaultExpanded ?? false);
|
|
34
35
|
|
|
35
|
-
const running =
|
|
36
|
-
const runningLabel =
|
|
37
|
-
|
|
38
|
-
?
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
const running = [...items].reverse().find((it) => it.type === "step" && it.status === "running");
|
|
37
|
+
const runningLabel =
|
|
38
|
+
running && running.type === "step"
|
|
39
|
+
? running.kind === "tool"
|
|
40
|
+
? resolveToolMeta(running.label, labelForTool).label
|
|
41
|
+
: running.label
|
|
42
|
+
: undefined;
|
|
41
43
|
const compact = label ?? runningLabel ?? (state === "done" ? "Done" : state === "error" ? "Stopped" : "Working…");
|
|
42
44
|
const streaming = state === "streaming";
|
|
43
45
|
|
|
@@ -46,7 +48,7 @@ export function AgentProgress(props: AgentProgressProps) {
|
|
|
46
48
|
{expanded ? (
|
|
47
49
|
<View style={styles.panel}>
|
|
48
50
|
<ScrollView style={{ maxHeight: 260 }} contentContainerStyle={{ padding: 16 }}>
|
|
49
|
-
<AgentRun
|
|
51
|
+
<AgentRun items={items} state={state} labelForTool={labelForTool} stepsLabel={stepsLabel} />
|
|
50
52
|
</ScrollView>
|
|
51
53
|
</View>
|
|
52
54
|
) : null}
|