@lotics/ui 5.7.0 → 5.8.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 +41 -26
- package/examples/tpl_approvals.tsx +10 -10
- 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_ratedesk.tsx +11 -11
- package/examples/tpl_report.tsx +3 -3
- package/examples/tpl_stock.tsx +3 -3
- package/examples/tpl_triage.tsx +1 -1
- package/package.json +3 -3
- 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/{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 +38 -14
- 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/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/number_input.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KeyboardEvent } from "react";
|
|
2
2
|
import { colors } from "./colors";
|
|
3
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
3
4
|
import { fontFamilyRegular, inputTextStyleWeb } from "./text_utils";
|
|
4
5
|
import { useFormField } from "./form_field";
|
|
5
6
|
|
|
@@ -50,7 +51,7 @@ export function NumberInput(props: NumberInputProps) {
|
|
|
50
51
|
height: 40,
|
|
51
52
|
paddingLeft: 8,
|
|
52
53
|
paddingRight: 8,
|
|
53
|
-
borderRadius:
|
|
54
|
+
borderRadius: CONTROL_RADIUS,
|
|
54
55
|
borderWidth: 1,
|
|
55
56
|
borderStyle: "solid",
|
|
56
57
|
borderColor: colors.border,
|
package/src/picker.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { Picker as RNPicker } from "@react-native-picker/picker";
|
|
|
2
2
|
import { StyleSheet, View, Pressable, StyleProp, ViewStyle, TextStyle } from "react-native";
|
|
3
3
|
import { useState, useCallback, useMemo, useEffect, useRef } from "react";
|
|
4
4
|
import { colors } from "./colors";
|
|
5
|
-
import { ACTIVE_RING } from "./control_surface";
|
|
5
|
+
import { ACTIVE_RING, CONTROL_RADIUS } from "./control_surface";
|
|
6
6
|
import { Text } from "./text";
|
|
7
7
|
import { fontFamilyRegular, getInputTextStyle } from "./text_utils";
|
|
8
8
|
import { Icon } from "./icon";
|
|
@@ -310,7 +310,7 @@ const styles = StyleSheet.create({
|
|
|
310
310
|
height: 40,
|
|
311
311
|
paddingHorizontal: 6,
|
|
312
312
|
paddingRight: 28,
|
|
313
|
-
borderRadius:
|
|
313
|
+
borderRadius: CONTROL_RADIUS,
|
|
314
314
|
borderWidth: 1,
|
|
315
315
|
borderColor: colors.border,
|
|
316
316
|
fontFamily: fontFamilyRegular,
|
|
@@ -324,7 +324,7 @@ const styles = StyleSheet.create({
|
|
|
324
324
|
paddingHorizontal: 6,
|
|
325
325
|
borderWidth: 1,
|
|
326
326
|
borderColor: colors.border,
|
|
327
|
-
borderRadius:
|
|
327
|
+
borderRadius: CONTROL_RADIUS,
|
|
328
328
|
cursor: "auto",
|
|
329
329
|
height: 40,
|
|
330
330
|
},
|
package/src/popover_header.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { View, StyleSheet } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { IconButton } from "./icon_button";
|
|
4
4
|
import { Text } from "./text";
|
|
5
5
|
import { usePopoverNav } from "./popover_nav";
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ export function PopoverHeader(props: PopoverHeaderProps) {
|
|
|
18
18
|
return (
|
|
19
19
|
<View style={styles.container}>
|
|
20
20
|
{canGoBack && (
|
|
21
|
-
<
|
|
21
|
+
<IconButton icon="chevron-left" size="lg" color="secondary" accessibilityLabel={backLabel} onPress={goBack} />
|
|
22
22
|
)}
|
|
23
23
|
<Text size="sm" weight="medium" style={{ flex: 1 }}>
|
|
24
24
|
{title}
|
package/src/radio_picker.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useCallback, useRef } from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
3
|
import { colors } from "./colors";
|
|
4
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
4
5
|
import { Text } from "./text";
|
|
5
6
|
import { PressableHighlight } from "./pressable_highlight";
|
|
6
7
|
import { Icon } from "./icon";
|
|
@@ -120,7 +121,7 @@ function RadioOption<T extends string | number | symbol>(
|
|
|
120
121
|
flexDirection: "row",
|
|
121
122
|
alignItems: "center",
|
|
122
123
|
padding: compact ? 8 : 12,
|
|
123
|
-
borderRadius:
|
|
124
|
+
borderRadius: CONTROL_RADIUS,
|
|
124
125
|
gap: compact ? 8 : 16,
|
|
125
126
|
}}
|
|
126
127
|
onPress={handlePress}
|
package/src/range_slider.tsx
CHANGED
|
@@ -24,7 +24,7 @@ export interface RangeSliderProps {
|
|
|
24
24
|
type Thumb = "low" | "high";
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* A short human summary of a range selection for a `
|
|
27
|
+
* A short human summary of a range selection for a `FilterChip` preview —
|
|
28
28
|
* "5tr–10tr", or "≥ 5tr" / "≤ 10tr" when one end sits at its bound, and
|
|
29
29
|
* `undefined` at the full range (no active filter). Mirrors `columnFilterSummary`.
|
|
30
30
|
*/
|
package/src/review_card.tsx
CHANGED
|
@@ -79,7 +79,7 @@ export function ReviewCard(props: ReviewCardProps) {
|
|
|
79
79
|
<Text size="sm" weight="medium" color="muted" numberOfLines={1}>
|
|
80
80
|
{accepted ? props.acceptedLabel ?? "Accepted" : props.dismissedLabel ?? "Dismissed"}
|
|
81
81
|
</Text>
|
|
82
|
-
{props.onUndo ? <Button title="Undo" color="muted"
|
|
82
|
+
{props.onUndo ? <Button title="Undo" color="muted" onPress={props.onUndo} /> : null}
|
|
83
83
|
</View>
|
|
84
84
|
);
|
|
85
85
|
}
|
|
@@ -132,7 +132,7 @@ export function ReviewCard(props: ReviewCardProps) {
|
|
|
132
132
|
<View style={styles.footer}>
|
|
133
133
|
{actions.map((a, i) => {
|
|
134
134
|
const kind = a.kind ?? (i === actions.length - 1 ? "primary" : "muted");
|
|
135
|
-
return <Button key={a.label} title={a.label} color={kind}
|
|
135
|
+
return <Button key={a.label} title={a.label} color={kind} onPress={a.onPress} />;
|
|
136
136
|
})}
|
|
137
137
|
</View>
|
|
138
138
|
) : null}
|
package/src/scan_field.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StyleSheet, View } from "react-native";
|
|
2
2
|
import { colors, solid } from "./colors";
|
|
3
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
3
4
|
import { Text } from "./text";
|
|
4
5
|
import { TextInputField } from "./text_input_field";
|
|
5
6
|
|
|
@@ -52,7 +53,7 @@ export function ScanField(props: ScanFieldProps) {
|
|
|
52
53
|
|
|
53
54
|
const styles = StyleSheet.create({
|
|
54
55
|
field: {
|
|
55
|
-
borderRadius:
|
|
56
|
+
borderRadius: CONTROL_RADIUS,
|
|
56
57
|
backgroundColor: colors.white,
|
|
57
58
|
},
|
|
58
59
|
});
|
package/src/scored_option.tsx
CHANGED
package/src/search_input.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type ViewStyle,
|
|
10
10
|
} from "react-native";
|
|
11
11
|
import { colors } from "./colors";
|
|
12
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
12
13
|
import { TextInputField } from "./text_input_field";
|
|
13
14
|
|
|
14
15
|
type SearchInputProps = Omit<
|
|
@@ -57,7 +58,7 @@ export function SearchInput(props: SearchInputProps) {
|
|
|
57
58
|
|
|
58
59
|
const styles = StyleSheet.create({
|
|
59
60
|
// Search reads as a view-control by its leading search glyph + white fill —
|
|
60
|
-
// NOT by a distinct shape. It shares the
|
|
61
|
+
// NOT by a distinct shape. It shares the kit-wide `CONTROL_RADIUS` of every other
|
|
61
62
|
// input/picker (TextInputField, Combobox, the date filter), so a toolbar of
|
|
62
63
|
// controls reads as one consistent band. The white fill still pops against
|
|
63
64
|
// the zinc-50 canvas where most toolbars live; a zinc-300 border (one step up
|
|
@@ -65,7 +66,7 @@ const styles = StyleSheet.create({
|
|
|
65
66
|
// the fill alone would vanish. 40px (TextInputField default) — the system
|
|
66
67
|
// control height every band aligns to.
|
|
67
68
|
search: {
|
|
68
|
-
borderRadius:
|
|
69
|
+
borderRadius: CONTROL_RADIUS,
|
|
69
70
|
backgroundColor: colors.white,
|
|
70
71
|
// A thin 1px resting border (TextInputField's default width) — interaction
|
|
71
72
|
// emphasis comes from the input's own focus outline, so it stays quiet at
|
|
@@ -3,6 +3,7 @@ import { StyleSheet, View, type StyleProp, type ViewStyle } from "react-native";
|
|
|
3
3
|
import { PressableHighlight } from "./pressable_highlight";
|
|
4
4
|
import { Text } from "./text";
|
|
5
5
|
import { colors, withAlpha } from "./colors";
|
|
6
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
6
7
|
|
|
7
8
|
export interface SegmentOption<T extends string> {
|
|
8
9
|
label: string;
|
|
@@ -183,7 +184,7 @@ const styles = StyleSheet.create({
|
|
|
183
184
|
height: 40,
|
|
184
185
|
gap: 2,
|
|
185
186
|
padding: 3,
|
|
186
|
-
borderRadius:
|
|
187
|
+
borderRadius: CONTROL_RADIUS,
|
|
187
188
|
backgroundColor: colors.zinc["100"],
|
|
188
189
|
},
|
|
189
190
|
trackDisabled: {
|
package/src/status_badge.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import { useEffect, useRef } from "react";
|
|
|
2
2
|
import { View, StyleSheet, Animated, Easing } from "react-native";
|
|
3
3
|
import { Text } from "./text";
|
|
4
4
|
import { colors } from "./colors";
|
|
5
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
5
6
|
|
|
6
7
|
interface StatusBadgeProps {
|
|
7
8
|
enabled: boolean;
|
|
@@ -69,7 +70,7 @@ const styles = StyleSheet.create({
|
|
|
69
70
|
gap: 8,
|
|
70
71
|
paddingVertical: 4,
|
|
71
72
|
paddingHorizontal: 8,
|
|
72
|
-
borderRadius:
|
|
73
|
+
borderRadius: CONTROL_RADIUS,
|
|
73
74
|
},
|
|
74
75
|
dotWrapper: {
|
|
75
76
|
width: 10,
|
package/src/stepper.tsx
CHANGED
|
@@ -155,8 +155,9 @@ export function Step(props: StepProps) {
|
|
|
155
155
|
|
|
156
156
|
// The node — status drives fill, never size. Monochrome: reached fills with ink,
|
|
157
157
|
// the current step is a ring around white (pulsing when live), what's ahead is a
|
|
158
|
-
// faint grey ring, the terminal is a checked fill.
|
|
159
|
-
|
|
158
|
+
// faint grey ring, the terminal is a checked fill. Exported so `AgentRun` reuses
|
|
159
|
+
// the exact same dot in its flat activity rows.
|
|
160
|
+
export function Marker({ status, color, live }: { status: StepStatus; color: string; live: boolean }) {
|
|
160
161
|
if (status === "done") {
|
|
161
162
|
// A passed step: filled in the accent ink with a white check.
|
|
162
163
|
return (
|
package/src/switch_button.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { Text } from "./text";
|
|
|
3
3
|
import { Switch, type SwitchProps } from "./switch";
|
|
4
4
|
import { PressableHighlight } from "./pressable_highlight";
|
|
5
5
|
import { Icon, type IconName } from "./icon";
|
|
6
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
6
7
|
|
|
7
8
|
export interface SwitchButtonProps extends SwitchProps {
|
|
8
9
|
icon?: IconName;
|
|
@@ -22,7 +23,7 @@ export function SwitchButton(props: SwitchButtonProps) {
|
|
|
22
23
|
paddingVertical: 4,
|
|
23
24
|
paddingLeft: 8,
|
|
24
25
|
paddingRight: 6,
|
|
25
|
-
borderRadius:
|
|
26
|
+
borderRadius: CONTROL_RADIUS,
|
|
26
27
|
}}
|
|
27
28
|
onPress={() => onChange?.(!value)}
|
|
28
29
|
tooltip={tooltip}
|
package/src/switcher.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "./popover";
|
|
|
7
7
|
import { Stack } from "./stack";
|
|
8
8
|
import { Text } from "./text";
|
|
9
9
|
import { colors } from "./colors";
|
|
10
|
+
import { CONTROL_HEIGHT, CONTROL_RADIUS } from "./control_surface";
|
|
10
11
|
|
|
11
12
|
export interface SwitcherItem {
|
|
12
13
|
id: string;
|
|
@@ -100,9 +101,9 @@ const styles = StyleSheet.create({
|
|
|
100
101
|
flexDirection: "row",
|
|
101
102
|
alignItems: "center",
|
|
102
103
|
gap: 6,
|
|
104
|
+
height: CONTROL_HEIGHT,
|
|
103
105
|
paddingHorizontal: 10,
|
|
104
|
-
|
|
105
|
-
borderRadius: 8,
|
|
106
|
+
borderRadius: CONTROL_RADIUS,
|
|
106
107
|
},
|
|
107
108
|
popoverBody: {
|
|
108
109
|
minWidth: 220,
|
package/src/tabs.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { View } from "react-native";
|
|
|
3
3
|
import { PressableHighlight } from "./pressable_highlight";
|
|
4
4
|
import { Text } from "./text";
|
|
5
5
|
import { colors } from "./colors";
|
|
6
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
6
7
|
|
|
7
8
|
export interface TabOption<T extends string> {
|
|
8
9
|
label: string;
|
|
@@ -138,7 +139,7 @@ function TabButton<T extends string>(props: TabButtonProps<T>) {
|
|
|
138
139
|
style={{
|
|
139
140
|
paddingVertical: 8,
|
|
140
141
|
paddingHorizontal: 16,
|
|
141
|
-
borderRadius:
|
|
142
|
+
borderRadius: CONTROL_RADIUS,
|
|
142
143
|
backgroundColor: pressed
|
|
143
144
|
? colors.zinc["100"]
|
|
144
145
|
: hovered
|
package/src/tag_input.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMemo, useRef, useState } from "react";
|
|
2
2
|
import { Pressable, ScrollView, StyleSheet, View, type StyleProp, type ViewStyle } from "react-native";
|
|
3
3
|
import { colors } from "./colors";
|
|
4
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
4
5
|
import { Text } from "./text";
|
|
5
6
|
import { Icon } from "./icon";
|
|
6
7
|
import { TextInputField } from "./text_input_field";
|
|
@@ -161,7 +162,7 @@ const styles = StyleSheet.create({
|
|
|
161
162
|
paddingVertical: 5,
|
|
162
163
|
borderWidth: 1,
|
|
163
164
|
borderColor: colors.border,
|
|
164
|
-
borderRadius:
|
|
165
|
+
borderRadius: CONTROL_RADIUS,
|
|
165
166
|
backgroundColor: colors.background,
|
|
166
167
|
},
|
|
167
168
|
chip: {
|
package/src/text_input_field.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
View,
|
|
6
6
|
} from "react-native";
|
|
7
7
|
import { colors } from "./colors";
|
|
8
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
8
9
|
import { Ref, useCallback } from "react";
|
|
9
10
|
import { Icon, IconName } from "./icon";
|
|
10
11
|
import { IconButton } from "./icon_button";
|
|
@@ -163,7 +164,7 @@ export function TextInputField(props: TextInputFieldProps) {
|
|
|
163
164
|
|
|
164
165
|
const styles = StyleSheet.create({
|
|
165
166
|
input: {
|
|
166
|
-
borderRadius:
|
|
167
|
+
borderRadius: CONTROL_RADIUS,
|
|
167
168
|
borderWidth: 1,
|
|
168
169
|
borderColor: colors.border,
|
|
169
170
|
height: 40,
|
package/src/time_field.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { Pressable, ScrollView, StyleSheet, View } from "react-native";
|
|
3
3
|
import { colors } from "./colors";
|
|
4
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
4
5
|
import { Text } from "./text";
|
|
5
6
|
import { Icon } from "./icon";
|
|
6
7
|
import { Popover, PopoverContent } from "./popover";
|
|
@@ -266,7 +267,7 @@ const styles = StyleSheet.create({
|
|
|
266
267
|
height: 40,
|
|
267
268
|
paddingHorizontal: 8,
|
|
268
269
|
gap: 2,
|
|
269
|
-
borderRadius:
|
|
270
|
+
borderRadius: CONTROL_RADIUS,
|
|
270
271
|
borderWidth: 1,
|
|
271
272
|
borderColor: colors.border,
|
|
272
273
|
backgroundColor: colors.background,
|
package/src/time_picker.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { KeyboardEvent } from "react";
|
|
2
2
|
import { colors } from "@lotics/ui/colors";
|
|
3
3
|
import { fontFamilyRegular, inputTextStyleWeb } from "@lotics/ui/text_utils";
|
|
4
|
+
import { CONTROL_RADIUS } from "./control_surface";
|
|
4
5
|
export interface TimePickerProps {
|
|
5
6
|
value?: string;
|
|
6
7
|
onValueChange: (value: string) => void;
|
|
@@ -31,7 +32,7 @@ export function TimePicker(props: TimePickerProps) {
|
|
|
31
32
|
height: 40,
|
|
32
33
|
paddingLeft: 8,
|
|
33
34
|
paddingRight: 8,
|
|
34
|
-
borderRadius:
|
|
35
|
+
borderRadius: CONTROL_RADIUS,
|
|
35
36
|
borderWidth: 1,
|
|
36
37
|
borderStyle: "solid",
|
|
37
38
|
borderColor: colors.border,
|
package/src/triage_row.tsx
CHANGED
|
@@ -74,9 +74,9 @@ export function TriageRow(props: TriageRowProps) {
|
|
|
74
74
|
</Text>
|
|
75
75
|
) : (
|
|
76
76
|
<View style={styles.footer}>
|
|
77
|
-
{props.onOverride ? <Button title="Reclassify" color="muted"
|
|
78
|
-
{props.onDismiss ? <Button title="Dismiss" color="muted"
|
|
79
|
-
{props.onAccept ? <Button title="Accept" color="primary"
|
|
77
|
+
{props.onOverride ? <Button title="Reclassify" color="muted" onPress={props.onOverride} /> : null}
|
|
78
|
+
{props.onDismiss ? <Button title="Dismiss" color="muted" onPress={props.onDismiss} /> : null}
|
|
79
|
+
{props.onAccept ? <Button title="Accept" color="primary" onPress={props.onAccept} /> : null}
|
|
80
80
|
</View>
|
|
81
81
|
)}
|
|
82
82
|
</View>
|