@gogitcms/design-system 0.16.0-next.5 → 0.16.0-next.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gogitcms/design-system",
|
|
3
|
-
"version": "0.16.0-next.
|
|
3
|
+
"version": "0.16.0-next.7",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"types": "src/index.ts",
|
|
6
6
|
"// exports": "The root entry is the react-native source the SPAs, desktop app and mobile app consume. ./web is the plain-DOM build for server-rendered surfaces (the Astro docs site) that don't run react-native-web, and ./css ships the tokens as custom properties. The trailing wildcard keeps deep paths resolvable — plugin bundling and the Vite aliases reach into src/ directly.",
|
|
@@ -146,3 +146,51 @@ test("failure surfaces the error and a dismiss button", () => {
|
|
|
146
146
|
expect(screen.getByTestId("merge-error")).toHaveTextContent("main moved while merging");
|
|
147
147
|
expect(screen.getByTestId("apply-dismiss")).toBeInTheDocument();
|
|
148
148
|
});
|
|
149
|
+
|
|
150
|
+
test("with a review reason the confirmation step promises a review, not a merge commit", () => {
|
|
151
|
+
render(
|
|
152
|
+
wrap(
|
|
153
|
+
<ApplyChangesModal
|
|
154
|
+
{...branches}
|
|
155
|
+
reviewReason="main is protected, so this opens a change request for review."
|
|
156
|
+
onConfirm={() => {}}
|
|
157
|
+
onClose={() => {}}
|
|
158
|
+
/>,
|
|
159
|
+
),
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const confirm = screen.getByTestId("apply-confirm");
|
|
163
|
+
// The run will stop before the push, so the copy must not describe one.
|
|
164
|
+
expect(confirm).not.toHaveTextContent("pushes a merge commit");
|
|
165
|
+
expect(confirm).not.toHaveTextContent("is then deleted");
|
|
166
|
+
expect(screen.getByTestId("apply-confirm-review")).toHaveTextContent("opens a pull request for review");
|
|
167
|
+
expect(confirm).toHaveTextContent("Nothing is pushed to origin/main until it is approved");
|
|
168
|
+
expect(confirm).toHaveTextContent("main is protected");
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("needs_review without code conflicts explains the review instead of listing files", () => {
|
|
172
|
+
const onCreateChangeRequest = jest.fn();
|
|
173
|
+
render(
|
|
174
|
+
wrap(
|
|
175
|
+
<ApplyChangesModal
|
|
176
|
+
{...branches}
|
|
177
|
+
reviewReason="main is protected, so this opens a change request for review."
|
|
178
|
+
progress={{ ...base, status: "needs_review", step: "merging", escalationFiles: [] }}
|
|
179
|
+
onCreateChangeRequest={onCreateChangeRequest}
|
|
180
|
+
onClose={() => {}}
|
|
181
|
+
/>,
|
|
182
|
+
),
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
const panel = screen.getByTestId("merge-needs-review");
|
|
186
|
+
// No conflict: it is not called one, and no empty file list is drawn.
|
|
187
|
+
expect(panel).not.toHaveTextContent("Code conflicts need a developer");
|
|
188
|
+
expect(panel).toHaveTextContent("This merge needs a review");
|
|
189
|
+
expect(screen.getByTestId("merge-needs-review-reason")).toHaveTextContent("nothing was pushed to main");
|
|
190
|
+
expect(screen.getByTestId("merge-needs-review-reason")).toHaveTextContent("main is protected");
|
|
191
|
+
|
|
192
|
+
// The same escalation flow: an explanation, then a change request.
|
|
193
|
+
fireEvent.change(screen.getByTestId("change-request-explanation"), { target: { value: "Spring copy" } });
|
|
194
|
+
fireEvent.click(screen.getByTestId("create-change-request-submit"));
|
|
195
|
+
expect(onCreateChangeRequest).toHaveBeenCalledWith("Spring copy");
|
|
196
|
+
});
|
|
@@ -35,6 +35,15 @@ export type ApplyChangesModalProps = {
|
|
|
35
35
|
progress?: MergeProgress;
|
|
36
36
|
/** A short summary of what will be merged, shown on the confirmation step. */
|
|
37
37
|
summary?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Why this apply cannot push to the target directly and opens a change
|
|
40
|
+
* request instead — the target is protected, or the caller cannot publish
|
|
41
|
+
* every project on the branch. When set, the confirmation step describes the
|
|
42
|
+
* review that will happen rather than a merge commit that will not, and the
|
|
43
|
+
* needs_review panel gives this reason when there are no code conflicts to
|
|
44
|
+
* list. Absent for an ordinary direct merge.
|
|
45
|
+
*/
|
|
46
|
+
reviewReason?: string;
|
|
38
47
|
/** Number of unresolved conflicts, shown on the conflicted state. */
|
|
39
48
|
conflictCount?: number;
|
|
40
49
|
/**
|
|
@@ -99,7 +108,7 @@ function StepRow({ label, state }: { label: string; state: "done" | "active" | "
|
|
|
99
108
|
* (spinner → green check), then shows a success panel with the commit + stats,
|
|
100
109
|
* or an error. Read-only: it reflects a run the host drives via a subscription.
|
|
101
110
|
*/
|
|
102
|
-
export function ApplyChangesModal({ sourceBranch, targetBranch, progress, summary, conflictCount, changeRequestOpen, changeRequestUrl, creatingChangeRequest, onConfirm, onReviewConflicts, onCreateChangeRequest, onViewChangeRequest, onClose, onDone }: ApplyChangesModalProps) {
|
|
111
|
+
export function ApplyChangesModal({ sourceBranch, targetBranch, progress, summary, reviewReason, conflictCount, changeRequestOpen, changeRequestUrl, creatingChangeRequest, onConfirm, onReviewConflicts, onCreateChangeRequest, onViewChangeRequest, onClose, onDone }: ApplyChangesModalProps) {
|
|
103
112
|
const t = useTheme();
|
|
104
113
|
const done = onDone ?? onClose;
|
|
105
114
|
const [explanation, setExplanation] = useState("");
|
|
@@ -121,6 +130,13 @@ export function ApplyChangesModal({ sourceBranch, targetBranch, progress, summar
|
|
|
121
130
|
const status = progress?.status;
|
|
122
131
|
const conflicted = status === "conflicted";
|
|
123
132
|
const needsReview = status === "needs_review";
|
|
133
|
+
// A needs_review run either lists code files a developer must resolve, or
|
|
134
|
+
// lists nothing because the merge was clean and simply may not be pushed by
|
|
135
|
+
// this run (a protected target, or partial project access). The two need
|
|
136
|
+
// different words: the second is not a conflict and naming it one would send
|
|
137
|
+
// the editor looking for files that are not there.
|
|
138
|
+
const escalationFiles = progress?.escalationFiles ?? [];
|
|
139
|
+
const codeConflicts = escalationFiles.length > 0;
|
|
124
140
|
const terminal = status === "succeeded" || status === "failed" || conflicted || needsReview;
|
|
125
141
|
const current = progress ? stepOrder[progress.step] : 0;
|
|
126
142
|
|
|
@@ -201,30 +217,63 @@ export function ApplyChangesModal({ sourceBranch, targetBranch, progress, summar
|
|
|
201
217
|
// Confirmation step: spell out the irreversible, outward-facing effects
|
|
202
218
|
// before anything is pushed to the remote.
|
|
203
219
|
<View testID="apply-confirm" style={{ gap: t.space(3) }}>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
220
|
+
{reviewReason ? (
|
|
221
|
+
// The run will stop before the push, so promising a merge commit
|
|
222
|
+
// on origin here would be describing something that will not
|
|
223
|
+
// happen. Say what will: a review, and nothing on the target
|
|
224
|
+
// until it is approved.
|
|
225
|
+
<>
|
|
226
|
+
<Text variant="body" color="secondary" testID="apply-confirm-review">
|
|
227
|
+
{`This merges ${sourceBranch} into ${targetBranch} in the CMS and opens a pull request for review. Nothing is pushed to origin/${targetBranch} until it is approved.`}
|
|
228
|
+
</Text>
|
|
229
|
+
<Text variant="body" color="secondary">{reviewReason}</Text>
|
|
230
|
+
</>
|
|
231
|
+
) : (
|
|
232
|
+
<>
|
|
233
|
+
<Text variant="body" color="secondary">
|
|
234
|
+
{`This merges ${sourceBranch} into ${targetBranch}, commits the result, and pushes a merge commit to origin/${targetBranch}.`}
|
|
235
|
+
</Text>
|
|
236
|
+
<Text variant="body" color="secondary">
|
|
237
|
+
{`${sourceBranch} is then deleted. This can’t be undone.`}
|
|
238
|
+
</Text>
|
|
239
|
+
</>
|
|
240
|
+
)}
|
|
210
241
|
{summary ? <Text variant="monoSm" color="tertiary">{summary}</Text> : null}
|
|
211
242
|
</View>
|
|
212
243
|
) : needsReview ? (
|
|
213
|
-
// Content merged, but
|
|
214
|
-
//
|
|
244
|
+
// Content merged, but the run may not push it. Either code/config
|
|
245
|
+
// files conflict — a content editor can't resolve these — or the
|
|
246
|
+
// target can't take a direct push from this run. Both collect an
|
|
247
|
+
// explanation and escalate through a pull request.
|
|
215
248
|
<View testID="merge-needs-review" style={{ gap: t.space(3) }}>
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
<
|
|
226
|
-
|
|
227
|
-
|
|
249
|
+
{codeConflicts ? (
|
|
250
|
+
<>
|
|
251
|
+
<View style={{ flexDirection: "row", alignItems: "center", gap: t.space(2) }}>
|
|
252
|
+
<Icon name="gitPullRequest" size={16} color={t.color.diffDelFg} />
|
|
253
|
+
<Text variant="body" weight="medium">Code conflicts need a developer</Text>
|
|
254
|
+
</View>
|
|
255
|
+
<Text variant="body" color="secondary">
|
|
256
|
+
{`The content merged cleanly, but these files changed on both ${sourceBranch} and ${targetBranch} and need a developer to resolve:`}
|
|
257
|
+
</Text>
|
|
258
|
+
<View style={{ gap: 2, padding: t.space(2), borderRadius: t.radius.md, backgroundColor: t.color.diffDelBg }}>
|
|
259
|
+
{escalationFiles.map((f) => (
|
|
260
|
+
<Text key={f} variant="monoSm" color={t.color.diffDelFg} testID={`escalation-file-${f}`}>{f}</Text>
|
|
261
|
+
))}
|
|
262
|
+
</View>
|
|
263
|
+
</>
|
|
264
|
+
) : (
|
|
265
|
+
<>
|
|
266
|
+
<View style={{ flexDirection: "row", alignItems: "center", gap: t.space(2) }}>
|
|
267
|
+
<Icon name="gitPullRequest" size={16} color={t.color.textSecondary} />
|
|
268
|
+
<Text variant="body" weight="medium">This merge needs a review</Text>
|
|
269
|
+
</View>
|
|
270
|
+
<Text variant="body" color="secondary" testID="merge-needs-review-reason">
|
|
271
|
+
{`The content merged cleanly and nothing was pushed to ${targetBranch}. ` +
|
|
272
|
+
(reviewReason ?? `Someone with the authority to publish it has to approve it.`) +
|
|
273
|
+
` Opening a change request creates a pull request for that review.`}
|
|
274
|
+
</Text>
|
|
275
|
+
</>
|
|
276
|
+
)}
|
|
228
277
|
<Input
|
|
229
278
|
value={explanation}
|
|
230
279
|
onChangeText={setExplanation}
|
|
@@ -483,6 +483,9 @@ export type ContentBrowserProps = {
|
|
|
483
483
|
canApplyChanges?: boolean;
|
|
484
484
|
applyOpen?: boolean;
|
|
485
485
|
applySummary?: string;
|
|
486
|
+
// Why applying opens a change request instead of merging (see
|
|
487
|
+
// ApplyChangesModal.reviewReason). Absent for a direct merge.
|
|
488
|
+
applyReviewReason?: string;
|
|
486
489
|
applyProgress?: MergeProgress;
|
|
487
490
|
applyConflictCount?: number;
|
|
488
491
|
onConfirmApply?: () => void;
|
|
@@ -3767,6 +3770,7 @@ function ApplyModalOverlay(props: ContentBrowserProps) {
|
|
|
3767
3770
|
sourceBranch={props.workspace.branch}
|
|
3768
3771
|
targetBranch={props.targetBranch ?? props.defaultBranch ?? ""}
|
|
3769
3772
|
summary={props.applySummary}
|
|
3773
|
+
reviewReason={props.applyReviewReason}
|
|
3770
3774
|
progress={props.applyProgress}
|
|
3771
3775
|
conflictCount={props.applyConflictCount}
|
|
3772
3776
|
changeRequestOpen={props.changeRequestOpen}
|
|
@@ -4,10 +4,11 @@ import { useTheme, useThemeMode, ThemeScope } from "../ThemeProvider";
|
|
|
4
4
|
import { lightTheme, darkTheme } from "../theme";
|
|
5
5
|
import { Text } from "./Text";
|
|
6
6
|
import { Icon } from "./Icon";
|
|
7
|
+
import type { IconName } from "../icons";
|
|
7
8
|
import { Spinner } from "./Spinner";
|
|
8
9
|
|
|
9
10
|
// One notification, shaped for display. Transport-agnostic: the frontend/mobile
|
|
10
|
-
// apps map GraphQL rows and the desktop
|
|
11
|
+
// apps map GraphQL rows and the desktop and dashboard map REST rows into this.
|
|
11
12
|
export type NotificationItem = {
|
|
12
13
|
id: string;
|
|
13
14
|
title: string;
|
|
@@ -16,8 +17,39 @@ export type NotificationItem = {
|
|
|
16
17
|
read: boolean;
|
|
17
18
|
createdAt: string; // ISO 8601
|
|
18
19
|
author?: string; // display name/email of who caused it, when known
|
|
20
|
+
// What produced it — picks the icon. Unknown kinds fall back to the bell.
|
|
21
|
+
kind?: NotificationKind | string;
|
|
22
|
+
// Where it happened, for a list that spans several repositories/projects.
|
|
23
|
+
// Omit whichever the list is already scoped to.
|
|
24
|
+
repository?: string;
|
|
25
|
+
project?: string;
|
|
19
26
|
};
|
|
20
27
|
|
|
28
|
+
export type NotificationKind = "import" | "export" | "merge" | "change_request" | "member" | "branch" | "project";
|
|
29
|
+
|
|
30
|
+
// The icon for a notification kind. Exported so hosts that draw their own rows
|
|
31
|
+
// (a scope picker's section headers, say) agree with the list.
|
|
32
|
+
export function notificationKindIcon(kind?: string): IconName {
|
|
33
|
+
switch (kind) {
|
|
34
|
+
case "import":
|
|
35
|
+
return "download";
|
|
36
|
+
case "export":
|
|
37
|
+
return "upload";
|
|
38
|
+
case "merge":
|
|
39
|
+
return "gitMerge";
|
|
40
|
+
case "change_request":
|
|
41
|
+
return "gitPullRequest";
|
|
42
|
+
case "member":
|
|
43
|
+
return "user";
|
|
44
|
+
case "branch":
|
|
45
|
+
return "gitBranch";
|
|
46
|
+
case "project":
|
|
47
|
+
return "folder";
|
|
48
|
+
default:
|
|
49
|
+
return "bell";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
21
53
|
// relativeTime renders a compact age ("just now", "5m", "3h", "2d").
|
|
22
54
|
function relativeTime(iso: string): string {
|
|
23
55
|
const then = Date.parse(iso);
|
|
@@ -32,7 +64,65 @@ function relativeTime(iso: string): string {
|
|
|
32
64
|
return `${days}d`;
|
|
33
65
|
}
|
|
34
66
|
|
|
35
|
-
//
|
|
67
|
+
// InlineCode renders a sentence whose backticked spans (`main`, `#12`'s
|
|
68
|
+
// branch) are set in the mono face, so a title like "Created `zyx` branch"
|
|
69
|
+
// reads as prose around a name rather than as punctuation. An unmatched
|
|
70
|
+
// backtick is left as typed.
|
|
71
|
+
export function InlineCode({
|
|
72
|
+
text,
|
|
73
|
+
variant = "sm",
|
|
74
|
+
weight,
|
|
75
|
+
color,
|
|
76
|
+
numberOfLines,
|
|
77
|
+
testID,
|
|
78
|
+
}: {
|
|
79
|
+
text: string;
|
|
80
|
+
variant?: "sm" | "body" | "monoSm" | "xs";
|
|
81
|
+
weight?: "regular" | "medium" | "semibold";
|
|
82
|
+
color?: string;
|
|
83
|
+
numberOfLines?: number;
|
|
84
|
+
testID?: string;
|
|
85
|
+
}) {
|
|
86
|
+
const t = useTheme();
|
|
87
|
+
const parts = text.split("`");
|
|
88
|
+
// An even number of parts means an odd number of backticks: not a pair, so
|
|
89
|
+
// render the text untouched.
|
|
90
|
+
if (parts.length % 2 === 0) {
|
|
91
|
+
return (
|
|
92
|
+
<Text variant={variant} weight={weight} color={color} numberOfLines={numberOfLines} testID={testID}>
|
|
93
|
+
{text}
|
|
94
|
+
</Text>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
return (
|
|
98
|
+
<Text variant={variant} weight={weight} color={color} numberOfLines={numberOfLines} testID={testID}>
|
|
99
|
+
{parts.map((part, i) =>
|
|
100
|
+
i % 2 === 1 ? (
|
|
101
|
+
<Text
|
|
102
|
+
key={i}
|
|
103
|
+
variant={variant}
|
|
104
|
+
weight={weight}
|
|
105
|
+
color={color}
|
|
106
|
+
mono
|
|
107
|
+
style={{
|
|
108
|
+
backgroundColor: t.color.surfaceSunken,
|
|
109
|
+
borderRadius: t.radius.sm,
|
|
110
|
+
paddingHorizontal: 3,
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
{part}
|
|
114
|
+
</Text>
|
|
115
|
+
) : (
|
|
116
|
+
part
|
|
117
|
+
),
|
|
118
|
+
)}
|
|
119
|
+
</Text>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// A single notification row: a kind icon, the title (unread rows in bold, error
|
|
124
|
+
// rows tinted), the body, and a context line — where it happened and who did
|
|
125
|
+
// it — with the age on the right.
|
|
36
126
|
function NotificationRow({
|
|
37
127
|
item,
|
|
38
128
|
divided,
|
|
@@ -44,12 +134,16 @@ function NotificationRow({
|
|
|
44
134
|
}) {
|
|
45
135
|
const t = useTheme();
|
|
46
136
|
const titleColor = item.level === "error" ? t.color.diffDelFg : t.color.textPrimary;
|
|
137
|
+
const context = [item.repository, item.project].filter(Boolean).join(" · ");
|
|
138
|
+
const meta = [context, item.author ? `by ${item.author}` : ""].filter(Boolean).join(" · ");
|
|
47
139
|
return (
|
|
48
140
|
<Pressable
|
|
49
141
|
onPress={onPress}
|
|
142
|
+
disabled={!onPress}
|
|
143
|
+
testID={`notification-${item.id}`}
|
|
50
144
|
style={({ pressed, hovered }: { pressed: boolean; hovered?: boolean }) => ({
|
|
51
145
|
flexDirection: "row",
|
|
52
|
-
gap: t.space(
|
|
146
|
+
gap: t.space(3),
|
|
53
147
|
paddingHorizontal: t.space(4),
|
|
54
148
|
paddingVertical: t.space(3),
|
|
55
149
|
borderBottomWidth: divided ? 1 : 0,
|
|
@@ -57,33 +151,57 @@ function NotificationRow({
|
|
|
57
151
|
backgroundColor: hovered || pressed ? t.color.surfaceHover : "transparent",
|
|
58
152
|
})}
|
|
59
153
|
>
|
|
60
|
-
<View
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
color={
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
154
|
+
<View style={{ width: 28, height: 28, alignItems: "center", justifyContent: "center", position: "relative" }}>
|
|
155
|
+
<View
|
|
156
|
+
style={{
|
|
157
|
+
width: 28,
|
|
158
|
+
height: 28,
|
|
159
|
+
borderRadius: t.radius.pill,
|
|
160
|
+
alignItems: "center",
|
|
161
|
+
justifyContent: "center",
|
|
162
|
+
backgroundColor: item.level === "error" ? t.color.diffDelBg : t.color.surfaceSunken,
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
<Icon
|
|
166
|
+
name={notificationKindIcon(item.kind)}
|
|
167
|
+
size={14}
|
|
168
|
+
color={item.level === "error" ? t.color.diffDelFg : t.color.textSecondary}
|
|
169
|
+
/>
|
|
170
|
+
</View>
|
|
171
|
+
{/* Unread dot, riding on the icon's corner. */}
|
|
172
|
+
{item.read ? null : (
|
|
173
|
+
<View
|
|
174
|
+
testID="notification-unread"
|
|
175
|
+
style={{
|
|
176
|
+
position: "absolute",
|
|
177
|
+
top: -1,
|
|
178
|
+
right: -1,
|
|
179
|
+
width: 8,
|
|
180
|
+
height: 8,
|
|
181
|
+
borderRadius: t.radius.pill,
|
|
182
|
+
backgroundColor: t.color.diffDelFg,
|
|
183
|
+
borderWidth: 1,
|
|
184
|
+
borderColor: t.color.surfaceRaised,
|
|
185
|
+
}}
|
|
186
|
+
/>
|
|
187
|
+
)}
|
|
188
|
+
</View>
|
|
189
|
+
<View style={{ flex: 1, gap: 2, minWidth: 0 }}>
|
|
190
|
+
<View style={{ flexDirection: "row", alignItems: "flex-start", gap: t.space(2) }}>
|
|
191
|
+
<View style={{ flex: 1, minWidth: 0 }}>
|
|
192
|
+
<InlineCode
|
|
193
|
+
text={item.title}
|
|
194
|
+
variant="sm"
|
|
195
|
+
weight={item.read ? "medium" : "semibold"}
|
|
196
|
+
color={titleColor}
|
|
197
|
+
numberOfLines={2}
|
|
198
|
+
/>
|
|
199
|
+
</View>
|
|
80
200
|
<Text variant="monoSm" color="tertiary">{relativeTime(item.createdAt)}</Text>
|
|
81
201
|
</View>
|
|
82
|
-
{item.body ?
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
{item.author ? (
|
|
86
|
-
<Text variant="monoSm" color="tertiary" numberOfLines={1}>{`by ${item.author}`}</Text>
|
|
202
|
+
{item.body ? <InlineCode text={item.body} variant="monoSm" color={t.color.textSecondary} numberOfLines={2} /> : null}
|
|
203
|
+
{meta ? (
|
|
204
|
+
<Text variant="monoSm" color="tertiary" numberOfLines={1}>{meta}</Text>
|
|
87
205
|
) : null}
|
|
88
206
|
</View>
|
|
89
207
|
</Pressable>
|
package/src/icons.ts
CHANGED
|
@@ -28,6 +28,7 @@ export const icons = {
|
|
|
28
28
|
chevronDown: ["m6 9 6 6 6-6"],
|
|
29
29
|
chevronUp: ["m18 15-6-6-6 6"],
|
|
30
30
|
folder: ["M3 6a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"],
|
|
31
|
+
user: ["M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", "M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z"],
|
|
31
32
|
building: ["M3 21h18", "M6 21V7l7-4v18", "M18 21V11l-5-3"],
|
|
32
33
|
menu: ["M3 6h18", "M3 12h18", "M3 18h18"],
|
|
33
34
|
plus: ["M5 12h14", "M12 5v14"],
|
package/src/index.ts
CHANGED
|
@@ -115,9 +115,10 @@ export { Spinner } from "./components/Spinner";
|
|
|
115
115
|
export type { SpinnerProps } from "./components/Spinner";
|
|
116
116
|
|
|
117
117
|
// Notifications
|
|
118
|
-
export { NotificationBell, NotificationList } from "./components/Notifications";
|
|
118
|
+
export { NotificationBell, NotificationList, InlineCode, notificationKindIcon } from "./components/Notifications";
|
|
119
119
|
export type {
|
|
120
120
|
NotificationItem,
|
|
121
|
+
NotificationKind,
|
|
121
122
|
NotificationBellProps,
|
|
122
123
|
NotificationListProps,
|
|
123
124
|
} from "./components/Notifications";
|