@ciridae/ui 1.0.2 → 1.0.4

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 (209) 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 +89 -0
  21. package/dist/chat/conversation-source.js +1 -0
  22. package/dist/chat/describe-tool-call.d.ts +3 -3
  23. package/dist/chat/describe-tool-call.js +3 -3
  24. package/dist/chat/message-text.d.ts +1 -1
  25. package/dist/chat/message-text.js +116 -48
  26. package/dist/chat/use-conversation-list.d.ts +6 -6
  27. package/dist/ciridae.css +16 -4
  28. package/dist/components/activity-feed.d.ts +3 -2
  29. package/dist/components/activity-feed.js +1 -0
  30. package/dist/components/agent-work.d.ts +3 -3
  31. package/dist/components/app-frame.d.ts +91 -0
  32. package/dist/components/app-frame.js +134 -0
  33. package/dist/components/app-navigation.d.ts +30 -3
  34. package/dist/components/app-navigation.js +105 -14
  35. package/dist/components/badge.d.ts +30 -5
  36. package/dist/components/badge.js +134 -15
  37. package/dist/components/brand-icons.d.ts +3 -3
  38. package/dist/components/bulk-action-bar.d.ts +1 -1
  39. package/dist/components/bulk-action-bar.js +3 -3
  40. package/dist/components/button.d.ts +12 -5
  41. package/dist/components/button.js +77 -44
  42. package/dist/components/calendar.d.ts +1 -1
  43. package/dist/components/calendar.js +44 -17
  44. package/dist/components/centered-page.d.ts +1 -1
  45. package/dist/components/centered-page.js +2 -2
  46. package/dist/components/chart.d.ts +22 -2
  47. package/dist/components/chart.js +251 -51
  48. package/dist/components/chat-client-source.d.ts +16 -0
  49. package/dist/components/chat-client-source.js +297 -0
  50. package/dist/components/chat-page.d.ts +9 -8
  51. package/dist/components/chat-page.js +7 -11
  52. package/dist/components/chat-sheet-controller.d.ts +11 -14
  53. package/dist/components/chat-sheet-controller.js +3 -3
  54. package/dist/components/chat-sheet.d.ts +18 -11
  55. package/dist/components/chat-sheet.js +188 -289
  56. package/dist/components/chat.d.ts +109 -19
  57. package/dist/components/chat.js +520 -124
  58. package/dist/components/checkbox-item.d.ts +6 -3
  59. package/dist/components/checkbox-item.js +9 -5
  60. package/dist/components/checkbox-list.d.ts +1 -1
  61. package/dist/components/chip.d.ts +6 -1
  62. package/dist/components/chip.js +27 -1
  63. package/dist/components/collapsible.d.ts +1 -1
  64. package/dist/components/color-theme.d.ts +1 -1
  65. package/dist/components/column-settings.d.ts +1 -1
  66. package/dist/components/column-settings.js +1 -1
  67. package/dist/components/command-menu.d.ts +5 -1
  68. package/dist/components/command-menu.js +98 -32
  69. package/dist/components/command-palette.d.ts +7 -3
  70. package/dist/components/command-palette.js +20 -11
  71. package/dist/components/copyable-id.d.ts +22 -5
  72. package/dist/components/copyable-id.js +46 -6
  73. package/dist/components/data-display.d.ts +39 -8
  74. package/dist/components/data-display.js +138 -19
  75. package/dist/components/data-grid.d.ts +23 -11
  76. package/dist/components/data-grid.js +61 -26
  77. package/dist/components/date-range-picker.d.ts +1 -1
  78. package/dist/components/date-range-picker.js +9 -20
  79. package/dist/components/date-time.d.ts +1 -1
  80. package/dist/components/dialog-height-context.d.ts +1 -1
  81. package/dist/components/document-viewer.d.ts +2 -2
  82. package/dist/components/drawer.d.ts +11 -6
  83. package/dist/components/drawer.js +91 -54
  84. package/dist/components/dropzone.d.ts +4 -4
  85. package/dist/components/editable-field.d.ts +12 -3
  86. package/dist/components/editable-field.js +57 -27
  87. package/dist/components/email-input.d.ts +1 -1
  88. package/dist/components/email-input.js +6 -5
  89. package/dist/components/environment-frame.d.ts +2 -2
  90. package/dist/components/environment-frame.js +37 -6
  91. package/dist/components/expandable-text.d.ts +1 -1
  92. package/dist/components/feedback-screenshot.d.ts +1 -1
  93. package/dist/components/feedback-sheet.d.ts +18 -3
  94. package/dist/components/feedback-sheet.js +216 -55
  95. package/dist/components/field-context.d.ts +1 -1
  96. package/dist/components/filter-bar.d.ts +3 -3
  97. package/dist/components/filter-bar.js +43 -29
  98. package/dist/components/form-controls.d.ts +12 -3
  99. package/dist/components/form-controls.js +46 -22
  100. package/dist/components/form-layout.d.ts +14 -10
  101. package/dist/components/form-layout.js +68 -23
  102. package/dist/components/glass-menu.d.ts +3 -0
  103. package/dist/components/glass-menu.js +63 -0
  104. package/dist/components/gradient-edge.d.ts +9 -0
  105. package/dist/components/gradient-edge.js +31 -0
  106. package/dist/components/hotkeys.d.ts +2 -2
  107. package/dist/components/icon.d.ts +1 -1
  108. package/dist/components/input.d.ts +7 -5
  109. package/dist/components/input.js +29 -17
  110. package/dist/components/keyboard-shortcuts.d.ts +2 -2
  111. package/dist/components/keycap.d.ts +10 -6
  112. package/dist/components/keycap.js +57 -19
  113. package/dist/components/layout.d.ts +13 -13
  114. package/dist/components/lightbox.d.ts +9 -3
  115. package/dist/components/lightbox.js +13 -9
  116. package/dist/components/link.d.ts +1 -1
  117. package/dist/components/locale.d.ts +42 -2
  118. package/dist/components/locale.js +43 -3
  119. package/dist/components/log-entry.d.ts +40 -0
  120. package/dist/components/log-entry.js +146 -0
  121. package/dist/components/log-list.d.ts +3 -3
  122. package/dist/components/mention-input.d.ts +2 -2
  123. package/dist/components/mention-input.js +4 -3
  124. package/dist/components/menu.d.ts +7 -3
  125. package/dist/components/menu.js +34 -37
  126. package/dist/components/meter.d.ts +10 -2
  127. package/dist/components/meter.js +64 -6
  128. package/dist/components/navigation.d.ts +21 -4
  129. package/dist/components/navigation.js +84 -19
  130. package/dist/components/notification-tray.d.ts +1 -1
  131. package/dist/components/notification-tray.js +5 -4
  132. package/dist/components/overlays.d.ts +6 -4
  133. package/dist/components/overlays.js +69 -40
  134. package/dist/components/page-frame.d.ts +4 -4
  135. package/dist/components/page-frame.js +1 -1
  136. package/dist/components/panel.d.ts +4 -4
  137. package/dist/components/panel.js +18 -12
  138. package/dist/components/profile-header.d.ts +1 -1
  139. package/dist/components/progress.d.ts +1 -1
  140. package/dist/components/project-avatar.d.ts +1 -1
  141. package/dist/components/radio-card.d.ts +2 -2
  142. package/dist/components/radio-card.js +10 -9
  143. package/dist/components/record.d.ts +29 -5
  144. package/dist/components/record.js +147 -18
  145. package/dist/components/resolved-file-url.d.ts +19 -0
  146. package/dist/components/resolved-file-url.js +49 -0
  147. package/dist/components/scroll-area.d.ts +1 -1
  148. package/dist/components/secret-dialog.d.ts +1 -1
  149. package/dist/components/segmented-bar.d.ts +4 -2
  150. package/dist/components/segmented-bar.js +16 -6
  151. package/dist/components/select.d.ts +9 -6
  152. package/dist/components/select.js +103 -127
  153. package/dist/components/settings.d.ts +4 -4
  154. package/dist/components/shell-skeleton.d.ts +1 -1
  155. package/dist/components/shell-skeleton.js +1 -1
  156. package/dist/components/shell.d.ts +21 -21
  157. package/dist/components/shell.js +43 -43
  158. package/dist/components/side-panel.d.ts +3 -3
  159. package/dist/components/sidebar.d.ts +13 -8
  160. package/dist/components/sidebar.js +55 -27
  161. package/dist/components/single-line-text.d.ts +2 -0
  162. package/dist/components/single-line-text.js +16 -0
  163. package/dist/components/site-banner.d.ts +5 -2
  164. package/dist/components/site-banner.js +17 -6
  165. package/dist/components/skeleton.d.ts +8 -7
  166. package/dist/components/skeleton.js +28 -16
  167. package/dist/components/skeletons.d.ts +17 -5
  168. package/dist/components/skeletons.js +71 -8
  169. package/dist/components/stages.d.ts +83 -11
  170. package/dist/components/stages.js +512 -156
  171. package/dist/components/stat-card.d.ts +12 -4
  172. package/dist/components/stat-card.js +92 -37
  173. package/dist/components/status-banner.d.ts +1 -1
  174. package/dist/components/status-banner.js +1 -1
  175. package/dist/components/status.d.ts +2 -2
  176. package/dist/components/steps.d.ts +1 -1
  177. package/dist/components/switch.d.ts +1 -1
  178. package/dist/components/tabs.d.ts +8 -8
  179. package/dist/components/tabs.js +26 -13
  180. package/dist/components/theme-customizer.d.ts +2 -2
  181. package/dist/components/theme-toggle.d.ts +4 -0
  182. package/dist/components/theme-toggle.js +67 -0
  183. package/dist/components/toast.d.ts +10 -3
  184. package/dist/components/toast.js +78 -29
  185. package/dist/components/use-new-version-available.d.ts +6 -0
  186. package/dist/components/use-new-version-available.js +29 -0
  187. package/dist/components/user-chip.d.ts +3 -3
  188. package/dist/components/wizard.d.ts +2 -2
  189. package/dist/feedback/contract.d.ts +136 -136
  190. package/dist/feedback/feedback-controller.d.ts +6 -6
  191. package/dist/feedback/generated/zod.gen.d.ts +28 -28
  192. package/dist/feedback/operator-contract.d.ts +11 -11
  193. package/dist/feedback/operator-controller.d.ts +32 -13
  194. package/dist/feedback/operator-controller.js +44 -11
  195. package/dist/preset.js +289 -33
  196. package/dist/styled-system/styles.css +3294 -1079
  197. package/dist/styled-system/tokens/index.mjs +598 -22
  198. package/dist/styled-system/tokens/tokens.d.ts +11 -11
  199. package/dist/styled-system/types/prop-type.d.ts +2 -2
  200. package/dist/styles.css +16 -4
  201. package/dist/theme/color.d.ts +3 -0
  202. package/dist/theme/color.js +5 -0
  203. package/dist/theme/derive.d.ts +9 -2
  204. package/dist/theme/derive.js +72 -12
  205. package/dist/theme/palettes.d.ts +49 -6
  206. package/dist/theme/palettes.js +84 -15
  207. package/dist/theme/tokens.d.ts +3 -3
  208. package/dist/theme/tokens.js +107 -32
  209. package/package.json +40 -3
@@ -1,18 +1,44 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { css, cx } from "#primitives/css";
2
+ import { css, cva, cx } from "#primitives/css";
3
3
  import { detectPlatform, formatForDisplay } from "./hotkeys.js";
4
- const keycap = css({
5
- display: "grid",
6
- placeItems: "center",
7
- width: "control.shortcut",
8
- height: "control.shortcut",
9
- border: "1px solid token(colors.border.glass)",
10
- borderRadius: "keycap",
11
- background: "bg.hover",
12
- color: "fg.muted",
13
- fontSize: "body",
14
- fontFamily: "sans",
15
- lineHeight: "tight",
4
+ /*
5
+ * A key on the raised face: a glyph such as ⌘ or ↵ sits in a 22px square, and a word such as Esc
6
+ * in a wider cap. The edge is the canvas hairline.
7
+ */
8
+ const keycap = cva({
9
+ base: {
10
+ display: "inline-grid",
11
+ placeItems: "center",
12
+ flexShrink: "0",
13
+ width: "control.chip",
14
+ height: "control.chip",
15
+ paddingInline: "none",
16
+ border: "1px solid token(colors.border.canvas)",
17
+ borderRadius: "keycap",
18
+ background: "token(gradients.raised)",
19
+ color: "fg.primary",
20
+ fontFamily: "sans",
21
+ fontSize: "code",
22
+ fontWeight: "medium",
23
+ letterSpacing: "compact",
24
+ lineHeight: "tight",
25
+ whiteSpace: "nowrap",
26
+ "& > svg": { fontSize: "icon.small" },
27
+ },
28
+ variants: {
29
+ // A longer word than Esc, such as Shift, still widens the cap rather than spilling out of it.
30
+ label: {
31
+ glyph: {},
32
+ word: { width: "auto", minWidth: "control.wordKeycap", paddingInline: "control.iconGap" },
33
+ },
34
+ },
35
+ });
36
+ const keycaps = css({
37
+ display: "inline-flex",
38
+ alignItems: "center",
39
+ gap: "control.trackInset",
40
+ flexShrink: "0",
41
+ _phone: { display: "none" },
16
42
  });
17
43
  // A quiet inline hint, as a menu writes its shortcuts: no box, no extra height, and none on a
18
44
  // phone, which has no keyboard to press it on.
@@ -31,15 +57,27 @@ const shortcut = css({
31
57
  });
32
58
  // "⌘K" on a Mac, as a menu writes it; "Ctrl+K" elsewhere.
33
59
  const separatorToken = detectPlatform() === "mac" ? "" : undefined;
34
- /** One key as a 24px cap, such as the `K` after a search field. */
35
- export function Keycap({ className, ...props }) {
36
- return _jsx("kbd", { ...props, className: cx(keycap, className), "data-ciridae-ui": "" });
60
+ // Between the keys of a boxed hint, split apart again so each takes its own cap.
61
+ const keySeparator = "\n";
62
+ /**
63
+ * One key as a 22px square cap, such as the `K` after a search field. A label of more than one
64
+ * character, such as `Esc`, takes the wider word cap on its own.
65
+ */
66
+ export function Keycap({ className, children, ...props }) {
67
+ const holdsWord = typeof children === "string" && Array.from(children).length > 1;
68
+ return (_jsx("kbd", { ...props, className: cx(keycap({ label: holdsWord ? "word" : "glyph" }), className), "data-ciridae-ui": "", children: children }));
37
69
  }
38
70
  /**
39
71
  * A hotkey as one quiet line, as the hotkeys layer writes it: `Mod` is "⌘" on a Mac and "Ctrl"
40
- * elsewhere, and a sequence's steps are spaced ("G I"). `Keycap` is the boxed key for a place
41
- * that wants it.
72
+ * elsewhere, and a sequence's steps are spaced ("G I"). `boxed` sets each key in its own
73
+ * `Keycap`, 2px apart, as a menu row or a search field shows it.
42
74
  */
43
- export function ShortcutHint({ hotkey, className, ...props }) {
75
+ export function ShortcutHint({ hotkey, boxed = false, className, ...props }) {
76
+ if (boxed) {
77
+ const keys = formatForDisplay(hotkey, { separatorToken: keySeparator })
78
+ .split(/[\n ]/)
79
+ .filter((key) => key !== "");
80
+ return (_jsx("kbd", { ...props, dir: "ltr", "aria-label": formatForDisplay(hotkey, { useSymbols: false }), className: cx(keycaps, className), "data-ciridae-ui": "", children: keys.map((key, index) => (_jsx(Keycap, { "aria-hidden": "true", children: key }, index))) }));
81
+ }
44
82
  return (_jsx("kbd", { ...props, dir: "ltr", "aria-label": formatForDisplay(hotkey, { useSymbols: false }), className: cx(shortcut, className), "data-ciridae-ui": "", children: formatForDisplay(hotkey, { separatorToken }) }));
45
83
  }
@@ -9,14 +9,14 @@ export type StackProps = useRender.ComponentProps<"div"> & {
9
9
  justify?: "start" | "center" | "end" | "between";
10
10
  };
11
11
  /** Children in a column. It never forces its parent wider than the parent's own box. */
12
- export declare function Stack({ gap, align, justify, render, className, ...props }: StackProps): import("@types/react").ReactElement<unknown, string | import("@types/react").JSXElementConstructor<any>>;
12
+ export declare function Stack({ gap, align, justify, render, className, ...props }: StackProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
13
13
  export type ClusterProps = useRender.ComponentProps<"div"> & {
14
14
  gap?: Gap;
15
15
  /** Wraps onto more lines when narrow; `false` keeps one line. Defaults to true. */
16
16
  wrap?: boolean;
17
17
  };
18
18
  /** Children in a row, centered on one line. */
19
- export declare function Cluster({ gap, wrap, render, className, ...props }: ClusterProps): import("@types/react").ReactElement<unknown, string | import("@types/react").JSXElementConstructor<any>>;
19
+ export declare function Cluster({ gap, wrap, render, className, ...props }: ClusterProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
20
20
  /**
21
21
  * The kit's text colors and sizes, for a run of text in a layout. `tone` and `size` inherit when
22
22
  * left out; `code` is the 12px label size, set compact. `MutedText` and `Eyebrow` are its two
@@ -76,11 +76,11 @@ export type TextProps = useRender.ComponentProps<"span"> & {
76
76
  /** The element to render; `render` takes any element instead. Defaults to `span`. */
77
77
  as?: "span" | "p" | "div" | "strong" | "small" | "label" | "time";
78
78
  };
79
- export declare function Text({ tone, size, weight, truncate, as, render, className, ...props }: TextProps): import("@types/react").ReactElement<unknown, string | import("@types/react").JSXElementConstructor<any>>;
79
+ export declare function Text({ tone, size, weight, truncate, as, render, className, ...props }: TextProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
80
80
  /** Muted caption text: a value's secondary line, or an empty value such as "Never". */
81
- export declare function MutedText(props: Omit<TextProps, "tone" | "size">): import("@types/react").JSX.Element;
81
+ export declare function MutedText(props: Omit<TextProps, "tone" | "size">): import("react").JSX.Element;
82
82
  /** The small muted label over a title or a field, such as a drawer's eyebrow or a group's name. */
83
- export declare function Eyebrow({ className, ...props }: Omit<TextProps, "size" | "weight">): import("@types/react").JSX.Element;
83
+ export declare function Eyebrow({ className, ...props }: Omit<TextProps, "size" | "weight">): import("react").JSX.Element;
84
84
  /**
85
85
  * The one heading style: `page` for the title a page's heading opens with; `large` for a title in
86
86
  * content, such as a standalone page's; `medium` for a section of a page or a dialog; `small` for
@@ -109,10 +109,10 @@ export type HeadingProps = ComponentProps<"h1"> & {
109
109
  level: 1 | 2 | 3 | 4;
110
110
  size?: "page" | "large" | "medium" | "small";
111
111
  };
112
- export declare function Heading({ level, size, className, ...props }: HeadingProps): import("@types/react").JSX.Element;
112
+ export declare function Heading({ level, size, className, ...props }: HeadingProps): import("react").JSX.Element;
113
113
  /** A bordered list whose items are divided by hairlines, such as a checklist of sources. */
114
- export declare function ListGroup({ className, ...props }: ComponentProps<"ul">): import("@types/react").JSX.Element;
115
- export declare function ListGroupItem({ className, ...props }: ComponentProps<"li">): import("@types/react").JSX.Element;
114
+ export declare function ListGroup({ className, ...props }: ComponentProps<"ul">): import("react").JSX.Element;
115
+ export declare function ListGroupItem({ className, ...props }: ComponentProps<"li">): import("react").JSX.Element;
116
116
  /** Whether a control sits in a `Toolbar`, which sets the height of the controls in it. */
117
117
  export declare function useInToolbar(): boolean;
118
118
  export type ToolbarProps = useRender.ComponentProps<"div"> & {
@@ -127,7 +127,7 @@ export type ToolbarProps = useRender.ComponentProps<"div"> & {
127
127
  * actions, wrapping onto more lines when narrow. Its controls share the small button's height: a
128
128
  * `SearchInput` or `SegmentedControl` in it is compact unless it sets its own size.
129
129
  */
130
- export declare function Toolbar({ gap, justify, stackOnPhone, render, className, ...props }: ToolbarProps): import("@types/react").JSX.Element;
130
+ export declare function Toolbar({ gap, justify, stackOnPhone, render, className, ...props }: ToolbarProps): import("react").JSX.Element;
131
131
  /**
132
132
  * A row's label with its muted detail line under it, or after it on the same line when `inline`.
133
133
  * `ListRow` draws one; use it alone where the label sits inside another control, such as a
@@ -137,7 +137,7 @@ export declare function ListRowText({ label, detail, inline, }: {
137
137
  label: ReactNode;
138
138
  detail?: ReactNode;
139
139
  inline?: boolean;
140
- }): import("@types/react").JSX.Element;
140
+ }): import("react").JSX.Element;
141
141
  /**
142
142
  * One row of a list: a leading mark or control, a label with an optional muted detail, and
143
143
  * trailing controls. `flush` drops the row's own height and inset for a table cell, keeping it to
@@ -159,9 +159,9 @@ export type ListRowProps = Omit<useRender.ComponentProps<"div">, "children"> & {
159
159
  */
160
160
  href?: string;
161
161
  };
162
- export declare function ListRow({ leading, label, detail, trailing, checkbox, flush, loading, href, render, className, ...props }: ListRowProps): import("@types/react").ReactElement<unknown, string | import("@types/react").JSXElementConstructor<any>>;
162
+ export declare function ListRow({ leading, label, detail, trailing, checkbox, flush, loading, href, render, className, ...props }: ListRowProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
163
163
  /** A responsive grid of ChoiceCards, shared by provider, role, and client pickers. */
164
- export declare function ChoiceGrid({ className, ...props }: ComponentProps<"div">): import("@types/react").JSX.Element;
164
+ export declare function ChoiceGrid({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
165
165
  /**
166
166
  * A card to pick one option from a grid, such as a provider or a role, laid out as a `ListRow`. Pass
167
167
  * `pressed` when it is one of several that stay chosen; leave it out for a card that acts as soon as
@@ -170,5 +170,5 @@ export declare function ChoiceGrid({ className, ...props }: ComponentProps<"div"
170
170
  export declare function ChoiceCard({ icon: leading, pressed, children, className, ...props }: Omit<ComponentProps<"button">, "type"> & {
171
171
  icon?: ReactNode;
172
172
  pressed?: boolean;
173
- }): import("@types/react").JSX.Element;
173
+ }): import("react").JSX.Element;
174
174
  export {};
@@ -1,8 +1,12 @@
1
- /** A file the lightbox shows: an image, a PDF, text or HTML by its `mediaType` or name. */
1
+ import { type ResolveFileUrl } from "./resolved-file-url.js";
2
+ /**
3
+ * A file the lightbox shows: an image, a PDF, text or HTML by its `mediaType` or name. Without a
4
+ * `url` it loads through the lightbox's `resolveUrl`.
5
+ */
2
6
  export type LightboxItem = {
3
7
  id: string;
4
8
  name: string;
5
- url: string;
9
+ url?: string | null;
6
10
  mediaType?: string;
7
11
  };
8
12
  export type LightboxProps = {
@@ -10,5 +14,7 @@ export type LightboxProps = {
10
14
  /** The file showing; null closes the lightbox. */
11
15
  index: number | null;
12
16
  onIndexChange: (index: number | null) => void;
17
+ /** Loads the link of a file with no `url`; see `ResolveFileUrl`. */
18
+ resolveUrl?: ResolveFileUrl<LightboxItem>;
13
19
  };
14
- export declare function Lightbox({ items, index, onIndexChange }: LightboxProps): import("@types/react").JSX.Element;
20
+ export declare function Lightbox({ items, index, onIndexChange, resolveUrl }: LightboxProps): import("react").JSX.Element;
@@ -1,8 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /*
3
3
  * A full-window viewer for files, such as a message's attachments: an image fits the window, a
4
4
  * PDF, text or HTML file shows in a frame, and anything else offers its download. With several
5
- * files it steps between them by its arrows or the arrow keys.
5
+ * files it steps between them by its arrows or the arrow keys. A file with no `url`, such as one
6
+ * served behind a bearer token, loads through `resolveUrl` when it shows.
6
7
  */
7
8
  import { Dialog as BaseDialog } from "@base-ui/react/dialog";
8
9
  import { ArrowSquareOutIcon, CaretLeftIcon, CaretRightIcon, DownloadSimpleIcon, XIcon, } from "@phosphor-icons/react";
@@ -10,8 +11,9 @@ import { css, cx } from "#primitives/css";
10
11
  import { Button, IconButton } from "./button.js";
11
12
  import { fileTypeIcon } from "./dropzone.js";
12
13
  import { HotkeyLayer } from "./hotkeys.js";
13
- import { directional, icon } from "./icon.js";
14
+ import { directional, icon, Spinner } from "./icon.js";
14
15
  import { useCiridaeLocale } from "./locale.js";
16
+ import { useResolvedFileUrl } from "./resolved-file-url.js";
15
17
  const popup = css({
16
18
  position: "fixed",
17
19
  inset: "none",
@@ -56,7 +58,8 @@ const stage = css({
56
58
  height: "100%",
57
59
  border: "0",
58
60
  borderRadius: "action",
59
- background: "bg.card",
61
+ // Solid, so a document with no background of its own does not show the scrim through it.
62
+ background: "bg.surface",
60
63
  },
61
64
  });
62
65
  const step = css({
@@ -86,7 +89,7 @@ function kindOf({ name, mediaType = "" }) {
86
89
  function isHtml({ name, mediaType }) {
87
90
  return mediaType === "text/html" || /\.html?$/i.test(name);
88
91
  }
89
- export function Lightbox({ items, index, onIndexChange }) {
92
+ export function Lightbox({ items, index, onIndexChange, resolveUrl }) {
90
93
  const item = index === null ? undefined : items[index];
91
94
  return (_jsx(BaseDialog.Root, { open: item !== undefined, onOpenChange: (open) => {
92
95
  if (!open)
@@ -103,15 +106,16 @@ export function Lightbox({ items, index, onIndexChange }) {
103
106
  event.preventDefault();
104
107
  const rtl = getComputedStyle(event.currentTarget).direction === "rtl";
105
108
  onIndexChange((index + (rtl ? -offset : offset) + items.length) % items.length);
106
- }, children: item && index !== null && (_jsx(HotkeyLayer, { children: _jsx(LightboxView, { items: items, index: index, item: item, onIndexChange: onIndexChange }) })) }) }) }));
109
+ }, children: item && index !== null && (_jsx(HotkeyLayer, { children: _jsx(LightboxView, { items: items, index: index, item: item, onIndexChange: onIndexChange, resolveUrl: resolveUrl }) })) }) }) }));
107
110
  }
108
- function LightboxView({ items, index, item, onIndexChange, }) {
111
+ function LightboxView({ items, index, item, onIndexChange, resolveUrl, }) {
109
112
  const { labels } = useCiridaeLocale();
110
113
  const several = items.length > 1;
111
114
  const go = (offset) => onIndexChange((index + offset + items.length) % items.length);
112
115
  const kind = kindOf(item);
113
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: bar, children: [_jsx(BaseDialog.Title, { className: title, children: item.name }), several && (_jsx("span", { className: position, children: labels.lightbox.position(index + 1, items.length) })), _jsx(IconButton, { "aria-label": labels.lightbox.openInNewTab, variant: "ghost", nativeButton: false, render: _jsx("a", { href: item.url, target: "_blank", rel: "noreferrer" }), children: _jsx(ArrowSquareOutIcon, { className: icon({ size: "small" }) }) }), _jsx(IconButton, { "aria-label": labels.lightbox.download, variant: "ghost", nativeButton: false, render: _jsx("a", { href: item.url, download: item.name }), children: _jsx(DownloadSimpleIcon, { className: icon({ size: "small" }) }) }), _jsx(BaseDialog.Close, { render: _jsx(IconButton, { "aria-label": labels.common.close, variant: "ghost" }), children: _jsx(XIcon, { className: icon({ size: "small" }) }) })] }), _jsxs("div", { className: stage, children: [kind === "image" ? (_jsx("img", { src: item.url, alt: item.name }, item.id)) : kind === "frame" ? (_jsx("iframe", { src: item.url, title: item.name,
116
+ const { url, state } = useResolvedFileUrl(item, resolveUrl);
117
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: bar, children: [_jsx(BaseDialog.Title, { className: title, children: item.name }), several && (_jsx("span", { className: position, children: labels.lightbox.position(index + 1, items.length) })), url && (_jsxs(_Fragment, { children: [_jsx(IconButton, { "aria-label": labels.lightbox.openInNewTab, variant: "ghost", nativeButton: false, render: _jsx("a", { href: url, target: "_blank", rel: "noreferrer" }), children: _jsx(ArrowSquareOutIcon, { className: icon({ size: "small" }) }) }), _jsx(IconButton, { "aria-label": labels.lightbox.download, variant: "ghost", nativeButton: false, render: _jsx("a", { href: url, download: item.name }), children: _jsx(DownloadSimpleIcon, { className: icon({ size: "small" }) }) })] })), _jsx(BaseDialog.Close, { render: _jsx(IconButton, { "aria-label": labels.common.close, variant: "ghost" }), children: _jsx(XIcon, { className: icon({ size: "small" }) }) })] }), _jsxs("div", { className: stage, children: [!url ? (state === "pending" ? (_jsx(Spinner, { label: labels.common.loading })) : (_jsx("div", { className: fallback, children: fileTypeIcon({ name: item.name, type: item.mediaType ?? "" }) }))) : kind === "image" ? (_jsx("img", { src: url, alt: item.name }, item.id)) : kind === "frame" ? (_jsx("iframe", { src: url, title: item.name,
114
118
  // A sent HTML file only draws: no scripts, no reach into the page. A PDF keeps the
115
119
  // browser's own viewer, which a sandbox would block.
116
- sandbox: isHtml(item) ? "" : undefined }, item.id)) : (_jsxs("div", { className: fallback, children: [fileTypeIcon({ name: item.name, type: item.mediaType ?? "" }), _jsx(Button, { nativeButton: false, render: _jsx("a", { href: item.url, download: item.name }), children: labels.lightbox.download })] })), several && (_jsxs(_Fragment, { children: [_jsx("span", { className: step, "data-step": "previous", children: _jsx(IconButton, { "aria-label": labels.lightbox.previous, onClick: () => go(-1), children: _jsx(CaretLeftIcon, { className: cx(icon({ size: "small" }), directional) }) }) }), _jsx("span", { className: step, "data-step": "next", children: _jsx(IconButton, { "aria-label": labels.lightbox.next, onClick: () => go(1), children: _jsx(CaretRightIcon, { className: cx(icon({ size: "small" }), directional) }) }) })] }))] })] }));
120
+ sandbox: isHtml(item) ? "" : undefined }, item.id)) : (_jsxs("div", { className: fallback, children: [fileTypeIcon({ name: item.name, type: item.mediaType ?? "" }), _jsx(Button, { nativeButton: false, render: _jsx("a", { href: url, download: item.name }), children: labels.lightbox.download })] })), several && (_jsxs(_Fragment, { children: [_jsx("span", { className: step, "data-step": "previous", children: _jsx(IconButton, { "aria-label": labels.lightbox.previous, onClick: () => go(-1), children: _jsx(CaretLeftIcon, { className: cx(icon({ size: "small" }), directional) }) }) }), _jsx("span", { className: step, "data-step": "next", children: _jsx(IconButton, { "aria-label": labels.lightbox.next, onClick: () => go(1), children: _jsx(CaretRightIcon, { className: cx(icon({ size: "small" }), directional) }) }) })] }))] })] }));
117
121
  }
@@ -10,4 +10,4 @@ export type LinkProps = ComponentProps<"a"> & {
10
10
  * One anchor style for the whole app. `external` carries the new-tab wiring so callers never
11
11
  * repeat `target`/`rel`, and a router link passes through `render`.
12
12
  */
13
- export declare function Link({ tone, external, render, className, children, ...props }: LinkProps): import("@types/react").JSX.Element;
13
+ export declare function Link({ tone, external, render, className, children, ...props }: LinkProps): import("react").JSX.Element;
@@ -49,6 +49,10 @@ export declare const englishLabels: {
49
49
  /** Between the items of a list, such as the actions one update line joins. */
50
50
  listSeparator: string;
51
51
  };
52
+ clipboard: {
53
+ copyFailed: string;
54
+ copyByHand: string;
55
+ };
52
56
  shell: {
53
57
  menu: string;
54
58
  breadcrumb: string;
@@ -59,6 +63,9 @@ export declare const englishLabels: {
59
63
  label: string;
60
64
  previous: string;
61
65
  next: string;
66
+ /** The rows a page shows and the page size, from numbers already formatted. */
67
+ summary: (first: string, last: string, total: string) => string;
68
+ perPage: (count: string) => string;
62
69
  };
63
70
  calendar: {
64
71
  previousMonth: string;
@@ -72,6 +79,9 @@ export declare const englishLabels: {
72
79
  };
73
80
  commandMenu: {
74
81
  title: string;
82
+ /** The footer's key hints beside the close key. */
83
+ move: string;
84
+ open: string;
75
85
  };
76
86
  keyboard: {
77
87
  shortcuts: string;
@@ -153,7 +163,7 @@ export declare const englishLabels: {
153
163
  sendTitle: string;
154
164
  sentTitle: string;
155
165
  newTab: string;
156
- sentTab: string;
166
+ ticketsTab: string;
157
167
  type: string;
158
168
  where: string;
159
169
  whatHappened: string;
@@ -201,6 +211,18 @@ export declare const englishLabels: {
201
211
  pointerNote: (index: number) => string;
202
212
  removePointer: (index: number) => string;
203
213
  };
214
+ /** The feedback sheet's Tickets tab, for the people who answer feedback. */
215
+ feedbackOperator: {
216
+ allTitle: string;
217
+ mine: string;
218
+ search: string;
219
+ status: string;
220
+ type: string;
221
+ reporter: string;
222
+ noneReceived: string;
223
+ noMatches: string;
224
+ statusFailed: string;
225
+ };
204
226
  lightbox: {
205
227
  previous: string;
206
228
  next: string;
@@ -214,6 +236,8 @@ export declare const englishLabels: {
214
236
  sendMessage: string;
215
237
  stopped: string;
216
238
  failed: string;
239
+ /** The title of a failed reply's notice. */
240
+ couldNotAnswer: string;
217
241
  notSent: string;
218
242
  typing: string;
219
243
  resize: string;
@@ -226,6 +250,8 @@ export declare const englishLabels: {
226
250
  answered: (answers: string) => string;
227
251
  allow: string;
228
252
  deny: string;
253
+ allowed: string;
254
+ denied: string;
229
255
  conversations: string;
230
256
  searchConversations: string;
231
257
  newChat: string;
@@ -233,6 +259,9 @@ export declare const englishLabels: {
233
259
  previousWeek: string;
234
260
  approve: string;
235
261
  waitingOnYou: string;
262
+ sending: string;
263
+ reading: string;
264
+ scrollToLatest: string;
236
265
  };
237
266
  projectCard: {
238
267
  default: string;
@@ -351,6 +380,8 @@ export declare const englishLabels: {
351
380
  runToGo: string;
352
381
  runDoneLabel: (count: number) => string;
353
382
  runToGoLabel: (count: number) => string;
383
+ /** The folded finished stages, with their count. */
384
+ runDoneShort: (count: number) => string;
354
385
  checklistProgress: (done: number, total: number) => string;
355
386
  };
356
387
  settings: {
@@ -379,6 +410,15 @@ export declare const englishLabels: {
379
410
  fullScreen: string;
380
411
  exitFullScreen: string;
381
412
  };
413
+ appFrame: {
414
+ status: string;
415
+ localBuild: string;
416
+ updateAvailable: string;
417
+ };
418
+ accountMenu: {
419
+ menu: string;
420
+ signOut: string;
421
+ };
382
422
  themeCustomizer: {
383
423
  palette: string;
384
424
  paletteName: (name: string) => string;
@@ -458,6 +498,6 @@ export type CiridaeLocaleProviderProps = {
458
498
  dir?: "ltr" | "rtl";
459
499
  children: ReactNode;
460
500
  };
461
- export declare function CiridaeLocaleProvider({ locale, labels, dir, children, }: CiridaeLocaleProviderProps): import("@types/react").JSX.Element;
501
+ export declare function CiridaeLocaleProvider({ locale, labels, dir, children, }: CiridaeLocaleProviderProps): import("react").JSX.Element;
462
502
  /** The locale's labels and formatters; English for the browser's language outside a provider. */
463
503
  export declare function useCiridaeLocale(): CiridaeLocale;
@@ -43,13 +43,21 @@ export const englishLabels = {
43
43
  /** Between the items of a list, such as the actions one update line joins. */
44
44
  listSeparator: ", ",
45
45
  },
46
+ clipboard: { copyFailed: "Couldn't copy", copyByHand: "Select it and copy it by hand." },
46
47
  shell: {
47
48
  menu: "Menu",
48
49
  breadcrumb: "Breadcrumb",
49
50
  parentPages: "Parent pages",
50
51
  environment: (label) => `${label} environment`,
51
52
  },
52
- pagination: { label: "Pagination", previous: "Previous", next: "Next" },
53
+ pagination: {
54
+ label: "Pagination",
55
+ previous: "Previous",
56
+ next: "Next",
57
+ /** The rows a page shows and the page size, from numbers already formatted. */
58
+ summary: (first, last, total) => `Showing ${first} to ${last} of ${total}`,
59
+ perPage: (count) => `${count} per page`,
60
+ },
53
61
  calendar: { previousMonth: "Previous month", nextMonth: "Next month" },
54
62
  select: {
55
63
  placeholder: "Select…",
@@ -57,7 +65,12 @@ export const englishLabels = {
57
65
  searchLabel: "Search options",
58
66
  filters: "Filters",
59
67
  },
60
- commandMenu: { title: "Command menu" },
68
+ commandMenu: {
69
+ title: "Command menu",
70
+ /** The footer's key hints beside the close key. */
71
+ move: "Move",
72
+ open: "Open",
73
+ },
61
74
  keyboard: {
62
75
  shortcuts: "Keyboard shortcuts",
63
76
  /** The group of a shortcut registered without one. */
@@ -132,7 +145,7 @@ export const englishLabels = {
132
145
  sendTitle: "Send feedback",
133
146
  sentTitle: "Sent feedback",
134
147
  newTab: "New",
135
- sentTab: "Sent",
148
+ ticketsTab: "Tickets",
136
149
  type: "Type",
137
150
  where: "Where",
138
151
  whatHappened: "What happened?",
@@ -180,6 +193,18 @@ export const englishLabels = {
180
193
  pointerNote: (index) => `Pointer ${index} note`,
181
194
  removePointer: (index) => `Remove pointer ${index}`,
182
195
  },
196
+ /** The feedback sheet's Tickets tab, for the people who answer feedback. */
197
+ feedbackOperator: {
198
+ allTitle: "All feedback",
199
+ mine: "Mine",
200
+ search: "Search feedback",
201
+ status: "Status",
202
+ type: "Type",
203
+ reporter: "Reporter",
204
+ noneReceived: "No feedback yet",
205
+ noMatches: "No feedback matches",
206
+ statusFailed: "Couldn't change the status",
207
+ },
183
208
  lightbox: {
184
209
  previous: "Previous file",
185
210
  next: "Next file",
@@ -193,6 +218,8 @@ export const englishLabels = {
193
218
  sendMessage: "Send message",
194
219
  stopped: "Stopped",
195
220
  failed: "Failed",
221
+ /** The title of a failed reply's notice. */
222
+ couldNotAnswer: "Couldn't finish that answer",
196
223
  notSent: "Not sent",
197
224
  typing: "Typing",
198
225
  resize: "Resize",
@@ -205,6 +232,8 @@ export const englishLabels = {
205
232
  answered: (answers) => `Answered ${answers}`,
206
233
  allow: "Allow",
207
234
  deny: "Deny",
235
+ allowed: "Allowed",
236
+ denied: "Denied",
208
237
  conversations: "Conversations",
209
238
  searchConversations: "Search conversations",
210
239
  newChat: "New chat",
@@ -212,6 +241,9 @@ export const englishLabels = {
212
241
  previousWeek: "Previous 7 days",
213
242
  approve: "Approve",
214
243
  waitingOnYou: "Waiting on you",
244
+ sending: "Sending",
245
+ reading: "Reading",
246
+ scrollToLatest: "Scroll to latest",
215
247
  },
216
248
  projectCard: {
217
249
  default: "Default",
@@ -324,6 +356,8 @@ export const englishLabels = {
324
356
  runToGo: "To go",
325
357
  runDoneLabel: (count) => `${count} stages done`,
326
358
  runToGoLabel: (count) => `${count} stages to go`,
359
+ /** The folded finished stages, with their count. */
360
+ runDoneShort: (count) => `${count} done`,
327
361
  checklistProgress: (done, total) => `${done} of ${total}`,
328
362
  },
329
363
  settings: { navigation: "Settings" },
@@ -346,6 +380,8 @@ export const englishLabels = {
346
380
  fullScreen: "Full screen",
347
381
  exitFullScreen: "Exit full screen",
348
382
  },
383
+ appFrame: { status: "Status", localBuild: "local", updateAvailable: "Update available" },
384
+ accountMenu: { menu: "Account menu", signOut: "Sign out" },
349
385
  themeCustomizer: {
350
386
  palette: "Palette",
351
387
  paletteName: (name) => name.charAt(0).toUpperCase() + name.slice(1),
@@ -431,6 +467,10 @@ function mergeLabels(overrides) {
431
467
  documentViewer: { ...englishLabels.documentViewer, ...overrides.documentViewer },
432
468
  themeCustomizer: { ...englishLabels.themeCustomizer, ...overrides.themeCustomizer },
433
469
  profileHeader: { ...englishLabels.profileHeader, ...overrides.profileHeader },
470
+ feedbackOperator: { ...englishLabels.feedbackOperator, ...overrides.feedbackOperator },
471
+ clipboard: { ...englishLabels.clipboard, ...overrides.clipboard },
472
+ accountMenu: { ...englishLabels.accountMenu, ...overrides.accountMenu },
473
+ appFrame: { ...englishLabels.appFrame, ...overrides.appFrame },
434
474
  };
435
475
  }
436
476
  /** The locale value `useCiridaeLocale` returns, for use outside React or in tests. */
@@ -0,0 +1,40 @@
1
+ import type { ComponentProps, ReactNode } from "react";
2
+ export type LogEntryProps = Omit<ComponentProps<"div">, "children"> & {
3
+ /** When it happened, epoch milliseconds, written as the time of day. */
4
+ at: number;
5
+ /** Who did it: a person's avatar, or a system's or an agent's icon. */
6
+ actor: ReactNode;
7
+ /** What happened, such as "The agent drafted remittance advice for INV-4799". */
8
+ headline: ReactNode;
9
+ /** A line more about it, such as what it waits on. */
10
+ detail?: ReactNode;
11
+ /** At the end of the row, such as a badge naming whether a person, a model or an agent did it. */
12
+ badge?: ReactNode;
13
+ /** `comfortable` for a page's log, `compact` for one line per entry, `panel` in a drawer. */
14
+ density?: "comfortable" | "compact" | "panel";
15
+ selected?: boolean;
16
+ /** A hairline under the row, between it and the next. */
17
+ divider?: boolean;
18
+ /** Makes the row a button, such as one that opens the entry beside the log. */
19
+ onSelect?: () => void;
20
+ };
21
+ /** One thing that happened, as a row of a log. */
22
+ export declare function LogEntry({ at, actor, headline, detail, badge, density, selected, divider, onSelect, className, ...props }: LogEntryProps): import("react").JSX.Element;
23
+ export type LogGroupHeaderProps = Omit<ComponentProps<"div">, "children"> & {
24
+ /** What the group is, such as "Today". */
25
+ label: ReactNode;
26
+ /** Beside it, quieter, such as the date. */
27
+ meta?: ReactNode;
28
+ };
29
+ /** A log's heading over a group of its rows, such as a day's: "Today", then "Oct 6". */
30
+ export declare function LogGroupHeader({ label, meta, className, ...props }: LogGroupHeaderProps): import("react").JSX.Element;
31
+ export type LogActorProps = {
32
+ /** Who or what acted, read out in place of the mark. */
33
+ name: string;
34
+ /** A person's photo; their initials stand in without one. */
35
+ src?: string | null;
36
+ /** For an agent, a sync or a rule: its icon in place of a person's photo or initials. */
37
+ icon?: ReactNode;
38
+ };
39
+ /** Who did a log entry's thing, as the mark for its `actor`. */
40
+ export declare function LogActor({ name, src, icon }: LogActorProps): import("react").JSX.Element;