convex-feedback-ui 0.1.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 (118) hide show
  1. package/README.md +187 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/native/context.d.ts +10 -0
  4. package/dist/native/context.d.ts.map +1 -0
  5. package/dist/native/context.js +33 -0
  6. package/dist/native/context.js.map +1 -0
  7. package/dist/native/index.d.ts +7 -0
  8. package/dist/native/index.d.ts.map +1 -0
  9. package/dist/native/index.js +6 -0
  10. package/dist/native/index.js.map +1 -0
  11. package/dist/native/primitives.d.ts +94 -0
  12. package/dist/native/primitives.d.ts.map +1 -0
  13. package/dist/native/primitives.js +303 -0
  14. package/dist/native/primitives.js.map +1 -0
  15. package/dist/native/screen.d.ts +3 -0
  16. package/dist/native/screen.d.ts.map +1 -0
  17. package/dist/native/screen.js +284 -0
  18. package/dist/native/screen.js.map +1 -0
  19. package/dist/react/context.d.ts +22 -0
  20. package/dist/react/context.d.ts.map +1 -0
  21. package/dist/react/context.js +41 -0
  22. package/dist/react/context.js.map +1 -0
  23. package/dist/react/index.d.ts +7 -0
  24. package/dist/react/index.d.ts.map +1 -0
  25. package/dist/react/index.js +6 -0
  26. package/dist/react/index.js.map +1 -0
  27. package/dist/react/primitives.d.ts +105 -0
  28. package/dist/react/primitives.d.ts.map +1 -0
  29. package/dist/react/primitives.js +217 -0
  30. package/dist/react/primitives.js.map +1 -0
  31. package/dist/react/screen.d.ts +6 -0
  32. package/dist/react/screen.d.ts.map +1 -0
  33. package/dist/react/screen.js +152 -0
  34. package/dist/react/screen.js.map +1 -0
  35. package/dist/react/styles.css +299 -0
  36. package/dist/shared/messages.d.ts +4 -0
  37. package/dist/shared/messages.d.ts.map +1 -0
  38. package/dist/shared/messages.js +85 -0
  39. package/dist/shared/messages.js.map +1 -0
  40. package/dist/shared/render.d.ts +4 -0
  41. package/dist/shared/render.d.ts.map +1 -0
  42. package/dist/shared/render.js +6 -0
  43. package/dist/shared/render.js.map +1 -0
  44. package/dist/shared/theme.d.ts +4 -0
  45. package/dist/shared/theme.d.ts.map +1 -0
  46. package/dist/shared/theme.js +23 -0
  47. package/dist/shared/theme.js.map +1 -0
  48. package/dist/shared/types/board.d.ts +43 -0
  49. package/dist/shared/types/board.d.ts.map +1 -0
  50. package/dist/shared/types/board.js +2 -0
  51. package/dist/shared/types/board.js.map +1 -0
  52. package/dist/shared/types/comment.d.ts +85 -0
  53. package/dist/shared/types/comment.d.ts.map +1 -0
  54. package/dist/shared/types/comment.js +2 -0
  55. package/dist/shared/types/comment.js.map +1 -0
  56. package/dist/shared/types/context.d.ts +68 -0
  57. package/dist/shared/types/context.d.ts.map +1 -0
  58. package/dist/shared/types/context.js +2 -0
  59. package/dist/shared/types/context.js.map +1 -0
  60. package/dist/shared/types/entry.d.ts +41 -0
  61. package/dist/shared/types/entry.d.ts.map +1 -0
  62. package/dist/shared/types/entry.js +2 -0
  63. package/dist/shared/types/entry.js.map +1 -0
  64. package/dist/shared/types/form.d.ts +25 -0
  65. package/dist/shared/types/form.d.ts.map +1 -0
  66. package/dist/shared/types/form.js +2 -0
  67. package/dist/shared/types/form.js.map +1 -0
  68. package/dist/shared/types/helpers.d.ts +2 -0
  69. package/dist/shared/types/helpers.d.ts.map +1 -0
  70. package/dist/shared/types/helpers.js +2 -0
  71. package/dist/shared/types/helpers.js.map +1 -0
  72. package/dist/shared/types/index.d.ts +10 -0
  73. package/dist/shared/types/index.d.ts.map +1 -0
  74. package/dist/shared/types/index.js +2 -0
  75. package/dist/shared/types/index.js.map +1 -0
  76. package/dist/shared/types/messages.d.ts +117 -0
  77. package/dist/shared/types/messages.d.ts.map +1 -0
  78. package/dist/shared/types/messages.js +2 -0
  79. package/dist/shared/types/messages.js.map +1 -0
  80. package/dist/shared/types/render.d.ts +12 -0
  81. package/dist/shared/types/render.d.ts.map +1 -0
  82. package/dist/shared/types/render.js +2 -0
  83. package/dist/shared/types/render.js.map +1 -0
  84. package/dist/shared/types/screen.d.ts +95 -0
  85. package/dist/shared/types/screen.d.ts.map +1 -0
  86. package/dist/shared/types/screen.js +2 -0
  87. package/dist/shared/types/screen.js.map +1 -0
  88. package/dist/shared/types/theme.d.ts +48 -0
  89. package/dist/shared/types/theme.d.ts.map +1 -0
  90. package/dist/shared/types/theme.js +2 -0
  91. package/dist/shared/types/theme.js.map +1 -0
  92. package/package.json +58 -0
  93. package/src/native/README.md +17 -0
  94. package/src/native/context.tsx +74 -0
  95. package/src/native/index.ts +39 -0
  96. package/src/native/primitives.tsx +730 -0
  97. package/src/native/screen.tsx +831 -0
  98. package/src/react/README.md +7 -0
  99. package/src/react/context.tsx +83 -0
  100. package/src/react/index.ts +42 -0
  101. package/src/react/primitives.tsx +589 -0
  102. package/src/react/screen.tsx +633 -0
  103. package/src/react/styles.css +299 -0
  104. package/src/shared/README.md +9 -0
  105. package/src/shared/messages.ts +99 -0
  106. package/src/shared/render.ts +12 -0
  107. package/src/shared/theme.ts +27 -0
  108. package/src/shared/types/board.ts +48 -0
  109. package/src/shared/types/comment.ts +101 -0
  110. package/src/shared/types/context.ts +81 -0
  111. package/src/shared/types/entry.ts +48 -0
  112. package/src/shared/types/form.ts +27 -0
  113. package/src/shared/types/helpers.ts +1 -0
  114. package/src/shared/types/index.ts +45 -0
  115. package/src/shared/types/messages.ts +160 -0
  116. package/src/shared/types/render.ts +12 -0
  117. package/src/shared/types/screen.ts +123 -0
  118. package/src/shared/types/theme.ts +61 -0
@@ -0,0 +1,48 @@
1
+ import type { FeedbackEntry } from "convex-feedback";
2
+
3
+ import type { RenderChildren } from "./render.js";
4
+
5
+ /**
6
+ * Platform-neutral props shared by `FeedbackEntry.Root` implementations.
7
+ */
8
+ export interface EntryRootBaseProps {
9
+ /** Entry exposed to every nested `FeedbackEntry.*` primitive. */
10
+ entry: FeedbackEntry;
11
+ }
12
+
13
+ /**
14
+ * State and actions exposed to a custom `FeedbackEntry.Upvote` renderer.
15
+ */
16
+ export interface EntryUpvoteState {
17
+ /** Current entry. */
18
+ entry: FeedbackEntry;
19
+
20
+ /** Whether the current viewer has upvoted the entry. */
21
+ active: boolean;
22
+
23
+ /** Current total upvote count. */
24
+ count: number;
25
+
26
+ /** Requests the opposite of the current upvote state. */
27
+ toggle: () => void | Promise<void>;
28
+ }
29
+
30
+ /**
31
+ * Platform-neutral props shared by `FeedbackEntry.Upvote` implementations.
32
+ */
33
+ export interface EntryUpvoteBaseProps {
34
+ /**
35
+ * Called with the desired final upvote state.
36
+ *
37
+ * `true` means ensure the viewer has upvoted the entry. `false` means ensure
38
+ * the viewer has not upvoted it. The server mutation is state-setting rather
39
+ * than toggle-based so it remains idempotent.
40
+ */
41
+ onToggle: (desiredState: boolean) => void | Promise<void>;
42
+
43
+ /**
44
+ * Normal children replace the default content. A render-function child
45
+ * replaces the complete control and receives `EntryUpvoteState`.
46
+ */
47
+ children?: RenderChildren<EntryUpvoteState> | undefined;
48
+ }
@@ -0,0 +1,27 @@
1
+ import type { RenderChildren } from "./render.js";
2
+
3
+ /**
4
+ * State exposed to a custom `FeedbackForm.Submit` renderer.
5
+ */
6
+ export interface FormSubmitState {
7
+ /** Whether form submission is currently in progress. */
8
+ submitting: boolean;
9
+ }
10
+
11
+ /**
12
+ * Platform-neutral props shared by `FeedbackForm.Submit` implementations.
13
+ */
14
+ export interface FormSubmitBaseProps {
15
+ /**
16
+ * Whether form submission is currently in progress.
17
+ *
18
+ * @default false
19
+ */
20
+ submitting?: boolean | undefined;
21
+
22
+ /**
23
+ * Normal children replace the default content. A render-function child
24
+ * replaces the complete control and receives `FormSubmitState`.
25
+ */
26
+ children?: RenderChildren<FormSubmitState> | undefined;
27
+ }
@@ -0,0 +1 @@
1
+ export type Require<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
@@ -0,0 +1,45 @@
1
+ export type {
2
+ BoardRootBaseProps,
3
+ BoardSearchBaseProps,
4
+ BoardSearchState,
5
+ } from "./board.js";
6
+ export type {
7
+ CommentActionBaseProps,
8
+ CommentActionState,
9
+ CommentLikeBaseProps,
10
+ CommentLikeState,
11
+ CommentRootBaseProps,
12
+ RepliesButtonBaseProps,
13
+ RepliesButtonState,
14
+ } from "./comment.js";
15
+ export type {
16
+ FeedbackColorProps,
17
+ FeedbackProviderProps,
18
+ FeedbackUiContextValue,
19
+ } from "./context.js";
20
+ export type {
21
+ EntryRootBaseProps,
22
+ EntryUpvoteBaseProps,
23
+ EntryUpvoteState,
24
+ } from "./entry.js";
25
+ export type { FormSubmitBaseProps, FormSubmitState } from "./form.js";
26
+ export type { FeedbackMessageOverrides, FeedbackMessages } from "./messages.js";
27
+ export type { RenderChildren } from "./render.js";
28
+ export type {
29
+ FeedbackActorRenderer,
30
+ FeedbackCommentTransform,
31
+ FeedbackScreenBaseProps,
32
+ FeedbackScreenBodyProps,
33
+ FeedbackScreenCommentBranchProps,
34
+ FeedbackScreenEntryBaseProps,
35
+ FeedbackScreenEntryCardProps,
36
+ FeedbackScreenEntryDetailProps,
37
+ FeedbackScreenEntryModalProps,
38
+ FeedbackScreenReplyListProps,
39
+ FeedbackScreenRootProps,
40
+ } from "./screen.js";
41
+ export type {
42
+ FeedbackColors,
43
+ FeedbackTheme,
44
+ FeedbackThemeOverride,
45
+ } from "./theme.js";
@@ -0,0 +1,160 @@
1
+ import type { EntryKind, EntryStatus } from "convex-feedback";
2
+
3
+ /**
4
+ * Localizable package-owned UI copy used by both React DOM and React Native.
5
+ *
6
+ * User-generated entry and comment content is never translated or rewritten
7
+ * by the UI package.
8
+ */
9
+ export interface FeedbackMessages {
10
+ /** Feedback-board copy. */
11
+ board: {
12
+ /** Main board heading. */
13
+ title: string;
14
+
15
+ /** Supporting copy shown near the board heading. */
16
+ subtitle: string;
17
+
18
+ /** Search input placeholder. */
19
+ searchPlaceholder: string;
20
+
21
+ /** CTA for opening the create-entry flow. */
22
+ createEntry: string;
23
+
24
+ /** Empty-state copy when no entries exist. */
25
+ noEntries: string;
26
+
27
+ /** Empty-state copy when a search produces no results. */
28
+ noSearchResults: string;
29
+
30
+ /** Generic loading copy. */
31
+ loading: string;
32
+
33
+ /** Entry pagination CTA. */
34
+ loadMore: string;
35
+ };
36
+
37
+ /** Localized display labels for each fixed entry kind. */
38
+ kinds: Record<EntryKind, string>;
39
+
40
+ /** Localized display labels for each fixed workflow status. */
41
+ statuses: Record<EntryStatus, string>;
42
+
43
+ /** Entry-level action and counter copy. */
44
+ entry: {
45
+ /** Accessible/default label for adding an upvote. */
46
+ upvote: string;
47
+
48
+ /** Accessible/default label for removing an upvote. */
49
+ removeUpvote: string;
50
+
51
+ /** Formats the total comment count. */
52
+ comments: (count: number) => string;
53
+
54
+ /** Label for opening an entry. */
55
+ open: string;
56
+
57
+ /** Label for returning to the feedback list. */
58
+ back: string;
59
+ };
60
+
61
+ /** Create-entry form copy. */
62
+ form: {
63
+ /** Entry-kind field label. */
64
+ kind: string;
65
+
66
+ /** Entry-title field label. */
67
+ title: string;
68
+
69
+ /** Entry-title placeholder. */
70
+ titlePlaceholder: string;
71
+
72
+ /** Entry-body field label. */
73
+ body: string;
74
+
75
+ /** Entry-body placeholder. */
76
+ bodyPlaceholder: string;
77
+
78
+ /** Create-entry submit CTA. */
79
+ submit: string;
80
+
81
+ /** Generic form/dialog cancel action. */
82
+ cancel: string;
83
+
84
+ /** Heading shown when likely duplicate entries are found. */
85
+ possibleDuplicates: string;
86
+
87
+ /** Heading shown when an exact normalized-title match exists. */
88
+ exactDuplicate: string;
89
+
90
+ /** Warning shown before submitting while duplicate suggestions exist. */
91
+ duplicateWarning: string;
92
+
93
+ /** Confirmation action that submits despite duplicate suggestions. */
94
+ submitAnyway: string;
95
+ };
96
+
97
+ /** Comment-thread copy. */
98
+ comments: {
99
+ /** Discussion/thread heading. */
100
+ title: string;
101
+
102
+ /** Comment/reply input placeholder. */
103
+ placeholder: string;
104
+
105
+ /** Top-level comment submit action. */
106
+ submit: string;
107
+
108
+ /** Reply action. */
109
+ reply: string;
110
+
111
+ /** Cancels an in-progress reply. */
112
+ cancelReply: string;
113
+
114
+ /** Adds a comment like. */
115
+ like: string;
116
+
117
+ /** Removes a comment like. */
118
+ unlike: string;
119
+
120
+ /** Formats the lazy-load-replies action for a direct-reply count. */
121
+ viewReplies: (count: number) => string;
122
+
123
+ /** Collapses an expanded reply branch. */
124
+ hideReplies: string;
125
+
126
+ /** Placeholder copy for a soft-deleted comment. */
127
+ deleted: string;
128
+
129
+ /** Empty-state copy when no comments exist. */
130
+ noComments: string;
131
+
132
+ /** Comment/reply pagination CTA. */
133
+ loadMore: string;
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Partial localization/copy overrides for the feedback UI.
139
+ *
140
+ * Values not supplied here fall back to the package's built-in English copy.
141
+ */
142
+ export interface FeedbackMessageOverrides {
143
+ /** Board copy overrides. */
144
+ board?: Partial<FeedbackMessages["board"]> | undefined;
145
+
146
+ /** Entry-kind label overrides. */
147
+ kinds?: Partial<FeedbackMessages["kinds"]> | undefined;
148
+
149
+ /** Workflow-status label overrides. */
150
+ statuses?: Partial<FeedbackMessages["statuses"]> | undefined;
151
+
152
+ /** Entry action/counter copy overrides. */
153
+ entry?: Partial<FeedbackMessages["entry"]> | undefined;
154
+
155
+ /** Create-entry form copy overrides. */
156
+ form?: Partial<FeedbackMessages["form"]> | undefined;
157
+
158
+ /** Comment-thread copy overrides. */
159
+ comments?: Partial<FeedbackMessages["comments"]> | undefined;
160
+ }
@@ -0,0 +1,12 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ /**
4
+ * Children accepted by replaceable feedback UI primitives.
5
+ *
6
+ * Pass normal React children to replace only the primitive's default content,
7
+ * or pass a render function to replace the complete visual implementation
8
+ * while retaining the primitive's typed state and actions.
9
+ *
10
+ * @typeParam State - State and actions exposed to a render-function child.
11
+ */
12
+ export type RenderChildren<State> = ReactNode | ((state: State) => ReactNode);
@@ -0,0 +1,123 @@
1
+ import type {
2
+ CommentSort,
3
+ EntryKind,
4
+ EntrySort,
5
+ FeedbackComment,
6
+ FeedbackEntry,
7
+ } from "convex-feedback";
8
+ import type { FeedbackHooks } from "convex-feedback/react";
9
+ import type { ReactNode } from "react";
10
+
11
+ import type { FeedbackColorProps, FeedbackProviderProps } from "./context.js";
12
+ import type { Require } from "./helpers.js";
13
+
14
+ /**
15
+ * Presentation-only transform applied to one currently loaded comment page.
16
+ *
17
+ * This does not affect Convex ordering, pagination, or which descendants are
18
+ * loaded. It is intended only for host-specific presentation transforms.
19
+ */
20
+ export type FeedbackCommentTransform = (
21
+ comments: readonly FeedbackComment[],
22
+ ) => readonly FeedbackComment[];
23
+
24
+ /**
25
+ * Host renderer for actor information associated with entries/comments.
26
+ *
27
+ * The feedback component stores only stable actor IDs; profile data remains
28
+ * owned by the host application.
29
+ */
30
+ export type FeedbackActorRenderer = (actorId: string) => ReactNode;
31
+
32
+ export interface FeedbackScreenBaseProps extends FeedbackColorProps {
33
+ /** Hooks created with `createFeedbackHooks`. */
34
+ hooks: FeedbackHooks;
35
+
36
+ /**
37
+ * Server-side ordering used by the feedback board.
38
+ *
39
+ * @default "top"
40
+ */
41
+ entrySort?: EntrySort;
42
+
43
+ /**
44
+ * Server-side ordering used independently at every loaded comment/reply
45
+ * level.
46
+ *
47
+ * @default "top"
48
+ */
49
+ commentSort?: CommentSort;
50
+
51
+ /**
52
+ * Entry kinds visible in the board/search and available in the create form.
53
+ *
54
+ * The prebuilt screen passes these kinds into the Convex list/search queries;
55
+ * filtering must not be performed after pagination on the client.
56
+ *
57
+ * @default ["feedback", "feature_request", "bug_report"]
58
+ */
59
+ enabledKinds?: readonly EntryKind[];
60
+
61
+ /**
62
+ * Maximum nesting depth for which the prebuilt UI exposes a Reply action.
63
+ *
64
+ * The server-side component configuration remains authoritative and may
65
+ * reject a reply if this value exceeds the configured backend maximum.
66
+ *
67
+ * @default 5
68
+ */
69
+ maxCommentDepth?: number;
70
+
71
+ /**
72
+ * Optional presentation-only transform applied to each loaded page of
73
+ * comments/replies before rendering.
74
+ */
75
+ transformComments?: FeedbackCommentTransform;
76
+
77
+ /**
78
+ * Optional host renderer for actor IDs, useful for names, avatars, or other
79
+ * host-owned profile information.
80
+ */
81
+ renderActor?: FeedbackActorRenderer;
82
+ }
83
+
84
+ export interface FeedbackScreenRootProps
85
+ extends Omit<FeedbackProviderProps, "children">, FeedbackScreenBaseProps {}
86
+
87
+ export type FeedbackScreenBodyProps = Require<
88
+ FeedbackScreenBaseProps,
89
+ "entrySort" | "commentSort" | "enabledKinds" | "maxCommentDepth"
90
+ >;
91
+
92
+ export interface FeedbackScreenEntryCardProps {
93
+ entry: FeedbackEntry;
94
+ hooks: FeedbackHooks;
95
+ onOpen: () => void;
96
+ }
97
+
98
+ export interface FeedbackScreenEntryModalProps {
99
+ hooks: FeedbackHooks;
100
+ enabledKinds: readonly EntryKind[];
101
+ onCreated: (id: string) => void;
102
+ }
103
+
104
+ export interface FeedbackScreenEntryBaseProps {
105
+ entryId: string;
106
+ hooks: FeedbackHooks;
107
+ commentSort: CommentSort;
108
+ maxCommentDepth: number;
109
+ transformComments?: FeedbackScreenBaseProps["transformComments"];
110
+ renderActor?: FeedbackScreenBaseProps["renderActor"];
111
+ }
112
+
113
+ export interface FeedbackScreenEntryDetailProps extends FeedbackScreenEntryBaseProps {
114
+ onBack: () => void;
115
+ }
116
+
117
+ export interface FeedbackScreenCommentBranchProps extends FeedbackScreenEntryBaseProps {
118
+ comment: FeedbackComment;
119
+ }
120
+
121
+ export interface FeedbackScreenReplyListProps extends FeedbackScreenEntryBaseProps {
122
+ parentCommentId: string;
123
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Semantic colors used by the feedback UI on both React DOM and React Native.
3
+ */
4
+ export interface FeedbackColors {
5
+ /** Primary interaction and accent color. */
6
+ primary: string;
7
+
8
+ /** Main screen or board background color. */
9
+ background: string;
10
+
11
+ /** Default card and control surface color. */
12
+ surface: string;
13
+
14
+ /** Secondary or muted surface color. */
15
+ surfaceMuted: string;
16
+
17
+ /** Primary text color. */
18
+ text: string;
19
+
20
+ /** Secondary, metadata, and helper text color. */
21
+ mutedText: string;
22
+
23
+ /** Border and separator color. */
24
+ border: string;
25
+
26
+ /** Destructive and error-state color. */
27
+ danger: string;
28
+
29
+ /** Positive and success-state color. */
30
+ success: string;
31
+ }
32
+
33
+ /**
34
+ * Fully resolved visual theme consumed by feedback UI primitives.
35
+ */
36
+ export interface FeedbackTheme {
37
+ /** Semantic feedback color palette. */
38
+ colors: FeedbackColors;
39
+
40
+ /** Base corner radius in logical pixels. */
41
+ radius: number;
42
+
43
+ /** Base spacing unit in logical pixels. */
44
+ spacing: number;
45
+ }
46
+
47
+ /**
48
+ * Partial theme accepted by feedback providers and prebuilt screens.
49
+ *
50
+ * Missing values fall back to the package's default feedback theme.
51
+ */
52
+ export interface FeedbackThemeOverride {
53
+ /** Partial semantic color overrides. */
54
+ colors?: Partial<FeedbackColors> | undefined;
55
+
56
+ /** Base corner-radius override. */
57
+ radius?: number | undefined;
58
+
59
+ /** Base spacing-unit override. */
60
+ spacing?: number | undefined;
61
+ }