@ciridae/ui 1.0.1 → 1.0.3

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.
Files changed (141) hide show
  1. package/dist/app/auth.d.ts +10 -0
  2. package/dist/app/auth.js +60 -0
  3. package/dist/app/error-boundary.d.ts +18 -0
  4. package/dist/app/error-boundary.js +45 -0
  5. package/dist/app/feedback.d.ts +12 -0
  6. package/dist/app/feedback.js +128 -0
  7. package/dist/app/index.d.ts +8 -0
  8. package/dist/app/index.js +8 -0
  9. package/dist/app/request-errors.d.ts +63 -0
  10. package/dist/app/request-errors.js +172 -0
  11. package/dist/app/sentry.d.ts +18 -0
  12. package/dist/app/sentry.js +52 -0
  13. package/dist/app/telemetry.d.ts +7 -0
  14. package/dist/app/telemetry.js +28 -0
  15. package/dist/app/trail.d.ts +9 -0
  16. package/dist/app/trail.js +18 -0
  17. package/dist/chat/chat-query-keys.d.ts +3 -3
  18. package/dist/chat/contract.d.ts +15 -15
  19. package/dist/chat/conversation-items-query-options.d.ts +114 -114
  20. package/dist/chat/conversation-source.d.ts +75 -0
  21. package/dist/chat/conversation-source.js +1 -0
  22. package/dist/chat/message-text.d.ts +1 -1
  23. package/dist/chat/message-text.js +114 -46
  24. package/dist/chat/use-conversation-list.d.ts +6 -6
  25. package/dist/components/activity-feed.d.ts +2 -2
  26. package/dist/components/agent-work.d.ts +3 -3
  27. package/dist/components/app-frame.d.ts +79 -0
  28. package/dist/components/app-frame.js +92 -0
  29. package/dist/components/app-navigation.d.ts +3 -3
  30. package/dist/components/badge.d.ts +1 -1
  31. package/dist/components/brand-icons.d.ts +3 -3
  32. package/dist/components/bulk-action-bar.d.ts +1 -1
  33. package/dist/components/button.d.ts +4 -4
  34. package/dist/components/calendar.d.ts +1 -1
  35. package/dist/components/centered-page.d.ts +1 -1
  36. package/dist/components/chart.d.ts +22 -2
  37. package/dist/components/chart.js +239 -44
  38. package/dist/components/chat-client-source.d.ts +16 -0
  39. package/dist/components/chat-client-source.js +256 -0
  40. package/dist/components/chat-page.d.ts +9 -8
  41. package/dist/components/chat-page.js +7 -11
  42. package/dist/components/chat-sheet-controller.d.ts +10 -14
  43. package/dist/components/chat-sheet-controller.js +2 -3
  44. package/dist/components/chat-sheet.d.ts +10 -11
  45. package/dist/components/chat-sheet.js +135 -273
  46. package/dist/components/chat.d.ts +22 -8
  47. package/dist/components/chat.js +128 -33
  48. package/dist/components/checkbox-item.d.ts +1 -1
  49. package/dist/components/checkbox-list.d.ts +1 -1
  50. package/dist/components/chip.d.ts +1 -1
  51. package/dist/components/collapsible.d.ts +1 -1
  52. package/dist/components/color-theme.d.ts +1 -1
  53. package/dist/components/column-settings.d.ts +1 -1
  54. package/dist/components/command-menu.d.ts +1 -1
  55. package/dist/components/command-palette.d.ts +3 -3
  56. package/dist/components/command-palette.js +1 -2
  57. package/dist/components/copyable-id.d.ts +22 -5
  58. package/dist/components/copyable-id.js +46 -6
  59. package/dist/components/data-display.d.ts +4 -4
  60. package/dist/components/data-grid.d.ts +10 -10
  61. package/dist/components/date-range-picker.d.ts +1 -1
  62. package/dist/components/date-time.d.ts +1 -1
  63. package/dist/components/dialog-height-context.d.ts +1 -1
  64. package/dist/components/document-viewer.d.ts +2 -2
  65. package/dist/components/drawer.d.ts +6 -6
  66. package/dist/components/dropzone.d.ts +4 -4
  67. package/dist/components/editable-field.d.ts +2 -2
  68. package/dist/components/email-input.d.ts +1 -1
  69. package/dist/components/environment-frame.d.ts +1 -1
  70. package/dist/components/expandable-text.d.ts +1 -1
  71. package/dist/components/feedback-screenshot.d.ts +1 -1
  72. package/dist/components/feedback-sheet.d.ts +18 -3
  73. package/dist/components/feedback-sheet.js +216 -55
  74. package/dist/components/field-context.d.ts +1 -1
  75. package/dist/components/filter-bar.d.ts +3 -3
  76. package/dist/components/filter-bar.js +4 -1
  77. package/dist/components/form-controls.d.ts +4 -4
  78. package/dist/components/form-layout.d.ts +7 -7
  79. package/dist/components/hotkeys.d.ts +2 -2
  80. package/dist/components/icon.d.ts +2 -2
  81. package/dist/components/input.d.ts +4 -4
  82. package/dist/components/input.js +3 -2
  83. package/dist/components/keyboard-shortcuts.d.ts +2 -2
  84. package/dist/components/keycap.d.ts +2 -2
  85. package/dist/components/layout.d.ts +15 -15
  86. package/dist/components/lightbox.d.ts +9 -3
  87. package/dist/components/lightbox.js +11 -8
  88. package/dist/components/link.d.ts +1 -1
  89. package/dist/components/locale.d.ts +32 -2
  90. package/dist/components/locale.js +25 -1
  91. package/dist/components/log-list.d.ts +3 -3
  92. package/dist/components/mention-input.d.ts +2 -2
  93. package/dist/components/menu.d.ts +2 -2
  94. package/dist/components/meter.d.ts +1 -1
  95. package/dist/components/navigation.d.ts +2 -2
  96. package/dist/components/notification-tray.d.ts +1 -1
  97. package/dist/components/overlays.d.ts +4 -4
  98. package/dist/components/page-frame.d.ts +4 -4
  99. package/dist/components/panel.d.ts +4 -4
  100. package/dist/components/profile-header.d.ts +1 -1
  101. package/dist/components/progress.d.ts +1 -1
  102. package/dist/components/project-avatar.d.ts +1 -1
  103. package/dist/components/radio-card.d.ts +2 -2
  104. package/dist/components/record.d.ts +4 -4
  105. package/dist/components/resolved-file-url.d.ts +19 -0
  106. package/dist/components/resolved-file-url.js +49 -0
  107. package/dist/components/scroll-area.d.ts +1 -1
  108. package/dist/components/secret-dialog.d.ts +1 -1
  109. package/dist/components/segmented-bar.d.ts +1 -1
  110. package/dist/components/select.d.ts +4 -4
  111. package/dist/components/settings.d.ts +4 -4
  112. package/dist/components/shell-skeleton.d.ts +1 -1
  113. package/dist/components/shell.d.ts +19 -19
  114. package/dist/components/shell.js +3 -1
  115. package/dist/components/side-panel.d.ts +3 -3
  116. package/dist/components/sidebar.d.ts +6 -6
  117. package/dist/components/site-banner.d.ts +2 -2
  118. package/dist/components/skeleton.d.ts +1 -1
  119. package/dist/components/skeletons.d.ts +5 -5
  120. package/dist/components/stages.d.ts +5 -5
  121. package/dist/components/stat-card.d.ts +3 -3
  122. package/dist/components/status-banner.d.ts +1 -1
  123. package/dist/components/status.d.ts +2 -2
  124. package/dist/components/steps.d.ts +1 -1
  125. package/dist/components/switch.d.ts +1 -1
  126. package/dist/components/tabs.d.ts +8 -8
  127. package/dist/components/theme-customizer.d.ts +2 -2
  128. package/dist/components/toast.d.ts +1 -1
  129. package/dist/components/use-new-version-available.d.ts +6 -0
  130. package/dist/components/use-new-version-available.js +29 -0
  131. package/dist/components/user-chip.d.ts +3 -3
  132. package/dist/components/wizard.d.ts +2 -2
  133. package/dist/feedback/contract.d.ts +136 -136
  134. package/dist/feedback/feedback-controller.d.ts +6 -6
  135. package/dist/feedback/generated/zod.gen.d.ts +28 -28
  136. package/dist/feedback/operator-contract.d.ts +11 -11
  137. package/dist/feedback/operator-controller.d.ts +32 -13
  138. package/dist/feedback/operator-controller.js +44 -11
  139. package/dist/styled-system/styles.css +203 -59
  140. package/dist/theme/tokens.js +17 -8
  141. package/package.json +32 -3
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { ArrowClockwiseIcon, ArrowUpIcon } from "@phosphor-icons/react";
2
+ import { ArrowClockwiseIcon, ArrowDownIcon, ArrowUpIcon } from "@phosphor-icons/react";
3
3
  import { isSameDay, isToday, isYesterday } from "date-fns";
4
4
  import { Fragment, useEffect, useRef, useState, useSyncExternalStore, } from "react";
5
5
  import { css, cva, cx } from "#primitives/css";
@@ -11,6 +11,8 @@ import { icon, Spinner } from "./icon.js";
11
11
  import { Lightbox } from "./lightbox.js";
12
12
  import { useCiridaeLocale } from "./locale.js";
13
13
  import { MentionInput } from "./mention-input.js";
14
+ import { useResolvedFileUrl } from "./resolved-file-url.js";
15
+ export { MessageText, splitSources, } from "../chat/message-text.js";
14
16
  /*
15
17
  * Two composers share one behaviour: `page` is the wide card of a chat page, and `sheet` the
16
18
  * composer at the foot of the agent sheet, its parts side by side as a messaging app's: the tools
@@ -192,6 +194,9 @@ const thread = css({
192
194
  flexDirection: "column",
193
195
  gap: "layout.tightGap",
194
196
  padding: "panel.default",
197
+ // The thread follows its newest entry itself: the browser's scroll anchoring would hold the
198
+ // view on what was there as a reply lands and pull it off the foot.
199
+ overflowAnchor: "none",
195
200
  "&[data-density=compact]": {
196
201
  paddingBlock: "layout.controlGap",
197
202
  "& > [data-group-position=single], & > [data-group-position=first]": {
@@ -199,6 +204,24 @@ const thread = css({
199
204
  },
200
205
  },
201
206
  });
207
+ /*
208
+ * Under the thread, held at the foot of the scrolling area while the reader is away from the
209
+ * newest entry: the jump back to it. Takes no height, so showing it moves nothing.
210
+ */
211
+ const latestSlot = css({
212
+ position: "sticky",
213
+ bottom: "layout.controlGap",
214
+ zIndex: "1",
215
+ display: "flex",
216
+ alignItems: "flex-end",
217
+ justifyContent: "center",
218
+ height: "0",
219
+ marginTop: "calc(token(spacing.layout.tightGap) * -1)",
220
+ pointerEvents: "none",
221
+ "& > *": { pointerEvents: "auto", boxShadow: "card" },
222
+ });
223
+ /** How close to the bottom the reader must be for new content to keep the thread at its foot. */
224
+ const followDistancePx = 96;
202
225
  /* A reply's sources under its bubble: small links in a row. */
203
226
  const sourceRow = css({
204
227
  display: "flex",
@@ -338,7 +361,7 @@ const typingDots = css({
338
361
  "& > span:nth-child(2)": { animationDelay: "0.2s" },
339
362
  "& > span:nth-child(3)": { animationDelay: "0.4s" },
340
363
  });
341
- export function ChatComposer({ value, defaultValue = "", onValueChange, onSend, placeholder, ariaLabel: ownAriaLabel, tools, actions, submitLabel: ownSubmitLabel, sendDisabled = false, sendsWithoutText = false, attachments, variant = "page", autoFocus, mentions, mentionMark, mentionsLabel, inputProps, className, ...props }) {
364
+ export function ChatComposer({ value, defaultValue = "", onValueChange, onSend, placeholder, ariaLabel: ownAriaLabel, tools, actions, submitLabel: ownSubmitLabel, sendDisabled = false, sendsWithoutText = false, attachments, onPasteFiles, variant = "page", autoFocus, mentions, mentionMark, mentionsLabel, inputProps, className, ...props }) {
342
365
  const { labels } = useCiridaeLocale();
343
366
  const ariaLabel = ownAriaLabel ?? labels.chat.message;
344
367
  const submitLabel = ownSubmitLabel ?? labels.chat.sendMessage;
@@ -357,14 +380,27 @@ export function ChatComposer({ value, defaultValue = "", onValueChange, onSend,
357
380
  setValue("");
358
381
  };
359
382
  const sheet = variant !== "page";
383
+ // In the capture phase, ahead of the text field and of an enclosing `Dropzone`, which would
384
+ // take the same files again.
385
+ const pasteFiles = onPasteFiles
386
+ ? (event) => {
387
+ const { files, types } = event.clipboardData;
388
+ // Rich text comes with a picture of itself, as office apps copy it: that stays text.
389
+ if (files.length === 0 || types.includes("text/html"))
390
+ return;
391
+ event.preventDefault();
392
+ event.stopPropagation();
393
+ onPasteFiles(Array.from(files));
394
+ }
395
+ : undefined;
360
396
  const input = (_jsx(MentionInput, { ...inputProps, "aria-label": ariaLabel, autoFocus: autoFocus, className: cx(sheet ? sheetInput : pageInput, inputProps?.className), value: currentValue, onValueChange: setValue, triggers: mentions, mentionMark: mentionMark, listLabel: mentionsLabel, placeholder: placeholder, submitOn: variant === "feed" ? "mod+enter" : "enter", onSubmit: send }));
361
397
  // The sheet's send is quiet until there is something to send.
362
398
  const sendButton = (_jsx(IconButton, { "aria-label": submitLabel, disabled: !canSend, onClick: send, variant: sheet ? (canSend ? "primary" : "ghost") : "raised", children: _jsx(ArrowUpIcon, { className: icon({ size: "small" }), weight: "bold" }) }));
363
399
  const waiting = attachments ? _jsx("div", { "data-attachments": "", children: attachments }) : null;
364
400
  if (sheet) {
365
- return (_jsxs("div", { ...props, className: cx(sheetComposer, className), "data-ciridae-ui": "", children: [tools && _jsx("div", { className: sheetSide, children: tools }), _jsxs("div", { className: sheetColumn, children: [waiting, _jsxs("div", { className: sheetBox, children: [input, actions && _jsx("div", { "data-actions": "", children: actions })] })] }), _jsx("div", { className: sheetSide, children: sendButton })] }));
401
+ return (_jsxs("div", { ...props, className: cx(sheetComposer, className), "data-ciridae-ui": "", onPasteCapture: pasteFiles, children: [tools && _jsx("div", { className: sheetSide, children: tools }), _jsxs("div", { className: sheetColumn, children: [waiting, _jsxs("div", { className: sheetBox, children: [input, actions && _jsx("div", { "data-actions": "", children: actions })] })] }), _jsx("div", { className: sheetSide, children: sendButton })] }));
366
402
  }
367
- return (_jsxs("div", { ...props, className: cx(pageComposer, className), "data-ciridae-ui": "", children: [waiting, input, _jsxs("div", { className: composerFooter, children: [_jsx("div", { className: actionGroup, children: tools }), _jsxs("div", { className: actionGroup, children: [actions, sendButton] })] })] }));
403
+ return (_jsxs("div", { ...props, className: cx(pageComposer, className), "data-ciridae-ui": "", onPasteCapture: pasteFiles, children: [waiting, input, _jsxs("div", { className: composerFooter, children: [_jsx("div", { className: actionGroup, children: tools }), _jsxs("div", { className: actionGroup, children: [actions, sendButton] })] })] }));
368
404
  }
369
405
  /** A message bubble in the agent sheet. */
370
406
  export function ChatBubble({ side, groupPosition, className, ...props }) {
@@ -384,12 +420,13 @@ export function ChatAction({ className, ...props }) {
384
420
  /*
385
421
  * A conversation in time order. Close messages from one author read as a group: bubbles 4px
386
422
  * apart, groups 8px apart, the author's avatar beside the group's last bubble on the assistant's
387
- * side and the author and time once under it. The nearest scrolling ancestor, or the thread
388
- * itself, follows the newest entry.
423
+ * side and the author and time once under it. The nearest scrolling ancestor follows the newest
424
+ * entry while the reader is at its foot; scrolled up, reading back, a jump to the newest shows
425
+ * instead. A message the user sends always brings the thread to its foot.
389
426
  */
390
- export function ChatThread({ entries, assistant, renderCustom, formatTime, density = "comfortable", attachmentTiles = false, dayLabels = false, className, }) {
427
+ export function ChatThread({ entries, assistant, renderCustom, formatTime, density = "comfortable", attachmentTiles = false, dayLabels = false, resolveAttachmentUrl, className, }) {
391
428
  const rootRef = useRef(null);
392
- const { formatDateTime } = useCiridaeLocale();
429
+ const { formatDateTime, labels } = useCiridaeLocale();
393
430
  const authorOf = (entry) => entry.kind === "line" || entrySide(entry) === "user"
394
431
  ? undefined
395
432
  : ((entry.kind === "message" ? entry.author : undefined) ?? assistant);
@@ -398,20 +435,16 @@ export function ChatThread({ entries, assistant, renderCustom, formatTime, densi
398
435
  at: entry.at,
399
436
  author: authorOf(entry)?.name,
400
437
  })));
401
- // Follows the newest entry.
402
- const newestEntry = entries[entries.length - 1];
403
- useEffect(() => {
404
- const root = rootRef.current;
405
- const scroller = root && findScrollContainer(root);
406
- if (scroller)
407
- scroller.scrollTop = scroller.scrollHeight;
408
- }, [newestEntry?.id, entries.length]);
409
- return (_jsx("div", { ref: rootRef, className: cx(thread, className), "data-ciridae-ui": "", "data-density": density === "compact" ? "compact" : undefined, children: entries.map((entry, index) => {
410
- const previous = entries[index - 1];
411
- const newDay = dayLabels && (!previous || !isSameDay(previous.at, entry.at));
412
- const content = renderEntry(entry, index);
413
- return newDay ? (_jsxs(Fragment, { children: [_jsx(DayLabel, { at: entry.at }), content] }, entry.id)) : (content);
414
- }) }));
438
+ const newestUserMessage = [...entries]
439
+ .reverse()
440
+ .find((entry) => entry.kind === "message" && entry.side === "user");
441
+ const latest = useFollowLatest(rootRef, newestUserMessage?.id);
442
+ return (_jsxs("div", { ref: rootRef, className: cx(thread, className), "data-ciridae-ui": "", "data-density": density === "compact" ? "compact" : undefined, children: [entries.map((entry, index) => {
443
+ const previous = entries[index - 1];
444
+ const newDay = dayLabels && (!previous || !isSameDay(previous.at, entry.at));
445
+ const content = renderEntry(entry, index);
446
+ return newDay ? (_jsxs(Fragment, { children: [_jsx(DayLabel, { at: entry.at }), content] }, entry.id)) : (content);
447
+ }), _jsx("div", { className: latestSlot, children: latest.away && (_jsx(IconButton, { "aria-label": labels.chat.scrollToLatest, size: "compact", variant: "raised", onClick: latest.scrollToLatest, children: _jsx(ArrowDownIcon, { className: icon({ size: "small" }) }) })) })] }));
415
448
  function renderEntry(entry, index) {
416
449
  if (entry.kind === "line") {
417
450
  return (_jsx(ChatSystemLine, { tone: entry.tone, children: entry.text }, entry.id));
@@ -424,7 +457,7 @@ export function ChatThread({ entries, assistant, renderCustom, formatTime, densi
424
457
  const tiles = attachmentTiles && message?.attachments && message.attachments.length > 0
425
458
  ? message.attachments
426
459
  : null;
427
- return (_jsxs("div", { className: entryBlock, "data-side": side, "data-group-position": position, children: [tiles && _jsx(AttachmentTiles, { attachments: tiles }), !(tiles && message?.body === "") && (_jsxs("div", { className: entryRow, title: message ? formatDateTime(entry.at) : undefined, children: [side === "assistant" && (_jsx("span", { className: avatarSlot, children: closesGroup && author && (_jsx(Avatar, { kind: author.kind, src: author.src, label: author.name, size: "small", "aria-hidden": "true" })) })), _jsx(ThreadEntryContent, { entry: entry, side: side, groupPosition: position, renderCustom: renderCustom, attachmentTiles: attachmentTiles }), message?.actions && !message.sending && (_jsx("span", { "data-entry-actions": "", children: message.actions }))] })), message?.sources && message.sources.length > 0 && (_jsx("span", { className: sourceRow, children: message.sources.map((source) => source.href ? (_jsx("a", { href: source.href, children: source.label }, source.id)) : (_jsx("span", { children: source.label }, source.id))) })), closesGroup && entry.kind !== "typing" && (_jsx("span", { className: entryFooter, children: message?.sending ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { "aria-hidden": "true", size: "compact" }), "Sending"] })) : (_jsxs("span", { children: [author && (_jsxs(_Fragment, { children: [author.label ?? author.name, " · "] })), _jsx(MessageTime, { at: entry.at, format: formatTime, dated: !dayLabels })] })) }))] }, entry.id));
460
+ return (_jsxs("div", { className: entryBlock, "data-side": side, "data-group-position": position, children: [tiles && _jsx(AttachmentTiles, { attachments: tiles, resolveUrl: resolveAttachmentUrl }), !(tiles && message?.body === "") && (_jsxs("div", { className: entryRow, title: message ? formatDateTime(entry.at) : undefined, children: [side === "assistant" && (_jsx("span", { className: avatarSlot, children: closesGroup && author && (_jsx(Avatar, { kind: author.kind, src: author.src, label: author.name, size: "small", "aria-hidden": "true" })) })), _jsx(ThreadEntryContent, { entry: entry, side: side, groupPosition: position, renderCustom: renderCustom, attachmentTiles: attachmentTiles }), message?.actions && !message.sending && (_jsx("span", { "data-entry-actions": "", children: message.actions }))] })), message?.sources && message.sources.length > 0 && (_jsx("span", { className: sourceRow, children: message.sources.map((source) => source.href ? (_jsx("a", { href: source.href, children: source.label }, source.id)) : (_jsx("span", { children: source.label }, source.id))) })), closesGroup && entry.kind !== "typing" && (_jsx("span", { className: entryFooter, children: message?.sending ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { "aria-hidden": "true", size: "compact" }), labels.chat.sending] })) : (_jsxs("span", { children: [author && (_jsxs(_Fragment, { children: [author.label ?? author.name, " · "] })), _jsx(MessageTime, { at: entry.at, format: formatTime, dated: !dayLabels })] })) }))] }, entry.id));
428
461
  }
429
462
  }
430
463
  /** A day's heading in a thread that runs over days: Today, Yesterday, or the date. */
@@ -440,17 +473,23 @@ function DayLabel({ at }) {
440
473
  export function ChatSuggestions({ suggestions, onSelect, className }) {
441
474
  return (_jsx("div", { className: cx(suggestionList, className), "data-ciridae-ui": "", children: suggestions.map((text) => (_jsx("button", { type: "button", className: suggestion, onClick: () => onSelect(text), children: text }, text))) }));
442
475
  }
443
- function AttachmentTiles({ attachments }) {
444
- const { labels } = useCiridaeLocale();
476
+ function AttachmentTiles({ attachments, resolveUrl, }) {
445
477
  const [open, setOpen] = useState(null);
446
- // The files the lightbox can show, in the message's order: those the service has a link for.
447
- const viewable = attachments.flatMap((attachment) => attachment.url ? [{ ...attachment, url: attachment.url }] : []);
478
+ // The files the lightbox can show, in the message's order: those with a link or a way to one.
479
+ const viewable = attachments.filter((attachment) => attachment.url || resolveUrl);
448
480
  return (_jsxs("span", { className: attachmentTiles, children: [attachments.map((attachment) => {
449
- const image = attachment.url && attachment.mediaType?.startsWith("image/");
450
- const content = image ? (_jsx("img", { src: attachment.url ?? undefined, alt: attachment.name })) : (_jsxs(_Fragment, { children: [fileTypeIcon({ name: attachment.name, type: attachment.mediaType ?? "" }), _jsx("span", { children: attachment.name })] }));
451
- const index = viewable.findIndex((item) => item.id === attachment.id);
452
- return index >= 0 ? (_jsx("button", { type: "button", className: fileSquare, "data-image": image || undefined, "aria-label": labels.lightbox.preview(attachment.name), title: attachment.name, onClick: () => setOpen(index), children: content }, attachment.id)) : (_jsx("span", { className: fileSquare, title: attachment.name, children: content }, attachment.id));
453
- }), _jsx(Lightbox, { items: viewable, index: open, onIndexChange: setOpen })] }));
481
+ const index = viewable.indexOf(attachment);
482
+ return (_jsx(AttachmentTile, { attachment: attachment, resolveUrl: resolveUrl, onOpen: index >= 0 ? () => setOpen(index) : undefined }, attachment.id));
483
+ }), _jsx(Lightbox, { items: viewable, index: open, onIndexChange: setOpen, resolveUrl: resolveUrl })] }));
484
+ }
485
+ /** An image's thumbnail, loaded through `resolveUrl` when it has no link, or the file's icon and name. */
486
+ function AttachmentTile({ attachment, resolveUrl, onOpen, }) {
487
+ const { labels } = useCiridaeLocale();
488
+ const imageType = attachment.mediaType?.startsWith("image/") ?? false;
489
+ const { url } = useResolvedFileUrl(attachment, resolveUrl, imageType);
490
+ const image = imageType && url !== null;
491
+ const content = image ? (_jsx("img", { src: url, alt: attachment.name })) : (_jsxs(_Fragment, { children: [fileTypeIcon({ name: attachment.name, type: attachment.mediaType ?? "" }), _jsx("span", { children: attachment.name })] }));
492
+ return onOpen ? (_jsx("button", { type: "button", className: fileSquare, "data-image": image || undefined, "aria-label": labels.lightbox.preview(attachment.name), title: attachment.name, onClick: onOpen, children: content })) : (_jsx("span", { className: fileSquare, "data-image": image || undefined, title: attachment.name, children: content }));
454
493
  }
455
494
  function ThreadEntryContent({ entry, side, groupPosition, renderCustom, attachmentTiles: tiles, }) {
456
495
  const { labels } = useCiridaeLocale();
@@ -460,7 +499,7 @@ function ThreadEntryContent({ entry, side, groupPosition, renderCustom, attachme
460
499
  case "typing":
461
500
  return (_jsxs(ChatBubble, { side: side, groupPosition: groupPosition, className: typingBubble, role: "status", "aria-label": labels.chat.typing, children: [entry.label, _jsx(ChatTypingDots, {})] }));
462
501
  case "failure":
463
- return (_jsxs(ChatBubble, { side: side, groupPosition: groupPosition, className: errorBubble, role: "alert", children: [entry.message, _jsx(Button, { variant: "ghost", icon: _jsx(ArrowClockwiseIcon, { className: icon({ size: "small" }) }), onClick: entry.onRetry, children: "Retry" })] }));
502
+ return (_jsxs(ChatBubble, { side: side, groupPosition: groupPosition, className: errorBubble, role: "alert", children: [entry.message, _jsx(Button, { variant: "ghost", icon: _jsx(ArrowClockwiseIcon, { className: icon({ size: "small" }) }), onClick: entry.onRetry, children: labels.common.retry })] }));
464
503
  case "custom":
465
504
  return renderCustom?.(entry.data);
466
505
  }
@@ -535,6 +574,62 @@ function MessageTime({ at, format: formatAt, dated, }) {
535
574
  : formatTime(at);
536
575
  return (_jsxs("time", { dateTime: new Date(at).toISOString(), className: messageTime, children: [_jsx("span", { "data-shown": "", children: text }), exact !== text && _jsx("span", { "data-exact": "", children: exact })] }));
537
576
  }
577
+ /**
578
+ * Keeps the nearest scrolling ancestor of `rootRef` at its foot while the reader is there, as
579
+ * entries land or images in them load; `away` while they have scrolled up from it. A new
580
+ * `sentMessageId`, the user's own message, brings it to the foot from anywhere.
581
+ */
582
+ function useFollowLatest(rootRef, sentMessageId) {
583
+ const [away, setAway] = useState(false);
584
+ const atFootRef = useRef(true);
585
+ const scrollerRef = useRef(null);
586
+ useEffect(() => {
587
+ const root = rootRef.current;
588
+ const scroller = root && findScrollContainer(root);
589
+ if (!root || !scroller)
590
+ return;
591
+ scrollerRef.current = scroller;
592
+ const toFoot = () => {
593
+ scroller.scrollTop = scroller.scrollHeight;
594
+ };
595
+ // Content that grew since the last look keeps a reader at the foot there, whichever of its
596
+ // resize or the scroll it caused is seen first; a reader's own scroll leaves the height.
597
+ let lastHeight = scroller.scrollHeight;
598
+ const follow = () => {
599
+ const grew = scroller.scrollHeight !== lastHeight;
600
+ lastHeight = scroller.scrollHeight;
601
+ if (grew && atFootRef.current)
602
+ return toFoot();
603
+ const distance = scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight;
604
+ atFootRef.current = distance < followDistancePx;
605
+ setAway(!atFootRef.current);
606
+ };
607
+ toFoot();
608
+ const resizes = new ResizeObserver(follow);
609
+ resizes.observe(root);
610
+ resizes.observe(scroller);
611
+ scroller.addEventListener("scroll", follow, { passive: true });
612
+ return () => {
613
+ resizes.disconnect();
614
+ scroller.removeEventListener("scroll", follow);
615
+ };
616
+ }, [rootRef]);
617
+ useEffect(() => {
618
+ const scroller = scrollerRef.current;
619
+ if (!scroller || sentMessageId === undefined)
620
+ return;
621
+ atFootRef.current = true;
622
+ scroller.scrollTop = scroller.scrollHeight;
623
+ }, [sentMessageId]);
624
+ return {
625
+ away,
626
+ scrollToLatest: () => {
627
+ const scroller = scrollerRef.current;
628
+ atFootRef.current = true;
629
+ scroller?.scrollTo({ top: scroller.scrollHeight, behavior: "smooth" });
630
+ },
631
+ };
632
+ }
538
633
  function findScrollContainer(element) {
539
634
  for (let node = element; node; node = node.parentElement) {
540
635
  const { overflowY } = getComputedStyle(node);
@@ -8,4 +8,4 @@ export type CheckboxItemProps = Omit<ComponentProps<typeof BaseCheckbox.Root>, "
8
8
  grip?: boolean;
9
9
  className?: string;
10
10
  };
11
- export declare function CheckboxItem({ children, meta, grip: showGrip, className, ...props }: CheckboxItemProps): import("@types/react").JSX.Element;
11
+ export declare function CheckboxItem({ children, meta, grip: showGrip, className, ...props }: CheckboxItemProps): import("react").JSX.Element;
@@ -48,4 +48,4 @@ export type CheckboxListProps = {
48
48
  * group. A long list can take a search, and bulk actions that touch only the items it leaves shown,
49
49
  * so nothing is ticked or cleared out of sight.
50
50
  */
51
- export declare function CheckboxList(props: CheckboxListProps): import("@types/react").JSX.Element;
51
+ export declare function CheckboxList(props: CheckboxListProps): import("react").JSX.Element;
@@ -14,4 +14,4 @@ export type ChipProps = Omit<ComponentProps<"span">, "children"> & {
14
14
  /** Compact recipients and inline tags; regular preserves the standalone chip. */
15
15
  size?: "regular" | "compact";
16
16
  };
17
- export declare function Chip({ children, icon, tone, onRemove, removeLabel, disabled, invalid, size, className, ...props }: ChipProps): import("@types/react").JSX.Element;
17
+ export declare function Chip({ children, icon, tone, onRemove, removeLabel, disabled, invalid, size, className, ...props }: ChipProps): import("react").JSX.Element;
@@ -5,4 +5,4 @@ export type CollapsibleProps = Omit<ComponentProps<typeof BaseCollapsible.Root>,
5
5
  label: ReactNode;
6
6
  children: ReactNode;
7
7
  };
8
- export declare function Collapsible({ label, children, ...rootProps }: CollapsibleProps): import("@types/react").JSX.Element;
8
+ export declare function Collapsible({ label, children, ...rootProps }: CollapsibleProps): import("react").JSX.Element;
@@ -33,7 +33,7 @@ export type ThemeProviderProps = {
33
33
  * `_light` values resolve through, so every component follows without
34
34
  * threading a prop.
35
35
  */
36
- export declare function ThemeProvider({ children, defaultColorTheme, storageKey, brand, palette, fonts, }: ThemeProviderProps): import("@types/react").JSX.Element;
36
+ export declare function ThemeProvider({ children, defaultColorTheme, storageKey, brand, palette, fonts, }: ThemeProviderProps): import("react").JSX.Element;
37
37
  /** Throws outside a `ThemeProvider`, where there is no theme to report or change. */
38
38
  export declare function useColorTheme(): ColorThemeContextValue;
39
39
  /** Throws outside a `ThemeProvider` given a `brand`, where there is no name to show. */
@@ -19,4 +19,4 @@ export declare function ColumnSettings<Row extends RowData>({ columns, columnVis
19
19
  open?: boolean;
20
20
  onOpenChange?: (open: boolean) => void;
21
21
  labels?: Partial<CiridaeLabels["table"]>;
22
- }): import("@types/react").JSX.Element;
22
+ }): import("react").JSX.Element;
@@ -40,4 +40,4 @@ export type CommandMenuProps = {
40
40
  /** Shown when no row matches, above any `unfiltered` row; the locale's "No results" by default. */
41
41
  empty?: ReactNode;
42
42
  };
43
- export declare function CommandMenu({ open, onOpenChange, query, onQueryChange, groups, title: ownTitle, placeholder: ownPlaceholder, empty: ownEmpty, }: CommandMenuProps): import("@types/react").JSX.Element;
43
+ export declare function CommandMenu({ open, onOpenChange, query, onQueryChange, groups, title: ownTitle, placeholder: ownPlaceholder, empty: ownEmpty, }: CommandMenuProps): import("react").JSX.Element;
@@ -24,13 +24,13 @@ export declare function useCommandPalette({ hotkey }?: {
24
24
  hotkey?: HotkeyChord;
25
25
  }): {
26
26
  open: boolean;
27
- setOpen: import("@types/react").Dispatch<import("@types/react").SetStateAction<boolean>>;
27
+ setOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
28
28
  toggle: () => void;
29
29
  };
30
- export declare function CommandPalette({ open, onOpenChange, groups, onQueryChange, footerItem, title, placeholder, empty, }: CommandPaletteProps): import("@types/react").JSX.Element;
30
+ export declare function CommandPalette({ open, onOpenChange, groups, onQueryChange, footerItem, title, placeholder, empty, }: CommandPaletteProps): import("react").JSX.Element;
31
31
  export type CommandPaletteTriggerProps = ComponentProps<"button"> & {
32
32
  /** The hotkey `useCommandPalette` opens it with, shown at the end; Cmd/Ctrl+K by default. */
33
33
  hotkey?: HotkeyChord;
34
34
  };
35
35
  /** A search field's face, as a button that opens the palette; reads "Search" unless given text. */
36
- export declare function CommandPaletteTrigger({ hotkey, className, children, ...props }: CommandPaletteTriggerProps): import("@types/react").JSX.Element;
36
+ export declare function CommandPaletteTrigger({ hotkey, className, children, ...props }: CommandPaletteTriggerProps): import("react").JSX.Element;
@@ -54,8 +54,7 @@ const trigger = css({
54
54
  alignItems: "center",
55
55
  gap: "control.iconGap",
56
56
  width: "100%",
57
- // The sidebar row's height, so it sits in the column as one of its items.
58
- height: "control.small",
57
+ height: "control.compact",
59
58
  paddingInlineStart: "control.compactInline",
60
59
  paddingInlineEnd: "control.iconGap",
61
60
  border: "1px solid token(colors.border.control)",
@@ -1,9 +1,11 @@
1
1
  import { type IconButtonProps } from "./button.js";
2
2
  /**
3
3
  * Copies `value` (or what it returns, read at the moment of copying) and reports `copied` for a
4
- * moment afterwards, for a check-mark confirmation.
4
+ * moment afterwards, for a check-mark confirmation. A copy the browser refuses, such as a denied
5
+ * permission or an insecure origin with no clipboard, goes to `onError`, or without one raises the
6
+ * kit's error toast, so a reader never pastes a stale clipboard thinking it holds the value.
5
7
  */
6
- export declare function useCopy(value: string | (() => string), onCopied?: () => void): {
8
+ export declare function useCopy(value: string | (() => string), onCopied?: () => void, onError?: (error: unknown) => void): {
7
9
  copied: boolean;
8
10
  copy: () => undefined;
9
11
  };
@@ -16,10 +18,12 @@ export type CopyButtonProps = {
16
18
  variant?: "raised" | "ghost" | "inline";
17
19
  size?: IconButtonProps["size"];
18
20
  onCopied?: () => void;
21
+ /** A refused copy; the kit's error toast without it. */
22
+ onError?: (error: unknown) => void;
19
23
  className?: string;
20
24
  };
21
25
  /** A button that copies `value`, its icon turning into a check once copied. */
22
- export declare function CopyButton({ value, label, variant, size, onCopied, className, }: CopyButtonProps): import("@types/react").JSX.Element;
26
+ export declare function CopyButton({ value, label, variant, size, onCopied, onError, className, }: CopyButtonProps): import("react").JSX.Element;
23
27
  /**
24
28
  * A long identifier, such as an error's trace ID, shown short and copied whole on click so a
25
29
  * reader can hand it to support.
@@ -28,10 +32,23 @@ export declare function CopyableId({ value, label, className, }: {
28
32
  value: string;
29
33
  label?: string;
30
34
  className?: string;
31
- }): import("@types/react").JSX.Element;
35
+ }): import("react").JSX.Element;
32
36
  /** Text shown in full with a copy control; `label` names what gets copied, such as a key's name. */
33
37
  export declare function CopyableText({ text, label, className, }: {
34
38
  text: string;
35
39
  label: string;
36
40
  className?: string;
37
- }): import("@types/react").JSX.Element;
41
+ }): import("react").JSX.Element;
42
+ /**
43
+ * A value to paste elsewhere, such as a command or a connection code, as a labelled read-only
44
+ * field with a copy button: it selects on focus and reads like the field it is pasted into. The
45
+ * row stays while there is no value yet, showing `placeholder`. The value is masked from session
46
+ * recorders, since such values are often credentials.
47
+ */
48
+ export declare function CopyField({ label, value, placeholder, className, }: {
49
+ label: string;
50
+ value: string | undefined;
51
+ /** What an absent value means, such as that it is not generated yet. */
52
+ placeholder?: string;
53
+ className?: string;
54
+ }): import("react").JSX.Element;
@@ -3,8 +3,11 @@ import { CheckIcon, CopyIcon } from "@phosphor-icons/react";
3
3
  import { useEffect, useRef, useState } from "react";
4
4
  import { css, cx } from "#primitives/css";
5
5
  import { IconButton } from "./button.js";
6
+ import { Field, FieldLabel } from "./form-layout.js";
6
7
  import { icon } from "./icon.js";
8
+ import { Input } from "./input.js";
7
9
  import { useCiridaeLocale } from "./locale.js";
10
+ import { useToast } from "./toast.js";
8
11
  const copyableId = css({
9
12
  display: "inline-flex",
10
13
  alignItems: "center",
@@ -23,20 +26,41 @@ const shownLength = 8;
23
26
  const copiedFeedbackMs = 1500;
24
27
  /**
25
28
  * Copies `value` (or what it returns, read at the moment of copying) and reports `copied` for a
26
- * moment afterwards, for a check-mark confirmation.
29
+ * moment afterwards, for a check-mark confirmation. A copy the browser refuses, such as a denied
30
+ * permission or an insecure origin with no clipboard, goes to `onError`, or without one raises the
31
+ * kit's error toast, so a reader never pastes a stale clipboard thinking it holds the value.
27
32
  */
28
- export function useCopy(value, onCopied) {
33
+ export function useCopy(value, onCopied, onError) {
29
34
  const [copied, setCopied] = useState(false);
35
+ const { labels } = useCiridaeLocale();
36
+ const toast = useToast();
30
37
  useEffect(() => {
31
38
  if (!copied)
32
39
  return;
33
40
  const timer = setTimeout(() => setCopied(false), copiedFeedbackMs);
34
41
  return () => clearTimeout(timer);
35
42
  }, [copied]);
36
- const copy = () => void navigator.clipboard.writeText(typeof value === "function" ? value() : value).then(() => {
43
+ // `await` rather than `.catch`: an insecure origin has no `navigator.clipboard` at all and
44
+ // throws before a promise exists.
45
+ const writeValue = async () => {
46
+ try {
47
+ await navigator.clipboard.writeText(typeof value === "function" ? value() : value);
48
+ }
49
+ catch (error) {
50
+ if (onError)
51
+ onError(error);
52
+ else
53
+ toast.add({
54
+ variant: "error",
55
+ title: labels.clipboard.copyFailed,
56
+ description: labels.clipboard.copyByHand,
57
+ });
58
+ return;
59
+ }
37
60
  setCopied(true);
38
61
  onCopied?.();
39
- });
62
+ };
63
+ const copy = () => void writeValue();
40
64
  return { copied, copy };
41
65
  }
42
66
  const inlineCopy = css({
@@ -51,8 +75,8 @@ const inlineCopy = css({
51
75
  _focusVisible: { focusRing: "outer", borderRadius: "control" },
52
76
  });
53
77
  /** A button that copies `value`, its icon turning into a check once copied. */
54
- export function CopyButton({ value, label, variant = "raised", size, onCopied, className, }) {
55
- const { copied, copy } = useCopy(value, onCopied);
78
+ export function CopyButton({ value, label, variant = "raised", size, onCopied, onError, className, }) {
79
+ const { copied, copy } = useCopy(value, onCopied, onError);
56
80
  const { labels } = useCiridaeLocale();
57
81
  const name = copied
58
82
  ? labels.common.copied
@@ -134,3 +158,19 @@ export function CopyableText({ text, label, className, }) {
134
158
  };
135
159
  return (_jsxs("span", { className: copyableText, "data-ciridae-ui": "", onMouseEnter: measureOverflow, children: [_jsx("span", { ref: box, className: cx(marqueeBox, className), title: text, children: _jsx("span", { children: text }) }), _jsx("button", { type: "button", className: copyTextButton, "aria-label": labels.common.copy(label), "data-copied": copied || undefined, onClick: copy, children: copied ? (_jsx(CheckIcon, { className: icon({ size: "small" }) })) : (_jsx(CopyIcon, { className: icon({ size: "small" }) })) })] }));
136
160
  }
161
+ const copyFieldRow = css({
162
+ display: "grid",
163
+ gridTemplateColumns: "minmax(0, 1fr) auto",
164
+ alignItems: "end",
165
+ gap: "layout.tightGap",
166
+ });
167
+ const copyFieldValue = css({ fontFamily: "mono", fontSize: "code" });
168
+ /**
169
+ * A value to paste elsewhere, such as a command or a connection code, as a labelled read-only
170
+ * field with a copy button: it selects on focus and reads like the field it is pasted into. The
171
+ * row stays while there is no value yet, showing `placeholder`. The value is masked from session
172
+ * recorders, since such values are often credentials.
173
+ */
174
+ export function CopyField({ label, value, placeholder, className, }) {
175
+ return (_jsxs("div", { className: cx(copyFieldRow, className), "data-ciridae-ui": "", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { children: label }), _jsx(Input, { className: cx("ph-no-capture", copyFieldValue), "data-sentry-mask": true, onFocus: (event) => event.target.select(), placeholder: placeholder, readOnly: true, value: value ?? "" })] }), value !== undefined && _jsx(CopyButton, { label: label, value: value, variant: "ghost" })] }));
176
+ }
@@ -19,12 +19,12 @@ export declare function Avatar({ label, src, size, kind, icon, badge, color, cla
19
19
  icon?: ReactNode;
20
20
  badge?: ReactNode;
21
21
  color?: AvatarColor;
22
- }): import("@types/react").JSX.Element;
22
+ }): import("react").JSX.Element;
23
23
  export declare function Divider({ inset, className, ...props }: Omit<ComponentProps<typeof BaseSeparator>, "className"> & {
24
24
  className?: string;
25
25
  /** `menu` insets it to a menu's or a popover's rows. */
26
26
  inset?: "none" | "menu";
27
- }): import("@types/react").JSX.Element;
27
+ }): import("react").JSX.Element;
28
28
  export type DescriptionRow = [label: string, value: ReactNode];
29
29
  /**
30
30
  * Label-value pairs in two columns. Rows whose value is `null` or `undefined` are left out, so
@@ -36,7 +36,7 @@ export declare function DescriptionList({ rows, density, loading, className, ...
36
36
  rows: DescriptionRow[];
37
37
  density?: "default" | "compact";
38
38
  loading?: boolean;
39
- }): import("@types/react").JSX.Element;
39
+ }): import("react").JSX.Element;
40
40
  /**
41
41
  * Scrollable block of literal text, such as a command or a generated file. `copy` adds a copy
42
42
  * button with that text, which can differ from what is shown (e.g. masked secrets).
@@ -44,4 +44,4 @@ export declare function DescriptionList({ rows, density, loading, className, ...
44
44
  export declare function CodeBlock({ className, copy, copyLabel, ...props }: ComponentProps<"pre"> & {
45
45
  copy?: string;
46
46
  copyLabel?: string;
47
- }): import("@types/react").JSX.Element;
47
+ }): import("react").JSX.Element;
@@ -38,10 +38,10 @@ export type TableColumnMeta = {
38
38
  hideOnNarrow?: boolean;
39
39
  };
40
40
  declare const tableFeatureSet: {
41
- rowSortingFeature: import("@tanstack/react-table/dist").TableFeature;
42
- columnVisibilityFeature: import("@tanstack/react-table/dist").TableFeature;
43
- columnOrderingFeature: import("@tanstack/react-table/dist").TableFeature;
44
- sortedRowModel: (table: import("@tanstack/react-table/dist").Table<any, any>) => () => import("@tanstack/react-table/dist").RowModel<any, any>;
41
+ rowSortingFeature: import("@tanstack/react-table").TableFeature;
42
+ columnVisibilityFeature: import("@tanstack/react-table").TableFeature;
43
+ columnOrderingFeature: import("@tanstack/react-table").TableFeature;
44
+ sortedRowModel: (table: import("@tanstack/react-table").Table<any, any>) => () => import("@tanstack/react-table").RowModel<any, any>;
45
45
  columnMeta: TableColumnMeta;
46
46
  };
47
47
  export type TableFeatureSet = typeof tableFeatureSet;
@@ -52,10 +52,10 @@ export type TableColumns<Row extends RowData> = ReturnType<ColumnHelper<TableFea
52
52
  * columns render without one. See `TableColumnMeta` for the per-column options.
53
53
  */
54
54
  export declare function createTableColumns<Row extends RowData>(): ColumnHelper<{
55
- rowSortingFeature: import("@tanstack/react-table/dist").TableFeature;
56
- columnVisibilityFeature: import("@tanstack/react-table/dist").TableFeature;
57
- columnOrderingFeature: import("@tanstack/react-table/dist").TableFeature;
58
- sortedRowModel: (table: import("@tanstack/react-table/dist").Table<any, any>) => () => import("@tanstack/react-table/dist").RowModel<any, any>;
55
+ rowSortingFeature: import("@tanstack/react-table").TableFeature;
56
+ columnVisibilityFeature: import("@tanstack/react-table").TableFeature;
57
+ columnOrderingFeature: import("@tanstack/react-table").TableFeature;
58
+ sortedRowModel: (table: import("@tanstack/react-table").Table<any, any>) => () => import("@tanstack/react-table").RowModel<any, any>;
59
59
  columnMeta: TableColumnMeta;
60
60
  }, Row>;
61
61
  /** A column's id and name as column settings list them. */
@@ -156,7 +156,7 @@ export type DataGridProps<Row extends RowData> = Omit<ComponentProps<"div">, "ch
156
156
  * hover-revealed row actions, groups, loading, empty and no-results states. `role="table"`; Enter
157
157
  * on a pressable row opens it.
158
158
  */
159
- export declare function DataGrid<Row extends RowData>({ data, columns, getRowId, variant, density, sorting: sortingProp, defaultSorting, onSortingChange, manualSorting, enableRowSelection, rowSelection: rowSelectionProp, defaultRowSelection, onRowSelectionChange, stickySelectColumn, columnVisibility: columnVisibilityProp, defaultColumnVisibility, onColumnVisibilityChange, columnOrder: columnOrderProp, defaultColumnOrder, onColumnOrderChange, headerMenu, filters, onFiltersChange, getRowHref, renderRowLink, onRowClick, activeRowId, keyboardNavigation, virtualize, rowActions, renderRowDetail, groupBy, renderGroupRow, loading, empty, noResults, filtered, hideHeader, fill, narrowScreenLayout, footer, labels: ownLabels, className, frameClassName, style, ...props }: DataGridProps<Row>): import("@types/react").JSX.Element;
159
+ export declare function DataGrid<Row extends RowData>({ data, columns, getRowId, variant, density, sorting: sortingProp, defaultSorting, onSortingChange, manualSorting, enableRowSelection, rowSelection: rowSelectionProp, defaultRowSelection, onRowSelectionChange, stickySelectColumn, columnVisibility: columnVisibilityProp, defaultColumnVisibility, onColumnVisibilityChange, columnOrder: columnOrderProp, defaultColumnOrder, onColumnOrderChange, headerMenu, filters, onFiltersChange, getRowHref, renderRowLink, onRowClick, activeRowId, keyboardNavigation, virtualize, rowActions, renderRowDetail, groupBy, renderGroupRow, loading, empty, noResults, filtered, hideHeader, fill, narrowScreenLayout, footer, labels: ownLabels, className, frameClassName, style, ...props }: DataGridProps<Row>): import("react").JSX.Element;
160
160
  export type TableProps<Row extends RowData> = Omit<DataGridProps<Row>, "defaultSorting" | "empty"> & {
161
161
  /** The sort the table starts with; `defaultSorting` on `DataGrid`. */
162
162
  initialSorting?: SortingState;
@@ -167,4 +167,4 @@ export type TableProps<Row extends RowData> = Omit<DataGridProps<Row>, "defaultS
167
167
  * `DataGrid` with the plain look: flush with its section, heads in caps, rows that light on hover
168
168
  * when they lead somewhere.
169
169
  */
170
- export declare function Table<Row extends RowData>({ variant, initialSorting, emptyMessage, ...props }: TableProps<Row>): import("@types/react").JSX.Element;
170
+ export declare function Table<Row extends RowData>({ variant, initialSorting, emptyMessage, ...props }: TableProps<Row>): import("react").JSX.Element;
@@ -41,4 +41,4 @@ export declare function DateRangePicker({ value: ownValue, defaultValue, onValue
41
41
  today?: Date;
42
42
  labels?: Partial<CiridaeLabels["dateRange"]>;
43
43
  className?: string;
44
- }): import("@types/react").JSX.Element;
44
+ }): import("react").JSX.Element;
@@ -8,4 +8,4 @@ import { type DateInput } from "./locale.js";
8
8
  export declare function DateTime({ value, mode, }: {
9
9
  value: DateInput | null;
10
10
  mode?: "auto" | "date" | "dateTime" | "relative";
11
- }): import("@types/react").JSX.Element | null;
11
+ }): import("react").JSX.Element | null;
@@ -1,2 +1,2 @@
1
1
  /** A Wizard starts a new height scope on each step; filtering within that step keeps its height. */
2
- export declare const DialogHeightResetContext: import("@types/react").Context<(() => void) | null>;
2
+ export declare const DialogHeightResetContext: import("react").Context<(() => void) | null>;
@@ -49,7 +49,7 @@ export type DocumentViewerProps = Omit<ComponentProps<"div">, "children"> & {
49
49
  actions?: ReactNode;
50
50
  labels?: Partial<CiridaeLabels["documentViewer"]>;
51
51
  };
52
- export declare function DocumentViewer({ pages, regions, activeRegionId: ownActiveRegionId, defaultActiveRegionId, onActiveRegionChange, pageId: ownPageId, defaultPageId, onPageChange, zoom: ownZoom, defaultZoom, onZoomChange, aside, actions, labels: ownLabels, className, ...props }: DocumentViewerProps): import("@types/react").JSX.Element;
52
+ export declare function DocumentViewer({ pages, regions, activeRegionId: ownActiveRegionId, defaultActiveRegionId, onActiveRegionChange, pageId: ownPageId, defaultPageId, onPageChange, zoom: ownZoom, defaultZoom, onZoomChange, aside, actions, labels: ownLabels, className, ...props }: DocumentViewerProps): import("react").JSX.Element;
53
53
  export type DocumentFieldProps = useRender.ComponentProps<"button"> & {
54
54
  /** The region this field was read from; selecting either marks the other. */
55
55
  regionId: string;
@@ -59,4 +59,4 @@ export type DocumentFieldProps = useRender.ComponentProps<"button"> & {
59
59
  * selected, marked while its region is hovered, and scrolled into view when its region is
60
60
  * selected on the page.
61
61
  */
62
- export declare function DocumentField({ regionId, render, className, onClick, onMouseEnter, onMouseLeave, ...props }: DocumentFieldProps): import("@types/react").ReactElement<unknown, string | import("@types/react").JSXElementConstructor<any>>;
62
+ export declare function DocumentField({ regionId, render, className, onClick, onMouseEnter, onMouseLeave, ...props }: DocumentFieldProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;