composeai 0.1.4 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -30,6 +30,8 @@ interface ComposerIcons {
30
30
  stop: IconComponent;
31
31
  /** Toolbar: attach any file. */
32
32
  attach: IconComponent;
33
+ /** Compact variant: the "+" trigger that opens the quick-actions popover. */
34
+ plus: IconComponent;
33
35
  /** Toolbar: pick an image. */
34
36
  image: IconComponent;
35
37
  /** Voice plugin: start recording. */
@@ -291,9 +293,24 @@ interface MentionConfig {
291
293
  trigger?: string;
292
294
  /** Limit suggestion count. Defaults to 8. */
293
295
  maxItems?: number;
296
+ /**
297
+ * When true, serialize mentions to markdown as a link that carries the
298
+ * stable id — `[<trigger><label>](mention:<id>)`, e.g. `[@orca](mention:u_42)`
299
+ * — so the receiving end can resolve mentions by id and render them as
300
+ * clickable chips. Default (false/omitted) keeps the plain `<trigger><label>`
301
+ * form. Only affects the `markdown` field of the submit payload; the
302
+ * structured `mentions: MentionRef[]` array is unchanged either way.
303
+ */
304
+ linkedMention?: boolean;
294
305
  }
295
306
  interface SlashConfig {
296
307
  items: SlashCommand[] | ((query: string) => SlashCommand[] | Promise<SlashCommand[]>);
308
+ /**
309
+ * The symbol that opens this menu. Defaults to `"/"`. Any single character
310
+ * works — `"/"` for commands, `"#"` for issues/tags, `":"` for emoji, etc.
311
+ * When registering {@link ComposerFeatures.slashCommands | multiple configs},
312
+ * give each a DISTINCT trigger.
313
+ */
297
314
  trigger?: string;
298
315
  maxItems?: number;
299
316
  }
@@ -514,16 +531,101 @@ interface GhostedAutoCompleteConfig {
514
531
  */
515
532
  minLength?: number;
516
533
  }
534
+ /**
535
+ * Editor helpers handed to a {@link CustomAction} when it's clicked, so a
536
+ * custom toolbar button can mutate the composer the same way a slash command
537
+ * can. All three are safe to call outside any Lexical update scope — they wrap
538
+ * `editor.update(...)` internally.
539
+ */
540
+ interface CustomActionContext {
541
+ /** Insert plain text at the current selection. */
542
+ insertText: (text: string) => void;
543
+ /**
544
+ * Insert markdown at the current selection. Multi-line aware: each newline
545
+ * becomes a real paragraph break so fences / lists / headings form.
546
+ */
547
+ insertMarkdown: (markdown: string) => void;
548
+ /** Submit the composer immediately (same pipeline as the Send button). */
549
+ submit: () => void;
550
+ }
551
+ /**
552
+ * A consumer-defined toolbar action. Renders as a button in the `full`
553
+ * variant's toolbar and as a row in the compact variant's "+" popover, placed
554
+ * between the built-in actions and `toolbarExtras`.
555
+ *
556
+ * @example
557
+ * ```tsx
558
+ * features={{
559
+ * custom: [
560
+ * {
561
+ * title: "Insert template",
562
+ * icon: <FileIcon />,
563
+ * onClick: ({ insertMarkdown }) => insertMarkdown("## Summary\n- "),
564
+ * },
565
+ * {
566
+ * title: "Formal tone",
567
+ * icon: <WandIcon />,
568
+ * active: tone === "formal",
569
+ * onClick: () => setTone((t) => (t === "formal" ? "neutral" : "formal")),
570
+ * },
571
+ * ],
572
+ * }}
573
+ * ```
574
+ */
575
+ interface CustomAction {
576
+ /** Stable identifier (React key). Falls back to the array index if omitted. */
577
+ id?: string;
578
+ /** Tooltip text and accessible label for the control. */
579
+ title: string;
580
+ /** Leading icon — the toolbar button glyph / the menu-row icon. */
581
+ icon: ReactNode;
582
+ /** Click handler. Receives editor helpers ({@link CustomActionContext}). */
583
+ onClick: (ctx: CustomActionContext) => void;
584
+ /** Render in a pressed / highlighted state — for toggle-style actions. */
585
+ active?: boolean;
586
+ /** Disable the control (greyed out, not clickable). */
587
+ disabled?: boolean;
588
+ }
517
589
  interface ComposerFeatures {
518
590
  /** `true` (default) → hybrid mode. Pass a {@link MarkdownConfig} to opt
519
591
  * into `"live"` (Notion-style) or otherwise customise behaviour. */
520
592
  markdown?: boolean | MarkdownConfig;
521
593
  attachments?: boolean | AttachmentsConfig;
522
594
  mentions?: false | MentionConfig;
523
- slashCommands?: false | SlashConfig;
595
+ /**
596
+ * Trigger-driven command menus. Each {@link SlashConfig} binds a trigger
597
+ * symbol (`trigger`, default `"/"`) to a list of {@link SlashCommand}s, and
598
+ * every command runs a callback action via `onSelect(ctx)` when chosen.
599
+ *
600
+ * Pass a SINGLE config for one trigger, or an ARRAY to register **multiple
601
+ * trigger symbols at once** — each with its own menu and actions. This lets a
602
+ * consumer wire, say, `"/"` → commands AND `"#"` → issues side-by-side
603
+ * (alongside the separate `@` mentions menu). Give each config a distinct
604
+ * `trigger`.
605
+ *
606
+ * @example
607
+ * ```tsx
608
+ * features={{
609
+ * slashCommands: [
610
+ * { trigger: "/", items: commands }, // each command's onSelect runs an action
611
+ * { trigger: "#", items: issues }, // insert a link, etc.
612
+ * ],
613
+ * }}
614
+ * ```
615
+ */
616
+ slashCommands?: false | SlashConfig | SlashConfig[];
524
617
  voice?: boolean;
525
618
  mermaid?: boolean | MermaidConfig;
526
619
  web?: boolean;
620
+ /**
621
+ * Consumer-defined toolbar actions. Each entry ({@link CustomAction})
622
+ * renders as a button in the `full` variant's toolbar and as a row in the
623
+ * compact variant's "+" popover, between the built-in actions and
624
+ * `toolbarExtras`. The click handler receives editor helpers
625
+ * ({@link CustomActionContext}) so it can insert text/markdown or submit.
626
+ * Defaults to `[]` (no custom actions).
627
+ */
628
+ custom?: CustomAction[];
527
629
  /**
528
630
  * Inline ghost-text autocomplete suggested from a list. Accepts a plain
529
631
  * `string[]` shorthand or a {@link GhostedAutoCompleteConfig} for
@@ -710,6 +812,27 @@ interface ComposerProps {
710
812
  * `mode` and work in both.
711
813
  */
712
814
  mode?: "markdown" | "text";
815
+ /**
816
+ * Visual layout of the composer card.
817
+ *
818
+ * - `"compact"` (default): a slim chat-bar that reads as a single line
819
+ * and grows as the user types or presses **Shift+Enter**. The quick
820
+ * actions that would otherwise sit in the toolbar (attach, image, web,
821
+ * and any `toolbarExtras`) collapse behind a single **"+"** button that
822
+ * opens a popover; the voice button floats to the right, beside Send.
823
+ * This keeps the resting state to one tidy row while still exposing
824
+ * everything one tap away.
825
+ *
826
+ * - `"full"`: the classic layout — a multi-line editor area with a full
827
+ * toolbar row (all action buttons visible) above the Send button.
828
+ * Honours `multiline` exactly as before (`multiline: false` collapses
829
+ * it to the inline single-row bar).
830
+ *
831
+ * Independent of `multiline`: `variant` controls the *chrome layout*, while
832
+ * `multiline` controls whether newlines are allowed. The compact variant
833
+ * defaults to `multiline: true` so Shift+Enter can grow it.
834
+ */
835
+ variant?: "compact" | "full";
713
836
  /** Toggle / configure built-in plugins. */
714
837
  features?: ComposerFeatures;
715
838
  /** Extra controls rendered after the built-in toolbar buttons. */
@@ -736,24 +859,24 @@ interface ComposerProps {
736
859
  */
737
860
  submitOnEnter?: boolean;
738
861
  /**
739
- * Smart "context-aware" Enter behavior. Defaults to `true`. Only takes
740
- * effect when `multiline` is `true`.
862
+ * Smart list continuation on Enter. Defaults to `true`. Only takes
863
+ * effect in markdown mode when `multiline` is `true`.
864
+ *
865
+ * When the cursor sits inside a list paragraph (`- `, `* `, `+ `, or
866
+ * `N. `), Enter continues the list with the next marker (bullet
867
+ * character preserved, numbers auto-incremented). Pressing Enter on an
868
+ * empty list item exits the list — the marker is cleared and the cursor
869
+ * stays on the now-plain line, where the next Enter sends.
741
870
  *
742
- * - While the editor holds a single line, Enter submits as usual
743
- * (subject to `submitOnEnter`).
744
- * - As soon as the editor contains more than one line, Enter inserts
745
- * a newline instead of submitting, and the user must press
746
- * Cmd/Ctrl+Enter (or click Send) to submit. This prevents
747
- * accidental sends while composing longer messages.
748
- * - In markdown mode, when the cursor sits inside a list paragraph
749
- * (`- `, `* `, `+ `, or `N. `), Enter continues the list with the
750
- * next marker (bullet character preserved, numbers
751
- * auto-incremented). Pressing Enter on an empty list item exits
752
- * the list — the marker is cleared and the cursor stays on the
753
- * now-plain line.
871
+ * This is the ONLY case where plain Enter inserts a line rather than
872
+ * submitting. Everywhere else Enter sends (subject to `submitOnEnter`)
873
+ * regardless of how many lines the draft already holds, and Shift+Enter
874
+ * is the newline gesture. Set to `false` to disable list continuation so
875
+ * Enter inside a bullet sends like anywhere else.
754
876
  *
755
- * Set to `false` to keep Enter's behavior fixed regardless of how many
756
- * lines the user has typed or whether they're inside a list.
877
+ * NOTE: earlier versions also blocked Enter from submitting once the
878
+ * editor held more than one line (forcing Cmd/Ctrl+Enter). That rule was
879
+ * removed — Enter now sends whether the draft is one line or many.
757
880
  */
758
881
  smartNewline?: boolean;
759
882
  /**
@@ -893,4 +1016,4 @@ interface SuggestionRowProps {
893
1016
  }
894
1017
  declare function SuggestionRow({ items, onSelect, className }: SuggestionRowProps): react.JSX.Element;
895
1018
 
896
- export { type Attachment, type AttachmentKind, type AttachmentOptions, type AttachmentStatus, type AttachmentTypeOption, type AttachmentsConfig, Composer, type ComposerFeatures, type ComposerHandle, type ComposerIcons, type ComposerPromptBehavior, type ComposerPromptsConfig, type ComposerProps, type ComposerSlot, type ComposerSlotClassNames, type ComposerSlots, type ComposerSubmitPayload, type ComposerSxMap, type ComposerSxValue, type ComposerTokens, type DiagramRenderer, type GhostedAutoCompleteConfig, type IconComponent, type IconProps, type MarkdownConfig, type MarkdownMode, type MentionConfig, type MentionItem, type MentionRef, type MermaidConfig, type SendButtonRenderProps, type SlashCommand, type SlashCommandContext, type SlashConfig, type StopButtonRenderProps, SuggestionRow, type SuggestionRowProps };
1019
+ export { type Attachment, type AttachmentKind, type AttachmentOptions, type AttachmentStatus, type AttachmentTypeOption, type AttachmentsConfig, Composer, type ComposerFeatures, type ComposerHandle, type ComposerIcons, type ComposerPromptBehavior, type ComposerPromptsConfig, type ComposerProps, type ComposerSlot, type ComposerSlotClassNames, type ComposerSlots, type ComposerSubmitPayload, type ComposerSxMap, type ComposerSxValue, type ComposerTokens, type CustomAction, type CustomActionContext, type DiagramRenderer, type GhostedAutoCompleteConfig, type IconComponent, type IconProps, type MarkdownConfig, type MarkdownMode, type MentionConfig, type MentionItem, type MentionRef, type MermaidConfig, type SendButtonRenderProps, type SlashCommand, type SlashCommandContext, type SlashConfig, type StopButtonRenderProps, SuggestionRow, type SuggestionRowProps };
package/dist/index.d.ts CHANGED
@@ -30,6 +30,8 @@ interface ComposerIcons {
30
30
  stop: IconComponent;
31
31
  /** Toolbar: attach any file. */
32
32
  attach: IconComponent;
33
+ /** Compact variant: the "+" trigger that opens the quick-actions popover. */
34
+ plus: IconComponent;
33
35
  /** Toolbar: pick an image. */
34
36
  image: IconComponent;
35
37
  /** Voice plugin: start recording. */
@@ -291,9 +293,24 @@ interface MentionConfig {
291
293
  trigger?: string;
292
294
  /** Limit suggestion count. Defaults to 8. */
293
295
  maxItems?: number;
296
+ /**
297
+ * When true, serialize mentions to markdown as a link that carries the
298
+ * stable id — `[<trigger><label>](mention:<id>)`, e.g. `[@orca](mention:u_42)`
299
+ * — so the receiving end can resolve mentions by id and render them as
300
+ * clickable chips. Default (false/omitted) keeps the plain `<trigger><label>`
301
+ * form. Only affects the `markdown` field of the submit payload; the
302
+ * structured `mentions: MentionRef[]` array is unchanged either way.
303
+ */
304
+ linkedMention?: boolean;
294
305
  }
295
306
  interface SlashConfig {
296
307
  items: SlashCommand[] | ((query: string) => SlashCommand[] | Promise<SlashCommand[]>);
308
+ /**
309
+ * The symbol that opens this menu. Defaults to `"/"`. Any single character
310
+ * works — `"/"` for commands, `"#"` for issues/tags, `":"` for emoji, etc.
311
+ * When registering {@link ComposerFeatures.slashCommands | multiple configs},
312
+ * give each a DISTINCT trigger.
313
+ */
297
314
  trigger?: string;
298
315
  maxItems?: number;
299
316
  }
@@ -514,16 +531,101 @@ interface GhostedAutoCompleteConfig {
514
531
  */
515
532
  minLength?: number;
516
533
  }
534
+ /**
535
+ * Editor helpers handed to a {@link CustomAction} when it's clicked, so a
536
+ * custom toolbar button can mutate the composer the same way a slash command
537
+ * can. All three are safe to call outside any Lexical update scope — they wrap
538
+ * `editor.update(...)` internally.
539
+ */
540
+ interface CustomActionContext {
541
+ /** Insert plain text at the current selection. */
542
+ insertText: (text: string) => void;
543
+ /**
544
+ * Insert markdown at the current selection. Multi-line aware: each newline
545
+ * becomes a real paragraph break so fences / lists / headings form.
546
+ */
547
+ insertMarkdown: (markdown: string) => void;
548
+ /** Submit the composer immediately (same pipeline as the Send button). */
549
+ submit: () => void;
550
+ }
551
+ /**
552
+ * A consumer-defined toolbar action. Renders as a button in the `full`
553
+ * variant's toolbar and as a row in the compact variant's "+" popover, placed
554
+ * between the built-in actions and `toolbarExtras`.
555
+ *
556
+ * @example
557
+ * ```tsx
558
+ * features={{
559
+ * custom: [
560
+ * {
561
+ * title: "Insert template",
562
+ * icon: <FileIcon />,
563
+ * onClick: ({ insertMarkdown }) => insertMarkdown("## Summary\n- "),
564
+ * },
565
+ * {
566
+ * title: "Formal tone",
567
+ * icon: <WandIcon />,
568
+ * active: tone === "formal",
569
+ * onClick: () => setTone((t) => (t === "formal" ? "neutral" : "formal")),
570
+ * },
571
+ * ],
572
+ * }}
573
+ * ```
574
+ */
575
+ interface CustomAction {
576
+ /** Stable identifier (React key). Falls back to the array index if omitted. */
577
+ id?: string;
578
+ /** Tooltip text and accessible label for the control. */
579
+ title: string;
580
+ /** Leading icon — the toolbar button glyph / the menu-row icon. */
581
+ icon: ReactNode;
582
+ /** Click handler. Receives editor helpers ({@link CustomActionContext}). */
583
+ onClick: (ctx: CustomActionContext) => void;
584
+ /** Render in a pressed / highlighted state — for toggle-style actions. */
585
+ active?: boolean;
586
+ /** Disable the control (greyed out, not clickable). */
587
+ disabled?: boolean;
588
+ }
517
589
  interface ComposerFeatures {
518
590
  /** `true` (default) → hybrid mode. Pass a {@link MarkdownConfig} to opt
519
591
  * into `"live"` (Notion-style) or otherwise customise behaviour. */
520
592
  markdown?: boolean | MarkdownConfig;
521
593
  attachments?: boolean | AttachmentsConfig;
522
594
  mentions?: false | MentionConfig;
523
- slashCommands?: false | SlashConfig;
595
+ /**
596
+ * Trigger-driven command menus. Each {@link SlashConfig} binds a trigger
597
+ * symbol (`trigger`, default `"/"`) to a list of {@link SlashCommand}s, and
598
+ * every command runs a callback action via `onSelect(ctx)` when chosen.
599
+ *
600
+ * Pass a SINGLE config for one trigger, or an ARRAY to register **multiple
601
+ * trigger symbols at once** — each with its own menu and actions. This lets a
602
+ * consumer wire, say, `"/"` → commands AND `"#"` → issues side-by-side
603
+ * (alongside the separate `@` mentions menu). Give each config a distinct
604
+ * `trigger`.
605
+ *
606
+ * @example
607
+ * ```tsx
608
+ * features={{
609
+ * slashCommands: [
610
+ * { trigger: "/", items: commands }, // each command's onSelect runs an action
611
+ * { trigger: "#", items: issues }, // insert a link, etc.
612
+ * ],
613
+ * }}
614
+ * ```
615
+ */
616
+ slashCommands?: false | SlashConfig | SlashConfig[];
524
617
  voice?: boolean;
525
618
  mermaid?: boolean | MermaidConfig;
526
619
  web?: boolean;
620
+ /**
621
+ * Consumer-defined toolbar actions. Each entry ({@link CustomAction})
622
+ * renders as a button in the `full` variant's toolbar and as a row in the
623
+ * compact variant's "+" popover, between the built-in actions and
624
+ * `toolbarExtras`. The click handler receives editor helpers
625
+ * ({@link CustomActionContext}) so it can insert text/markdown or submit.
626
+ * Defaults to `[]` (no custom actions).
627
+ */
628
+ custom?: CustomAction[];
527
629
  /**
528
630
  * Inline ghost-text autocomplete suggested from a list. Accepts a plain
529
631
  * `string[]` shorthand or a {@link GhostedAutoCompleteConfig} for
@@ -710,6 +812,27 @@ interface ComposerProps {
710
812
  * `mode` and work in both.
711
813
  */
712
814
  mode?: "markdown" | "text";
815
+ /**
816
+ * Visual layout of the composer card.
817
+ *
818
+ * - `"compact"` (default): a slim chat-bar that reads as a single line
819
+ * and grows as the user types or presses **Shift+Enter**. The quick
820
+ * actions that would otherwise sit in the toolbar (attach, image, web,
821
+ * and any `toolbarExtras`) collapse behind a single **"+"** button that
822
+ * opens a popover; the voice button floats to the right, beside Send.
823
+ * This keeps the resting state to one tidy row while still exposing
824
+ * everything one tap away.
825
+ *
826
+ * - `"full"`: the classic layout — a multi-line editor area with a full
827
+ * toolbar row (all action buttons visible) above the Send button.
828
+ * Honours `multiline` exactly as before (`multiline: false` collapses
829
+ * it to the inline single-row bar).
830
+ *
831
+ * Independent of `multiline`: `variant` controls the *chrome layout*, while
832
+ * `multiline` controls whether newlines are allowed. The compact variant
833
+ * defaults to `multiline: true` so Shift+Enter can grow it.
834
+ */
835
+ variant?: "compact" | "full";
713
836
  /** Toggle / configure built-in plugins. */
714
837
  features?: ComposerFeatures;
715
838
  /** Extra controls rendered after the built-in toolbar buttons. */
@@ -736,24 +859,24 @@ interface ComposerProps {
736
859
  */
737
860
  submitOnEnter?: boolean;
738
861
  /**
739
- * Smart "context-aware" Enter behavior. Defaults to `true`. Only takes
740
- * effect when `multiline` is `true`.
862
+ * Smart list continuation on Enter. Defaults to `true`. Only takes
863
+ * effect in markdown mode when `multiline` is `true`.
864
+ *
865
+ * When the cursor sits inside a list paragraph (`- `, `* `, `+ `, or
866
+ * `N. `), Enter continues the list with the next marker (bullet
867
+ * character preserved, numbers auto-incremented). Pressing Enter on an
868
+ * empty list item exits the list — the marker is cleared and the cursor
869
+ * stays on the now-plain line, where the next Enter sends.
741
870
  *
742
- * - While the editor holds a single line, Enter submits as usual
743
- * (subject to `submitOnEnter`).
744
- * - As soon as the editor contains more than one line, Enter inserts
745
- * a newline instead of submitting, and the user must press
746
- * Cmd/Ctrl+Enter (or click Send) to submit. This prevents
747
- * accidental sends while composing longer messages.
748
- * - In markdown mode, when the cursor sits inside a list paragraph
749
- * (`- `, `* `, `+ `, or `N. `), Enter continues the list with the
750
- * next marker (bullet character preserved, numbers
751
- * auto-incremented). Pressing Enter on an empty list item exits
752
- * the list — the marker is cleared and the cursor stays on the
753
- * now-plain line.
871
+ * This is the ONLY case where plain Enter inserts a line rather than
872
+ * submitting. Everywhere else Enter sends (subject to `submitOnEnter`)
873
+ * regardless of how many lines the draft already holds, and Shift+Enter
874
+ * is the newline gesture. Set to `false` to disable list continuation so
875
+ * Enter inside a bullet sends like anywhere else.
754
876
  *
755
- * Set to `false` to keep Enter's behavior fixed regardless of how many
756
- * lines the user has typed or whether they're inside a list.
877
+ * NOTE: earlier versions also blocked Enter from submitting once the
878
+ * editor held more than one line (forcing Cmd/Ctrl+Enter). That rule was
879
+ * removed — Enter now sends whether the draft is one line or many.
757
880
  */
758
881
  smartNewline?: boolean;
759
882
  /**
@@ -893,4 +1016,4 @@ interface SuggestionRowProps {
893
1016
  }
894
1017
  declare function SuggestionRow({ items, onSelect, className }: SuggestionRowProps): react.JSX.Element;
895
1018
 
896
- export { type Attachment, type AttachmentKind, type AttachmentOptions, type AttachmentStatus, type AttachmentTypeOption, type AttachmentsConfig, Composer, type ComposerFeatures, type ComposerHandle, type ComposerIcons, type ComposerPromptBehavior, type ComposerPromptsConfig, type ComposerProps, type ComposerSlot, type ComposerSlotClassNames, type ComposerSlots, type ComposerSubmitPayload, type ComposerSxMap, type ComposerSxValue, type ComposerTokens, type DiagramRenderer, type GhostedAutoCompleteConfig, type IconComponent, type IconProps, type MarkdownConfig, type MarkdownMode, type MentionConfig, type MentionItem, type MentionRef, type MermaidConfig, type SendButtonRenderProps, type SlashCommand, type SlashCommandContext, type SlashConfig, type StopButtonRenderProps, SuggestionRow, type SuggestionRowProps };
1019
+ export { type Attachment, type AttachmentKind, type AttachmentOptions, type AttachmentStatus, type AttachmentTypeOption, type AttachmentsConfig, Composer, type ComposerFeatures, type ComposerHandle, type ComposerIcons, type ComposerPromptBehavior, type ComposerPromptsConfig, type ComposerProps, type ComposerSlot, type ComposerSlotClassNames, type ComposerSlots, type ComposerSubmitPayload, type ComposerSxMap, type ComposerSxValue, type ComposerTokens, type CustomAction, type CustomActionContext, type DiagramRenderer, type GhostedAutoCompleteConfig, type IconComponent, type IconProps, type MarkdownConfig, type MarkdownMode, type MentionConfig, type MentionItem, type MentionRef, type MermaidConfig, type SendButtonRenderProps, type SlashCommand, type SlashCommandContext, type SlashConfig, type StopButtonRenderProps, SuggestionRow, type SuggestionRowProps };