@youasked/react 0.0.0-stage → 0.5.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 +84 -2
- package/dist/YouAsked.d.ts +40 -0
- package/dist/capture-FYZGL54F.js +1578 -0
- package/dist/capture.d.ts +4 -0
- package/dist/client.d.ts +164 -0
- package/dist/context.d.ts +71 -0
- package/dist/demo.d.ts +6 -0
- package/dist/entries.d.ts +47 -0
- package/dist/icons.d.ts +14 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2120 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.js +11 -0
- package/dist/shared.d.ts +51 -0
- package/dist/styles.d.ts +2 -0
- package/dist/theme.d.ts +32 -0
- package/dist/views.d.ts +9 -0
- package/package.json +65 -4
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
export type Status = "open" | "planned" | "in_progress" | "shipped" | "declined" | "pending";
|
|
2
|
+
export type FeatureRequest = {
|
|
3
|
+
id: string;
|
|
4
|
+
/** Shown as YA-12; commits and PRs that say "closes YA-12" ship it. */
|
|
5
|
+
number: number;
|
|
6
|
+
title: string;
|
|
7
|
+
body: string;
|
|
8
|
+
status: Status;
|
|
9
|
+
votes: number;
|
|
10
|
+
comments: number;
|
|
11
|
+
shipNote: string | null;
|
|
12
|
+
shippedAt: number | null;
|
|
13
|
+
/** Where it was asked from: the page path and/or a topic like "charts". */
|
|
14
|
+
context: {
|
|
15
|
+
path?: string;
|
|
16
|
+
topic?: string;
|
|
17
|
+
} | null;
|
|
18
|
+
/** Set when the team found this ask elsewhere ("reddit" or "appstore") and added it. */
|
|
19
|
+
source?: string;
|
|
20
|
+
sourceUrl?: string | null;
|
|
21
|
+
/** First name of the person who asked, when they opted in to being thanked and it has shipped. */
|
|
22
|
+
creditName: string | null;
|
|
23
|
+
createdAt: number;
|
|
24
|
+
voted: boolean;
|
|
25
|
+
mine: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type Attachment = {
|
|
28
|
+
id: string;
|
|
29
|
+
url: string;
|
|
30
|
+
};
|
|
31
|
+
/** What shipped since this person was last shown the list. */
|
|
32
|
+
export type WhatsNew = {
|
|
33
|
+
/** Items shown, newest first with the ones they asked for or voted on at the top. */
|
|
34
|
+
items: {
|
|
35
|
+
id: string;
|
|
36
|
+
title: string;
|
|
37
|
+
shipNote: string | null;
|
|
38
|
+
shippedAt: number;
|
|
39
|
+
mine: boolean;
|
|
40
|
+
}[];
|
|
41
|
+
/** How many shipped in all; more than items.length when the list was cut short. */
|
|
42
|
+
total: number;
|
|
43
|
+
};
|
|
44
|
+
export type RequestComment = {
|
|
45
|
+
id: string;
|
|
46
|
+
body: string;
|
|
47
|
+
team: boolean;
|
|
48
|
+
author: string | null;
|
|
49
|
+
mine: boolean;
|
|
50
|
+
createdAt: number;
|
|
51
|
+
};
|
|
52
|
+
export type Notice = {
|
|
53
|
+
id: string;
|
|
54
|
+
/** "shipped", or "reply" when the team answered */
|
|
55
|
+
kind: string;
|
|
56
|
+
requestId: string;
|
|
57
|
+
title: string;
|
|
58
|
+
shipNote: string | null;
|
|
59
|
+
reply: string | null;
|
|
60
|
+
};
|
|
61
|
+
export type Config = {
|
|
62
|
+
app: {
|
|
63
|
+
name: string;
|
|
64
|
+
};
|
|
65
|
+
watermark: boolean;
|
|
66
|
+
identified: boolean;
|
|
67
|
+
/** Identified with a name, so "Credit me when it ships" makes sense. */
|
|
68
|
+
canCredit: boolean;
|
|
69
|
+
unseen: Notice[];
|
|
70
|
+
whatsNew: WhatsNew | null;
|
|
71
|
+
mode?: "test" | "live";
|
|
72
|
+
};
|
|
73
|
+
export type NewRequest = {
|
|
74
|
+
title: string;
|
|
75
|
+
body: string;
|
|
76
|
+
/** Ids from `upload()`. */
|
|
77
|
+
attachments?: string[];
|
|
78
|
+
context?: {
|
|
79
|
+
path?: string;
|
|
80
|
+
topic?: string;
|
|
81
|
+
};
|
|
82
|
+
credit?: boolean;
|
|
83
|
+
};
|
|
84
|
+
export type RequestDetail = {
|
|
85
|
+
request?: FeatureRequest;
|
|
86
|
+
comments?: RequestComment[];
|
|
87
|
+
attachments?: Attachment[];
|
|
88
|
+
/** Whether this person asked to try it before it ships. */
|
|
89
|
+
earlyAccess?: boolean;
|
|
90
|
+
/** The person wrote it and nobody else has joined in yet, so they can take it back. */
|
|
91
|
+
canDelete?: boolean;
|
|
92
|
+
redirect?: string;
|
|
93
|
+
};
|
|
94
|
+
export type YouAskedUser = {
|
|
95
|
+
id: string | number;
|
|
96
|
+
email?: string | null;
|
|
97
|
+
name?: string | null;
|
|
98
|
+
};
|
|
99
|
+
export declare class YouAskedError extends Error {
|
|
100
|
+
code: string;
|
|
101
|
+
/** A ready-to-show sentence from the server, when it sent one (spam and rate-limit answers do). */
|
|
102
|
+
detail?: string | undefined;
|
|
103
|
+
constructor(code: string,
|
|
104
|
+
/** A ready-to-show sentence from the server, when it sent one (spam and rate-limit answers do). */
|
|
105
|
+
detail?: string | undefined);
|
|
106
|
+
}
|
|
107
|
+
export type ClientOptions = {
|
|
108
|
+
appKey: string;
|
|
109
|
+
apiUrl: string;
|
|
110
|
+
user?: YouAskedUser | null;
|
|
111
|
+
signature?: string | null;
|
|
112
|
+
};
|
|
113
|
+
export declare function createClient({ appKey, apiUrl, user, signature }: ClientOptions): {
|
|
114
|
+
config: () => Promise<Config>;
|
|
115
|
+
list: (sort: "top" | "new", status: "active" | "shipped" | "all") => Promise<FeatureRequest[]>;
|
|
116
|
+
similar: (q: string) => Promise<FeatureRequest[]>;
|
|
117
|
+
get: (id: string) => Promise<RequestDetail>;
|
|
118
|
+
create: (input: NewRequest) => Promise<{
|
|
119
|
+
attachments: Attachment[];
|
|
120
|
+
id: string;
|
|
121
|
+
/** Shown as YA-12; commits and PRs that say "closes YA-12" ship it. */
|
|
122
|
+
number: number;
|
|
123
|
+
title: string;
|
|
124
|
+
body: string;
|
|
125
|
+
status: Status;
|
|
126
|
+
votes: number;
|
|
127
|
+
comments: number;
|
|
128
|
+
shipNote: string | null;
|
|
129
|
+
shippedAt: number | null;
|
|
130
|
+
/** Where it was asked from: the page path and/or a topic like "charts". */
|
|
131
|
+
context: {
|
|
132
|
+
path?: string;
|
|
133
|
+
topic?: string;
|
|
134
|
+
} | null;
|
|
135
|
+
/** Set when the team found this ask elsewhere ("reddit" or "appstore") and added it. */
|
|
136
|
+
source?: string;
|
|
137
|
+
sourceUrl?: string | null;
|
|
138
|
+
/** First name of the person who asked, when they opted in to being thanked and it has shipped. */
|
|
139
|
+
creditName: string | null;
|
|
140
|
+
createdAt: number;
|
|
141
|
+
voted: boolean;
|
|
142
|
+
mine: boolean;
|
|
143
|
+
}>;
|
|
144
|
+
upload: (image: Blob) => Promise<Attachment>;
|
|
145
|
+
remove: (id: string) => Promise<{
|
|
146
|
+
ok: true;
|
|
147
|
+
}>;
|
|
148
|
+
earlyAccess: (id: string) => Promise<{
|
|
149
|
+
earlyAccess: boolean;
|
|
150
|
+
}>;
|
|
151
|
+
whatsNewSeen: () => Promise<{
|
|
152
|
+
ok: true;
|
|
153
|
+
}>;
|
|
154
|
+
vote: (id: string) => Promise<{
|
|
155
|
+
voted: boolean;
|
|
156
|
+
votes: number;
|
|
157
|
+
}>;
|
|
158
|
+
comment: (id: string, body: string) => Promise<RequestComment>;
|
|
159
|
+
mine: () => Promise<FeatureRequest[]>;
|
|
160
|
+
seen: (ids: string[]) => Promise<{
|
|
161
|
+
ok: true;
|
|
162
|
+
}>;
|
|
163
|
+
};
|
|
164
|
+
export type Client = ReturnType<typeof createClient>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
import type { Client, Config, WhatsNew } from "./client";
|
|
3
|
+
export type OpenOptions = {
|
|
4
|
+
/** "home" is the chat-style start screen; "new" opens it with the composer focused. */
|
|
5
|
+
view?: "home" | "new" | "board" | "shipped" | "mine";
|
|
6
|
+
requestId?: string;
|
|
7
|
+
/** Pre-fills the composer, e.g. "Export to Excel" from a locked feature. */
|
|
8
|
+
draft?: string;
|
|
9
|
+
/**
|
|
10
|
+
* What the request is about, e.g. "charts". It's saved with the request, and the composer asks
|
|
11
|
+
* "What would make charts better?". "search" and "locked" are used by AskForIt and keep the default wording.
|
|
12
|
+
*/
|
|
13
|
+
topic?: string;
|
|
14
|
+
/** Replaces the composer's placeholder. */
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
};
|
|
17
|
+
export type Route = {
|
|
18
|
+
view: "home";
|
|
19
|
+
draft?: string;
|
|
20
|
+
focus?: boolean;
|
|
21
|
+
topic?: string;
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
} | {
|
|
24
|
+
view: "board";
|
|
25
|
+
tab?: "top" | "new" | "shipped";
|
|
26
|
+
} | {
|
|
27
|
+
view: "detail";
|
|
28
|
+
id: string;
|
|
29
|
+
} | {
|
|
30
|
+
view: "mine";
|
|
31
|
+
};
|
|
32
|
+
export declare function toRoute(o?: OpenOptions): Route;
|
|
33
|
+
export type InternalContext = {
|
|
34
|
+
open: (options?: OpenOptions) => void;
|
|
35
|
+
close: () => void;
|
|
36
|
+
isOpen: boolean;
|
|
37
|
+
unseenCount: number;
|
|
38
|
+
client: Client;
|
|
39
|
+
config: Config | null;
|
|
40
|
+
markSeen: (ids: string[]) => void;
|
|
41
|
+
/** What shipped since this person's last visit, until they've been shown it. */
|
|
42
|
+
whatsNew: WhatsNew | null;
|
|
43
|
+
dismissWhatsNew: () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Hides the sheet, lets the person draw on the page, and resolves with a screenshot of it
|
|
46
|
+
* (null if they cancel or the page can't be captured).
|
|
47
|
+
*/
|
|
48
|
+
pointAtIt: () => Promise<Blob | null>;
|
|
49
|
+
/** Spread onto any element that renders widget UI inside the host page. */
|
|
50
|
+
scope: {
|
|
51
|
+
className: string;
|
|
52
|
+
style?: CSSProperties;
|
|
53
|
+
"data-ya-mode"?: string;
|
|
54
|
+
};
|
|
55
|
+
appName: string;
|
|
56
|
+
/** The app's icon: from the appIcon prop, else the page's apple-touch-icon or a large favicon, else null. */
|
|
57
|
+
appIcon: string | null;
|
|
58
|
+
title: string;
|
|
59
|
+
greeting?: string;
|
|
60
|
+
};
|
|
61
|
+
export declare const YouAskedContext: import("react").Context<InternalContext | null>;
|
|
62
|
+
export declare function useInternal(): InternalContext;
|
|
63
|
+
/** Open, close and the unseen badge count, for wiring YouAsked to your own buttons. */
|
|
64
|
+
export declare function useYouAsked(): {
|
|
65
|
+
open: (options?: OpenOptions) => void;
|
|
66
|
+
close: () => void;
|
|
67
|
+
isOpen: boolean;
|
|
68
|
+
unseenCount: number;
|
|
69
|
+
};
|
|
70
|
+
/** Opens the panel from anywhere, even outside React. */
|
|
71
|
+
export declare function openYouAsked(options?: OpenOptions): void;
|
package/dist/demo.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Client, type Notice } from "./client";
|
|
2
|
+
export type DemoClient = Client & {
|
|
3
|
+
/** Calls back when the pretend team writes in. Returns an unsubscribe. */
|
|
4
|
+
onNotice: (fn: (n: Notice) => void) => () => void;
|
|
5
|
+
};
|
|
6
|
+
export declare function createDemoClient(appName?: string): DemoClient;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
type Common = {
|
|
3
|
+
className?: string;
|
|
4
|
+
style?: CSSProperties;
|
|
5
|
+
};
|
|
6
|
+
/** A chat-style input bar. Tapping it opens the composer. Good at the top of a home screen or under an empty state. */
|
|
7
|
+
export declare function AskBar({ placeholder, className, style }: Common & {
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
/** A card with the top requests and vote buttons, for a dashboard or home tab. */
|
|
11
|
+
export declare function FeatureCard({ heading, description, limit, className, style, }: Common & {
|
|
12
|
+
heading?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
limit?: number;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* A button for your own toolbar or menu.
|
|
18
|
+
* - "pill": tinted pill with an icon and label
|
|
19
|
+
* - "icon": round icon button, e.g. in a header
|
|
20
|
+
* - "row": a settings-style row with a chevron
|
|
21
|
+
*/
|
|
22
|
+
export declare function RequestButton({ variant, label, sublabel, className, style, }: Common & {
|
|
23
|
+
variant?: "pill" | "icon" | "row";
|
|
24
|
+
label?: string;
|
|
25
|
+
sublabel?: string;
|
|
26
|
+
}): import("react").JSX.Element;
|
|
27
|
+
/**
|
|
28
|
+
* A quiet line next to a feature: "Want more from charts?". Opens the composer already about that
|
|
29
|
+
* topic, and the request is saved with it so you can see which feature people are asking about.
|
|
30
|
+
*/
|
|
31
|
+
export declare function AskAbout({ topic, prompt, className, style, }: Common & {
|
|
32
|
+
topic: string;
|
|
33
|
+
prompt?: string;
|
|
34
|
+
}): import("react").JSX.Element;
|
|
35
|
+
/**
|
|
36
|
+
* For an empty search: "Can't find “export”? Ask for it". Opens the composer with the search as the
|
|
37
|
+
* draft, tagged as a search so you can tell what people looked for and didn't find.
|
|
38
|
+
*/
|
|
39
|
+
export declare function AskForIt({ query, className, style }: Common & {
|
|
40
|
+
query: string;
|
|
41
|
+
}): import("react").JSX.Element;
|
|
42
|
+
/** The whole experience inline, for a /feedback page or a tab. */
|
|
43
|
+
export declare function FeatureBoard({ start, height, className, style, }: Common & {
|
|
44
|
+
start?: "home" | "board";
|
|
45
|
+
height?: number | string;
|
|
46
|
+
}): import("react").JSX.Element;
|
|
47
|
+
export {};
|
package/dist/icons.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const IconUp: () => import("react").JSX.Element;
|
|
2
|
+
export declare const IconClose: () => import("react").JSX.Element;
|
|
3
|
+
export declare const IconBack: () => import("react").JSX.Element;
|
|
4
|
+
export declare const IconChevron: () => import("react").JSX.Element;
|
|
5
|
+
export declare const IconPlus: () => import("react").JSX.Element;
|
|
6
|
+
export declare const IconCheck: () => import("react").JSX.Element;
|
|
7
|
+
export declare const IconChat: () => import("react").JSX.Element;
|
|
8
|
+
export declare const IconSend: () => import("react").JSX.Element;
|
|
9
|
+
export declare const IconBulb: () => import("react").JSX.Element;
|
|
10
|
+
/** Viewfinder corners: "show us" a spot on the page. */
|
|
11
|
+
export declare const IconFrame: () => import("react").JSX.Element;
|
|
12
|
+
export declare const IconSpark: () => import("react").JSX.Element;
|
|
13
|
+
/** YouAsked's own mark for asking: a speech bubble with an up arrow (ask, and vote it up). */
|
|
14
|
+
export declare const IconIdea: () => import("react").JSX.Element;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { YouAsked, DEFAULT_API_URL } from "./YouAsked";
|
|
2
|
+
export type { YouAskedProps } from "./YouAsked";
|
|
3
|
+
export { useYouAsked, openYouAsked } from "./context";
|
|
4
|
+
export type { OpenOptions } from "./context";
|
|
5
|
+
export { AskBar, AskAbout, AskForIt, FeatureCard, RequestButton, FeatureBoard } from "./entries";
|
|
6
|
+
export type { Appearance } from "./theme";
|
|
7
|
+
export type { Attachment, FeatureRequest, RequestComment, Status, WhatsNew, YouAskedUser } from "./client";
|