@vvedantb/ui 0.13.0 → 0.13.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.
package/README.md
CHANGED
|
@@ -982,7 +982,7 @@ const store: ArtifactStateStore = {
|
|
|
982
982
|
- `ArtifactListToolbar`: controlled `ToolbarSearchInput` (`query`, `onQueryChange`), a type filter menu (`type`, `onTypeChange`, `types`; `undefined` is "All types") and a grid or list toggle (`layout`, `onLayoutChange`). The filter and the toggle show only with their callbacks. `children` go at the end.
|
|
983
983
|
- `ArtifactViewer`: the ai-elements `Artifact` container with a header (`headerStart`, type icon, title) and actions: versions menu (`versions`), Rename, Copy, Download (the format's extension and MIME type from `ARTIFACT_FORMAT_FILES`), Open in new tab (`href`), your `actions`, and Delete. Below it, `ArtifactRender` of `artifact.body`. Pass the body of the version on screen.
|
|
984
984
|
- `ArtifactVersionsMenu`: a "vN" button listing `versions` newest first, with the current one marked. With `onViewVersion`, picking a version shows it, and "Restore vN" (`onRestoreVersion`) appears while an older version is on screen. Without it, picking an older version restores it.
|
|
985
|
-
- Rename and delete use `ConfirmDialog` (`ArtifactRenameDialog`, `ArtifactDeleteDialog`, and `useArtifactEditDialogs` for custom surfaces). Rename sends the trimmed title, and does nothing when it is unchanged. Alt-click on Delete skips the dialog, as with `useRequestConfirm`. A callback that rejects keeps its dialog open and shows an error toast; copy and load failures toast too, so mount `SonnerToaster`.
|
|
985
|
+
- Rename and delete use `ConfirmDialog` (`ArtifactRenameDialog`, `ArtifactDeleteDialog`, and `useArtifactEditDialogs` for custom surfaces). Rename sends the trimmed title, and does nothing when it is unchanged. Alt-click on Delete skips the dialog, as with `useRequestConfirm`. The delete dialog says "This cannot be undone."; pass `deleteDescription` to `ArtifactViewer`, `ArtifactCard` or `ArtifactList` to change it (0.13.1), for example when your delete can be undone. A callback that rejects keeps its dialog open and shows an error toast; copy and load failures toast too, so mount `SonnerToaster`.
|
|
986
986
|
- `ArtifactTypeIcon` (`type`, `size`, `stroke`) and `ARTIFACT_TYPE_LABELS` (`mindmap` is "Mind map"). Helpers `downloadArtifactBody(title, format, body)`, `copyArtifactBody(body)`, `openArtifactInNewTab(href)`. Row types: `ArtifactSummary` (any `ArtifactListRow` fits), `ArtifactDocument`, `ArtifactVersionSummary`.
|
|
987
987
|
|
|
988
988
|
## Toaster
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vvedantb/ui",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Shared React 19 UI for web apps: one JavaScript entry (primitives, shell pieces, app helpers including the Convex and Clerk provider, VITE env parsing and ensure-user, artifact viewers over the @vvedantb/server artifacts core, native tokens), design-token CSS, shared Tailwind v4 CSS and a Tailwind preset.",
|
|
6
6
|
"type": "module",
|
|
@@ -33,6 +33,8 @@ export type ArtifactCardActions = {
|
|
|
33
33
|
onRename?: (artifact: ArtifactSummary, title: string) => void | Promise<void>;
|
|
34
34
|
/** Called after the delete dialog, or straight away on an Alt-click. */
|
|
35
35
|
onDelete?: (artifact: ArtifactSummary) => void | Promise<void>;
|
|
36
|
+
/** Text under the delete dialog's title, e.g. for a host that can undo. Defaults to "This cannot be undone." */
|
|
37
|
+
deleteDescription?: ReactNode;
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
export type ArtifactCardProps = ArtifactCardActions & {
|
|
@@ -69,12 +71,14 @@ export function ArtifactCard({
|
|
|
69
71
|
getBody,
|
|
70
72
|
onRename,
|
|
71
73
|
onDelete,
|
|
74
|
+
deleteDescription,
|
|
72
75
|
className,
|
|
73
76
|
}: ArtifactCardProps) {
|
|
74
77
|
const edit = useArtifactEditDialogs({
|
|
75
78
|
title: artifact.title,
|
|
76
79
|
onRename: onRename && ((title) => onRename(artifact, title)),
|
|
77
80
|
onDelete: onDelete && (() => onDelete(artifact)),
|
|
81
|
+
deleteDescription,
|
|
78
82
|
});
|
|
79
83
|
const href = getHref?.(artifact);
|
|
80
84
|
|
|
@@ -51,16 +51,25 @@ export type ArtifactDeleteDialogProps = {
|
|
|
51
51
|
title: string;
|
|
52
52
|
onConfirm: () => void;
|
|
53
53
|
pending?: boolean;
|
|
54
|
+
/** Text under the title. Defaults to "This cannot be undone." */
|
|
55
|
+
description?: ReactNode;
|
|
54
56
|
};
|
|
55
57
|
|
|
56
58
|
/** "Delete <title>?" confirmation. Cancel is focused on open. */
|
|
57
|
-
export function ArtifactDeleteDialog({
|
|
59
|
+
export function ArtifactDeleteDialog({
|
|
60
|
+
open,
|
|
61
|
+
onOpenChange,
|
|
62
|
+
title,
|
|
63
|
+
onConfirm,
|
|
64
|
+
pending,
|
|
65
|
+
description = "This cannot be undone.",
|
|
66
|
+
}: ArtifactDeleteDialogProps) {
|
|
58
67
|
return (
|
|
59
68
|
<ConfirmDialog.Root alert={false} focusCancel pending={pending} open={open} onOpenChange={onOpenChange}>
|
|
60
69
|
<ConfirmDialog.Content className="max-w-sm" role="alertdialog">
|
|
61
70
|
<ConfirmDialog.Header>
|
|
62
71
|
<ConfirmDialog.Title>Delete "{title}"?</ConfirmDialog.Title>
|
|
63
|
-
<ConfirmDialog.Description>
|
|
72
|
+
<ConfirmDialog.Description>{description}</ConfirmDialog.Description>
|
|
64
73
|
</ConfirmDialog.Header>
|
|
65
74
|
<ConfirmDialog.Footer>
|
|
66
75
|
<ConfirmDialog.Cancel variant="secondary" />
|
|
@@ -78,13 +87,15 @@ export type ArtifactEditCallbacks = {
|
|
|
78
87
|
onRename?: (title: string) => void | Promise<void>;
|
|
79
88
|
/** Called after the delete dialog, or straight away on an Alt-click. */
|
|
80
89
|
onDelete?: () => void | Promise<void>;
|
|
90
|
+
/** Text under the delete dialog's title, e.g. for a host that can undo. Defaults to "This cannot be undone." */
|
|
91
|
+
deleteDescription?: ReactNode;
|
|
81
92
|
};
|
|
82
93
|
|
|
83
94
|
/**
|
|
84
95
|
* Rename and delete dialog state shared by the card and the viewer. `dialogs`
|
|
85
96
|
* must be rendered; `requestDelete(event)` skips the dialog on an Alt-click.
|
|
86
97
|
*/
|
|
87
|
-
export function useArtifactEditDialogs({ title, onRename, onDelete }: ArtifactEditCallbacks & { title: string }) {
|
|
98
|
+
export function useArtifactEditDialogs({ title, onRename, onDelete, deleteDescription }: ArtifactEditCallbacks & { title: string }) {
|
|
88
99
|
const [renameOpen, setRenameOpen] = useState(false);
|
|
89
100
|
const [renameValue, setRenameValue] = useState(title);
|
|
90
101
|
const [deleteOpen, setDeleteOpen] = useState(false);
|
|
@@ -137,6 +148,7 @@ export function useArtifactEditDialogs({ title, onRename, onDelete }: ArtifactEd
|
|
|
137
148
|
title={title}
|
|
138
149
|
onConfirm={remove}
|
|
139
150
|
pending={pending}
|
|
151
|
+
description={deleteDescription}
|
|
140
152
|
/>
|
|
141
153
|
) : null}
|
|
142
154
|
</>
|
|
@@ -45,11 +45,12 @@ export function ArtifactViewer({
|
|
|
45
45
|
href,
|
|
46
46
|
onRename,
|
|
47
47
|
onDelete,
|
|
48
|
+
deleteDescription,
|
|
48
49
|
headerStart,
|
|
49
50
|
actions,
|
|
50
51
|
className,
|
|
51
52
|
}: ArtifactViewerProps) {
|
|
52
|
-
const edit = useArtifactEditDialogs({ title: artifact.title, onRename, onDelete });
|
|
53
|
+
const edit = useArtifactEditDialogs({ title: artifact.title, onRename, onDelete, deleteDescription });
|
|
53
54
|
const extension = ARTIFACT_FORMAT_FILES[artifact.format].extension;
|
|
54
55
|
const actionClass = "h-8 min-w-8";
|
|
55
56
|
|