tempest-react-sdk 0.29.1 → 0.30.0

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 (61) hide show
  1. package/dist/components/Chat/Chat.cjs +2 -0
  2. package/dist/components/Chat/Chat.cjs.map +1 -0
  3. package/dist/components/Chat/Chat.js +126 -0
  4. package/dist/components/Chat/Chat.js.map +1 -0
  5. package/dist/components/Chat/Chat.module.cjs +2 -0
  6. package/dist/components/Chat/Chat.module.cjs.map +1 -0
  7. package/dist/components/Chat/Chat.module.js +32 -0
  8. package/dist/components/Chat/Chat.module.js.map +1 -0
  9. package/dist/components/Chat/ChatComposer.cjs +2 -0
  10. package/dist/components/Chat/ChatComposer.cjs.map +1 -0
  11. package/dist/components/Chat/ChatComposer.js +67 -0
  12. package/dist/components/Chat/ChatComposer.js.map +1 -0
  13. package/dist/components/Chat/chat-groups.cjs +2 -0
  14. package/dist/components/Chat/chat-groups.cjs.map +1 -0
  15. package/dist/components/Chat/chat-groups.js +89 -0
  16. package/dist/components/Chat/chat-groups.js.map +1 -0
  17. package/dist/components/Markdown/Markdown.cjs +2 -0
  18. package/dist/components/Markdown/Markdown.cjs.map +1 -0
  19. package/dist/components/Markdown/Markdown.js +124 -0
  20. package/dist/components/Markdown/Markdown.js.map +1 -0
  21. package/dist/components/Markdown/Markdown.module.cjs +2 -0
  22. package/dist/components/Markdown/Markdown.module.cjs.map +1 -0
  23. package/dist/components/Markdown/Markdown.module.js +23 -0
  24. package/dist/components/Markdown/Markdown.module.js.map +1 -0
  25. package/dist/components/Markdown/markdown-parse.cjs +7 -0
  26. package/dist/components/Markdown/markdown-parse.cjs.map +1 -0
  27. package/dist/components/Markdown/markdown-parse.js +269 -0
  28. package/dist/components/Markdown/markdown-parse.js.map +1 -0
  29. package/dist/components/Markdown/markdown-url.cjs +2 -0
  30. package/dist/components/Markdown/markdown-url.cjs.map +1 -0
  31. package/dist/components/Markdown/markdown-url.js +28 -0
  32. package/dist/components/Markdown/markdown-url.js.map +1 -0
  33. package/dist/components/Masonry/Masonry.cjs +2 -0
  34. package/dist/components/Masonry/Masonry.cjs.map +1 -0
  35. package/dist/components/Masonry/Masonry.js +70 -0
  36. package/dist/components/Masonry/Masonry.js.map +1 -0
  37. package/dist/components/Masonry/Masonry.module.cjs +2 -0
  38. package/dist/components/Masonry/Masonry.module.cjs.map +1 -0
  39. package/dist/components/Masonry/Masonry.module.js +10 -0
  40. package/dist/components/Masonry/Masonry.module.js.map +1 -0
  41. package/dist/components/Masonry/masonry-layout.cjs +2 -0
  42. package/dist/components/Masonry/masonry-layout.cjs.map +1 -0
  43. package/dist/components/Masonry/masonry-layout.js +20 -0
  44. package/dist/components/Masonry/masonry-layout.js.map +1 -0
  45. package/dist/components/Transfer/Transfer.cjs +2 -0
  46. package/dist/components/Transfer/Transfer.cjs.map +1 -0
  47. package/dist/components/Transfer/Transfer.js +163 -0
  48. package/dist/components/Transfer/Transfer.js.map +1 -0
  49. package/dist/components/Transfer/Transfer.module.cjs +2 -0
  50. package/dist/components/Transfer/Transfer.module.cjs.map +1 -0
  51. package/dist/components/Transfer/Transfer.module.js +19 -0
  52. package/dist/components/Transfer/Transfer.module.js.map +1 -0
  53. package/dist/components/Transfer/transfer-state.cjs +2 -0
  54. package/dist/components/Transfer/transfer-state.cjs.map +1 -0
  55. package/dist/components/Transfer/transfer-state.js +59 -0
  56. package/dist/components/Transfer/transfer-state.js.map +1 -0
  57. package/dist/styles.css +1 -1
  58. package/dist/tempest-react-sdk.cjs +1 -1
  59. package/dist/tempest-react-sdk.d.ts +493 -0
  60. package/dist/tempest-react-sdk.js +114 -105
  61. package/package.json +1 -1
@@ -359,6 +359,27 @@ export declare interface ApplyThemeOptions {
359
359
  target?: Document | ShadowRoot | HTMLElement;
360
360
  }
361
361
 
362
+ /**
363
+ * Apply a move and return the next value.
364
+ *
365
+ * Disabled rows are dropped here rather than at the call site, so no caller can
366
+ * move one by pressing the bulk button — the check has to live where the
367
+ * decision is made, not in each of the four places that trigger one.
368
+ *
369
+ * @param params.value - Current target ids.
370
+ * @param params.moving - Ids being moved.
371
+ * @param params.to - Destination pane.
372
+ * @param params.items - The catalogue, to look disabled rows up.
373
+ * @param params.order - Ids in catalogue order, so the result stays stable.
374
+ * @returns The next value, in catalogue order.
375
+ */
376
+ export declare function applyTransferMove({ value, moving, to, items, }: {
377
+ value: readonly string[];
378
+ moving: readonly string[];
379
+ to: TransferSide;
380
+ items: readonly TransferItem[];
381
+ }): string[];
382
+
362
383
  /**
363
384
  * Compose the Tempest app-wide providers in one place: error boundary →
364
385
  * TanStack Query → theme → i18n. Query and theme are on by default; i18n and
@@ -1095,6 +1116,177 @@ export declare const CEPInput: ForwardRefExoticComponent<Omit<InputProps, "value
1095
1116
  /** A `var(--tempest-chart-…)` reference, so the value follows the active theme. */
1096
1117
  export declare type ChartColorToken = string;
1097
1118
 
1119
+ /**
1120
+ * A message thread: grouped by author and by day, own messages on one side, with
1121
+ * delivery state, a typing indicator and an optional composer.
1122
+ *
1123
+ * Presentational and controlled, like the rest of the SDK: it takes a list and
1124
+ * emits intent (`onSend`, `onRetry`). Where messages come from — REST, the SDK's
1125
+ * `createWebSocket`, an SSE stream — and how an optimistic insert is done stay with
1126
+ * the app, because those differ per backend and a component that assumed one would
1127
+ * be wrong for most.
1128
+ *
1129
+ * It works as a comment thread too: that is the same component with
1130
+ * `currentUserId` set and no `typing`.
1131
+ *
1132
+ * @example
1133
+ * <Chat
1134
+ * messages={messages}
1135
+ * currentUserId={me.id}
1136
+ * typing={typingNames}
1137
+ * onSend={(text) => send({ text })}
1138
+ * onRetry={(message) => resend(message.id)}
1139
+ * />
1140
+ */
1141
+ export declare function Chat({ messages, currentUserId, onSend, onRetry, typing, renderAvatar, header, emptyState, groupWindowMs, locale, now, placeholder, composerActions, composerDisabled, onSendError, className, ...rest }: ChatProps): JSX.Element;
1142
+
1143
+ /**
1144
+ * The message field of a thread: a textarea that grows with its content, sends on
1145
+ * `Enter` and keeps `Shift+Enter` for a newline.
1146
+ *
1147
+ * Uncontrolled on purpose. A chat draft changes on every keystroke, and lifting
1148
+ * that into app state re-renders the whole thread per character — the one place
1149
+ * where "controlled by default" costs something visible. Apps that need the draft
1150
+ * (a persisted composer, a slash-command menu) read it from `onChange` or drive it
1151
+ * through the ref.
1152
+ *
1153
+ * @example
1154
+ * <ChatComposer onSend={(text) => api.post("/messages", { body: { text } })} />
1155
+ */
1156
+ export declare const ChatComposer: ForwardRefExoticComponent<ChatComposerProps & RefAttributes<ChatComposerHandle>>;
1157
+
1158
+ /** Imperative handle, so a thread can focus the field after retrying a message. */
1159
+ export declare interface ChatComposerHandle {
1160
+ focus: () => void;
1161
+ /** Replace the draft — used to put a failed message back in the field. */
1162
+ setValue: (text: string) => void;
1163
+ }
1164
+
1165
+ export declare interface ChatComposerProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, OverriddenDomProps_3> {
1166
+ /** Called with the trimmed text. The field clears only when this does not throw. */
1167
+ onSend: (text: string) => void | Promise<void>;
1168
+ /** Locale for the placeholder and the send label. Default `"pt-BR"`. */
1169
+ locale?: "pt-BR" | "en";
1170
+ /** Rendered to the left of the send button — an attach button, an emoji picker. */
1171
+ actions?: ReactNode;
1172
+ /** Largest height the field grows to, in lines. Default 6. */
1173
+ maxRows?: number;
1174
+ /** Send label. Defaults to the locale string. */
1175
+ sendLabel?: string;
1176
+ /**
1177
+ * Called when `onSend` rejects. The draft is kept either way.
1178
+ *
1179
+ * Without it the rejection is swallowed after the draft is preserved, because
1180
+ * the alternative is worse: re-throwing out of a DOM event handler surfaces as
1181
+ * an unhandled promise rejection — console noise for the developer, a hit in
1182
+ * whatever crash reporter the app runs, and nothing the user can act on. The
1183
+ * visible signal is the text still sitting in the field; wire this to a toast
1184
+ * to say why.
1185
+ */
1186
+ onError?: (error: unknown) => void;
1187
+ }
1188
+
1189
+ /** A date heading between runs. */
1190
+ export declare interface ChatDay {
1191
+ kind: "day";
1192
+ key: string;
1193
+ /** Midnight of that local day, epoch ms — the label is formatted by the view. */
1194
+ date: number;
1195
+ }
1196
+
1197
+ /** One entry in a thread. */
1198
+ export declare interface ChatMessage {
1199
+ /** Stable identity. Used as the React key and by `onRetry`. */
1200
+ id: string;
1201
+ /** What was said. A node, so an app can render a link, an image or a quote. */
1202
+ body: ReactNode;
1203
+ /** Who said it. Compared against `currentUserId` to decide sides. */
1204
+ authorId: string;
1205
+ /** Display name. Falls back to `authorId` in the header of a run. */
1206
+ authorName?: string;
1207
+ /** Epoch milliseconds. */
1208
+ sentAt: number;
1209
+ /**
1210
+ * Delivery state of an outgoing message.
1211
+ *
1212
+ * `"failed"` is the one that matters: without it an app has to invent its own
1213
+ * way to say "this never left", and the user re-types a message that is
1214
+ * sitting right there.
1215
+ */
1216
+ status?: "sending" | "sent" | "read" | "failed";
1217
+ /** Anything the app wants to carry through to its own renderers. */
1218
+ data?: Record<string, unknown>;
1219
+ }
1220
+
1221
+ export declare interface ChatProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_2> {
1222
+ /** The thread, **oldest first**. Never reordered by the component. */
1223
+ messages: readonly ChatMessage[];
1224
+ /** Author id treated as "own" — decides side, colour and status ticks. */
1225
+ currentUserId?: string;
1226
+ /** Renders the composer when given. Receives the trimmed text. */
1227
+ onSend?: (text: string) => void | Promise<void>;
1228
+ /** Enables the retry control on a `"failed"` message. */
1229
+ onRetry?: (message: ChatMessage) => void;
1230
+ /** Names currently typing. One, two or a count is phrased for you. */
1231
+ typing?: readonly string[];
1232
+ /** Avatar for the first message of a run — an `<Avatar>`, an `<Icon>`. */
1233
+ renderAvatar?: (message: ChatMessage) => ReactNode;
1234
+ /** Rendered above the thread, inside the panel. */
1235
+ header?: ReactNode;
1236
+ /** Shown when there are no messages. */
1237
+ emptyState?: ReactNode;
1238
+ /** Gap that still keeps consecutive messages in one run. Default 5 min. */
1239
+ groupWindowMs?: number;
1240
+ /** Locale for labels. Default `"pt-BR"`. */
1241
+ locale?: "pt-BR" | "en";
1242
+ /** Reference instant for "Hoje"/"Ontem". Default: now, at render time. */
1243
+ now?: number;
1244
+ /** Placeholder for the composer. */
1245
+ placeholder?: string;
1246
+ /** Extra controls inside the composer, before the send button. */
1247
+ composerActions?: ReactNode;
1248
+ /** Disable the composer — no permission, thread archived, offline. */
1249
+ composerDisabled?: boolean;
1250
+ /** Called when `onSend` rejects. The draft stays in the field either way. */
1251
+ onSendError?: (error: unknown) => void;
1252
+ }
1253
+
1254
+ /** A run of consecutive messages from one author, under one day. */
1255
+ export declare interface ChatRun {
1256
+ kind: "run";
1257
+ /** `${authorId}-${first message id}` — stable across re-renders. */
1258
+ key: string;
1259
+ authorId: string;
1260
+ authorName?: string;
1261
+ /** Whether this run belongs to the current user. */
1262
+ own: boolean;
1263
+ messages: ChatMessage[];
1264
+ }
1265
+
1266
+ export declare type ChatSection = ChatDay | ChatRun;
1267
+
1268
+ /** Labels the thread needs, per locale. */
1269
+ declare interface ChatStrings {
1270
+ thread: string;
1271
+ today: string;
1272
+ yesterday: string;
1273
+ you: string;
1274
+ typingOne: (name: string) => string;
1275
+ typingTwo: (a: string, b: string) => string;
1276
+ typingMany: (n: number) => string;
1277
+ sending: string;
1278
+ sent: string;
1279
+ read: string;
1280
+ failed: string;
1281
+ retry: string;
1282
+ empty: string;
1283
+ placeholder: string;
1284
+ send: string;
1285
+ }
1286
+
1287
+ /** Locale strings for the thread. */
1288
+ export declare function chatStrings(locale: "pt-BR" | "en"): ChatStrings;
1289
+
1098
1290
  /**
1099
1291
  * Accessible checkbox. Supports a tri-state via `indeterminate` and pairs the
1100
1292
  * input with a label/description column for forms.
@@ -2526,6 +2718,17 @@ export declare interface DateRangePickerProps extends Omit<HTMLAttributes<HTMLDi
2526
2718
  weekStartsOn?: WeekStart_2;
2527
2719
  }
2528
2720
 
2721
+ /**
2722
+ * Label for a date heading: `"Hoje"`, `"Ontem"`, or the formatted date.
2723
+ *
2724
+ * @param date - Local midnight of the day being labelled.
2725
+ * @param params.now - Reference instant, so tests and SSR-free renders are stable.
2726
+ */
2727
+ export declare function dayLabel(date: number, { locale, now }?: {
2728
+ locale?: "pt-BR" | "en";
2729
+ now?: number;
2730
+ }): string;
2731
+
2529
2732
  /** The visible time window of a day, in minutes from midnight. */
2530
2733
  export declare interface DayWindow {
2531
2734
  startMinute: number;
@@ -3575,6 +3778,33 @@ export declare interface GridProps extends HTMLAttributes<HTMLDivElement> {
3575
3778
  */
3576
3779
  export declare function groupBy<T, K extends PropertyKey>(items: T[], key: (item: T) => K): Record<K, T[]>;
3577
3780
 
3781
+ /**
3782
+ * Turn a flat message list into the sections a thread renders: a date heading
3783
+ * whenever the local day changes, and runs of consecutive messages from the same
3784
+ * author.
3785
+ *
3786
+ * Grouping is what makes a thread readable — repeating the avatar and the name on
3787
+ * every line of a five-line burst turns a conversation into a list of receipts.
3788
+ * The run breaks on a different author, a different day, or a gap longer than
3789
+ * `windowMs`: a reply an hour later is a new beat in the conversation even when
3790
+ * nobody else spoke, and joining it to the earlier burst would put one timestamp
3791
+ * on messages an hour apart.
3792
+ *
3793
+ * Order is taken as given, oldest first, and never sorted here: a thread that
3794
+ * reorders what the server sent would fight optimistic inserts, where the
3795
+ * pending message is deliberately last.
3796
+ *
3797
+ * @param params.messages - Oldest first.
3798
+ * @param params.currentUserId - Author id treated as "own".
3799
+ * @param params.windowMs - Gap that still keeps a run together. Default 5 min.
3800
+ * @returns Sections in render order.
3801
+ */
3802
+ export declare function groupMessages({ messages, currentUserId, windowMs, }: {
3803
+ messages: readonly ChatMessage[];
3804
+ currentUserId?: string;
3805
+ windowMs?: number;
3806
+ }): ChatSection[];
3807
+
3578
3808
  /**
3579
3809
  * Minimal subset of [`@growthbook/growthbook`](https://docs.growthbook.io/lib/js)
3580
3810
  * used by the adapter. Pass a `GrowthBook` instance directly.
@@ -4611,6 +4841,138 @@ export declare interface LongPressHandlers {
4611
4841
  onContextMenu: (event: MouseEvent_2) => void;
4612
4842
  }
4613
4843
 
4844
+ /**
4845
+ * Rendered Markdown, from a node tree — never from an HTML string.
4846
+ *
4847
+ * `dangerouslySetInnerHTML` appears nowhere in this component. That is what makes
4848
+ * rendering somebody else's Markdown safe by construction rather than by a promise
4849
+ * about escaping: a `<script>` in a comment is four characters of text, because text
4850
+ * is all a React child can be.
4851
+ *
4852
+ * Link and image URLs go through a scheme **allowlist** (`http`, `https`, `mailto`,
4853
+ * `tel`, `sms`, plus relative), so `[click](javascript:alert(1))` renders as plain
4854
+ * text. A blocklist would have to enumerate every spelling of `javascript:` and
4855
+ * would miss one.
4856
+ *
4857
+ * @example
4858
+ * <Markdown source={comentario.corpo} linkProps={{ target: "_blank", rel: "noreferrer" }} />
4859
+ */
4860
+ export declare function Markdown({ source, headingOffset, highlightCode, showLineNumbers, linkProps, className, ...rest }: MarkdownProps): JSX.Element;
4861
+
4862
+ /** Column alignment of a table, from the delimiter row. */
4863
+ export declare type MarkdownAlign = "left" | "center" | "right" | null;
4864
+
4865
+ /** Block content. */
4866
+ export declare type MarkdownBlock = {
4867
+ type: "heading";
4868
+ level: number;
4869
+ children: MarkdownInline[];
4870
+ } | {
4871
+ type: "paragraph";
4872
+ children: MarkdownInline[];
4873
+ } | {
4874
+ type: "code";
4875
+ language: string | null;
4876
+ value: string;
4877
+ } | {
4878
+ type: "quote";
4879
+ children: MarkdownBlock[];
4880
+ } | {
4881
+ type: "list";
4882
+ ordered: boolean;
4883
+ start: number;
4884
+ items: MarkdownBlock[][];
4885
+ } | {
4886
+ type: "table";
4887
+ align: MarkdownAlign[];
4888
+ head: MarkdownInline[][];
4889
+ rows: MarkdownInline[][][];
4890
+ } | {
4891
+ type: "rule";
4892
+ };
4893
+
4894
+ /** Inline content. */
4895
+ export declare type MarkdownInline = {
4896
+ type: "text";
4897
+ value: string;
4898
+ } | {
4899
+ type: "strong";
4900
+ children: MarkdownInline[];
4901
+ } | {
4902
+ type: "em";
4903
+ children: MarkdownInline[];
4904
+ } | {
4905
+ type: "del";
4906
+ children: MarkdownInline[];
4907
+ } | {
4908
+ type: "code";
4909
+ value: string;
4910
+ } | {
4911
+ type: "link";
4912
+ href: string;
4913
+ children: MarkdownInline[];
4914
+ } | {
4915
+ type: "image";
4916
+ src: string;
4917
+ alt: string;
4918
+ } | {
4919
+ type: "break";
4920
+ };
4921
+
4922
+ export declare interface MarkdownProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_6> {
4923
+ /** The Markdown source. */
4924
+ source: string;
4925
+ /**
4926
+ * Heading level the document's `#` maps to. Default 2.
4927
+ *
4928
+ * A comment body rendered inside a page whose `<h1>` is the page title must not
4929
+ * emit a second `<h1>`; shifting the whole scale keeps the outline valid.
4930
+ */
4931
+ headingOffset?: number;
4932
+ /** Render fenced code with `CodeBlock` (copy button, line numbers). Default `true`. */
4933
+ highlightCode?: boolean;
4934
+ /** Show line numbers in fenced code. Default `false`. */
4935
+ showLineNumbers?: boolean;
4936
+ /** Extra props for every link — `target="_blank"`, an analytics handler. */
4937
+ linkProps?: HTMLAttributes<HTMLAnchorElement> & {
4938
+ target?: string;
4939
+ rel?: string;
4940
+ };
4941
+ }
4942
+
4943
+ /**
4944
+ * Masonry layout: cards of uneven height packed into columns with an even bottom
4945
+ * edge.
4946
+ *
4947
+ * Measures the rendered cards and deals each one into the shortest column, rather
4948
+ * than using CSS `columns` or `grid-auto-flow: dense`. Both of those are one line
4949
+ * of CSS and neither does this job: CSS `columns` breaks a card across the column
4950
+ * boundary, and a dense grid keeps every row the height of its tallest cell, which
4951
+ * is the ragged bottom edge people reach for masonry to avoid.
4952
+ *
4953
+ * @example
4954
+ * <Masonry items={fotos} itemKey={(foto) => foto.id} columns={{ 0: 1, 700: 2, 1100: 4 }}>
4955
+ * {(foto) => <img src={foto.url} alt={foto.alt} />}
4956
+ * </Masonry>
4957
+ */
4958
+ export declare function Masonry<T>({ items, children, itemKey, columns, gap, className, style, ...rest }: MasonryProps<T>): JSX.Element;
4959
+
4960
+ export declare interface MasonryProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_5> {
4961
+ /** What to lay out. */
4962
+ items: readonly T[];
4963
+ /** Render one card. */
4964
+ children: (item: T, index: number) => ReactNode;
4965
+ /** Stable key per item. Index is a fallback nobody should rely on. */
4966
+ itemKey?: (item: T, index: number) => string | number;
4967
+ /**
4968
+ * Column count: a fixed number, or a `width → columns` map read as
4969
+ * "from this width up". Default `{ 0: 1, 640: 2, 1024: 3 }`.
4970
+ */
4971
+ columns?: number | Record<number, number>;
4972
+ /** Gap between cards, any CSS length. Default `var(--tempest-space-4)`. */
4973
+ gap?: string;
4974
+ }
4975
+
4614
4976
  /**
4615
4977
  * The matrix as an SVG path, one `M…h…v…h…z` rectangle per dark module.
4616
4978
  *
@@ -5544,6 +5906,21 @@ export { Outlet }
5544
5906
  */
5545
5907
  declare type OverriddenDomProps = "children" | "title" | "onSelect";
5546
5908
 
5909
+ /** DOM attributes this component redefines. */
5910
+ declare type OverriddenDomProps_2 = "children" | "onSubmit";
5911
+
5912
+ /** DOM attributes the composer redefines. */
5913
+ declare type OverriddenDomProps_3 = "onSubmit" | "value" | "defaultValue" | "rows";
5914
+
5915
+ /** DOM attributes this component redefines. */
5916
+ declare type OverriddenDomProps_4 = "children" | "onChange" | "defaultValue";
5917
+
5918
+ /** DOM attributes this component redefines. */
5919
+ declare type OverriddenDomProps_5 = "children";
5920
+
5921
+ /** DOM attributes this component redefines. */
5922
+ declare type OverriddenDomProps_6 = "children";
5923
+
5547
5924
  /**
5548
5925
  * Page wrapper with header + (optional) toolbar + content + footer. Pairs
5549
5926
  * with `Container` when you want a max-width content well.
@@ -5597,6 +5974,14 @@ export { Params }
5597
5974
  /** Query-param values accepted by the API client for a list request. */
5598
5975
  declare type ParamValue = string | number | boolean | undefined | null;
5599
5976
 
5977
+ /**
5978
+ * Parse a Markdown document into blocks.
5979
+ *
5980
+ * @param source - Raw Markdown.
5981
+ * @returns Block nodes in document order.
5982
+ */
5983
+ export declare function parseMarkdown(source: string): MarkdownBlock[];
5984
+
5600
5985
  /**
5601
5986
  * Validate an unknown response payload against a zod schema.
5602
5987
  *
@@ -6645,6 +7030,28 @@ export declare interface SafeAreaProps extends HTMLAttributes<HTMLDivElement> {
6645
7030
  children?: ReactNode;
6646
7031
  }
6647
7032
 
7033
+ /**
7034
+ * URL vetting for links and images in rendered Markdown.
7035
+ *
7036
+ * This is the security boundary of the whole component. Markdown that arrives from
7037
+ * a user — a comment, a ticket description, a review — reaches the DOM as a real
7038
+ * `href`, and `javascript:alert(1)` in a link is script execution on click. So the
7039
+ * scheme is checked against an allowlist rather than a blocklist: a blocklist has
7040
+ * to enumerate `javascript:`, `JaVaScRiPt:`, `java\tscript:`, `&#106;avascript:`
7041
+ * and whatever comes next, and misses the one nobody thought of.
7042
+ */
7043
+ /**
7044
+ * The href to render, or `null` when the URL must not be linked.
7045
+ *
7046
+ * Relative URLs (`/docs`, `./x`, `#anchor`, `foo/bar`) are kept: they cannot carry
7047
+ * a scheme, so they cannot execute anything, and dropping them would break every
7048
+ * in-app link.
7049
+ *
7050
+ * @param raw - URL as written in the Markdown.
7051
+ * @returns A safe href, or `null`.
7052
+ */
7053
+ export declare function safeLinkUrl(raw: string): string | null;
7054
+
6648
7055
  /** The ten steps of a Tempest tint scale, lightest to darkest. */
6649
7056
  export declare type ScaleStep = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
6650
7057
 
@@ -7289,6 +7696,25 @@ export declare interface SpinnerProps {
7289
7696
 
7290
7697
  export declare type SpinnerSize = "xs" | "sm" | "md" | "lg" | "xl";
7291
7698
 
7699
+ /**
7700
+ * Split the catalogue into the two panes.
7701
+ *
7702
+ * The selected ids are the single source of truth — the panes are derived, never
7703
+ * stored. Two stored lists drift the moment the catalogue changes under them: a
7704
+ * permission that is removed upstream lingers in whichever pane held it, and an
7705
+ * id that appears in both is a bug nobody can see.
7706
+ *
7707
+ * Order follows `items`, so both panes read in the catalogue's order rather than
7708
+ * in the order somebody happened to click.
7709
+ *
7710
+ * @param items - The whole catalogue.
7711
+ * @param value - Ids currently on the target side.
7712
+ */
7713
+ export declare function splitTransferSides(items: readonly TransferItem[], value: readonly string[]): {
7714
+ source: TransferItem[];
7715
+ target: TransferItem[];
7716
+ };
7717
+
7292
7718
  /** Flex-based vertical or horizontal stack with a numeric `gap`. */
7293
7719
  export declare function Stack({ direction, gap, align, justify, wrap, className, style, children, ...props }: StackProps): JSX.Element;
7294
7720
 
@@ -7916,6 +8342,9 @@ export declare function throttle<A extends unknown[]>(fn: (...args: A) => void,
7916
8342
  cancel: () => void;
7917
8343
  };
7918
8344
 
8345
+ /** Clock label for a single message — the time, not a relative phrase. */
8346
+ export declare function timeLabel(timestamp: number, locale?: "pt-BR" | "en"): string;
8347
+
7919
8348
  /**
7920
8349
  * Vertical event timeline — activity feeds, order trackers, audit logs.
7921
8350
  * Each entry has a marker (color or custom icon), title, optional
@@ -8227,6 +8656,67 @@ export declare interface TrajectoryMapProps extends Omit<HTMLAttributes<HTMLDivE
8227
8656
  onMarkerClick?: (marker: GeoMarker, index: number) => void;
8228
8657
  }
8229
8658
 
8659
+ /**
8660
+ * Two panes and a set of move controls: pick a subset out of a catalogue.
8661
+ *
8662
+ * Controlled on **ids of the target side only**. The panes are derived on every
8663
+ * render, never stored, because two stored lists drift the moment the catalogue
8664
+ * changes under them — a permission removed upstream lingers in whichever pane
8665
+ * held it, and an id in both panes is a bug nobody can see.
8666
+ *
8667
+ * @example
8668
+ * const [roles, setRoles] = useState<string[]>([]);
8669
+ *
8670
+ * <Transfer
8671
+ * items={allRoles}
8672
+ * value={roles}
8673
+ * onChange={setRoles}
8674
+ * sourceTitle="Papéis disponíveis"
8675
+ * targetTitle="Papéis do usuário"
8676
+ * />
8677
+ */
8678
+ export declare function Transfer({ items, value, onChange, sourceTitle, targetTitle, searchable, renderItem, locale, height, disabled, className, ...rest }: TransferProps): JSX.Element;
8679
+
8680
+ /** One movable entry. */
8681
+ export declare interface TransferItem {
8682
+ /** Stable identity. What `value`/`onChange` carry. */
8683
+ id: string;
8684
+ /** What the row shows. */
8685
+ label: ReactNode;
8686
+ /** Text the search box matches against. Falls back to `label` when it is a string. */
8687
+ searchText?: string;
8688
+ /** Row that cannot move — a mandatory permission, a locked seat. */
8689
+ disabled?: boolean;
8690
+ /** Anything the app wants back in `renderItem`. */
8691
+ data?: Record<string, unknown>;
8692
+ }
8693
+
8694
+ export declare interface TransferProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_4> {
8695
+ /** The whole catalogue. Both panes are derived from it. */
8696
+ items: readonly TransferItem[];
8697
+ /** Ids on the target side. Controlled. */
8698
+ value: readonly string[];
8699
+ /** Next value, always in catalogue order. */
8700
+ onChange: (value: string[]) => void;
8701
+ /** Heading of the left pane. Default `"Disponíveis"`. */
8702
+ sourceTitle?: ReactNode;
8703
+ /** Heading of the right pane. Default `"Selecionados"`. */
8704
+ targetTitle?: ReactNode;
8705
+ /** Show a search box above each pane. Default `true` past 8 items. */
8706
+ searchable?: boolean;
8707
+ /** Custom row body. Gets the item and which side it is on. */
8708
+ renderItem?: (item: TransferItem, side: TransferSide) => ReactNode;
8709
+ /** Locale for labels. Default `"pt-BR"`. */
8710
+ locale?: "pt-BR" | "en";
8711
+ /** Height of each pane's scroll area, any CSS length. Default `"16rem"`. */
8712
+ height?: string;
8713
+ /** Block every move. */
8714
+ disabled?: boolean;
8715
+ }
8716
+
8717
+ /** Which pane an operation is about. */
8718
+ export declare type TransferSide = "source" | "target";
8719
+
8230
8720
  /**
8231
8721
  * Estimated travel between two coordinates. Mirrors the `TravelEstimate`
8232
8722
  * schema from `tempest-fastapi-sdk` (`geo/schemas.py`), snake_case preserved so
@@ -8350,6 +8840,9 @@ export declare interface TruncateTextProps extends HTMLAttributes<HTMLDivElement
8350
8840
  children: ReactNode;
8351
8841
  }
8352
8842
 
8843
+ /** Sentence for the typing indicator, or `null` when nobody is typing. */
8844
+ export declare function typingLabel(names: readonly string[], locale?: "pt-BR" | "en"): string | null;
8845
+
8353
8846
  /**
8354
8847
  * Remove duplicate items, keeping the first occurrence of each distinct key.
8355
8848
  *