chat 4.10.0 → 4.11.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.
@@ -118,7 +118,7 @@ function fromReactElement(element) {
118
118
  return null;
119
119
  }
120
120
  const convertedChildren = props.children ? convertChildren(props.children) : [];
121
- const isCardChild = (el) => el.type !== "card" && el.type !== "button" && el.type !== "link-button" && el.type !== "field";
121
+ const isCardChild = (el) => el.type !== "card" && el.type !== "button" && el.type !== "link-button" && el.type !== "field" && el.type !== "select" && el.type !== "radio_select";
122
122
  switch (componentName) {
123
123
  case "Card":
124
124
  return Card({
@@ -143,7 +143,7 @@ function fromReactElement(element) {
143
143
  case "Actions":
144
144
  return Actions(
145
145
  convertedChildren.filter(
146
- (c) => c.type === "button" || c.type === "link-button"
146
+ (c) => c.type === "button" || c.type === "link-button" || c.type === "select" || c.type === "radio_select"
147
147
  )
148
148
  );
149
149
  case "Button": {
@@ -239,6 +239,7 @@ function childToFallbackText(child) {
239
239
  var VALID_MODAL_CHILD_TYPES = [
240
240
  "text_input",
241
241
  "select",
242
+ "radio_select",
242
243
  "text",
243
244
  "fields"
244
245
  ];
@@ -283,6 +284,9 @@ function TextInput(options) {
283
284
  };
284
285
  }
285
286
  function Select(options) {
287
+ if (!options.options || options.options.length === 0) {
288
+ throw new Error("Select requires at least one option");
289
+ }
286
290
  return {
287
291
  type: "select",
288
292
  id: options.id,
@@ -296,7 +300,21 @@ function Select(options) {
296
300
  function SelectOption(options) {
297
301
  return {
298
302
  label: options.label,
299
- value: options.value
303
+ value: options.value,
304
+ description: options.description
305
+ };
306
+ }
307
+ function RadioSelect(options) {
308
+ if (!options.options || options.options.length === 0) {
309
+ throw new Error("RadioSelect requires at least one option");
310
+ }
311
+ return {
312
+ type: "radio_select",
313
+ id: options.id,
314
+ label: options.label,
315
+ options: options.options,
316
+ initialOption: options.initialOption,
317
+ optional: options.optional
300
318
  };
301
319
  }
302
320
  function isReactElement2(value) {
@@ -314,6 +332,7 @@ var modalComponentMap = /* @__PURE__ */ new Map([
314
332
  [Modal, "Modal"],
315
333
  [TextInput, "TextInput"],
316
334
  [Select, "Select"],
335
+ [RadioSelect, "RadioSelect"],
317
336
  [SelectOption, "SelectOption"]
318
337
  ]);
319
338
  function fromReactModalElement(element) {
@@ -367,10 +386,21 @@ function fromReactModalElement(element) {
367
386
  initialOption: props.initialOption,
368
387
  optional: props.optional
369
388
  });
389
+ case "RadioSelect":
390
+ return RadioSelect({
391
+ id: props.id,
392
+ label: props.label,
393
+ options: convertedChildren.filter(
394
+ (c) => c !== null && "label" in c && "value" in c && !("type" in c)
395
+ ),
396
+ initialOption: props.initialOption,
397
+ optional: props.optional
398
+ });
370
399
  case "SelectOption":
371
400
  return SelectOption({
372
401
  label: props.label,
373
- value: props.value
402
+ value: props.value,
403
+ description: props.description
374
404
  });
375
405
  default:
376
406
  return null;
@@ -455,14 +485,16 @@ function resolveJSXElement(element) {
455
485
  const processedChildren = processChildren(children);
456
486
  if (type === Text) {
457
487
  const textProps = isTextProps(props) ? props : { style: void 0 };
458
- const content = processedChildren.length > 0 ? String(processedChildren[0]) : String(textProps.children ?? "");
488
+ const content = processedChildren.length > 0 ? processedChildren.map(String).join("") : String(textProps.children ?? "");
459
489
  return Text(content, { style: textProps.style });
460
490
  }
461
491
  if (type === Section) {
462
492
  return Section(processedChildren);
463
493
  }
464
494
  if (type === Actions) {
465
- return Actions(processedChildren);
495
+ return Actions(
496
+ processedChildren
497
+ );
466
498
  }
467
499
  if (type === Fields) {
468
500
  return Fields(processedChildren);
@@ -471,7 +503,7 @@ function resolveJSXElement(element) {
471
503
  if (!isButtonProps(props)) {
472
504
  throw new Error("Button requires an 'id' prop");
473
505
  }
474
- const label = processedChildren.length > 0 ? String(processedChildren[0]) : props.label ?? "";
506
+ const label = processedChildren.length > 0 ? processedChildren.map(String).join("") : props.label ?? "";
475
507
  return Button({
476
508
  id: props.id,
477
509
  label,
@@ -483,7 +515,7 @@ function resolveJSXElement(element) {
483
515
  if (!isLinkButtonProps(props)) {
484
516
  throw new Error("LinkButton requires a 'url' prop");
485
517
  }
486
- const label = processedChildren.length > 0 ? String(processedChildren[0]) : props.label ?? "";
518
+ const label = processedChildren.length > 0 ? processedChildren.map(String).join("") : props.label ?? "";
487
519
  return LinkButton({
488
520
  url: props.url,
489
521
  label,
@@ -549,13 +581,26 @@ function resolveJSXElement(element) {
549
581
  options: processedChildren
550
582
  });
551
583
  }
584
+ if (type === RadioSelect) {
585
+ if (!isSelectProps(props)) {
586
+ throw new Error("RadioSelect requires 'id' and 'label' props");
587
+ }
588
+ return RadioSelect({
589
+ id: props.id,
590
+ label: props.label,
591
+ initialOption: props.initialOption,
592
+ optional: props.optional,
593
+ options: processedChildren
594
+ });
595
+ }
552
596
  if (type === SelectOption) {
553
597
  if (!isSelectOptionProps(props)) {
554
598
  throw new Error("SelectOption requires 'label' and 'value' props");
555
599
  }
556
600
  return SelectOption({
557
601
  label: props.label,
558
- value: props.value
602
+ value: props.value,
603
+ description: props.description
559
604
  });
560
605
  }
561
606
  const cardProps = isCardProps(props) ? props : {};
@@ -642,6 +687,7 @@ export {
642
687
  TextInput,
643
688
  Select,
644
689
  SelectOption,
690
+ RadioSelect,
645
691
  fromReactModalElement,
646
692
  jsx,
647
693
  jsxs,
@@ -651,4 +697,4 @@ export {
651
697
  toModalElement,
652
698
  isJSX
653
699
  };
654
- //# sourceMappingURL=chunk-GGEG4KZT.js.map
700
+ //# sourceMappingURL=chunk-WKJEG4FE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cards.ts","../src/modals.ts","../src/jsx-runtime.ts"],"sourcesContent":["/**\n * Card elements for cross-platform rich messaging.\n *\n * Provides a builder API for creating rich cards that automatically\n * convert to platform-specific formats:\n * - Slack: Block Kit\n * - Teams: Adaptive Cards\n * - Google Chat: Card v2\n *\n * Supports both function-call and JSX syntax:\n *\n * @example Function API\n * ```ts\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * Card({\n * title: \"Order #1234\",\n * children: [\n * Text(\"Total: $50.00\"),\n * Actions([\n * Button({ id: \"approve\", label: \"Approve\", style: \"primary\" }),\n * Button({ id: \"reject\", label: \"Reject\", style: \"danger\" }),\n * ]),\n * ],\n * })\n * );\n * ```\n *\n * @example JSX API (requires jsxImportSource: \"chat\" in tsconfig)\n * ```tsx\n * /** @jsxImportSource chat *\\/\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * <Card title=\"Order #1234\">\n * <Text>Total: $50.00</Text>\n * <Actions>\n * <Button id=\"approve\" style=\"primary\">Approve</Button>\n * <Button id=\"reject\" style=\"danger\">Reject</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport type { RadioSelectElement, SelectElement } from \"./modals\";\n\n// ============================================================================\n// Card Element Types\n// ============================================================================\n\n/** Button style options */\nexport type ButtonStyle = \"primary\" | \"danger\" | \"default\";\n\n/** Text style options */\nexport type TextStyle = \"plain\" | \"bold\" | \"muted\";\n\n/** Button element for interactive actions */\nexport interface ButtonElement {\n type: \"button\";\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/** Link button element that opens a URL */\nexport interface LinkButtonElement {\n type: \"link-button\";\n /** URL to open when clicked */\n url: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n}\n\n/** Text content element */\nexport interface TextElement {\n type: \"text\";\n /** Text content (supports markdown in some platforms) */\n content: string;\n /** Text style */\n style?: TextStyle;\n}\n\n/** Image element */\nexport interface ImageElement {\n type: \"image\";\n /** Image URL */\n url: string;\n /** Alt text for accessibility */\n alt?: string;\n}\n\n/** Visual divider/separator */\nexport interface DividerElement {\n type: \"divider\";\n}\n\n/** Container for action buttons and selects */\nexport interface ActionsElement {\n type: \"actions\";\n /** Button, link button, select, and radio select elements */\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[];\n}\n\n/** Section container for grouping elements */\nexport interface SectionElement {\n type: \"section\";\n /** Section children */\n children: CardChild[];\n}\n\n/** Field for key-value display */\nexport interface FieldElement {\n type: \"field\";\n /** Field label */\n label: string;\n /** Field value */\n value: string;\n}\n\n/** Fields container for multi-column layout */\nexport interface FieldsElement {\n type: \"fields\";\n /** Field elements */\n children: FieldElement[];\n}\n\n/** Union of all card child element types */\nexport type CardChild =\n | TextElement\n | ImageElement\n | DividerElement\n | ActionsElement\n | SectionElement\n | FieldsElement;\n\n/** Union of all element types (including nested children) */\ntype AnyCardElement =\n | CardChild\n | CardElement\n | ButtonElement\n | LinkButtonElement\n | FieldElement\n | SelectElement\n | RadioSelectElement;\n\n/** Root card element */\nexport interface CardElement {\n type: \"card\";\n /** Card title */\n title?: string;\n /** Card subtitle */\n subtitle?: string;\n /** Header image URL */\n imageUrl?: string;\n /** Card content */\n children: CardChild[];\n}\n\n/** Type guard for CardElement */\nexport function isCardElement(value: unknown): value is CardElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as CardElement).type === \"card\"\n );\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\n/** Options for Card */\nexport interface CardOptions {\n title?: string;\n subtitle?: string;\n imageUrl?: string;\n children?: CardChild[];\n}\n\n/**\n * Create a Card element.\n *\n * @example\n * ```ts\n * Card({\n * title: \"Welcome\",\n * children: [Text(\"Hello!\")],\n * })\n * ```\n */\nexport function Card(options: CardOptions = {}): CardElement {\n return {\n type: \"card\",\n title: options.title,\n subtitle: options.subtitle,\n imageUrl: options.imageUrl,\n children: options.children ?? [],\n };\n}\n\n/**\n * Create a Text element.\n *\n * @example\n * ```ts\n * Text(\"Hello, world!\")\n * Text(\"Important\", { style: \"bold\" })\n * ```\n */\nexport function Text(\n content: string,\n options: { style?: TextStyle } = {},\n): TextElement {\n return {\n type: \"text\",\n content,\n style: options.style,\n };\n}\n\n/**\n * Alias for Text that avoids conflicts with DOM's global Text constructor.\n * Use this when importing in environments where `Text` would conflict.\n *\n * @example\n * ```ts\n * import { CardText } from \"chat\";\n * CardText(\"Hello, world!\")\n * ```\n */\nexport const CardText = Text;\n\n/**\n * Create an Image element.\n *\n * @example\n * ```ts\n * Image({ url: \"https://example.com/image.png\", alt: \"Description\" })\n * ```\n */\nexport function Image(options: { url: string; alt?: string }): ImageElement {\n return {\n type: \"image\",\n url: options.url,\n alt: options.alt,\n };\n}\n\n/**\n * Create a Divider element.\n *\n * @example\n * ```ts\n * Divider()\n * ```\n */\nexport function Divider(): DividerElement {\n return { type: \"divider\" };\n}\n\n/**\n * Create a Section container.\n *\n * @example\n * ```ts\n * Section([\n * Text(\"Grouped content\"),\n * Image({ url: \"...\" }),\n * ])\n * ```\n */\nexport function Section(children: CardChild[]): SectionElement {\n return {\n type: \"section\",\n children,\n };\n}\n\n/**\n * Create an Actions container for buttons and selects.\n *\n * @example\n * ```ts\n * Actions([\n * Button({ id: \"ok\", label: \"OK\" }),\n * Button({ id: \"cancel\", label: \"Cancel\" }),\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\" }),\n * Select({ id: \"priority\", label: \"Priority\", options: [...] }),\n * RadioSelect({ id: \"status\", label: \"Status\", options: [...] }),\n * ])\n * ```\n */\nexport function Actions(\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[],\n): ActionsElement {\n return {\n type: \"actions\",\n children,\n };\n}\n\n/** Options for Button */\nexport interface ButtonOptions {\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/**\n * Create a Button element.\n *\n * @example\n * ```ts\n * Button({ id: \"submit\", label: \"Submit\", style: \"primary\" })\n * Button({ id: \"delete\", label: \"Delete\", style: \"danger\", value: \"item-123\" })\n * ```\n */\nexport function Button(options: ButtonOptions): ButtonElement {\n return {\n type: \"button\",\n id: options.id,\n label: options.label,\n style: options.style,\n value: options.value,\n };\n}\n\n/** Options for LinkButton */\nexport interface LinkButtonOptions {\n /** URL to open when clicked */\n url: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n}\n\n/**\n * Create a LinkButton element that opens a URL when clicked.\n *\n * @example\n * ```ts\n * LinkButton({ url: \"https://example.com\", label: \"View Docs\" })\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\", style: \"primary\" })\n * ```\n */\nexport function LinkButton(options: LinkButtonOptions): LinkButtonElement {\n return {\n type: \"link-button\",\n url: options.url,\n label: options.label,\n style: options.style,\n };\n}\n\n/**\n * Create a Field element for key-value display.\n *\n * @example\n * ```ts\n * Field({ label: \"Status\", value: \"Active\" })\n * ```\n */\nexport function Field(options: { label: string; value: string }): FieldElement {\n return {\n type: \"field\",\n label: options.label,\n value: options.value,\n };\n}\n\n/**\n * Create a Fields container for multi-column layout.\n *\n * @example\n * ```ts\n * Fields([\n * Field({ label: \"Name\", value: \"John\" }),\n * Field({ label: \"Email\", value: \"john@example.com\" }),\n * ])\n * ```\n */\nexport function Fields(children: FieldElement[]): FieldsElement {\n return {\n type: \"fields\",\n children,\n };\n}\n\n// ============================================================================\n// React Element Support\n// ============================================================================\n\n/** React element shape (minimal typing to avoid React dependency) */\ninterface ReactElement {\n $$typeof: symbol;\n type: unknown;\n props: Record<string, unknown>;\n}\n\n/**\n * Check if a value is a React element.\n */\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\n/**\n * Map of component functions to their names for React element conversion.\n */\nconst componentMap = new Map<unknown, string>([\n [Card, \"Card\"],\n [Text, \"Text\"],\n [Image, \"Image\"],\n [Divider, \"Divider\"],\n [Section, \"Section\"],\n [Actions, \"Actions\"],\n [Button, \"Button\"],\n [LinkButton, \"LinkButton\"],\n [Field, \"Field\"],\n [Fields, \"Fields\"],\n]);\n\n/**\n * Convert a React element tree to a CardElement tree.\n * This allows using React's JSX with our card components.\n *\n * @example\n * ```tsx\n * import React from \"react\";\n * import { Card, Text, fromReactElement } from \"chat\";\n *\n * const element = (\n * <Card title=\"Hello\">\n * <Text>World</Text>\n * </Card>\n * );\n *\n * const card = fromReactElement(element);\n * await thread.post(card);\n * ```\n */\nexport function fromReactElement(element: unknown): AnyCardElement | null {\n if (!isReactElement(element)) {\n // Already a card element or primitive\n if (isCardElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as CardChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = componentMap.get(type);\n\n if (!componentName) {\n // Check if it's an HTML element (string type like \"div\", \"a\", \"span\")\n if (typeof type === \"string\") {\n throw new Error(\n `HTML element <${type}> is not supported in card elements. ` +\n `Use Card, Text, Section, Actions, Button, Fields, Field, Image, or Divider components instead.`,\n );\n }\n\n // Unknown custom component - try to extract children\n if (props.children) {\n return convertChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n // Convert children recursively\n const convertedChildren = props.children\n ? convertChildren(props.children)\n : [];\n\n // Helper to filter for CardChild elements\n const isCardChild = (el: AnyCardElement): el is CardChild =>\n el.type !== \"card\" &&\n el.type !== \"button\" &&\n el.type !== \"link-button\" &&\n el.type !== \"field\" &&\n el.type !== \"select\" &&\n el.type !== \"radio_select\";\n\n // Call the appropriate builder function based on component type\n switch (componentName) {\n case \"Card\":\n return Card({\n title: props.title as string | undefined,\n subtitle: props.subtitle as string | undefined,\n imageUrl: props.imageUrl as string | undefined,\n children: convertedChildren.filter(isCardChild),\n });\n\n case \"Text\": {\n // JSX: <Text style=\"bold\">content</Text>\n const content = extractTextContent(props.children);\n return Text(content, { style: props.style as TextStyle | undefined });\n }\n\n case \"Image\":\n return Image({\n url: props.url as string,\n alt: props.alt as string | undefined,\n });\n\n case \"Divider\":\n return Divider();\n\n case \"Section\":\n return Section(convertedChildren.filter(isCardChild));\n\n case \"Actions\":\n return Actions(\n convertedChildren.filter(\n (\n c,\n ): c is\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement =>\n c.type === \"button\" ||\n c.type === \"link-button\" ||\n c.type === \"select\" ||\n c.type === \"radio_select\",\n ),\n );\n\n case \"Button\": {\n // JSX: <Button id=\"x\" style=\"primary\">Label</Button>\n const label = extractTextContent(props.children);\n return Button({\n id: props.id as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n value: props.value as string | undefined,\n });\n }\n\n case \"LinkButton\": {\n // JSX: <LinkButton url=\"https://...\" style=\"primary\">Label</LinkButton>\n const label = extractTextContent(props.children);\n return LinkButton({\n url: props.url as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n });\n }\n\n case \"Field\":\n return Field({\n label: props.label as string,\n value: props.value as string,\n });\n\n case \"Fields\":\n return Fields(\n convertedChildren.filter((c): c is FieldElement => c.type === \"field\"),\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Convert React children to card elements.\n */\nfunction convertChildren(children: unknown): AnyCardElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertChildren);\n }\n\n const converted = fromReactElement(children);\n if (converted && typeof converted === \"object\" && \"type\" in converted) {\n // If it's a card, extract its children\n if (converted.type === \"card\") {\n return (converted as CardElement).children;\n }\n return [converted];\n }\n\n return [];\n}\n\n/**\n * Extract text content from React children.\n */\nfunction extractTextContent(children: unknown): string {\n if (typeof children === \"string\") {\n return children;\n }\n if (typeof children === \"number\") {\n return String(children);\n }\n if (Array.isArray(children)) {\n return children.map(extractTextContent).join(\"\");\n }\n return \"\";\n}\n\n// ============================================================================\n// Fallback Text Generation\n// ============================================================================\n\n/**\n * Generate plain text fallback from a CardElement.\n * Used for platforms/clients that can't render rich cards,\n * and for the SentMessage.text property.\n */\nexport function cardToFallbackText(card: CardElement): string {\n const parts: string[] = [];\n\n if (card.title) {\n parts.push(card.title);\n }\n\n if (card.subtitle) {\n parts.push(card.subtitle);\n }\n\n for (const child of card.children) {\n const text = childToFallbackText(child);\n if (text) {\n parts.push(text);\n }\n }\n\n return parts.join(\"\\n\");\n}\n\n/**\n * Generate fallback text from a card child element.\n */\nfunction childToFallbackText(child: CardChild): string | null {\n switch (child.type) {\n case \"text\":\n return child.content;\n case \"fields\":\n return child.children.map((f) => `${f.label}: ${f.value}`).join(\"\\n\");\n case \"actions\":\n // Actions are interactive-only — exclude from fallback text.\n // See: https://docs.slack.dev/reference/methods/chat.postMessage\n return null;\n case \"section\":\n return child.children\n .map((c) => childToFallbackText(c))\n .filter(Boolean)\n .join(\"\\n\");\n default:\n return null;\n }\n}\n","/**\n * Modal elements for form dialogs.\n */\n\nimport type { FieldsElement, TextElement } from \"./cards\";\n\n// ============================================================================\n// Modal Element Types\n// ============================================================================\n\nexport const VALID_MODAL_CHILD_TYPES = [\n \"text_input\",\n \"select\",\n \"radio_select\",\n \"text\",\n \"fields\",\n] as const;\n\nexport type ModalChild =\n | TextInputElement\n | SelectElement\n | RadioSelectElement\n | TextElement\n | FieldsElement;\n\nexport interface ModalElement {\n type: \"modal\";\n callbackId: string;\n title: string;\n submitLabel?: string;\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n children: ModalChild[];\n}\n\nexport interface TextInputElement {\n type: \"text_input\";\n id: string;\n label: string;\n placeholder?: string;\n initialValue?: string;\n multiline?: boolean;\n optional?: boolean;\n maxLength?: number;\n}\n\nexport interface SelectElement {\n type: \"select\";\n id: string;\n label: string;\n placeholder?: string;\n options: SelectOptionElement[];\n initialOption?: string;\n optional?: boolean;\n}\n\nexport interface SelectOptionElement {\n label: string;\n value: string;\n description?: string;\n}\n\nexport interface RadioSelectElement {\n type: \"radio_select\";\n id: string;\n label: string;\n options: SelectOptionElement[];\n initialOption?: string;\n optional?: boolean;\n}\n\nexport function isModalElement(value: unknown): value is ModalElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as ModalElement).type === \"modal\"\n );\n}\n\nexport function filterModalChildren(children: unknown[]): ModalChild[] {\n const validChildren = children.filter(\n (c): c is ModalChild =>\n typeof c === \"object\" &&\n c !== null &&\n \"type\" in c &&\n VALID_MODAL_CHILD_TYPES.includes(\n (c as { type: string })\n .type as (typeof VALID_MODAL_CHILD_TYPES)[number],\n ),\n );\n if (validChildren.length < children.length) {\n console.warn(\n \"[chat] Modal contains unsupported child elements that were ignored\",\n );\n }\n return validChildren;\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\nexport interface ModalOptions {\n callbackId: string;\n title: string;\n submitLabel?: string;\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n children?: ModalChild[];\n}\n\nexport function Modal(options: ModalOptions): ModalElement {\n return {\n type: \"modal\",\n callbackId: options.callbackId,\n title: options.title,\n submitLabel: options.submitLabel,\n closeLabel: options.closeLabel,\n notifyOnClose: options.notifyOnClose,\n privateMetadata: options.privateMetadata,\n children: options.children ?? [],\n };\n}\n\nexport interface TextInputOptions {\n id: string;\n label: string;\n placeholder?: string;\n initialValue?: string;\n multiline?: boolean;\n optional?: boolean;\n maxLength?: number;\n}\n\nexport function TextInput(options: TextInputOptions): TextInputElement {\n return {\n type: \"text_input\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n initialValue: options.initialValue,\n multiline: options.multiline,\n optional: options.optional,\n maxLength: options.maxLength,\n };\n}\n\nexport interface SelectOptions {\n id: string;\n label: string;\n placeholder?: string;\n options: SelectOptionElement[];\n initialOption?: string;\n optional?: boolean;\n}\n\nexport function Select(options: SelectOptions): SelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"Select requires at least one option\");\n }\n return {\n type: \"select\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\nexport function SelectOption(options: {\n label: string;\n value: string;\n description?: string;\n}): SelectOptionElement {\n return {\n label: options.label,\n value: options.value,\n description: options.description,\n };\n}\n\nexport interface RadioSelectOptions {\n id: string;\n label: string;\n options: SelectOptionElement[];\n initialOption?: string;\n optional?: boolean;\n}\n\nexport function RadioSelect(options: RadioSelectOptions): RadioSelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"RadioSelect requires at least one option\");\n }\n return {\n type: \"radio_select\",\n id: options.id,\n label: options.label,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\n// ============================================================================\n// JSX Support\n// ============================================================================\n\ninterface ReactElement {\n $$typeof: symbol;\n type: unknown;\n props: Record<string, unknown>;\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\ntype AnyModalElement = ModalElement | ModalChild | SelectOptionElement;\n\nconst modalComponentMap = new Map<unknown, string>([\n [Modal, \"Modal\"],\n [TextInput, \"TextInput\"],\n [Select, \"Select\"],\n [RadioSelect, \"RadioSelect\"],\n [SelectOption, \"SelectOption\"],\n]);\n\nexport function fromReactModalElement(\n element: unknown,\n): AnyModalElement | null {\n if (!isReactElement(element)) {\n if (isModalElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as ModalChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = modalComponentMap.get(type);\n\n if (!componentName) {\n if (props.children) {\n return convertModalChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n const convertedChildren = props.children\n ? convertModalChildren(props.children)\n : [];\n\n switch (componentName) {\n case \"Modal\":\n return Modal({\n callbackId: props.callbackId as string,\n title: props.title as string,\n submitLabel: props.submitLabel as string | undefined,\n closeLabel: props.closeLabel as string | undefined,\n notifyOnClose: props.notifyOnClose as boolean | undefined,\n privateMetadata: props.privateMetadata as string | undefined,\n children: filterModalChildren(convertedChildren),\n });\n\n case \"TextInput\":\n return TextInput({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n initialValue: props.initialValue as string | undefined,\n multiline: props.multiline as boolean | undefined,\n optional: props.optional as boolean | undefined,\n maxLength: props.maxLength as number | undefined,\n });\n\n case \"Select\":\n return Select({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c),\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"RadioSelect\":\n return RadioSelect({\n id: props.id as string,\n label: props.label as string,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c),\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"SelectOption\":\n return SelectOption({\n label: props.label as string,\n value: props.value as string,\n description: props.description as string | undefined,\n });\n\n default:\n return null;\n }\n}\n\nfunction convertModalChildren(children: unknown): AnyModalElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertModalChildren);\n }\n\n const converted = fromReactModalElement(children);\n if (converted) {\n if (isModalElement(converted)) {\n return converted.children;\n }\n return [converted];\n }\n\n return [];\n}\n","/**\n * Custom JSX runtime for chat cards.\n *\n * This allows using JSX syntax without React. Configure your bundler:\n *\n * tsconfig.json:\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"chat\"\n * }\n * }\n *\n * Or per-file:\n * /** @jsxImportSource chat *\\/\n *\n * Usage:\n * ```tsx\n * import { Card, Text, Button, Actions } from \"chat\";\n *\n * const card = (\n * <Card title=\"Order #1234\">\n * <Text>Your order is ready!</Text>\n * <Actions>\n * <Button id=\"pickup\" style=\"primary\">Schedule Pickup</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport {\n Actions,\n Button,\n type ButtonElement,\n type ButtonStyle,\n Card,\n type CardChild,\n type CardElement,\n Divider,\n Field,\n type FieldElement,\n Fields,\n Image,\n LinkButton,\n type LinkButtonElement,\n Section,\n Text,\n type TextStyle,\n} from \"./cards\";\n\nimport {\n filterModalChildren,\n isModalElement,\n Modal,\n type ModalChild,\n type ModalElement,\n RadioSelect,\n type RadioSelectElement,\n Select,\n type SelectElement,\n SelectOption,\n type SelectOptionElement,\n TextInput,\n} from \"./modals\";\n\n// Symbol to identify our JSX elements before they're processed\nconst JSX_ELEMENT = Symbol.for(\"chat.jsx.element\");\n\n// ============================================================================\n// JSX Props Types - Strongly typed props for each component\n// ============================================================================\n\n/** Props for Card component in JSX */\nexport interface CardProps {\n title?: string;\n subtitle?: string;\n imageUrl?: string;\n children?: unknown;\n}\n\n/** Props for Text component in JSX */\nexport interface TextProps {\n style?: TextStyle;\n children?: string | number;\n}\n\n/** Props for Button component in JSX */\nexport interface ButtonProps {\n id: string;\n label?: string;\n style?: ButtonStyle;\n value?: string;\n children?: string | number;\n}\n\n/** Props for LinkButton component in JSX */\nexport interface LinkButtonProps {\n url: string;\n label?: string;\n style?: ButtonStyle;\n children?: string | number;\n}\n\n/** Props for Image component in JSX */\nexport interface ImageProps {\n url: string;\n alt?: string;\n}\n\n/** Props for Field component in JSX */\nexport interface FieldProps {\n label: string;\n value: string;\n}\n\n/** Props for container components (Section, Actions, Fields) */\nexport interface ContainerProps {\n children?: unknown;\n}\n\n/** Props for Divider component (no props) */\nexport type DividerProps = Record<string, never>;\n\n/** Props for Modal component in JSX */\nexport interface ModalProps {\n callbackId: string;\n title: string;\n submitLabel?: string;\n closeLabel?: string;\n notifyOnClose?: boolean;\n privateMetadata?: string;\n children?: unknown;\n}\n\n/** Props for TextInput component in JSX */\nexport interface TextInputProps {\n id: string;\n label: string;\n placeholder?: string;\n initialValue?: string;\n multiline?: boolean;\n optional?: boolean;\n maxLength?: number;\n}\n\n/** Props for Select component in JSX */\nexport interface SelectProps {\n id: string;\n label: string;\n placeholder?: string;\n initialOption?: string;\n optional?: boolean;\n children?: unknown;\n}\n\n/** Props for SelectOption component in JSX */\nexport interface SelectOptionProps {\n label: string;\n value: string;\n description?: string;\n}\n\n/** Union of all valid JSX props */\nexport type CardJSXProps =\n | CardProps\n | TextProps\n | ButtonProps\n | LinkButtonProps\n | ImageProps\n | FieldProps\n | ContainerProps\n | DividerProps\n | ModalProps\n | TextInputProps\n | SelectProps\n | SelectOptionProps;\n\n/** Component function type with proper overloads */\ntype CardComponentFunction =\n | typeof Card\n | typeof Text\n | typeof Button\n | typeof LinkButton\n | typeof Image\n | typeof Field\n | typeof Divider\n | typeof Section\n | typeof Actions\n | typeof Fields\n | typeof Modal\n | typeof TextInput\n | typeof Select\n | typeof RadioSelect\n | typeof SelectOption;\n\n/**\n * Represents a JSX element from the chat JSX runtime.\n * This is the type returned when using JSX syntax with chat components.\n */\nexport interface CardJSXElement<P extends CardJSXProps = CardJSXProps> {\n $$typeof: typeof JSX_ELEMENT;\n type: CardComponentFunction;\n props: P;\n children: unknown[];\n}\n\n// Internal alias for backwards compatibility\ntype JSXElement = CardJSXElement;\n\n/**\n * Check if a value is a JSX element from our runtime.\n */\nfunction isJSXElement(value: unknown): value is JSXElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as JSXElement).$$typeof === JSX_ELEMENT\n );\n}\n\n/** Non-null card element for children arrays */\ntype CardChildOrNested =\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | FieldElement\n | SelectElement\n | SelectOptionElement\n | RadioSelectElement;\n\n/**\n * Process children, converting JSX elements to card elements.\n */\nfunction processChildren(children: unknown): CardChildOrNested[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(processChildren);\n }\n\n // If it's a JSX element, resolve it\n if (isJSXElement(children)) {\n const resolved = resolveJSXElement(children);\n if (resolved) {\n return [resolved as CardChildOrNested];\n }\n return [];\n }\n\n // If it's already a card element, return it\n if (typeof children === \"object\" && \"type\" in children) {\n return [children as CardChildOrNested];\n }\n\n // If it's a string or number, it might be text content for a Button or Text\n if (typeof children === \"string\" || typeof children === \"number\") {\n // Return as string, the component will handle it\n return [String(children) as unknown as CardChildOrNested];\n }\n\n return [];\n}\n\n/** Any card element type that can be created */\ntype AnyCardElement =\n | CardElement\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | FieldElement\n | ModalElement\n | ModalChild\n | SelectOptionElement\n | null;\n\n/**\n * Type guard to check if props match TextProps\n */\nfunction isTextProps(props: CardJSXProps): props is TextProps {\n return !(\"id\" in props) && !(\"url\" in props) && !(\"label\" in props);\n}\n\n/**\n * Type guard to check if props match ButtonProps\n */\nfunction isButtonProps(props: CardJSXProps): props is ButtonProps {\n return \"id\" in props && typeof props.id === \"string\" && !(\"url\" in props);\n}\n\n/**\n * Type guard to check if props match LinkButtonProps\n */\nfunction isLinkButtonProps(props: CardJSXProps): props is LinkButtonProps {\n return \"url\" in props && typeof props.url === \"string\" && !(\"id\" in props);\n}\n\n/**\n * Type guard to check if props match ImageProps\n */\nfunction isImageProps(props: CardJSXProps): props is ImageProps {\n return \"url\" in props && typeof props.url === \"string\";\n}\n\n/**\n * Type guard to check if props match FieldProps\n */\nfunction isFieldProps(props: CardJSXProps): props is FieldProps {\n return (\n \"label\" in props &&\n \"value\" in props &&\n typeof props.label === \"string\" &&\n typeof props.value === \"string\"\n );\n}\n\n/**\n * Type guard to check if props match CardProps\n */\nfunction isCardProps(props: CardJSXProps): props is CardProps {\n return (\n !(\"id\" in props) &&\n !(\"url\" in props) &&\n !(\"callbackId\" in props) &&\n (\"title\" in props || \"subtitle\" in props || \"imageUrl\" in props)\n );\n}\n\n/**\n * Type guard to check if props match ModalProps\n */\nfunction isModalProps(props: CardJSXProps): props is ModalProps {\n return \"callbackId\" in props && \"title\" in props;\n}\n\n/**\n * Type guard to check if props match TextInputProps\n */\nfunction isTextInputProps(props: CardJSXProps): props is TextInputProps {\n return (\n \"id\" in props &&\n \"label\" in props &&\n !(\"options\" in props) &&\n !(\"value\" in props)\n );\n}\n\n/**\n * Type guard to check if props match SelectProps\n */\nfunction isSelectProps(props: CardJSXProps): props is SelectProps {\n return \"id\" in props && \"label\" in props && !(\"value\" in props);\n}\n\n/**\n * Type guard to check if props match SelectOptionProps\n */\nfunction isSelectOptionProps(props: CardJSXProps): props is SelectOptionProps {\n return \"label\" in props && \"value\" in props && !(\"id\" in props);\n}\n\n/**\n * Resolve a JSX element by calling its component function.\n * Transforms JSX props into the format each builder function expects.\n */\nfunction resolveJSXElement(element: JSXElement): AnyCardElement {\n const { type, props, children } = element;\n\n // Process children first\n const processedChildren = processChildren(children);\n\n // Use identity comparison to determine which builder function this is\n // This is necessary because function names get minified in production builds\n if (type === Text) {\n // Text(content: string, options?: { style })\n // JSX children become the content string\n const textProps = isTextProps(props) ? props : { style: undefined };\n const content =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : String(textProps.children ?? \"\");\n return Text(content, { style: textProps.style });\n }\n\n if (type === Section) {\n // Section takes array as first argument\n return Section(processedChildren as CardChild[]);\n }\n\n if (type === Actions) {\n // Actions takes array of ButtonElements, LinkButtonElements, SelectElements, and RadioSelectElements\n return Actions(\n processedChildren as (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[],\n );\n }\n\n if (type === Fields) {\n // Fields takes array of FieldElements\n return Fields(processedChildren as FieldElement[]);\n }\n\n if (type === Button) {\n // Button({ id, label, style, value })\n // JSX children become the label\n if (!isButtonProps(props)) {\n throw new Error(\"Button requires an 'id' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return Button({\n id: props.id,\n label,\n style: props.style,\n value: props.value,\n });\n }\n\n if (type === LinkButton) {\n // LinkButton({ url, label, style })\n // JSX children become the label\n if (!isLinkButtonProps(props)) {\n throw new Error(\"LinkButton requires a 'url' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return LinkButton({\n url: props.url,\n label,\n style: props.style,\n });\n }\n\n if (type === Image) {\n // Image({ url, alt })\n if (!isImageProps(props)) {\n throw new Error(\"Image requires a 'url' prop\");\n }\n return Image({ url: props.url, alt: props.alt });\n }\n\n if (type === Field) {\n // Field({ label, value })\n if (!isFieldProps(props)) {\n throw new Error(\"Field requires 'label' and 'value' props\");\n }\n return Field({\n label: props.label,\n value: props.value,\n });\n }\n\n if (type === Divider) {\n // Divider() - no args\n return Divider();\n }\n\n // Modal components\n if (type === Modal) {\n if (!isModalProps(props)) {\n throw new Error(\"Modal requires 'callbackId' and 'title' props\");\n }\n return Modal({\n callbackId: props.callbackId,\n title: props.title,\n submitLabel: props.submitLabel,\n closeLabel: props.closeLabel,\n notifyOnClose: props.notifyOnClose,\n privateMetadata: props.privateMetadata,\n children: filterModalChildren(processedChildren),\n });\n }\n\n if (type === TextInput) {\n if (!isTextInputProps(props)) {\n throw new Error(\"TextInput requires 'id' and 'label' props\");\n }\n return TextInput({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialValue: props.initialValue,\n multiline: props.multiline,\n optional: props.optional,\n maxLength: props.maxLength,\n });\n }\n\n if (type === Select) {\n if (!isSelectProps(props)) {\n throw new Error(\"Select requires 'id' and 'label' props\");\n }\n return Select({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === RadioSelect) {\n if (!isSelectProps(props)) {\n throw new Error(\"RadioSelect requires 'id' and 'label' props\");\n }\n return RadioSelect({\n id: props.id,\n label: props.label,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === SelectOption) {\n if (!isSelectOptionProps(props)) {\n throw new Error(\"SelectOption requires 'label' and 'value' props\");\n }\n return SelectOption({\n label: props.label,\n value: props.value,\n description: props.description,\n });\n }\n\n // Default: Card({ title, subtitle, imageUrl, children })\n const cardProps = isCardProps(props) ? props : {};\n return Card({\n title: cardProps.title,\n subtitle: cardProps.subtitle,\n imageUrl: cardProps.imageUrl,\n children: processedChildren as CardChild[],\n });\n}\n\n/**\n * JSX factory function (used by the JSX transform).\n * Creates a lazy JSX element that will be resolved when needed.\n */\nexport function jsx<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string,\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: children != null ? [children] : [],\n };\n}\n\n/**\n * JSX factory for elements with multiple children.\n */\nexport function jsxs<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string,\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: Array.isArray(children)\n ? children\n : children != null\n ? [children]\n : [],\n };\n}\n\n/**\n * Development JSX factory (same as jsx, but called in dev mode).\n */\nexport const jsxDEV = jsx;\n\n/**\n * Fragment support (flattens children).\n */\nexport function Fragment(props: { children?: unknown }): CardChild[] {\n return processChildren(props.children) as CardChild[];\n}\n\n/**\n * Convert a JSX element tree to a CardElement.\n * Call this on the root JSX element to get a usable CardElement.\n */\nexport function toCardElement(jsxElement: unknown): CardElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"card\"\n ) {\n return resolved as CardElement;\n }\n }\n\n // Already a CardElement\n if (\n typeof jsxElement === \"object\" &&\n jsxElement !== null &&\n \"type\" in jsxElement &&\n (jsxElement as CardElement).type === \"card\"\n ) {\n return jsxElement as CardElement;\n }\n\n return null;\n}\n\nexport function toModalElement(jsxElement: unknown): ModalElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"modal\"\n ) {\n return resolved as ModalElement;\n }\n }\n if (isModalElement(jsxElement)) {\n return jsxElement;\n }\n return null;\n}\n\n/**\n * Check if a value is a JSX element (from our runtime or React).\n */\nexport function isJSX(value: unknown): boolean {\n if (isJSXElement(value)) {\n return true;\n }\n // Check for React elements\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"$$typeof\" in value &&\n typeof (value as { $$typeof: unknown }).$$typeof === \"symbol\"\n ) {\n const symbolStr = (value as { $$typeof: symbol }).$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n }\n return false;\n}\n\n// Re-export for JSX namespace\nexport namespace JSX {\n export interface Element extends JSXElement {}\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX namespace\n export type IntrinsicElements = {};\n export interface ElementChildrenAttribute {\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX children attribute\n children: {};\n }\n}\n"],"mappings":"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","names":["isReactElement"]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CardElement, a as CardJSXElement, M as ModalElement, b as CardChild, A as Actions$1, B as Button$1, c as Card$1, T as Text$1, D as Divider$1, F as Field$1, d as Fields$1, f as fromReactElement$1, I as Image$1, i as isCardElement$1, e as isJSX$1, L as LinkButton$1, S as Section$1, t as toCardElement$1, g as toModalElement$1, h as fromReactModalElement$1, j as isModalElement$1, k as Modal$1, l as Select$1, m as SelectOption$1, n as TextInput$1 } from './jsx-runtime-CpIl1pEb.js';
2
- export { y as ActionsElement, z as ButtonElement, E as ButtonOptions, o as ButtonProps, G as ButtonStyle, p as CardJSXProps, H as CardOptions, q as CardProps, r as ContainerProps, J as DividerElement, s as DividerProps, K as FieldElement, u as FieldProps, N as FieldsElement, O as ImageElement, v as ImageProps, P as LinkButtonElement, Q as LinkButtonOptions, w as LinkButtonProps, W as ModalChild, X as ModalOptions, R as SectionElement, Y as SelectElement, Z as SelectOptionElement, _ as SelectOptions, U as TextElement, $ as TextInputElement, a0 as TextInputOptions, x as TextProps, V as TextStyle } from './jsx-runtime-CpIl1pEb.js';
1
+ import { C as CardElement, a as CardJSXElement, M as ModalElement, b as CardChild, A as Actions$1, B as Button$1, c as Card$1, T as Text$1, D as Divider$1, F as Field$1, d as Fields$1, f as fromReactElement$1, I as Image$1, i as isCardElement$1, e as isJSX$1, L as LinkButton$1, S as Section$1, t as toCardElement$1, g as toModalElement$1, h as fromReactModalElement$1, j as isModalElement$1, k as Modal$1, R as RadioSelect$1, l as Select$1, m as SelectOption$1, n as TextInput$1 } from './jsx-runtime-COVsDskT.js';
2
+ export { y as ActionsElement, z as ButtonElement, E as ButtonOptions, o as ButtonProps, G as ButtonStyle, p as CardJSXProps, H as CardOptions, q as CardProps, r as ContainerProps, J as DividerElement, s as DividerProps, K as FieldElement, u as FieldProps, N as FieldsElement, O as ImageElement, v as ImageProps, P as LinkButtonElement, Q as LinkButtonOptions, w as LinkButtonProps, X as ModalChild, Y as ModalOptions, Z as RadioSelectElement, _ as RadioSelectOptions, U as SectionElement, $ as SelectElement, a0 as SelectOptionElement, a1 as SelectOptions, V as TextElement, a2 as TextInputElement, a3 as TextInputOptions, x as TextProps, W as TextStyle } from './jsx-runtime-COVsDskT.js';
3
3
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
4
4
  import { Root, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, List, Paragraph, Strong, Text } from 'mdast';
5
5
  export { Blockquote, Code, Content, Delete, Emphasis, InlineCode, Link, List, ListItem, Paragraph, Root, Strong, Text } from 'mdast';
@@ -1492,7 +1492,7 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
1492
1492
  processModalSubmit(event: Omit<ModalSubmitEvent, "relatedThread" | "relatedMessage">, contextId?: string, _options?: WebhookOptions): Promise<ModalResponse | undefined>;
1493
1493
  processModalClose(event: Omit<ModalCloseEvent, "relatedThread" | "relatedMessage">, contextId?: string, options?: WebhookOptions): void;
1494
1494
  /**
1495
- * Store modal context server-side and return a context ID.
1495
+ * Store modal context server-side with a context ID.
1496
1496
  * Called when opening a modal to preserve thread/message for the submit handler.
1497
1497
  */
1498
1498
  private storeModalContext;
@@ -2098,8 +2098,9 @@ declare const toModalElement: typeof toModalElement$1;
2098
2098
  declare const fromReactModalElement: typeof fromReactModalElement$1;
2099
2099
  declare const isModalElement: typeof isModalElement$1;
2100
2100
  declare const Modal: typeof Modal$1;
2101
+ declare const RadioSelect: typeof RadioSelect$1;
2101
2102
  declare const Select: typeof Select$1;
2102
2103
  declare const SelectOption: typeof SelectOption$1;
2103
2104
  declare const TextInput: typeof TextInput$1;
2104
2105
 
2105
- export { type ActionEvent, type ActionHandler, Actions, type Adapter, type AdapterPostableMessage, type Attachment, type Author, BaseFormatConverter, Button, Card, CardChild, CardElement, CardJSXElement, CardText, Chat, type ChatConfig, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, Fields, type FileUpload, type FormatConverter, type FormattedContent, Image, LinkButton, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PostEphemeralOptions, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, Select, SelectOption, type SentMessage, type SerializedMessage, type SerializedThread, type StateAdapter, type StreamOptions, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, TextInput, type Thread, ThreadImpl, type ThreadInfo, type WebhookOptions, type WellKnownEmoji, blockquote, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, emoji, emphasis, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, text, toCardElement, toModalElement, toPlainText, walkAst };
2106
+ export { type ActionEvent, type ActionHandler, Actions, type Adapter, type AdapterPostableMessage, type Attachment, type Author, BaseFormatConverter, Button, Card, CardChild, CardElement, CardJSXElement, CardText, Chat, type ChatConfig, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, Fields, type FileUpload, type FormatConverter, type FormattedContent, Image, LinkButton, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PostEphemeralOptions, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RadioSelect, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, Select, SelectOption, type SentMessage, type SerializedMessage, type SerializedThread, type StateAdapter, type StreamOptions, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, TextInput, type Thread, ThreadImpl, type ThreadInfo, type WebhookOptions, type WellKnownEmoji, blockquote, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, emoji, emphasis, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, text, toCardElement, toModalElement, toPlainText, walkAst };
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  Image,
10
10
  LinkButton,
11
11
  Modal,
12
+ RadioSelect,
12
13
  Section,
13
14
  Select,
14
15
  SelectOption,
@@ -21,7 +22,7 @@ import {
21
22
  isModalElement,
22
23
  toCardElement,
23
24
  toModalElement
24
- } from "./chunk-GGEG4KZT.js";
25
+ } from "./chunk-WKJEG4FE.js";
25
26
 
26
27
  // src/chat-singleton.ts
27
28
  var _singleton = null;
@@ -602,7 +603,12 @@ var ThreadImpl = class _ThreadImpl {
602
603
  postable = card;
603
604
  }
604
605
  const rawMessage = await this.adapter.postMessage(this.id, postable);
605
- return this.createSentMessage(rawMessage.id, postable, rawMessage.threadId);
606
+ const result = this.createSentMessage(
607
+ rawMessage.id,
608
+ postable,
609
+ rawMessage.threadId
610
+ );
611
+ return result;
606
612
  }
607
613
  async postEphemeral(user, message, options) {
608
614
  const { fallbackToDM } = options;
@@ -1335,18 +1341,21 @@ var Chat = class {
1335
1341
  }
1336
1342
  }
1337
1343
  /**
1338
- * Store modal context server-side and return a context ID.
1344
+ * Store modal context server-side with a context ID.
1339
1345
  * Called when opening a modal to preserve thread/message for the submit handler.
1340
1346
  */
1341
- async storeModalContext(adapterName, thread, message) {
1342
- const contextId = crypto.randomUUID();
1347
+ storeModalContext(adapterName, contextId, thread, message) {
1343
1348
  const key = `modal-context:${adapterName}:${contextId}`;
1344
1349
  const context = {
1345
1350
  thread: thread.toJSON(),
1346
1351
  message: message?.toJSON()
1347
1352
  };
1348
- await this._stateAdapter.set(key, context, MODAL_CONTEXT_TTL_MS);
1349
- return contextId;
1353
+ this._stateAdapter.set(key, context, MODAL_CONTEXT_TTL_MS).catch((err) => {
1354
+ this.logger.error("Failed to store modal context", {
1355
+ contextId,
1356
+ error: err
1357
+ });
1358
+ });
1350
1359
  }
1351
1360
  /**
1352
1361
  * Retrieve and delete modal context from server-side storage.
@@ -1388,20 +1397,21 @@ var Chat = class {
1388
1397
  });
1389
1398
  return;
1390
1399
  }
1391
- const [isSubscribed, fetchedMessage] = await Promise.all([
1392
- this._stateAdapter.isSubscribed(event.threadId),
1393
- event.messageId && event.adapter.fetchMessage ? event.adapter.fetchMessage(event.threadId, event.messageId).catch((err) => {
1394
- this.logger.warn("Failed to fetch message for action event", {
1395
- messageId: event.messageId,
1396
- error: err
1397
- });
1398
- return null;
1399
- }) : Promise.resolve(null)
1400
- ]);
1400
+ const isSubscribed = false;
1401
+ const messageForThread = event.messageId ? new Message({
1402
+ id: event.messageId,
1403
+ threadId: event.threadId,
1404
+ text: "",
1405
+ formatted: { type: "root", children: [] },
1406
+ raw: event.raw,
1407
+ author: event.user,
1408
+ metadata: { dateSent: /* @__PURE__ */ new Date(), edited: false },
1409
+ attachments: []
1410
+ }) : {};
1401
1411
  const thread = await this.createThread(
1402
1412
  event.adapter,
1403
1413
  event.threadId,
1404
- fetchedMessage ?? {},
1414
+ messageForThread,
1405
1415
  isSubscribed
1406
1416
  );
1407
1417
  const fullEvent = {
@@ -1426,10 +1436,28 @@ var Chat = class {
1426
1436
  }
1427
1437
  modalElement = converted;
1428
1438
  }
1429
- const recentMessage = thread.recentMessages[0];
1430
- const message = recentMessage && typeof recentMessage.toJSON === "function" ? recentMessage : void 0;
1431
- const contextId = await this.storeModalContext(
1439
+ const isEphemeralMessage = event.messageId?.startsWith("ephemeral:");
1440
+ let message;
1441
+ if (isEphemeralMessage) {
1442
+ const recentMessage = thread.recentMessages[0];
1443
+ if (recentMessage && typeof recentMessage.toJSON === "function") {
1444
+ message = recentMessage;
1445
+ }
1446
+ } else if (event.messageId && event.adapter.fetchMessage) {
1447
+ const fetched = await event.adapter.fetchMessage(event.threadId, event.messageId).catch(() => null);
1448
+ if (fetched) {
1449
+ message = new Message(fetched);
1450
+ } else {
1451
+ const recentMessage = thread.recentMessages[0];
1452
+ if (recentMessage && typeof recentMessage.toJSON === "function") {
1453
+ message = recentMessage;
1454
+ }
1455
+ }
1456
+ }
1457
+ const contextId = crypto.randomUUID();
1458
+ this.storeModalContext(
1432
1459
  event.adapter.name,
1460
+ contextId,
1433
1461
  thread,
1434
1462
  message
1435
1463
  );
@@ -2168,6 +2196,7 @@ var toModalElement2 = toModalElement;
2168
2196
  var fromReactModalElement2 = fromReactModalElement;
2169
2197
  var isModalElement2 = isModalElement;
2170
2198
  var Modal2 = Modal;
2199
+ var RadioSelect2 = RadioSelect;
2171
2200
  var Select2 = Select;
2172
2201
  var SelectOption2 = SelectOption;
2173
2202
  var TextInput2 = TextInput;
@@ -2191,6 +2220,7 @@ export {
2191
2220
  Message,
2192
2221
  Modal2 as Modal,
2193
2222
  NotImplementedError,
2223
+ RadioSelect2 as RadioSelect,
2194
2224
  RateLimitError,
2195
2225
  Section2 as Section,
2196
2226
  Select2 as Select,