@lotics/ui 5.9.0 → 5.10.1

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.
Files changed (97) hide show
  1. package/AGENTS.md +131 -44
  2. package/examples/tpl_approvals.tsx +3 -3
  3. package/examples/tpl_dossier.tsx +5 -4
  4. package/examples/tpl_pipeline.tsx +400 -0
  5. package/examples/tpl_record.tsx +5 -4
  6. package/examples/tpl_shifts.tsx +7 -5
  7. package/examples/tpl_task_board.tsx +473 -0
  8. package/examples/tpl_tasks.tsx +456 -0
  9. package/package.json +10 -5
  10. package/src/accordion.tsx +1 -1
  11. package/src/agent_progress.tsx +1 -1
  12. package/src/agent_run.tsx +1 -1
  13. package/src/breakdown.tsx +2 -2
  14. package/src/button.tsx +12 -3
  15. package/src/calendar/calendar_view.tsx +10 -10
  16. package/src/calendar/month_view.tsx +30 -11
  17. package/src/calendar/time_grid_view.tsx +25 -7
  18. package/src/card_select_item.tsx +11 -13
  19. package/src/check_circle.tsx +88 -0
  20. package/src/checkbox_input.tsx +5 -1
  21. package/src/chip.tsx +1 -1
  22. package/src/chip_group.tsx +1 -1
  23. package/src/column_filter.tsx +3 -2
  24. package/src/combobox.tsx +84 -219
  25. package/src/confidence.tsx +14 -3
  26. package/src/control_surface.ts +22 -7
  27. package/src/data_grid.tsx +159 -0
  28. package/src/date_calendar.tsx +46 -23
  29. package/src/date_field.tsx +10 -2
  30. package/src/date_filter.tsx +5 -9
  31. package/src/date_picker.tsx +78 -26
  32. package/src/date_picker_value.ts +11 -0
  33. package/src/date_range_filter_field.tsx +6 -4
  34. package/src/drawer.tsx +1 -1
  35. package/src/file_dropzone.tsx +5 -0
  36. package/src/file_gallery_modal.tsx +43 -42
  37. package/src/file_preview.web.tsx +25 -11
  38. package/src/file_preview_types.ts +9 -0
  39. package/src/file_row.tsx +5 -1
  40. package/src/file_rows.tsx +6 -2
  41. package/src/file_thumbnail.tsx +13 -4
  42. package/src/file_thumbnail_grid.tsx +5 -0
  43. package/src/files_editor.tsx +232 -0
  44. package/src/filter_chip.tsx +25 -12
  45. package/src/focus_ring_pressable.tsx +34 -0
  46. package/src/form_picker.tsx +3 -3
  47. package/src/gantt/gantt_view.tsx +25 -7
  48. package/src/heatmap.tsx +5 -1
  49. package/src/icon_button.tsx +2 -2
  50. package/src/image_gallery.tsx +8 -10
  51. package/src/index.css +8 -12
  52. package/src/inline_date_picker.tsx +11 -11
  53. package/src/inline_edit.tsx +22 -6
  54. package/src/inline_member_select.tsx +1 -1
  55. package/src/inline_select.tsx +9 -8
  56. package/src/inline_text_input.tsx +4 -1
  57. package/src/link.tsx +11 -1
  58. package/src/link_button.tsx +1 -1
  59. package/src/list_item.tsx +2 -2
  60. package/src/member_select.tsx +9 -4
  61. package/src/menu_button.tsx +2 -2
  62. package/src/menu_list_item.tsx +2 -2
  63. package/src/number_input.tsx +11 -4
  64. package/src/option_list.tsx +211 -0
  65. package/src/peek.tsx +1 -1
  66. package/src/picker.tsx +24 -213
  67. package/src/pressable_highlight.tsx +42 -23
  68. package/src/radio_picker.tsx +2 -2
  69. package/src/range_slider.tsx +35 -7
  70. package/src/react_native.d.ts +3 -0
  71. package/src/scroll_to_bottom.tsx +1 -1
  72. package/src/section.tsx +7 -2
  73. package/src/segmented_control.tsx +2 -2
  74. package/src/select.tsx +299 -0
  75. package/src/sort_header.tsx +1 -1
  76. package/src/sources.tsx +1 -1
  77. package/src/spreadsheet_view.tsx +43 -17
  78. package/src/status_grid.tsx +4 -3
  79. package/src/stepper.tsx +1 -1
  80. package/src/switch.tsx +5 -1
  81. package/src/switch_button.tsx +1 -1
  82. package/src/switcher.tsx +1 -1
  83. package/src/table.tsx +5 -1
  84. package/src/tabs.tsx +2 -2
  85. package/src/text_input_field.tsx +15 -4
  86. package/src/time_picker.tsx +11 -4
  87. package/src/timeline.tsx +1 -1
  88. package/src/use_focus_ring.ts +80 -0
  89. package/src/use_hover.ts +26 -0
  90. package/src/use_list_keyboard_nav.test.ts +71 -0
  91. package/src/use_list_keyboard_nav.ts +52 -5
  92. package/src/use_option_list.test.ts +193 -0
  93. package/src/use_option_list.ts +354 -0
  94. package/src/command_menu.tsx +0 -205
  95. package/src/picker_menu.tsx +0 -355
  96. package/src/tag_input.tsx +0 -203
  97. package/src/time_field.tsx +0 -297
@@ -1,7 +1,8 @@
1
1
  import { useState } from "react";
2
- import { View, Pressable, StyleSheet } from "react-native";
2
+ import { View, StyleSheet } from "react-native";
3
3
  import { Text } from "../text";
4
4
  import { colors } from "../colors";
5
+ import { FocusRingPressable } from "../focus_ring_pressable";
5
6
  import { MonthView } from "./month_view";
6
7
  import { TimeGridView } from "./time_grid_view";
7
8
  import { addDays, addMonths, viewTitle } from "./dates";
@@ -50,15 +51,15 @@ export function CalendarView<T = unknown>(props: CalendarViewProps<T>) {
50
51
  <View style={styles.root}>
51
52
  <View style={styles.toolbar}>
52
53
  <View style={styles.navGroup}>
53
- <Pressable onPress={() => step(-1)} accessibilityRole="button" accessibilityLabel={L.previous} style={styles.iconBtn}>
54
+ <FocusRingPressable accessibilityRole="button" onPress={() => step(-1)} accessibilityLabel={L.previous} style={styles.iconBtn}>
54
55
  <Text size="lg" color="muted">‹</Text>
55
- </Pressable>
56
- <Pressable onPress={() => setDate(new Date())} accessibilityRole="button" style={styles.todayBtn}>
56
+ </FocusRingPressable>
57
+ <FocusRingPressable accessibilityRole="button" onPress={() => setDate(new Date())} style={styles.todayBtn}>
57
58
  <Text size="sm" weight="medium">{L.today}</Text>
58
- </Pressable>
59
- <Pressable onPress={() => step(1)} accessibilityRole="button" accessibilityLabel={L.next} style={styles.iconBtn}>
59
+ </FocusRingPressable>
60
+ <FocusRingPressable accessibilityRole="button" onPress={() => step(1)} accessibilityLabel={L.next} style={styles.iconBtn}>
60
61
  <Text size="lg" color="muted">›</Text>
61
- </Pressable>
62
+ </FocusRingPressable>
62
63
  </View>
63
64
 
64
65
  <Text size="lg" weight="semibold" style={styles.title} numberOfLines={1}>
@@ -67,16 +68,15 @@ export function CalendarView<T = unknown>(props: CalendarViewProps<T>) {
67
68
 
68
69
  <View style={styles.viewSwitch}>
69
70
  {VIEW_ORDER.map((v) => (
70
- <Pressable
71
+ <FocusRingPressable accessibilityRole="button"
71
72
  key={v}
72
73
  onPress={() => setView(v)}
73
- accessibilityRole="button"
74
74
  style={[styles.viewBtn, view === v && styles.viewBtnActive]}
75
75
  >
76
76
  <Text size="sm" weight={view === v ? "medium" : "regular"} color={view === v ? "default" : "muted"}>
77
77
  {L[v]}
78
78
  </Text>
79
- </Pressable>
79
+ </FocusRingPressable>
80
80
  ))}
81
81
  </View>
82
82
  </View>
@@ -1,7 +1,28 @@
1
- import { useMemo, useRef } from "react";
2
- import { View, Pressable, StyleSheet } from "react-native";
1
+ import { useMemo, useRef, type ReactNode, type Ref } from "react";
2
+ import { View, StyleSheet, type StyleProp, type ViewStyle } from "react-native";
3
3
  import { Text } from "../text";
4
4
  import { colors } from "../colors";
5
+ import { FocusRingPressable } from "../focus_ring_pressable";
6
+
7
+ function MonthPressable(props: {
8
+ onPress?: () => void;
9
+ accessibilityLabel?: string;
10
+ style: StyleProp<ViewStyle>;
11
+ pressableRef?: Ref<View>;
12
+ children: ReactNode;
13
+ }) {
14
+ return (
15
+ <FocusRingPressable
16
+ ref={props.pressableRef}
17
+ onPress={props.onPress}
18
+ accessibilityRole={props.onPress ? "button" : undefined}
19
+ accessibilityLabel={props.accessibilityLabel}
20
+ style={props.style}
21
+ >
22
+ {props.children}
23
+ </FocusRingPressable>
24
+ );
25
+ }
5
26
  import { usePointerDrag } from "../use_pointer_drag";
6
27
  import { packEventLanes } from "./layout";
7
28
  import { addDays, dayDiff, daysInView, isSameMonth, isToday, startOfDay, weekdayShort } from "./dates";
@@ -89,10 +110,9 @@ export function MonthView<T = unknown>(props: MonthViewProps<T>) {
89
110
  const inMonth = isSameMonth(day, date);
90
111
  const today = isToday(day, now);
91
112
  return (
92
- <Pressable
113
+ <MonthPressable
93
114
  key={day.toISOString()}
94
115
  onPress={onDayPress ? () => onDayPress(day) : undefined}
95
- accessibilityRole={onDayPress ? "button" : undefined}
96
116
  style={styles.dateCell}
97
117
  >
98
118
  <View style={[styles.dateBadge, today && { backgroundColor: colors.teal[600] }]}>
@@ -104,7 +124,7 @@ export function MonthView<T = unknown>(props: MonthViewProps<T>) {
104
124
  {day.getDate()}
105
125
  </Text>
106
126
  </View>
107
- </Pressable>
127
+ </MonthPressable>
108
128
  );
109
129
  })}
110
130
  </View>
@@ -124,11 +144,10 @@ export function MonthView<T = unknown>(props: MonthViewProps<T>) {
124
144
  const banner = bar.span > 1 || !!bar.event.allDay;
125
145
  const drag = live && live.id === bar.event.id ? live : null;
126
146
  return (
127
- <Pressable
147
+ <MonthPressable
128
148
  key={bar.event.id}
129
- ref={onEventDrop ? bind(bar.event.id, "grab") : undefined}
149
+ pressableRef={onEventDrop ? bind(bar.event.id, "grab") : undefined}
130
150
  onPress={onEventPress ? () => onEventPress(bar.event) : undefined}
131
- accessibilityRole={onEventPress ? "button" : undefined}
132
151
  accessibilityLabel={bar.event.title}
133
152
  style={{
134
153
  position: "absolute",
@@ -161,18 +180,18 @@ export function MonthView<T = unknown>(props: MonthViewProps<T>) {
161
180
  {bar.event.title}
162
181
  </Text>
163
182
  </View>
164
- </Pressable>
183
+ </MonthPressable>
165
184
  );
166
185
  })}
167
186
  {weekDays.map((day, col) =>
168
187
  overflow[col] > 0 ? (
169
- <Pressable
188
+ <MonthPressable
170
189
  key={`o${col}`}
171
190
  onPress={onDayPress ? () => onDayPress(day) : undefined}
172
191
  style={{ position: "absolute", top: MAX_LANES * (LANE_H + LANE_GAP), left: `${(col / 7) * 100}%`, width: `${100 / 7}%`, paddingHorizontal: 6 }}
173
192
  >
174
193
  <Text size="xs" color="muted">{moreLabel(overflow[col])}</Text>
175
- </Pressable>
194
+ </MonthPressable>
176
195
  ) : null,
177
196
  )}
178
197
  </View>
@@ -1,7 +1,26 @@
1
- import { useEffect, useMemo, useRef, useState } from "react";
2
- import { View, ScrollView, Pressable, StyleSheet, Text as RNText } from "react-native";
1
+ import { useEffect, useMemo, useRef, useState, type ReactNode } from "react";
2
+ import { View, ScrollView, StyleSheet, Text as RNText, type StyleProp, type ViewStyle } from "react-native";
3
3
  import { Text } from "../text";
4
4
  import { colors } from "../colors";
5
+ import { FocusRingPressable } from "../focus_ring_pressable";
6
+
7
+ function TimeGridPressable(props: {
8
+ onPress?: () => void;
9
+ accessibilityLabel?: string;
10
+ style: StyleProp<ViewStyle>;
11
+ children: ReactNode;
12
+ }) {
13
+ return (
14
+ <FocusRingPressable
15
+ onPress={props.onPress}
16
+ accessibilityRole={props.onPress ? "button" : undefined}
17
+ accessibilityLabel={props.accessibilityLabel}
18
+ style={props.style}
19
+ >
20
+ {props.children}
21
+ </FocusRingPressable>
22
+ );
23
+ }
5
24
  import { layoutDayColumns, packEventLanes } from "./layout";
6
25
  import {
7
26
  daysInView,
@@ -56,7 +75,7 @@ function EventBlock<T>({
56
75
  const accent = event.color || colors.teal[600];
57
76
  const compact = height < 34;
58
77
  return (
59
- <Pressable
78
+ <FocusRingPressable
60
79
  onPress={onPress ? () => onPress(event) : undefined}
61
80
  accessibilityRole={onPress ? "button" : undefined}
62
81
  accessibilityLabel={event.title}
@@ -90,7 +109,7 @@ function EventBlock<T>({
90
109
  </Text>
91
110
  ) : null}
92
111
  </View>
93
- </Pressable>
112
+ </FocusRingPressable>
94
113
  );
95
114
  }
96
115
 
@@ -170,10 +189,9 @@ export function TimeGridView<T = unknown>(props: TimeGridViewProps<T>) {
170
189
  {allDayPacked.bars.map((bar) => {
171
190
  const accent = bar.event.color || colors.teal[600];
172
191
  return (
173
- <Pressable
192
+ <TimeGridPressable
174
193
  key={bar.event.id}
175
194
  onPress={onEventPress ? () => onEventPress(bar.event) : undefined}
176
- accessibilityRole={onEventPress ? "button" : undefined}
177
195
  accessibilityLabel={bar.event.title}
178
196
  style={{
179
197
  position: "absolute",
@@ -189,7 +207,7 @@ export function TimeGridView<T = unknown>(props: TimeGridViewProps<T>) {
189
207
  {bar.event.title}
190
208
  </Text>
191
209
  </View>
192
- </Pressable>
210
+ </TimeGridPressable>
193
211
  );
194
212
  })}
195
213
  </View>
@@ -1,7 +1,7 @@
1
- import { PressableStateCallbackType, StyleProp, StyleSheet, ViewStyle } from "react-native";
1
+ import { StyleProp, StyleSheet, ViewStyle } from "react-native";
2
2
  import { colors } from "./colors";
3
- import { CONTROL_RADIUS } from "./control_surface";
4
- import { PressableHighlight } from "./pressable_highlight";
3
+ import { CONTROL_RADIUS, FOCUS_RING } from "./control_surface";
4
+ import { PressableHighlight, PressableHighlightState } from "./pressable_highlight";
5
5
 
6
6
  interface CardSelectItemProps {
7
7
  children: React.ReactNode;
@@ -18,8 +18,8 @@ interface CardSelectItemProps {
18
18
  /**
19
19
  * A bordered, card-shaped button — the selectable item used on auth screens
20
20
  * (organization picker, login choices) and in entity switchers. Always
21
- * interactive: a real focusable `button` that shows a 2px ring on hover/press,
22
- * matching the global keyboard focus ring. Pass `selected` to keep that ring on
21
+ * interactive: a real focusable `button` that shows the kit FOCUS_RING on
22
+ * hover/press/keyboard focus. Pass `selected` to keep that ring on
23
23
  * for the current item in a single-selection list. For a static surface use Card.
24
24
  */
25
25
  export function CardSelectItem(props: CardSelectItemProps) {
@@ -32,9 +32,8 @@ export function CardSelectItem(props: CardSelectItemProps) {
32
32
  accessibilityLabel={accessibilityLabel}
33
33
  aria-pressed={selected}
34
34
  onPress={onPress}
35
- style={(state: PressableStateCallbackType) => {
36
- const hovered = (state as { hovered?: boolean }).hovered;
37
- const active = selected || hovered || state.pressed;
35
+ style={(state: PressableHighlightState) => {
36
+ const active = selected || state.hovered || state.pressed || state.focusVisible;
38
37
  return [styles.container, active && styles.ring, style];
39
38
  }}
40
39
  >
@@ -51,11 +50,10 @@ const styles = StyleSheet.create({
51
50
  borderColor: colors.border,
52
51
  borderWidth: 1,
53
52
  },
54
- // A 2px ring flush against the border (spread 2, no offset/blur) — the same
55
- // weight and color as the global `:focus-visible` outline, so hover, press,
56
- // and keyboard focus all read as one consistent ring rather than a thin
57
- // border-darken. boxShadow keeps it layout-neutral (no 1px→2px reflow).
53
+ // The kit FOCUS_RING flush against the border (spread 2, no offset/blur), so
54
+ // hover, press, and keyboard focus all read as one consistent ring rather than a
55
+ // thin border-darken. boxShadow keeps it layout-neutral (no 1px→2px reflow).
58
56
  ring: {
59
- ...({ boxShadow: `0 0 0 2px ${colors.zinc["900"]}` } as ViewStyle),
57
+ ...({ boxShadow: FOCUS_RING } as ViewStyle),
60
58
  },
61
59
  });
@@ -0,0 +1,88 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { Animated, StyleSheet, View, type GestureResponderEvent } from "react-native";
3
+ import { colors } from "./colors";
4
+ import { FocusRingPressable } from "./focus_ring_pressable";
5
+ import { Icon } from "./icon";
6
+
7
+ export interface CheckCircleProps {
8
+ checked: boolean;
9
+ /** Toggle handler. Omit for a read-only ring (shows state, not pressable). */
10
+ onChange?: (checked: boolean) => void;
11
+ /** Fill colour when checked. Default zinc-900 (pass a list/project colour to tint it). */
12
+ color?: string;
13
+ /** Diameter. Default 20. */
14
+ size?: number;
15
+ disabled?: boolean;
16
+ accessibilityLabel: string;
17
+ }
18
+
19
+ /**
20
+ * A circular completion toggle — an empty ring that fills with a spring + a white
21
+ * check when checked (the iOS-Reminders / Linear "done" gesture), distinct from
22
+ * the square form `Checkbox`. The signature control for a task / to-do / checklist
23
+ * item; pair it with a title that strikes + mutes on the same `checked`. It stops
24
+ * the press, so it works inside a pressable row. Read-only (no `onChange`) shows
25
+ * the state without a tap.
26
+ */
27
+ export function CheckCircle(props: CheckCircleProps) {
28
+ const { checked, onChange, color = colors.zinc[900], size = 20, disabled, accessibilityLabel } = props;
29
+ const v = useRef(new Animated.Value(checked ? 1 : 0)).current;
30
+ useEffect(() => {
31
+ Animated.spring(v, { toValue: checked ? 1 : 0, useNativeDriver: false, friction: 6, tension: 160 }).start();
32
+ }, [checked, v]);
33
+
34
+ const face = (borderColor: string) => (
35
+ <View style={[styles.ring, { width: size, height: size, borderRadius: size / 2, borderColor }]}>
36
+ <Animated.View style={{ position: "absolute", width: size, height: size, borderRadius: size / 2, backgroundColor: color, transform: [{ scale: v }], opacity: v }} />
37
+ <Animated.View style={{ opacity: v, transform: [{ scale: v }] }}>
38
+ <Icon name="check" size={Math.round(size * 0.62)} color={colors.white} />
39
+ </Animated.View>
40
+ </View>
41
+ );
42
+
43
+ if (!onChange) {
44
+ return (
45
+ <View accessibilityRole="image" accessibilityLabel={accessibilityLabel} style={[styles.tap, { width: size, height: size }, disabled ? styles.disabled : null]}>
46
+ {face(checked ? color : colors.zinc[300])}
47
+ </View>
48
+ );
49
+ }
50
+
51
+ const press = (e: GestureResponderEvent) => {
52
+ e?.stopPropagation?.();
53
+ if (!disabled) onChange(!checked);
54
+ };
55
+ return (
56
+ <FocusRingPressable
57
+ accessibilityRole="checkbox"
58
+ accessibilityState={{ checked, disabled }}
59
+ accessibilityLabel={accessibilityLabel}
60
+ disabled={disabled}
61
+ onPress={press}
62
+ hitSlop={10}
63
+ // The ring follows the element's border-radius — round it to the circle so
64
+ // the keyboard ring hugs the toggle instead of boxing it.
65
+ style={[styles.tap, { width: size, height: size, borderRadius: size / 2 }, disabled ? styles.disabled : null]}
66
+ >
67
+ {({ hovered }: { hovered?: boolean }) => face(checked ? color : hovered ? colors.zinc[500] : colors.zinc[300])}
68
+ </FocusRingPressable>
69
+ );
70
+ }
71
+
72
+ const styles = StyleSheet.create({
73
+ tap: {
74
+ alignItems: "center",
75
+ justifyContent: "center",
76
+ // @ts-ignore rn-web
77
+ cursor: "pointer",
78
+ },
79
+ disabled: { opacity: 0.4 },
80
+ ring: {
81
+ alignItems: "center",
82
+ justifyContent: "center",
83
+ borderWidth: 1.5,
84
+ // @ts-ignore rn-web
85
+ transitionProperty: "border-color",
86
+ transitionDuration: "0.12s",
87
+ },
88
+ });
@@ -1,6 +1,8 @@
1
1
  import { useCallback } from "react";
2
2
  import { Pressable } from "react-native";
3
3
  import { Checkbox } from "./checkbox";
4
+ import { FOCUS_RING } from "./control_surface";
5
+ import { useFocusRing } from "./use_focus_ring";
4
6
  interface CheckboxInputProps {
5
7
  /**
6
8
  * Accessible name. Required because an unlabelled checkbox only announces
@@ -16,6 +18,7 @@ interface CheckboxInputProps {
16
18
 
17
19
  export function CheckboxInput(props: CheckboxInputProps) {
18
20
  const { accessibilityLabel, indeterminate, checked, onChange, disabled, testID } = props;
21
+ const { focusVisible, focusProps } = useFocusRing();
19
22
 
20
23
  const handlePress = useCallback(() => {
21
24
  if (!disabled) {
@@ -28,7 +31,8 @@ export function CheckboxInput(props: CheckboxInputProps) {
28
31
  testID={testID}
29
32
  onPress={handlePress}
30
33
  disabled={disabled}
31
- style={{ opacity: disabled ? 0.5 : 1 }}
34
+ {...focusProps}
35
+ style={[{ opacity: disabled ? 0.5 : 1, borderRadius: 6 }, focusVisible && { boxShadow: FOCUS_RING }]}
32
36
  // Use the W3C ARIA props directly: RN-web 0.21 no longer maps
33
37
  // `accessibilityState={{ checked }}` to `aria-checked`, which dropped the
34
38
  // checked state from the accessibility tree (a role="checkbox" with no
package/src/chip.tsx CHANGED
@@ -20,7 +20,7 @@ export function Chip(props: ChipProps) {
20
20
  <View ref={ref}>
21
21
  {onPress ? (
22
22
  <PressableHighlight
23
- testID={testID}
23
+ focusRing testID={testID}
24
24
  onPress={onPress}
25
25
  style={(state) => [chipSurfaceStyle(state), styles.pillLayout, onDismiss && styles.pillWithDismiss]}
26
26
  >
@@ -46,7 +46,7 @@ export function ChipGroup<T extends string = string>(props: ChipGroupProps<T>) {
46
46
  const active = option.value === value;
47
47
  return (
48
48
  <PressableHighlight
49
- key={option.value}
49
+ focusRing key={option.value}
50
50
  testID={option.testID}
51
51
  onPress={() => onValueChange(option.value)}
52
52
  accessibilityRole="button"
@@ -2,7 +2,7 @@ import { View, StyleSheet } from "react-native";
2
2
  import { Text } from "./text";
3
3
  import { TextInputField } from "./text_input_field";
4
4
  import { NumberInput } from "./number_input";
5
- import { PickerMenu } from "./picker_menu";
5
+ import { OptionList } from "./option_list";
6
6
  import { FilterChip } from "./filter_chip";
7
7
  import type { PickerOption } from "./picker";
8
8
 
@@ -143,7 +143,8 @@ export function ColumnFilter(props: ColumnFilterProps) {
143
143
  />
144
144
  </View>
145
145
  ) : (
146
- <PickerMenu
146
+ <OptionList
147
+ search={{ mode: "none" }}
147
148
  multi
148
149
  options={column.options ?? []}
149
150
  value={value?.kind === "select" ? value.selected : []}