@dropby/react 0.4.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/LICENSE +21 -0
- package/README.md +220 -0
- package/dist/chunks/chat-attachment-types-BG8VFQj5.d.ts +56 -0
- package/dist/chunks/chat-attachments-uP-PsyQf.js +21 -0
- package/dist/chunks/use-dropby-BW4iKpiA.js +54 -0
- package/dist/chunks/use-feature-gByQaSp1.js +78 -0
- package/dist/components/chat-attachments/index.d.ts +9 -0
- package/dist/components/chat-attachments/index.js +88 -0
- package/dist/components/index.d.ts +290 -0
- package/dist/components/index.js +1095 -0
- package/dist/index.d.ts +124 -0
- package/dist/index.js +47 -0
- package/package.json +59 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { n as ChatAttachmentsToolkit, t as ChatAttachmentDraft } from "../chunks/chat-attachment-types-BG8VFQj5.js";
|
|
2
|
+
import { ButtonHTMLAttributes, FormHTMLAttributes, HTMLAttributes, ReactNode } from "react";
|
|
3
|
+
import { AskField, AsksActions, AsyncResource, ChatActions, ChatHistoryLoadState, ChatThread as ChatThread$1, ChatThreadActions, ChatThreadsCollection, DropByError, DropById, FlagValue, Idea as Idea$1, IdeasActions, ListIdeasView, PagedCollection, PendingAsk, PendingAsksCollection } from "@dropby/browser";
|
|
4
|
+
/** Props for `Ask`, plus any `div` attribute. */
|
|
5
|
+
interface AskProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
6
|
+
/** The ask to show. */
|
|
7
|
+
ask: PendingAsk;
|
|
8
|
+
/** Passed to its `AskForm`. */
|
|
9
|
+
fieldsPerStep?: number;
|
|
10
|
+
/** Your own body, given the ask, in place of its title and form. */
|
|
11
|
+
children?: (state: {
|
|
12
|
+
ask: PendingAsk;
|
|
13
|
+
}) => ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/** One pending ask: its title and its `AskForm`, marked `data-pending`. */
|
|
16
|
+
export declare function Ask({ ask, fieldsPerStep, children, ...rest }: AskProps): import("react").JSX.Element;
|
|
17
|
+
/** One field's answer: text, the chosen option ids, or a rating. */
|
|
18
|
+
type AskAnswerValue = string | string[] | number;
|
|
19
|
+
/** The answers given so far, by field id. */
|
|
20
|
+
type AskAnswers = Record<string, AskAnswerValue>;
|
|
21
|
+
/** What an `AskForm` render function receives. */
|
|
22
|
+
interface AskFormState {
|
|
23
|
+
/** The ask being answered. */
|
|
24
|
+
ask: PendingAsk;
|
|
25
|
+
/** The fields on the current step. */
|
|
26
|
+
fields: AskField[];
|
|
27
|
+
/** The answers given so far. */
|
|
28
|
+
answers: AskAnswers;
|
|
29
|
+
/** Sets one field's answer, and clears its issue. */
|
|
30
|
+
setAnswer: (fieldId: string, value: AskAnswerValue) => void;
|
|
31
|
+
/** The current step, from 0. */
|
|
32
|
+
step: number;
|
|
33
|
+
/** How many steps there are. */
|
|
34
|
+
stepCount: number;
|
|
35
|
+
/** Whether this is the first step. */
|
|
36
|
+
isFirst: boolean;
|
|
37
|
+
/** Whether this is the last step. */
|
|
38
|
+
isLast: boolean;
|
|
39
|
+
/** Goes to the step before. */
|
|
40
|
+
back: () => void;
|
|
41
|
+
/** Goes to the next step when this one's answers are valid, or shows their issues. */
|
|
42
|
+
next: () => void;
|
|
43
|
+
/** Sends every answer when all are valid, or goes to the first step with an issue. */
|
|
44
|
+
submit: () => Promise<void>;
|
|
45
|
+
/** Dismisses the ask. */
|
|
46
|
+
dismiss: () => Promise<void>;
|
|
47
|
+
/** Whether a submit or dismissal is in flight. */
|
|
48
|
+
submitting: boolean;
|
|
49
|
+
/** Each field's issue, in copy for the user, by field id. */
|
|
50
|
+
issues: Record<string, string>;
|
|
51
|
+
/** Why the last submit or dismissal failed. */
|
|
52
|
+
error: DropByError | null;
|
|
53
|
+
}
|
|
54
|
+
/** Props for `AskForm`, plus any `form` attribute. */
|
|
55
|
+
interface AskFormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "children" | "onSubmit"> {
|
|
56
|
+
/** The ask to answer. */
|
|
57
|
+
ask: PendingAsk;
|
|
58
|
+
/** How many fields a step shows: all by default, 1 for one at a time. */
|
|
59
|
+
fieldsPerStep?: number;
|
|
60
|
+
/** Your own form body, given the form's state, in place of the default. */
|
|
61
|
+
children?: (state: AskFormState) => ReactNode;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The form to answer one ask: its fields, in steps when `fieldsPerStep` is set,
|
|
65
|
+
* then submit, and dismiss when the ask allows it. It checks each step's answers
|
|
66
|
+
* before moving on, and shows a failed submit or dismissal in plain copy.
|
|
67
|
+
*/
|
|
68
|
+
export declare function AskForm({ ask, fieldsPerStep, children, ...rest }: AskFormProps): import("react").JSX.Element;
|
|
69
|
+
/** What a `ChatComposer` render function receives. */
|
|
70
|
+
interface ChatComposerState {
|
|
71
|
+
/** The text being written. */
|
|
72
|
+
draft: string;
|
|
73
|
+
/** Changes the text. */
|
|
74
|
+
setDraft: (value: string) => void;
|
|
75
|
+
/**
|
|
76
|
+
* Sends the draft with any ready attachments, then clears both. Does nothing
|
|
77
|
+
* when the draft is empty, a send is in flight, or an upload is still in
|
|
78
|
+
* progress.
|
|
79
|
+
*/
|
|
80
|
+
send: () => Promise<void>;
|
|
81
|
+
/** Whether a send is in flight. */
|
|
82
|
+
sending: boolean;
|
|
83
|
+
/** Why the last send failed; the draft is kept to send again. */
|
|
84
|
+
error: DropByError | null;
|
|
85
|
+
/** The attachments passed in, if any. */
|
|
86
|
+
attachments: ChatAttachmentsToolkit | undefined;
|
|
87
|
+
}
|
|
88
|
+
/** Props for `ChatComposer`, plus any `form` attribute. */
|
|
89
|
+
interface ChatComposerProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "children" | "onSubmit"> {
|
|
90
|
+
/** The conversation to send to. */
|
|
91
|
+
threadId: DropById<"thr_">;
|
|
92
|
+
/**
|
|
93
|
+
* Attachments from `useChatAttachments`, in
|
|
94
|
+
* `@dropby/react/components/chat-attachments`. Omit for a text-only composer.
|
|
95
|
+
*/
|
|
96
|
+
attachments?: ChatAttachmentsToolkit;
|
|
97
|
+
/** Your own form body, given the draft and `send`, in place of the default. */
|
|
98
|
+
children?: (state: ChatComposerState) => ReactNode;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* A message box for one conversation. A message needs text, and sending is blocked
|
|
102
|
+
* while an upload is in progress; with `attachments`, it sends those that are
|
|
103
|
+
* ready. A failed send keeps the draft and shows plain copy; sending the same text
|
|
104
|
+
* and attachments again reuses the failed send's key, so a send whose answer was
|
|
105
|
+
* lost is not posted twice while this composer stays mounted.
|
|
106
|
+
*/
|
|
107
|
+
export declare function ChatComposer({ threadId, attachments, children, ...rest }: ChatComposerProps): import("react").JSX.Element;
|
|
108
|
+
/** What a `ChatThread` render function receives. */
|
|
109
|
+
interface ChatThreadState {
|
|
110
|
+
/** The load of older messages, once one started. */
|
|
111
|
+
olderMessages: ChatHistoryLoadState | undefined;
|
|
112
|
+
/** The load of the newest messages, once one started. */
|
|
113
|
+
latestMessages: ChatHistoryLoadState | undefined;
|
|
114
|
+
/** The conversation as loaded. */
|
|
115
|
+
thread: AsyncResource<ChatThread$1> | undefined;
|
|
116
|
+
/** The conversation's actions. */
|
|
117
|
+
actions: ChatThreadActions;
|
|
118
|
+
}
|
|
119
|
+
/** Props for `ChatThread`, plus any `div` attribute, which applies to the default body only. */
|
|
120
|
+
interface ChatThreadProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
121
|
+
/** The conversation to show. */
|
|
122
|
+
id: DropById<"thr_">;
|
|
123
|
+
/** Do not open the conversation on mount; call `actions.open()` yourself. */
|
|
124
|
+
manualLoad?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Mark replies seen once they are read on screen; true by default. Pass false
|
|
127
|
+
* to call `actions.markSeen` yourself. A render function's body is never
|
|
128
|
+
* watched.
|
|
129
|
+
*/
|
|
130
|
+
acknowledge?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Your own body, given the conversation and its actions, in place of the
|
|
133
|
+
* default, composer included. A custom body is never watched for reading.
|
|
134
|
+
*/
|
|
135
|
+
children?: (state: ChatThreadState) => ReactNode;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* One conversation: its messages, each with `data-author` and any attachments, in
|
|
139
|
+
* a live region, then a text-only composer. It opens the conversation on mount
|
|
140
|
+
* unless `manualLoad`, and shows the load in `data-status`. When the thread or an
|
|
141
|
+
* element around it scrolls (`overflow-y: auto` or `scroll`), the default body
|
|
142
|
+
* follows new messages while the reader is at the end, or when the message is
|
|
143
|
+
* their own; it never scrolls the page. It marks replies seen once they are read
|
|
144
|
+
* on screen.
|
|
145
|
+
*/
|
|
146
|
+
export declare function ChatThread({ id, manualLoad, acknowledge, children, ...rest }: ChatThreadProps): ReactNode;
|
|
147
|
+
/** What a `ChatThreadList` render function receives. */
|
|
148
|
+
interface ChatThreadListState {
|
|
149
|
+
/** The conversation list. */
|
|
150
|
+
threads: ChatThreadsCollection;
|
|
151
|
+
/** Chat's actions. */
|
|
152
|
+
actions: ChatActions;
|
|
153
|
+
}
|
|
154
|
+
/** Props for `ChatThreadList`, plus any `ul` attribute, which applies to the default list only. */
|
|
155
|
+
interface ChatThreadListProps extends Omit<HTMLAttributes<HTMLUListElement>, "children" | "onSelect"> {
|
|
156
|
+
/** Do not load the list on mount; call `actions.listThreads()` yourself. */
|
|
157
|
+
manualLoad?: boolean;
|
|
158
|
+
/** Makes each row a button that calls this with its conversation's id. */
|
|
159
|
+
onSelect?: (threadId: DropById<"thr_">) => void;
|
|
160
|
+
/** The conversation open now, marked `aria-current`; used only with `onSelect`. */
|
|
161
|
+
selectedId?: DropById<"thr_"> | null;
|
|
162
|
+
/** Your own list, given the conversations and chat's actions, in place of the default. */
|
|
163
|
+
children?: (state: ChatThreadListState) => ReactNode;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The user's conversations, newest first, a page at a time. It starts with a
|
|
167
|
+
* refresh button and an unread filter (`aria-pressed`), marks rows with unread
|
|
168
|
+
* replies `data-unread`, loads on mount unless `manualLoad`, shows the load in
|
|
169
|
+
* `data-status` and `data-empty`, and ends with a "show more conversations" item
|
|
170
|
+
* (`data-load-more`) while there are more, which also retries a page that failed.
|
|
171
|
+
*/
|
|
172
|
+
export declare function ChatThreadList({ manualLoad, onSelect, selectedId, children, ...rest }: ChatThreadListProps): ReactNode;
|
|
173
|
+
/** Props for `Feature`. */
|
|
174
|
+
interface FeatureProps {
|
|
175
|
+
/** The feature flag to read. */
|
|
176
|
+
name: string;
|
|
177
|
+
/** The value that turns it on; without it, any truthy value does. */
|
|
178
|
+
equals?: FlagValue;
|
|
179
|
+
/** What to render when the flag is off, unset, or not yet read. */
|
|
180
|
+
fallback?: ReactNode;
|
|
181
|
+
/** What to render when the flag is on. */
|
|
182
|
+
children: ReactNode;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Renders its children when a feature flag is on: equal to `equals` when given,
|
|
186
|
+
* otherwise truthy. Renders `fallback` otherwise, including until the session has
|
|
187
|
+
* loaded. It adds no markup of its own.
|
|
188
|
+
*/
|
|
189
|
+
export declare function Feature({ name, equals, fallback, children }: FeatureProps): ReactNode;
|
|
190
|
+
/** Props for `Idea`, plus any `div` attribute. */
|
|
191
|
+
interface IdeaProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
192
|
+
/** The idea to show. */
|
|
193
|
+
idea: Idea$1;
|
|
194
|
+
/**
|
|
195
|
+
* A function given the idea renders your own body in place of the default; other
|
|
196
|
+
* children are added after it.
|
|
197
|
+
*/
|
|
198
|
+
children?: ((state: {
|
|
199
|
+
idea: Idea$1;
|
|
200
|
+
}) => ReactNode) | ReactNode;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* One idea: its vote button, title and description, with `data-voted` when the
|
|
204
|
+
* user voted. In your own body, use `IdeaVoteButton` for voting.
|
|
205
|
+
*/
|
|
206
|
+
export declare function Idea({ idea, children, ...rest }: IdeaProps): import("react").JSX.Element;
|
|
207
|
+
/** What an `IdeaList` render function receives. */
|
|
208
|
+
interface IdeaListState {
|
|
209
|
+
/** The ideas list. */
|
|
210
|
+
ideas: PagedCollection<Idea$1>;
|
|
211
|
+
/** The board's actions. */
|
|
212
|
+
actions: IdeasActions;
|
|
213
|
+
}
|
|
214
|
+
/** Props for `IdeaList`, plus any `ul` attribute, which applies to the default list only. */
|
|
215
|
+
interface IdeaListProps extends Omit<HTMLAttributes<HTMLUListElement>, "children"> {
|
|
216
|
+
/**
|
|
217
|
+
* The user's ideas, or the public board; `owned` by default. Used only when the
|
|
218
|
+
* ideas store has not loaded yet; to switch later, call `actions.list({ view
|
|
219
|
+
* })`.
|
|
220
|
+
*/
|
|
221
|
+
view?: ListIdeasView;
|
|
222
|
+
/** Do not load on mount; call `actions.list()` yourself. */
|
|
223
|
+
manualLoad?: boolean;
|
|
224
|
+
/** Your own list, given the ideas and the board's actions, in place of the default. */
|
|
225
|
+
children?: (state: IdeaListState) => ReactNode;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Ideas, each an `Idea`, a page at a time: the board by votes, the user's ideas
|
|
229
|
+
* newest first. It loads on mount unless `manualLoad`, shows the load in
|
|
230
|
+
* `data-status` and `data-empty`, and ends with a "show more ideas" item
|
|
231
|
+
* (`data-load-more`) while there are more.
|
|
232
|
+
*/
|
|
233
|
+
export declare function IdeaList({ view, manualLoad, children, ...rest }: IdeaListProps): ReactNode;
|
|
234
|
+
/** What an `IdeaVoteButton` render function receives: one idea's vote. */
|
|
235
|
+
interface IdeaVoteState {
|
|
236
|
+
/** The idea. */
|
|
237
|
+
idea: Idea$1;
|
|
238
|
+
/** Whether the user voted for it. */
|
|
239
|
+
voted: boolean;
|
|
240
|
+
/** Whether the user can vote on it. */
|
|
241
|
+
votable: boolean;
|
|
242
|
+
/** Whether a vote is in flight. */
|
|
243
|
+
voting: boolean;
|
|
244
|
+
/** Why the last vote failed. */
|
|
245
|
+
error: DropByError | null;
|
|
246
|
+
/** Adds the user's vote. */
|
|
247
|
+
vote: () => Promise<void>;
|
|
248
|
+
/** Takes the user's vote back. */
|
|
249
|
+
unvote: () => Promise<void>;
|
|
250
|
+
/** Votes, or takes the vote back. */
|
|
251
|
+
toggle: () => Promise<void>;
|
|
252
|
+
}
|
|
253
|
+
/** Props for `IdeaVoteButton`, plus any `button` attribute. */
|
|
254
|
+
interface IdeaVoteButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
255
|
+
/** The idea to vote on. */
|
|
256
|
+
idea: Idea$1;
|
|
257
|
+
/** Your own content, or a function given the vote state, in place of the vote count. */
|
|
258
|
+
children?: ReactNode | ((state: IdeaVoteState) => ReactNode);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* A button that votes for an idea, or takes the vote back. It shows the vote
|
|
262
|
+
* count, is disabled while a vote is in flight or when the user cannot vote, and
|
|
263
|
+
* exposes its state in `aria-pressed`, `aria-busy`, `data-voted` and `data-busy`.
|
|
264
|
+
* Your own `onClick` runs first and can cancel the vote with `preventDefault()`;
|
|
265
|
+
* your own `disabled` wins over its own.
|
|
266
|
+
*/
|
|
267
|
+
export declare function IdeaVoteButton({ idea, children, onClick, disabled, ...rest }: IdeaVoteButtonProps): import("react").JSX.Element;
|
|
268
|
+
/** What a `PendingAsks` render function receives. */
|
|
269
|
+
interface PendingAsksState {
|
|
270
|
+
/** The asks waiting for the user. */
|
|
271
|
+
asks: PendingAsksCollection;
|
|
272
|
+
/** The asks' actions. */
|
|
273
|
+
actions: AsksActions;
|
|
274
|
+
}
|
|
275
|
+
/** Props for `PendingAsks`, plus any `ul` attribute, which applies to the default list only. */
|
|
276
|
+
interface PendingAsksProps extends Omit<HTMLAttributes<HTMLUListElement>, "children"> {
|
|
277
|
+
/** Passed to each ask's form. */
|
|
278
|
+
fieldsPerStep?: number;
|
|
279
|
+
/** Do not load on mount; call `actions.listPending()` yourself. */
|
|
280
|
+
manualLoad?: boolean;
|
|
281
|
+
/** Your own list, given the asks and their actions, in place of the default. */
|
|
282
|
+
children?: (state: PendingAsksState) => ReactNode;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* The asks waiting for the user, each an `Ask`, a page at a time. It loads on
|
|
286
|
+
* mount unless `manualLoad`, shows the load in `data-status` and `data-empty`,
|
|
287
|
+
* and ends with a "show more asks" item (`data-load-more`) while there are more.
|
|
288
|
+
*/
|
|
289
|
+
export declare function PendingAsks({ fieldsPerStep, manualLoad, children, ...rest }: PendingAsksProps): ReactNode;
|
|
290
|
+
export type { AskAnswerValue, AskAnswers, AskFormProps, AskFormState, AskProps, ChatAttachmentDraft, ChatAttachmentsToolkit, ChatComposerProps, ChatComposerState, ChatThreadListProps, ChatThreadListState, ChatThreadProps, ChatThreadState, FeatureProps, IdeaListProps, IdeaListState, IdeaProps, IdeaVoteButtonProps, IdeaVoteState, PendingAsksProps, PendingAsksState };
|