@netlify/spark-ui 1.8.2-alpha.0 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { u as a } from "../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
- import { C as t, K as r } from "../../../chunks/ChatInterface.BMDJO4i6.js";
2
+ import { C as t, K as r } from "../../../chunks/ChatInterface.BLB99yBP.js";
3
3
  import '../../../assets/AskNetlify.css';function n(e) {
4
4
  return /* @__PURE__ */ a(
5
5
  r,
@@ -1,6 +1,6 @@
1
1
  import "../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
2
  import "../../../../chunks/hooks.module.DGkdD5n9.js";
3
- import { C as f } from "../../../../chunks/ChatInterface.BMDJO4i6.js";
3
+ import { C as f } from "../../../../chunks/ChatInterface.BLB99yBP.js";
4
4
  import "./QuestionList/questions.js";
5
5
  import "./QuestionList/QuestionList.js";
6
6
  import "./BackButton.js";
@@ -1,3 +1,5 @@
1
- export declare function ChatMessages({ conversation }: {
1
+ import { Ref } from 'preact';
2
+ export declare function ChatMessages({ conversation, lastMessageRef, }: {
2
3
  conversation: any[];
4
+ lastMessageRef: Ref<HTMLDivElement>;
3
5
  }): import("preact").JSX.Element;
@@ -1564,17 +1564,30 @@ f.walkTokens;
1564
1564
  f.parseInline;
1565
1565
  $.parse;
1566
1566
  S.lex;
1567
- function ht({ conversation: n }) {
1568
- return /* @__PURE__ */ w($e, { children: n.map((e, t) => /* @__PURE__ */ w("div", { class: "n-ask-message", children: [
1569
- /* @__PURE__ */ w("div", { class: "n-ask-message-right", children: /* @__PURE__ */ w("div", { class: "n-ask-message-bubble n-ask-user-message", children: /* @__PURE__ */ w("p", { children: e.question }) }) }),
1570
- /* @__PURE__ */ w("div", { class: "n-ask-message-left", children: e.answer ? /* @__PURE__ */ w("div", { class: "n-ask-message-bubble n-ask-bot-message", children: /* @__PURE__ */ w(
1571
- "div",
1572
- {
1573
- class: "n-ask-message-answer prose flow",
1574
- dangerouslySetInnerHTML: { __html: f.parse(e.answer) }
1575
- }
1576
- ) }) : /* @__PURE__ */ w("div", { class: "n-ask-message-loader", children: /* @__PURE__ */ w(Se, { name: "askNetlify" }) }) })
1577
- ] }, e.id || `qa-${t}`)) });
1567
+ function ht({
1568
+ conversation: n,
1569
+ lastMessageRef: e
1570
+ }) {
1571
+ return /* @__PURE__ */ w($e, { children: n.map((t, r) => {
1572
+ const s = r === n.length - 1;
1573
+ return /* @__PURE__ */ w("div", { class: "n-ask-message", children: [
1574
+ /* @__PURE__ */ w("div", { class: "n-ask-message-right", children: /* @__PURE__ */ w(
1575
+ "div",
1576
+ {
1577
+ ref: s ? e : null,
1578
+ class: "n-ask-message-bubble n-ask-user-message",
1579
+ children: /* @__PURE__ */ w("p", { children: t.question })
1580
+ }
1581
+ ) }),
1582
+ /* @__PURE__ */ w("div", { class: "n-ask-message-left", children: t.answer ? /* @__PURE__ */ w("div", { class: "n-ask-message-bubble n-ask-bot-message", children: /* @__PURE__ */ w(
1583
+ "div",
1584
+ {
1585
+ class: "n-ask-message-answer prose flow",
1586
+ dangerouslySetInnerHTML: { __html: f.parse(t.answer) }
1587
+ }
1588
+ ) }) : /* @__PURE__ */ w("div", { class: "n-ask-message-loader", children: /* @__PURE__ */ w(Se, { name: "askNetlify" }) }) })
1589
+ ] }, t.id || `qa-${r}`);
1590
+ }) });
1578
1591
  }
1579
1592
  export {
1580
1593
  ht as ChatMessages
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@netlify/spark-ui",
3
3
  "description": "Assets, design tokens, components, and utilities",
4
- "version": "1.8.2-alpha.0",
4
+ "version": "1.8.3",
5
5
  "type": "module",
6
6
  "main": "dist/components/preact/index.js",
7
7
  "types": "dist/components/preact/index.d.ts",
@@ -68,4 +68,4 @@
68
68
  "prettier": "^3.5.3",
69
69
  "prettier-plugin-astro": "^0.14.1"
70
70
  }
71
- }
71
+ }
@@ -1,4 +1,4 @@
1
- import { useState, useRef } from 'preact/hooks';
1
+ import { useState, useRef, useEffect } from 'preact/hooks';
2
2
  import { useChat } from '@kapaai/react-sdk';
3
3
  import { questions } from './QuestionList/questions';
4
4
  import { QuestionList } from './QuestionList/QuestionList';
@@ -11,8 +11,10 @@ interface Props {
11
11
 
12
12
  export default function ChatInterface({ setModalState }: Props) {
13
13
  const [message, setMessage] = useState('');
14
+ const [newMessageReady, setNewMessageReady] = useState(false);
14
15
  const chatRef = useRef<HTMLDivElement>(null);
15
16
  const menuRef = useRef<HTMLUListElement>(null);
17
+ const lastMessageRef = useRef<HTMLDivElement | null>(null);
16
18
 
17
19
  const { conversation, submitQuery, isGeneratingAnswer, isPreparingAnswer, stopGeneration } =
18
20
  useChat();
@@ -27,8 +29,21 @@ export default function ChatInterface({ setModalState }: Props) {
27
29
  submitQuery(text.trim());
28
30
  }
29
31
  if (!id) setMessage('');
32
+
33
+ setNewMessageReady(true);
30
34
  };
31
35
 
36
+ /*
37
+ * When a new user message is ready, scroll it into view and reset the flag.
38
+ * This ensures the most recent message is visible to the user immediately after rendering.
39
+ */
40
+ useEffect(() => {
41
+ if (newMessageReady && lastMessageRef.current) {
42
+ lastMessageRef.current.scrollIntoView({ behavior: 'smooth' });
43
+ setNewMessageReady(false);
44
+ }
45
+ }, [newMessageReady]);
46
+
32
47
  return (
33
48
  <div className="n-ask-chat-container">
34
49
  <BackButton onClick={() => setModalState?.({ current: 'search' })} />
@@ -36,7 +51,7 @@ export default function ChatInterface({ setModalState }: Props) {
36
51
  {!conversation.length ? (
37
52
  <QuestionList onClick={handleSubmit} menuRef={menuRef} />
38
53
  ) : (
39
- <ChatMessages conversation={conversation} />
54
+ <ChatMessages conversation={conversation} lastMessageRef={lastMessageRef} />
40
55
  )}
41
56
  </div>
42
57
 
@@ -1,33 +1,46 @@
1
1
  import { marked } from 'marked';
2
2
  import Icon from '../../Icon';
3
+ import { Ref } from 'preact';
3
4
 
4
- export function ChatMessages({ conversation }: { conversation: any[] }) {
5
+ export function ChatMessages({
6
+ conversation,
7
+ lastMessageRef,
8
+ }: {
9
+ conversation: any[];
10
+ lastMessageRef: Ref<HTMLDivElement>;
11
+ }) {
5
12
  return (
6
13
  <>
7
- {conversation.map((qa, index) => (
8
- <div key={qa.id || `qa-${index}`} class="n-ask-message">
9
- <div class="n-ask-message-right">
10
- <div class="n-ask-message-bubble n-ask-user-message">
11
- <p>{qa.question}</p>
14
+ {conversation.map((qa, index) => {
15
+ const isLastMessage = index === conversation.length - 1;
16
+ return (
17
+ <div key={qa.id || `qa-${index}`} class="n-ask-message">
18
+ <div class="n-ask-message-right">
19
+ <div
20
+ ref={isLastMessage ? lastMessageRef : null}
21
+ class="n-ask-message-bubble n-ask-user-message"
22
+ >
23
+ <p>{qa.question}</p>
24
+ </div>
12
25
  </div>
13
- </div>
14
26
 
15
- <div class="n-ask-message-left">
16
- {qa.answer ? (
17
- <div class="n-ask-message-bubble n-ask-bot-message">
18
- <div
19
- class="n-ask-message-answer prose flow"
20
- dangerouslySetInnerHTML={{ __html: marked.parse(qa.answer) }}
21
- />
22
- </div>
23
- ) : (
24
- <div class="n-ask-message-loader">
25
- <Icon name="askNetlify" />
26
- </div>
27
- )}
27
+ <div class="n-ask-message-left">
28
+ {qa.answer ? (
29
+ <div class="n-ask-message-bubble n-ask-bot-message">
30
+ <div
31
+ class="n-ask-message-answer prose flow"
32
+ dangerouslySetInnerHTML={{ __html: marked.parse(qa.answer) }}
33
+ />
34
+ </div>
35
+ ) : (
36
+ <div class="n-ask-message-loader">
37
+ <Icon name="askNetlify" />
38
+ </div>
39
+ )}
40
+ </div>
28
41
  </div>
29
- </div>
30
- ))}
42
+ );
43
+ })}
31
44
  </>
32
45
  );
33
46
  }