@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.0",
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({ open, onOpenChange, title, onConfirm, pending }: ArtifactDeleteDialogProps) {
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 &quot;{title}&quot;?</ConfirmDialog.Title>
63
- <ConfirmDialog.Description>This cannot be undone.</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