convex-feedback-ui 0.1.5 → 0.1.7

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 (131) hide show
  1. package/README.md +143 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/native/expo/ExpoFeedbackBody.d.ts +1 -1
  4. package/dist/native/expo/ExpoFeedbackBody.d.ts.map +1 -1
  5. package/dist/native/expo/ExpoFeedbackBody.js +2 -2
  6. package/dist/native/expo/ExpoFeedbackBody.js.map +1 -1
  7. package/dist/native/expo/FeedbackCreateStackLayout.d.ts +3 -0
  8. package/dist/native/expo/FeedbackCreateStackLayout.d.ts.map +1 -0
  9. package/dist/native/expo/FeedbackCreateStackLayout.js +35 -0
  10. package/dist/native/expo/FeedbackCreateStackLayout.js.map +1 -0
  11. package/dist/native/expo/FeedbackRoutes.d.ts +4 -0
  12. package/dist/native/expo/FeedbackRoutes.d.ts.map +1 -0
  13. package/dist/native/expo/FeedbackRoutes.js +81 -0
  14. package/dist/native/expo/FeedbackRoutes.js.map +1 -0
  15. package/dist/native/expo/FeedbackScreen.d.ts +1 -1
  16. package/dist/native/expo/FeedbackScreen.d.ts.map +1 -1
  17. package/dist/native/expo/FeedbackScreen.js +2 -2
  18. package/dist/native/expo/FeedbackScreen.js.map +1 -1
  19. package/dist/native/expo/FeedbackStack.d.ts +1 -1
  20. package/dist/native/expo/FeedbackStack.d.ts.map +1 -1
  21. package/dist/native/expo/FeedbackStack.js +10 -5
  22. package/dist/native/expo/FeedbackStack.js.map +1 -1
  23. package/dist/native/expo/FeedbackStackLayout.d.ts +3 -0
  24. package/dist/native/expo/FeedbackStackLayout.d.ts.map +1 -0
  25. package/dist/native/expo/FeedbackStackLayout.js +54 -0
  26. package/dist/native/expo/FeedbackStackLayout.js.map +1 -0
  27. package/dist/native/expo/RoutedFeedbackContext.d.ts +4 -0
  28. package/dist/native/expo/RoutedFeedbackContext.d.ts.map +1 -0
  29. package/dist/native/expo/RoutedFeedbackContext.js +11 -0
  30. package/dist/native/expo/RoutedFeedbackContext.js.map +1 -0
  31. package/dist/native/expo/RoutedFeedbackModalContext.d.ts +7 -0
  32. package/dist/native/expo/RoutedFeedbackModalContext.d.ts.map +1 -0
  33. package/dist/native/expo/RoutedFeedbackModalContext.js +7 -0
  34. package/dist/native/expo/RoutedFeedbackModalContext.js.map +1 -0
  35. package/dist/native/expo/index.d.ts +4 -0
  36. package/dist/native/expo/index.d.ts.map +1 -1
  37. package/dist/native/expo/index.js +4 -0
  38. package/dist/native/expo/index.js.map +1 -1
  39. package/dist/native/expo/routes.d.ts +16 -0
  40. package/dist/native/expo/routes.d.ts.map +1 -0
  41. package/dist/native/expo/routes.js +23 -0
  42. package/dist/native/expo/routes.js.map +1 -0
  43. package/dist/native/expo/types.d.ts +53 -1
  44. package/dist/native/expo/types.d.ts.map +1 -1
  45. package/dist/native/native/FeedbackScreen.d.ts +1 -1
  46. package/dist/native/native/FeedbackScreen.d.ts.map +1 -1
  47. package/dist/native/native/FeedbackScreen.js +2 -2
  48. package/dist/native/native/FeedbackScreen.js.map +1 -1
  49. package/dist/native/shared/ui/BodyContent.d.ts +1 -1
  50. package/dist/native/shared/ui/BodyContent.d.ts.map +1 -1
  51. package/dist/native/shared/ui/BodyContent.js +2 -2
  52. package/dist/native/shared/ui/BodyContent.js.map +1 -1
  53. package/dist/native/shared/ui/Button.d.ts +2 -1
  54. package/dist/native/shared/ui/Button.d.ts.map +1 -1
  55. package/dist/native/shared/ui/Button.js +9 -4
  56. package/dist/native/shared/ui/Button.js.map +1 -1
  57. package/dist/native/shared/ui/FeedbackScreenHeader.d.ts.map +1 -1
  58. package/dist/native/shared/ui/FeedbackScreenHeader.js +8 -4
  59. package/dist/native/shared/ui/FeedbackScreenHeader.js.map +1 -1
  60. package/dist/native/shared/ui/FeedbackScreenList.d.ts +1 -1
  61. package/dist/native/shared/ui/FeedbackScreenList.d.ts.map +1 -1
  62. package/dist/native/shared/ui/FeedbackScreenList.js +18 -5
  63. package/dist/native/shared/ui/FeedbackScreenList.js.map +1 -1
  64. package/dist/native/shared/ui/NewEntry.d.ts +10 -0
  65. package/dist/native/shared/ui/NewEntry.d.ts.map +1 -1
  66. package/dist/native/shared/ui/NewEntry.js +7 -14
  67. package/dist/native/shared/ui/NewEntry.js.map +1 -1
  68. package/dist/native/shared/ui/primitives.d.ts +7 -1
  69. package/dist/native/shared/ui/primitives.d.ts.map +1 -1
  70. package/dist/native/shared/ui/primitives.js +38 -0
  71. package/dist/native/shared/ui/primitives.js.map +1 -1
  72. package/dist/react/primitives.d.ts +9 -1
  73. package/dist/react/primitives.d.ts.map +1 -1
  74. package/dist/react/primitives.js +12 -0
  75. package/dist/react/primitives.js.map +1 -1
  76. package/dist/react/screen.d.ts +1 -1
  77. package/dist/react/screen.d.ts.map +1 -1
  78. package/dist/react/screen.js +21 -10
  79. package/dist/react/screen.js.map +1 -1
  80. package/dist/react/styles.css +38 -1
  81. package/dist/shared/context/FeedbackBodyProvider.d.ts +1 -1
  82. package/dist/shared/context/FeedbackBodyProvider.d.ts.map +1 -1
  83. package/dist/shared/context/FeedbackBodyProvider.js +5 -1
  84. package/dist/shared/context/FeedbackBodyProvider.js.map +1 -1
  85. package/dist/shared/helpers.d.ts +5 -1
  86. package/dist/shared/helpers.d.ts.map +1 -1
  87. package/dist/shared/helpers.js +11 -0
  88. package/dist/shared/helpers.js.map +1 -1
  89. package/dist/shared/messages.d.ts.map +1 -1
  90. package/dist/shared/messages.js +1 -0
  91. package/dist/shared/messages.js.map +1 -1
  92. package/dist/shared/types/choice.d.ts +10 -0
  93. package/dist/shared/types/choice.d.ts.map +1 -0
  94. package/dist/shared/types/choice.js +2 -0
  95. package/dist/shared/types/choice.js.map +1 -0
  96. package/dist/shared/types/index.d.ts +1 -0
  97. package/dist/shared/types/index.d.ts.map +1 -1
  98. package/dist/shared/types/messages.d.ts +2 -0
  99. package/dist/shared/types/messages.d.ts.map +1 -1
  100. package/dist/shared/types/screen.d.ts +13 -2
  101. package/dist/shared/types/screen.d.ts.map +1 -1
  102. package/package.json +12 -8
  103. package/src/native/expo/ExpoFeedbackBody.tsx +6 -1
  104. package/src/native/expo/FeedbackCreateStackLayout.tsx +62 -0
  105. package/src/native/expo/FeedbackRoutes.tsx +238 -0
  106. package/src/native/expo/FeedbackScreen.tsx +2 -0
  107. package/src/native/expo/FeedbackStack.tsx +40 -5
  108. package/src/native/expo/FeedbackStackLayout.tsx +118 -0
  109. package/src/native/expo/README.md +24 -0
  110. package/src/native/expo/RoutedFeedbackContext.tsx +20 -0
  111. package/src/native/expo/RoutedFeedbackModalContext.tsx +14 -0
  112. package/src/native/expo/index.ts +4 -0
  113. package/src/native/expo/routes.ts +41 -0
  114. package/src/native/expo/types.ts +65 -1
  115. package/src/native/native/FeedbackScreen.tsx +2 -0
  116. package/src/native/shared/ui/BodyContent.tsx +2 -0
  117. package/src/native/shared/ui/Button.tsx +12 -3
  118. package/src/native/shared/ui/FeedbackScreenHeader.tsx +25 -4
  119. package/src/native/shared/ui/FeedbackScreenList.tsx +48 -8
  120. package/src/native/shared/ui/NewEntry.tsx +12 -30
  121. package/src/native/shared/ui/primitives.tsx +90 -0
  122. package/src/react/primitives.tsx +55 -0
  123. package/src/react/screen.tsx +67 -33
  124. package/src/react/styles.css +38 -1
  125. package/src/shared/context/FeedbackBodyProvider.tsx +6 -0
  126. package/src/shared/helpers.ts +21 -1
  127. package/src/shared/messages.ts +1 -0
  128. package/src/shared/types/choice.ts +10 -0
  129. package/src/shared/types/index.ts +1 -0
  130. package/src/shared/types/messages.ts +3 -0
  131. package/src/shared/types/screen.ts +15 -1
@@ -11,6 +11,7 @@ import {
11
11
  FeedbackProvider,
12
12
  useFeedbackUi,
13
13
  } from "../shared/context/FeedbackProvider";
14
+ import { createEntryLabel, entryStatusChoices } from "../shared/helpers.js";
14
15
  import type {
15
16
  FeedbackScreenCommentBranchProps,
16
17
  FeedbackScreenContentProps,
@@ -22,6 +23,7 @@ import type {
22
23
  } from "../shared/types/";
23
24
  import {
24
25
  Comment,
26
+ ChoiceChips,
25
27
  FeedbackBoard,
26
28
  FeedbackEntry,
27
29
  FeedbackForm,
@@ -52,6 +54,7 @@ export function FeedbackScreen({
52
54
  renderActor,
53
55
  debounceDuration = 300,
54
56
  collectMetadata,
57
+ emptyState,
55
58
  ...props
56
59
  }: FeedbackScreenProps) {
57
60
  return (
@@ -64,6 +67,7 @@ export function FeedbackScreen({
64
67
  maxCommentDepth={maxCommentDepth}
65
68
  debounceDuration={debounceDuration}
66
69
  collectMetadata={collectMetadata}
70
+ emptyState={emptyState}
67
71
  collectStandardMetadata={collectWebMetadata}
68
72
  transformComments={transformComments}
69
73
  renderActor={renderActor}
@@ -90,16 +94,24 @@ function FeedbackScreenInner({
90
94
  setShowForm,
91
95
  setSelectedEntryId,
92
96
  selectedEntryId,
97
+ statusFilter,
98
+ setStatusFilter,
93
99
  query,
94
100
  setQuery,
95
101
  debouncedQuery,
102
+ emptyState,
96
103
  } = useFeedbackBody();
97
104
  const { messages } = useFeedbackUi();
98
105
 
99
- const list = hooks.useEntries({ sort: entrySort, kinds: enabledKinds });
106
+ const list = hooks.useEntries({
107
+ sort: entrySort,
108
+ kinds: enabledKinds,
109
+ statusFilter,
110
+ });
100
111
  const searchResults = hooks.useSearchEntries({
101
112
  searchQuery: debouncedQuery,
102
113
  kinds: enabledKinds,
114
+ statusFilter,
103
115
  });
104
116
 
105
117
  if (selectedEntryId !== null) {
@@ -125,13 +137,21 @@ function FeedbackScreenInner({
125
137
  <div>
126
138
  <FeedbackBoard.Title />
127
139
  <p className="cf-board__subtitle">{messages.board.subtitle}</p>
140
+ <ChoiceChips
141
+ aria-label={messages.board.statusFilter}
142
+ options={entryStatusChoices(messages)}
143
+ value={statusFilter}
144
+ onValueChange={setStatusFilter}
145
+ />
128
146
  </div>
129
147
  <button
130
148
  type="button"
131
149
  className="cf-button cf-button--primary"
132
150
  onClick={() => setShowForm((current) => !current)}
133
151
  >
134
- {showForm ? messages.form.cancel : messages.board.createEntry}
152
+ {showForm
153
+ ? messages.form.cancel
154
+ : createEntryLabel(enabledKinds, messages)}
135
155
  </button>
136
156
  </FeedbackBoard.Header>
137
157
 
@@ -146,26 +166,39 @@ function FeedbackScreenInner({
146
166
 
147
167
  <FeedbackBoard.Search value={query} onValueChange={setQuery} />
148
168
 
149
- {loading && <p className="cf-state">{messages.board.loading}</p>}
150
- {!loading && entries !== undefined && entries.length === 0 && (
151
- <p className="cf-state">
152
- {searching
153
- ? messages.board.noSearchResults
154
- : messages.board.noEntries}
155
- </p>
169
+ {loading ? (
170
+ <FeedbackBoard.State>
171
+ <span className="cf-state__message">{messages.board.loading}</span>
172
+ </FeedbackBoard.State>
173
+ ) : entries !== undefined && entries.length === 0 ? (
174
+ <FeedbackBoard.State>
175
+ {emptyState}
176
+ <span className="cf-state__message">
177
+ {searching
178
+ ? messages.board.noSearchResults
179
+ : messages.board.noEntries}
180
+ </span>
181
+ <button
182
+ type="button"
183
+ className="cf-button cf-button--primary"
184
+ onClick={() => setShowForm(true)}
185
+ >
186
+ {createEntryLabel(enabledKinds, messages)}
187
+ </button>
188
+ </FeedbackBoard.State>
189
+ ) : (
190
+ <FeedbackBoard.List>
191
+ {(entries ?? []).map((entry) => (
192
+ <EntryCard
193
+ key={entry.id}
194
+ entry={entry}
195
+ hooks={hooks}
196
+ onOpen={() => setSelectedEntryId(entry.id)}
197
+ />
198
+ ))}
199
+ </FeedbackBoard.List>
156
200
  )}
157
201
 
158
- <FeedbackBoard.List>
159
- {(entries ?? []).map((entry) => (
160
- <EntryCard
161
- key={entry.id}
162
- entry={entry}
163
- hooks={hooks}
164
- onOpen={() => setSelectedEntryId(entry.id)}
165
- />
166
- ))}
167
- </FeedbackBoard.List>
168
-
169
202
  {!searching && list.status === "CanLoadMore" && (
170
203
  <button
171
204
  type="button"
@@ -273,19 +306,20 @@ function CreateEntryForm({ onCreated }: FeedbackScreenEntryModalProps) {
273
306
 
274
307
  return (
275
308
  <FeedbackForm.Root onSubmit={submit}>
276
- <label className="cf-field">
277
- <span>{messages.form.kind}</span>
278
- <FeedbackForm.Select
279
- value={kind}
280
- onChange={(event) => setKind(event.currentTarget.value as EntryKind)}
281
- >
282
- {enabledKinds.map((value) => (
283
- <option key={value} value={value}>
284
- {messages.kinds[value]}
285
- </option>
286
- ))}
287
- </FeedbackForm.Select>
288
- </label>
309
+ {enabledKinds.length > 1 && (
310
+ <label className="cf-field">
311
+ <span>{messages.form.kind}</span>
312
+ <ChoiceChips
313
+ aria-label={messages.form.kind}
314
+ options={enabledKinds.map((value) => ({
315
+ value,
316
+ label: messages.kinds[value],
317
+ }))}
318
+ value={kind}
319
+ onValueChange={setKind}
320
+ />
321
+ </label>
322
+ )}
289
323
  <label className="cf-field">
290
324
  <span>{messages.form.title}</span>
291
325
  <FeedbackForm.Input
@@ -30,6 +30,33 @@
30
30
  margin: 0.4rem 0 0;
31
31
  color: var(--cf-muted);
32
32
  }
33
+ :where(.cf-board) :where(.cf-choice-chips) {
34
+ display: flex;
35
+ flex-wrap: wrap;
36
+ align-items: center;
37
+ gap: 7px;
38
+ margin-top: 0.75rem;
39
+ }
40
+ :where(.cf-board) :where(.cf-choice-chip) {
41
+ border: 1px solid var(--cf-border);
42
+ border-radius: 999px;
43
+ padding: 6px 10px;
44
+ background: var(--cf-surface);
45
+ color: var(--cf-muted);
46
+ font: inherit;
47
+ font-size: 0.85rem;
48
+ font-weight: 600;
49
+ cursor: pointer;
50
+ }
51
+ :where(.cf-board) :where(.cf-choice-chip[data-selected="true"]) {
52
+ border-color: var(--cf-primary);
53
+ background: color-mix(in srgb, var(--cf-primary) 10%, var(--cf-surface));
54
+ color: var(--cf-primary);
55
+ }
56
+ :where(.cf-board) :where(.cf-choice-chip:focus-visible) {
57
+ outline: 3px solid color-mix(in srgb, var(--cf-primary) 25%, transparent);
58
+ outline-offset: 2px;
59
+ }
33
60
  :where(.cf-board) :where(.cf-board__list),
34
61
  :where(.cf-board) :where(.cf-comments) {
35
62
  display: grid;
@@ -198,8 +225,18 @@
198
225
  -webkit-box-orient: vertical;
199
226
  }
200
227
  :where(.cf-board) :where(.cf-state) {
228
+ display: flex;
229
+ min-height: 180px;
230
+ flex-direction: column;
231
+ align-items: center;
232
+ justify-content: center;
233
+ gap: var(--cf-space);
234
+ padding: calc(var(--cf-space) * 1.5);
201
235
  color: var(--cf-muted);
202
- padding: 12px 2px;
236
+ text-align: center;
237
+ }
238
+ :where(.cf-board) :where(.cf-state__message) {
239
+ margin: 0;
203
240
  }
204
241
  :where(.cf-board) :where(.cf-detail),
205
242
  :where(.cf-board) :where(.cf-discussion) {
@@ -6,6 +6,7 @@ import {
6
6
  useMemo,
7
7
  useState,
8
8
  } from "react";
9
+ import type { EntryStatusFilter } from "convex-feedback";
9
10
  import { debounce } from "../helpers";
10
11
  import type {
11
12
  FeedbackScreenBodyContextValue,
@@ -23,6 +24,7 @@ export function FeedbackBodyProvider({
23
24
  maxCommentDepth,
24
25
  debounceDuration,
25
26
  collectMetadata,
27
+ emptyState,
26
28
  collectStandardMetadata,
27
29
  transformComments,
28
30
  renderActor,
@@ -33,6 +35,7 @@ export function FeedbackBodyProvider({
33
35
  const [isSearching, setIsSearching] = useState(false);
34
36
  const [query, setQuery] = useState("");
35
37
  const [debouncedQuery, setDebouncedQuery] = useState("");
38
+ const [statusFilter, setStatusFilter] = useState<EntryStatusFilter>("open");
36
39
 
37
40
  const updateDebouncedQuery = useMemo(
38
41
  () => debounce(setDebouncedQuery, debounceDuration),
@@ -51,12 +54,14 @@ export function FeedbackBodyProvider({
51
54
  showForm,
52
55
  isSearching,
53
56
  selectedEntryId,
57
+ statusFilter,
54
58
 
55
59
  setQuery,
56
60
  setDebouncedQuery,
57
61
  setShowForm,
58
62
  setIsSearching,
59
63
  setSelectedEntryId,
64
+ setStatusFilter,
60
65
 
61
66
  hooks,
62
67
  entrySort,
@@ -65,6 +70,7 @@ export function FeedbackBodyProvider({
65
70
  maxCommentDepth,
66
71
  debounceDuration,
67
72
  collectMetadata,
73
+ emptyState,
68
74
  collectStandardMetadata,
69
75
  transformComments,
70
76
  renderActor,
@@ -1,4 +1,6 @@
1
- import type { EntryKind } from "convex-feedback";
1
+ import type { EntryKind, EntryStatusFilter } from "convex-feedback";
2
+ import type { FeedbackMessages } from "./types/messages.js";
3
+ import type { ChoiceChipOption } from "./types/choice.js";
2
4
 
3
5
  export const kinds: readonly EntryKind[] = [
4
6
  "feedback",
@@ -6,6 +8,24 @@ export const kinds: readonly EntryKind[] = [
6
8
  "bug_report",
7
9
  ];
8
10
 
11
+ export function createEntryLabel(
12
+ enabledKinds: readonly EntryKind[],
13
+ messages: FeedbackMessages,
14
+ ): string {
15
+ return enabledKinds.length === 1
16
+ ? messages.newFeedback[enabledKinds[0]!]
17
+ : messages.board.createEntry;
18
+ }
19
+
20
+ export function entryStatusChoices(
21
+ messages: FeedbackMessages,
22
+ ): readonly ChoiceChipOption<EntryStatusFilter>[] {
23
+ return [
24
+ { value: "open", label: messages.statuses.open },
25
+ { value: "closed", label: messages.statuses.closed },
26
+ ];
27
+ }
28
+
9
29
  export function debounce<TArgs extends unknown[]>(
10
30
  callback: (...args: TArgs) => void,
11
31
  delay: number,
@@ -5,6 +5,7 @@ export const englishFeedbackMessages: FeedbackMessages = {
5
5
  title: "Feedback",
6
6
  subtitle: "Share ideas, report problems, and help shape what comes next.",
7
7
  searchPlaceholder: "Search feedback…",
8
+ statusFilter: "Filter by status",
8
9
  createEntry: "Create feedback",
9
10
  noEntries: "No feedback yet.",
10
11
  noSearchResults: "No matching feedback found.",
@@ -0,0 +1,10 @@
1
+ export interface ChoiceChipOption<Value extends string = string> {
2
+ value: Value;
3
+ label: string;
4
+ }
5
+
6
+ export interface ChoiceChipsBaseProps<Value extends string = string> {
7
+ options: readonly ChoiceChipOption<Value>[];
8
+ value: Value;
9
+ onValueChange: (value: Value) => void;
10
+ }
@@ -1,5 +1,6 @@
1
1
  export type * from "./board.js";
2
2
  export type * from "./comment.js";
3
+ export type * from "./choice.js";
3
4
  export type * from "./context.js";
4
5
  export type * from "./entry.js";
5
6
  export type * from "./form.js";
@@ -18,6 +18,9 @@ export interface FeedbackMessages {
18
18
  /** Search input placeholder. */
19
19
  searchPlaceholder: string;
20
20
 
21
+ /** Accessible label for the open/closed entry status filter. */
22
+ statusFilter: string;
23
+
21
24
  /** CTA for opening the create-entry flow.
22
25
  * This is shown when enabled kinds are two or more.
23
26
  * Use messages.newFeedback for a single-kind entry.
@@ -2,6 +2,7 @@ import type {
2
2
  CommentSort,
3
3
  EntryKind,
4
4
  EntrySort,
5
+ EntryStatusFilter,
5
6
  FeedbackComment,
6
7
  FeedbackEntry,
7
8
  } from "convex-feedback";
@@ -95,6 +96,9 @@ export interface FeedbackScreenBaseProps {
95
96
  * entry kind. Disabled by default.
96
97
  */
97
98
  collectMetadata?: CollectMetadata;
99
+
100
+ /** Optional host-owned content rendered above the empty-state message. */
101
+ emptyState?: ReactNode;
98
102
  }
99
103
 
100
104
  export interface FeedbackScreenRootProps
@@ -106,9 +110,10 @@ export interface FeedbackScreenRootProps
106
110
 
107
111
  export interface FeedbackScreenProviderProps
108
112
  extends
109
- Required<Omit<FeedbackScreenBaseProps, "collectMetadata">>,
113
+ Required<Omit<FeedbackScreenBaseProps, "collectMetadata" | "emptyState">>,
110
114
  FeedbackScreenTransformationProps {
111
115
  collectMetadata?: CollectMetadata;
116
+ emptyState?: ReactNode;
112
117
  collectStandardMetadata: StandardMetadataCollector;
113
118
  }
114
119
 
@@ -119,11 +124,13 @@ export interface FeedbackScreenBodyContextValue
119
124
  showForm: boolean;
120
125
  isSearching: boolean;
121
126
  selectedEntryId: string | null;
127
+ statusFilter: EntryStatusFilter;
122
128
  setQuery: React.Dispatch<React.SetStateAction<string>>;
123
129
  setDebouncedQuery: React.Dispatch<React.SetStateAction<string>>;
124
130
  setShowForm: React.Dispatch<React.SetStateAction<boolean>>;
125
131
  setIsSearching: React.Dispatch<React.SetStateAction<boolean>>;
126
132
  setSelectedEntryId: React.Dispatch<React.SetStateAction<string | null>>;
133
+ setStatusFilter: React.Dispatch<React.SetStateAction<EntryStatusFilter>>;
127
134
  }
128
135
 
129
136
  export type FeedbackScreenBodyProps = FeedbackColorProps;
@@ -139,6 +146,13 @@ export interface FeedbackScreenListProps {
139
146
  hideBackButton?: boolean;
140
147
  /** Callback when the EntryCard is opened. */
141
148
  onEntryOpen: (entryId: string) => void;
149
+ /** Whether provider-selected entries are rendered in place of the list.
150
+ * @default true
151
+ */
152
+ showSelectedEntry?: boolean;
153
+
154
+ /** Callback for the empty-state create-entry action. */
155
+ onCreateEntry?: () => void;
142
156
  }
143
157
 
144
158
  export interface FeedbackScreenContentProps